- Edited
Hi all,
I’m still relatively new to Bela and still getting familiar with the programming, so I’m learning as I go at the moment. I’m currently trying to record audio from a lav mic onto Bela utilising the libsndfile API to write to a .WAV file. The .WAV file is being created in the path and the code compiles/runs without error but unfortunately I do not have anything picked up from the microphone and the WAV file is empty. Just to note that no pure data is being used.
At present the mic is plugged into the 3.5mm jack audio adapter cable connected to the stereo audio input on the board. Here is the Lavalier mic that I’m using at the moment: http://www.boya-mic.com/lavaliermicrophones/BY-M1.html
At present I can’t get it to function as intended, so I’m currently slightly stuck on this issue. I know its probably some code that I’m missing.
I was also wondering the best approach with regards to code, for recording from more than the one microphone using the audio expander capelet?
Any help or suggestions would be greatly appreciated. Many thanks.
The current code that I’m using for testing is outlined below for reference:
#include <Bela.h>
#include <cmath>
#include <SampleData.h>
#include <libraries/sndfile/sndfile.h>
#include <cstdlib>
#define NUM_CHANNELS 2 // NUMBER OF CHANNELS IN THE FILE
#define BUFFER_LEN 2048 // BUFFER LENGTH
float bLSort[BUFFER_LEN*2];
int gCount = 1;
float gDuration = 10 * (60 * 44100); //longer duration recording (minutes)
float gFrequency = 440.0;
float gPhase;
float gInverseSampleRate;
// name of file generated
SampleData gSampleBuf[2][NUM_CHANNELS];
//index value of buffer array
int gPos = 1;
//start on second buffer because it will switch on first run through
int gActiveBuffer = 0;
int gDoneLoadingBuffer = 1;
int gChunk = 0;
/////
AuxiliaryTask gFillBufferTask;
SF_INFO sfinfo;
sf_count_t count;
SNDFILE * outfile;
const char* path = "./recording.wav";
void setupFile() {
sfinfo.channels = NUM_CHANNELS;
sfinfo.samplerate = 44100;
sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
}
void closeFile(void*) {
sf_write_sync(outfile);
sf_close(outfile);
printf(".wav file written and closed\n");
}
void writeFile(float *buf, int startSamp, int endSamp){
//calculate duration of write operation
int frameLen = endSamp - startSamp;
sf_write_float(outfile, &buf[0], frameLen);
}
void fillBuffer(void*) {
int end = gChunk + (BUFFER_LEN*2);
for (size_t i = 0; i < BUFFER_LEN; i++) {
bLSort[i*2] = gSampleBuf[!gActiveBuffer][0].samples[i];
bLSort[(i*2)+1] = gSampleBuf[!gActiveBuffer][1].samples[i];
}
writeFile(bLSort, gChunk, end);
//signal the file is written
gDoneLoadingBuffer = 1;
//increment by BUFFER_LEN
gChunk += BUFFER_LEN;
}
bool setup(BelaContext *context, void *userData) {
outfile = sf_open(path, SFM_WRITE, &sfinfo);
//initialise sine variables
gInverseSampleRate = 1.0 / context->audioSampleRate;
gPhase = 0.0;
//initialize auxiliary task
if((gFillBufferTask = Bela_createAuxiliaryTask(&fillBuffer, 90, "fill-buffer")) == 0) {
return false;
}
setupFile();
//initialize sample data struct with buffers/arrays
for(int ch=0;ch<NUM_CHANNELS;ch++) {
for(int i=0;i<2;i++) {
gSampleBuf[i][ch].sampleLen = BUFFER_LEN;
gSampleBuf[i][ch].samples = new float[BUFFER_LEN];
}
}
return true;
}
void render(BelaContext *context, void *userData) {
for(unsigned int n = 0; n < context->audioFrames; n++) {
//Update wrap phase and generate sine wave
float out = 0.8f * sinf(gPhase);
gPhase += 2.0f * (float)M_PI * gFrequency * gInverseSampleRate;
if(gPhase > M_PI) {
gPhase -= 2.0f * (float)M_PI;
//swap buffers when gPos reaches BUFFER_LEN
if(gPos == 0) {
if(!gDoneLoadingBuffer && gCount <= gDuration && gCount > 0) {
printf("increase buffer size!\n");
}
gDoneLoadingBuffer = 0;
gActiveBuffer = !gActiveBuffer;
if (gCount < gDuration) {
Bela_scheduleAuxiliaryTask(gFillBufferTask);
}
}
//if samples counted are more than duration, mute, otherwise output sine and write file
if (gCount > gDuration) {
for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) {
audioWrite(context, n, channel, 0);
}
} else {
gSampleBuf[gActiveBuffer][0].samples[gPos] = out;
for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) {
audioWrite(context, n, channel, out);
}
}
}
gCount++;
gPos = gCount%BUFFER_LEN;
}
}
void cleanup(BelaContext *context, void *userData) {
// Delete the allocated buffers
for(int ch=0;ch<NUM_CHANNELS;ch++) {
for(int i=0;i<2;i++) {
delete[] gSampleBuf[i][ch].samples;
}
}
}