mpc As using the same pipe causes issues but attempting to use two pipes (one for audio, one for analogue) causes errors when the code is running.
what error would you get? Two Pipe
s should work just fine, as long as you use two separate AuxiliaryTask
s.
Using one Pipe
is also fine, you should just make sure that you are sending data in exactly the same format and order as you are receiving them. In the example below I send audio first and analog second, and I receive them the same way. The while(1)
with break
is to make sure that if the thread didn't get a chance to run between invocations of render()
, it gets a chance to run and empty the content of gPipe
.
For instance:
void writeBuffer(void*) {
while(1) {
unsigned int numItems = gAudioFrames * gAudioInChannels;
float buf[numItems];
int ret;
if((ret = gPipe.readNonRt(buf, numItems) ) > 0)
{
sf_write_float(outfile, &buf[0], ret);
} else {
break;
}
unsigned int numItemsAn = numAnalogFrames * numAnalogChannels;
float bufAnalog[numItemsAn];
int retAn;
if ((retAn = gPipe.readNonRt(bufAnalog, numItemsAn)) > 0)
{
sf_write_float(outfile, &bufAnalog[0], retAn);
}
}
}
void render(BelaContext* context, void*)
{
...
gPipe.writeRt(context->audioIn, context->audioFrames * context->audioInChannels);
gPipe.writeRt(context->analogIn, context->analogFrames * context->analogInChannels);
...
}
A few notes:
- the code above is thread-safe only as long as it runs on one CPU. If you were to port it to an architecture that uses multiple CPUs, you'd have to be a bit more clever
- if you can accept a (probably minor or insignificant) performance penalty, you could pack all the relevant analog and audio samples in a single buffer and send them with a single
gPIpe.writeRt()
call, which would simplify thewriteBuffer()
function and be thread-safe. If currently you are sending more data than you need (e.g.: you are sending all the analog channels, but you are only using 4), then this solution would actually save some CPU time, instead of causing a performance penalty, as you would reduce the memory that gets copied to the pipe.