// This function runs in an auxiliary task on Bela, calling process_fft
void process_fft_background(void *)
{
process_fft(gInputBuffer, gCachedInputBufferPointer, gOutputBuffer, gOutputBufferWritePointer, mode, potValue);
// Update the output buffer write pointer to start at the next hop
gOutputBufferWritePointer = (gOutputBufferWritePointer + gHopSize) % gBufferSize;
}
void render(BelaContext *context, void *userData)
{
// Get the pitch shift in semitones from the GUI slider and convert to ratio
gBaseFrequency = gGuiController.getSliderValue(0);
for(unsigned int n = 0; n < context->audioFrames; n++) {
gPot1 = analogRead(context, n/gAudioFramesPerAnalogFrame, 0);
// detect falling edge of button and cycle through effects
int status = digitalRead(context, n, gButton);
if(status == LOW && gLastButtonStatus == HIGH){
gNumLocation++;
if(gNumLocation >= gNum.size()){
gNumLocation = 0;
}
}
gLastButtonStatus = status;
mode = gNum[gNumLocation];
if(mode==0){
gHopSize = 128;
potValue = map(gPot1, 0, 0.8, 55, 440);
}
if(mode==1){
potValue = map(gPot1, 0, 0.8, 64, 256);
int hopSize = floorf(potValue + 0.5);
// If hop size changes, recalculate the window based on an overlap of 4
if(hopSize != gHopSize){
int newLength = hopSize*4;
if(newLength > gFftSize)
newLength = gFftSize;
recalculate_window(newLength);
gHopSize = hopSize;
}
}
// Read the next sample from the buffer
float in = gPlayer.process();
//float in = 0.5*audioRead(context, n, 0) + 0.5*audioRead(context, n, 1);
// Store the sample ("in") in a buffer for the FFT
// Increment the pointer and when full window has been
// assembled, call process_fft()
gInputBuffer[gInputBufferPointer++] = in;
if(gInputBufferPointer >= gBufferSize) {
// Wrap the circular buffer
// Notice: this is not the condition for starting a new FFT
gInputBufferPointer = 0;
}
// Get the output sample from the output buffer
float out = gOutputBuffer[gOutputBufferReadPointer];
// Then clear the output sample in the buffer so it is ready for the next overlap-add
gOutputBuffer[gOutputBufferReadPointer] = 0;
// Scale the output down by the scale factor, compensating for the overlap
out *= (float)gHopSize / (float)gFftSize;
// Increment the read pointer in the output cicular buffer
gOutputBufferReadPointer++;
if(gOutputBufferReadPointer >= gBufferSize)
gOutputBufferReadPointer = 0;
// Increment the hop counter and start a new FFT if we've reached the hop size
if(++gHopCounter >= gHopSize) {
gHopCounter = 0;
gCachedInputBufferPointer = gInputBufferPointer;
Bela_scheduleAuxiliaryTask(gFftTask);
}
// Write the audio to the output
for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) {
audioWrite(context, n, channel, out);
}
// Log to the Scope
gScope.log(in, out);
}
}
void cleanup(BelaContext *context, void *userData)
{
}