I'm working on a software that integrates ofxPDSP engine and i've found a minor issue that appear sometimes on quit. In this software is possible to start and stop the DSP computing, plus is possible to re-configure it, changing the input and output device on the fly, so far no problems with that, but after a session whith device changings and reset/reload of the pdsp::Engine(), on quit appear this:
Thread 9 Crashed:: com.apple.audio.IOThread.client
0 org.example.Mosaic 0x00000001099caad4 pdsp::ExternalInput::copyInterleavedInput(float*, int, int, int const&) + 180
1 org.example.Mosaic 0x0000000109fcc73d pdsp::Engine::audioIn(ofSoundBuffer&) + 109
2 org.example.Mosaic 0x000000010a376b1b ofRtAudioSoundStream::rtAudioCallback(void*, void*, unsigned int, double, unsigned int, void*) + 149
3 org.example.Mosaic 0x000000010b6121e9 RtApiCore::callbackEvent(unsigned int, AudioBufferList const*, AudioBufferList const*) + 345
4 org.example.Mosaic 0x000000010b611537 callbackHandler(unsigned int, AudioTimeStamp const*, AudioBufferList const*, AudioTimeStamp const*, AudioBufferList*, AudioTimeStamp const*, void*) + 23
5 com.apple.audio.CoreAudio 0x00007fff8eea68ce HALC_ProxyIOContext::IOWorkLoop() + 5290
6 com.apple.audio.CoreAudio 0x00007fff8eea5264 HALC_ProxyIOContext::IOThreadEntry(void*) + 128
7 com.apple.audio.CoreAudio 0x00007fff8eea4fa3 HALB_IOThread::Entry(void*) + 75
8 libsystem_pthread.dylib 0x00007fffa530d93b _pthread_body + 180
9 libsystem_pthread.dylib 0x00007fffa530d887 _pthread_start + 286
10 libsystem_pthread.dylib 0x00007fffa530d08d thread_start + 13
and this:
Thread 9 Crashed:: com.apple.audio.IOThread.client
0 org.example.Mosaic 0x000000010127cb9f pdsp::ExternalInput::process(int) + 31
1 org.example.Mosaic 0x0000000101277265 pdsp::InputNode::process() + 293
2 org.example.Mosaic 0x000000010127d3f2 pdsp::PatchNode::process(int) + 18
3 org.example.Mosaic 0x000000010127dfbd pdsp::Processor::processAndCopyInterleaved(float*, int const&, int const&) + 173
4 org.example.Mosaic 0x000000010187e6bc pdsp::Engine::audioOut(ofSoundBuffer&) + 428
5 org.example.Mosaic 0x0000000101c28bc3 ofRtAudioSoundStream::rtAudioCallback(void*, void*, unsigned int, double, unsigned int, void*) + 301
6 org.example.Mosaic 0x0000000102ec41e9 RtApiCore::callbackEvent(unsigned int, AudioBufferList const*, AudioBufferList const*) + 345
7 org.example.Mosaic 0x0000000102ec3537 callbackHandler(unsigned int, AudioTimeStamp const*, AudioBufferList const*, AudioTimeStamp const*, AudioBufferList*, AudioTimeStamp const*, void*) + 23
8 com.apple.audio.CoreAudio 0x00007fff8eea68ce HALC_ProxyIOContext::IOWorkLoop() + 5290
9 com.apple.audio.CoreAudio 0x00007fff8eea5264 HALC_ProxyIOContext::IOThreadEntry(void*) + 128
10 com.apple.audio.CoreAudio 0x00007fff8eea4fa3 HALB_IOThread::Entry(void*) + 75
11 libsystem_pthread.dylib 0x00007fffa530d93b _pthread_body + 180
12 libsystem_pthread.dylib 0x00007fffa530d887 _pthread_start + 286
13 libsystem_pthread.dylib 0x00007fffa530d08d thread_start + 13
Where the first one is related to the engine audioIn() method and the second one to the audioOut().
So i've tried first the engine.close() and engine.stop() methods on exit but they hangs and forced me to force quit the app.
Then i've dig a little in the code and i've found an easy solution:
- the audioIn() method execute the copyInterleavedInput() call only if we have at least one input channel
- the audioOut() method execute the processAndCopyInterleaved() call always
So i've modified the Engine.cpp adding a conditional that leave the processAndCopyInterleaved() call alone if there are no putput channels:
if(outputChannels > 0){
processor.processAndCopyInterleaved(outBuffer.getBuffer().data(), outBuffer.getNumChannels(), outBuffer.getNumFrames());
}
Then, i've just added a engine->setChannels(0,0); in the exit() call, so just before quitting, neither audioIn() nor audioOut() engine calls will cause the issue.
Don't now if is the optimal solution or if this is happening because i've done something wrong, but the fix logic do no harm.
Anyway, i hope this helps in some way the development of your amazing addon, thanks for sharing.