This is an example of a more complex use of the GUI as a controller. The GUI here is used to set a filter's parameters and display its frequency response.
The best way to exerience this example is to play some audio into Bela's audio inputs. A low pass filter is applied to the audio input. If you press the GUI button you will find a control interface which allows you to control the Cutoff frequency (in Hertz) and Q (or resonance) of the filter applied to the audio input. You will hear the effect of the filter.
There are also various controls which allow you to adjust the visualisation of the filter's frequency response. The audio filter is applied in render() and we listen for changes to the settings of the GUI with the guiCallback function.
 
#include <vector>
#include <libraries/Fft/Fft.h>
#include <libraries/Gui/Gui.h>
#include <libraries/Biquad/Biquad.h>
#include <libraries/Pipe/Pipe.h>
#include <stdexcept>
 
 
std::vector<Biquad> gAudioBiquads;
unsigned int kFftLen = 2048;
 
static bool existsAndIsNumber(JSONObject& json, const std::wstring& str)
{
        return (json.find(str) != json.end() && json[str]->IsNumber());
}
static double retrieveAsNumber(JSONObject& json, const std::string& str)
{
        std::wstring ws = JSON::s2ws(str);
        if(existsAndIsNumber(json, ws))
        {
                double ret = json[ws]->AsNumber();
                printf("Received parameter \"%s\": %f\n", str.c_str(), ret);
                return ret;
        }
        else
                throw(std::runtime_error("Value " + str + "not found\n"));
}
 
bool guiCallback(JSONObject& json, void*)
{
        settings.
type = Biquad::lowpass;
        try {
                settings.
cutoff = retrieveAsNumber(json, 
"cutoff");
        } catch (std::exception& e) {}
        try {
                settings.
q = retrieveAsNumber(json, 
"q");
        } catch (std::exception& e) {}
        try {
                settings.
peakGainDb = retrieveAsNumber(json, 
"peakGainDb");
        } catch (std::exception& e) {}
 
        
        gPipe.writeNonRt(settings);
        
        static std::vector<float> ir(kFftLen);
        static std::vector<float> buf(kFftLen / 2);
        fft.setup(kFftLen);
        Biquad analysisBiquad(settings);
 
        for(unsigned int n = 0; n < ir.size(); ++n)
        {
                
                
                ir[n] = analysisBiquad.process(0 == n ? 1 : 0);
        }
        fft.fft(ir);
        float mx = -100000;
        for(unsigned int n = 0; n < buf.size(); ++n)
        {
                buf[n] = fft.fda(n);
                mx = mx < buf[n] ? buf[n] : mx;
        }
        gui.sendBuffer(0, buf);
        return false;
}
 
{
        gPipe.setup("guiToLoop");
        gAudioBiquads.resize(
                        .type = Biquad::lowpass,
                        .cutoff = 6000,
                        .q = 0.707,
                        .peakGainDb = 6,
                })
        );
        gui.setControlDataCallback(guiCallback, nullptr);
        return true;
}
 
{
        
        bool newSettingsReceived = false;
        while(1 == gPipe.readRt(settings))
        {
                newSettingsReceived = true;
                
                
                continue;
        }
        if(newSettingsReceived) {
                for(auto& b : gAudioBiquads)
                {
                        b.setup(settings);
                        b.clean(); 
                }
        }
 
        {
                for(unsigned int c = 0; c < gAudioBiquads.size(); ++c)
                {
                        
                        float out = gAudioBiquads[c].process(in);
                        
                }
        }
}
 
{
}
static float audioRead(BelaContext *context, int frame, int channel)
Read an audio input, specifying the frame number (when to read) and the channel.
Definition Bela.h:1458
static void audioWrite(BelaContext *context, int frame, int channel, float value)
Write an audio output, specifying the frame number (when to write) and the channel.
Definition Bela.h:1469
void render(BelaContext *context, void *userData)
User-defined callback function to process audio and sensor data.
Definition render.cpp:68
bool setup(BelaContext *context, void *userData)
User-defined initialisation function which runs before audio rendering begins.
Definition render.cpp:51
void cleanup(BelaContext *context, void *userData)
User-defined cleanup function which runs when the program finishes.
Definition render.cpp:96
Structure holding audio and sensor settings and pointers to I/O data buffers.
Definition Bela.h:231
const uint32_t audioOutChannels
The number of audio output channels.
Definition Bela.h:326
const uint32_t audioFrames
The number of audio frames per block.
Definition Bela.h:322
const uint32_t audioInChannels
The number of audio input channels.
Definition Bela.h:324
char projectName[MAX_PROJECTNAME_LENGTH]
Name of running project.
Definition Bela.h:417
const float audioSampleRate
The audio sample rate in Hz (currently always 44100.0).
Definition Bela.h:328
double fs
Sample rate in Hz.
Definition Biquad.h:35
double q
Quality factor.
Definition Biquad.h:38
double cutoff
Cutoff in Hz.
Definition Biquad.h:37
Type type
Filter type.
Definition Biquad.h:36
double peakGainDb
Maximum filter gain.
Definition Biquad.h:39