I need this program to allow me to record audio input and playback the recorded input. I have tried several techniques. The latest involves declaring different functions to call within the main render function but still no luck.
Extremely new to Bela. Have been learning C for a few months and banging my head against a wall with this project.
#include <Bela.h>
#include <libraries/AudioFile/AudioFile.h>
#include <libraries/Gui/Gui.h>
#include <libraries/GuiController/GuiController.h>
#include <libraries/Biquad/Biquad.h>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
// // INIT GUI
//=====================
Gui gui;
GuiController controller;
// INIT GLOBALS
//=====================
std::vector<std::vector<float> > gInputs;
const double gDurationSec = 20; // how many seconds to record.
unsigned int gWrittenFrames = 0; // how many frame have actually been written to gInputs and gOutputs
std::string gFilename = "inputs.wav"; // Name of the sound file (recorded and playback same file name)
std::vector<float> gSampleBuffer; // Buffer that holds the sound file
int gReadPointer = 0; // Position of the last frame we played
int gPlayRecord = 1;
float gVolume = 1;
int gReverse = 0;
// FUNCTION DECLARATIONS
//=====================
void play(BelaContext *context, void *userData);
void record(BelaContext *context, void *userData);
void write(BelaContext *context, void *userData);
// SETUP
//=====================
bool setup(BelaContext *context, void *userData)
{
//PLAYBACK SETUP
// Load the sample from storage into a buffer
gSampleBuffer = AudioFileUtilities::loadMono(gFilename);
// Check if the load succeeded
if (gSampleBuffer.size() == 0)
{
rt_printf("Error loading audio file '%s'\n", gFilename.c_str());
return false;
}
rt_printf("Loaded the audio file '%s' with %d frames (%.1f seconds)\n",
gFilename.c_str(), gSampleBuffer.size(),
gSampleBuffer.size() / context->audioSampleRate);
// Set up the GUI
gui.setup(context->projectName);
controller.setup(&gui, "Sample Controller");
// Arguments: name, default value, minimum, maximum, increment
controller.addSlider("Volume", 1, 0, 1, 0);
controller.addSlider("Reverse", 0, 0, 1, 1);
controller.addSlider("Play or Record", 1, 0, 1, 1);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//RECORD SETUP
// pre-allocate all the memory needed to store the audio data
unsigned int numFrames = context->audioSampleRate * gDurationSec;
gInputs.resize(context->audioInChannels);
// If we have too many channels or too many frames to store, we may run out of RAM and
// the program will fail to start.
try
{
for (auto &c : gInputs)
c.resize(numFrames);
}
catch (std::exception e)
{
fprintf(stderr, "Error while allocating memory. Maybe you are asking to record too many frames and/or too many channels\n");
return false;
}
return true;
}
// RENDER FUNCTION
//=====================
void render(BelaContext *context, void *userData)
{
//GUI MAPPING
gVolume = controller.getSliderValue(0); //map and make logarithmic
gReverse = controller.getSliderValue(1);
gPlayRecord = controller.getSliderValue(2);
// int pos = controller.getSliderValue(1);
// float pitch = controller.getSliderValue(x);
if (gPlayRecord == 1)
{
void record();
}
else if (gPlayRecord == 0)
{
void write();
void play();
}
}
// FUNCTION PROTOTYPES
//=====================
void record(BelaContext *context, void *userData)
{
for(unsigned int n = 0; n < context->audioFrames; ++n)
{
// store audio inputs
for(unsigned int c = 0; c < context->audioInChannels; ++c)
gInputs[c][gWrittenFrames] = audioRead(context, n, c);
}
++gWrittenFrames;
}
void play(BelaContext *context, void *userData)
{
//PLAYBACK RENDER
for (unsigned int n = 0; n < context->audioFrames; n++)
{
// NORMAL PLAYBACK
if (gReverse == 0)
{
gReadPointer++;
if (gReadPointer >= gSampleBuffer.size())
gReadPointer = 0;
}
// REVERSE AUDIO
else
{
gReadPointer--;
if (gReadPointer <= 1)
gReadPointer = gSampleBuffer.size();
}
float out = gSampleBuffer[gReadPointer] * gVolume;
for (unsigned int channel = 0; channel < context->audioOutChannels; channel++)
{
audioWrite(context, n, channel, out);
}
}
}
void write(BelaContext *context, void *userData)
{
for(auto& i : gInputs)
{
i.resize(gWrittenFrames);
AudioFileUtilities::write(gFilename, gInputs, context->audioSampleRate);
return;
}
}
void cleanup(BelaContext *context, void *userData)
{
}