These files demonstrate the ultra-efficient oscillator bank class.
OscillatorBank::init() allocates the needed buffers.
This program can run with a large number of oscillators (> 500, depending on the settings in use). Updating the frequencies of a large number of oscillators from within render(), for every sample or for every block would add significatively to the computational load. For this reason, we factored out the frequency update in an AuxiliaryTask which runs at most every 128 samples. If needed, the AuxiliaryTask will split the load over time across multiple calls to render(), thus avoiding audio dropouts.
 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 
#include <libraries/OscillatorBank/OscillatorBank.h>
 
const float kMinimumFrequency = 20.0f;
const float kMaximumFrequency = 8000.0f;
 
int gSampleCount;               
float gNewMinFrequency;
float gNewMaxFrequency;
 
 
int gNumOscillators = 500;
int gWavetableLength = 1024;
 
void recalculate_frequencies(void*);
{
                rt_printf("Error: this example needs stereo audio enabled\n");
                return false;
        }
 
        srandom(time(NULL));
 
        
        float* wavetable = osc.getWavetable();
        for(int n = 0; n < osc.getWavetableLength() + 1; n++){
                wavetable[n] = sinf(2.0 * M_PI * (float)n / (float)osc.getWavetableLength());
        }
 
        
        float freq = kMinimumFrequency;
        float increment = (kMaximumFrequency - kMinimumFrequency) / (float)gNumOscillators;
        for(int n = 0; n < gNumOscillators; n++) {
                        
                        osc.setFrequency(n, kMinimumFrequency + (kMaximumFrequency - kMinimumFrequency) * ((float)random() / (float)RAND_MAX));
                }
                else {
                        
                        osc.setFrequency(n, freq);
                        freq += increment;
                }
                osc.setAmplitude(n, (float)random() / (float)RAND_MAX / (float)gNumOscillators);
        }
 
        increment = 0;
        freq = 440.0;
 
        for(int n = 0; n < gNumOscillators; n++) {
                
                
                float randScale = 0.99 + .02 * (float)random() / (float)RAND_MAX;
                float newFreq = freq * randScale;
 
                
                osc.setFrequency(n, newFreq);
                freq += increment;
        }
 
        
                return false;
 
        gSampleCount = 0;
 
        return true;
}
 
{
 
        
        for(
unsigned int n = 0; n < context->
audioFrames; ++n){
 
        }
                gSampleCount = 0;
                gNewMinFrequency = 
map(context->
analogIn[0], 0, 1.0, 1000.0f, 8000.0f);
                gNewMaxFrequency = 
map(context->
analogIn[1], 0, 1.0, 1000.0f, 8000.0f);
 
                
                if(gNewMaxFrequency < gNewMinFrequency) {
                        float temp = gNewMaxFrequency;
                        gNewMaxFrequency = gNewMinFrequency;
                        gNewMinFrequency = temp;
                }
 
                
        }
}
 
 
void recalculate_frequencies(void*)
{
        float freq = gNewMinFrequency;
        float increment = (gNewMaxFrequency - gNewMinFrequency) / (float)gNumOscillators;
 
        for(int n = 0; n < gNumOscillators; n++) {
                
                
                float randScale = 0.99 + .02 * (float)random() / (float)RAND_MAX;
                float newFreq = freq * randScale;
 
                osc.setFrequency(n, newFreq);
                freq += increment;
        }
}
 
{}
Definition OscillatorBank.h:20
void * AuxiliaryTask
Definition Bela.h:561
int Bela_scheduleAuxiliaryTask(AuxiliaryTask task)
Run an auxiliary task which has previously been created.
AuxiliaryTask Bela_createAuxiliaryTask(void(*callback)(void *), int priority, const char *name, void *arg=NULL)
Create a new auxiliary task.
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
static float map(float x, float in_min, float in_max, float out_min, float out_max)
Linearly rescale a number from one range of values to another.
Definition Utilities.h:71
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 float *const analogIn
Buffer holding analog input samples.
Definition Bela.h:283
const float audioSampleRate
The audio sample rate in Hz (currently always 44100.0).
Definition Bela.h:328
const uint32_t analogFrames
The number of analog frames per block.
Definition Bela.h:341