Home > Net >  Stopping a `CallbackInstrument` prior to setting `AVAudioSession.setActive(false)`
Stopping a `CallbackInstrument` prior to setting `AVAudioSession.setActive(false)`

Time:08-26

In attempt to pause my signal chain when a user puts the app into the background, or is interrupted by a phone call, I am trying to handle the interruption by stopping all playing nodes and setting the AVAudioSession().setActive(false) as per convention.

It seems fine to call stop() on all nodes except CallbackInstrument, which crashes at line 231 of DSPBase.cpp in *CAudioKitEX from the AudioKitEX repo :

void DSPBase::processOrBypass(AUAudioFrameCount frameCount, AUAudioFrameCount bufferOffset) {

    if (isStarted) {
        process(FrameRange{bufferOffset, frameCount});
    } else {

        // Advance all ramps.
        stepRampsBy(frameCount);

        // Copy input to output.
        if (inputBufferLists.size() and !bCanProcessInPlace) {
            for (int channel=0; channel< channelCount;   channel) {
                auto input = (const float *)inputBufferLists[0]->mBuffers[channel].mData   bufferOffset;
                auto output = (float *)outputBufferList->mBuffers[channel].mData   bufferOffset;
                std::copy(input, input frameCount, output);
            }
        }

        // Generators should be silent.
        if (inputBufferLists.empty()) {
            zeroOutput(frameCount, bufferOffset);
        }
    }

}

My CallbackInstrument is attached to a Sequencer as a discrete track. The crash occurs when the sequencer is playing and I put the app into background, which is attempting to stop all current sequencers, stop all active nodes prior to calling AVAudioSession.setSession(false). I would simply ignore this and/or not stop CallbackInstrument however, by not attempting to stop or reset the CallbackInstrument node, AVAudioSession catches an error:

AVAudioSession_iOS.mm:1271  Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
Error seting audio session false:Error Domain=NSOSStatusErrorDomain Code=560030580 "(null)"

Error code=560030580 refers to AVAudioSessionErrorCodeIsBusy as stated here

Question If stopping a Sequencer with a CallbackInstrument does not in fact stop rendering audio/midi from the callback, how do we safely stop a signal chain with a CallbackInstrument in order to prepare for AVAudioSession.setActive(false)?

I have an example repo of the issue which can be found here.

CodePudding user response:

Nicely presented question by the way :)

Seems like doing it this way does not guarantee that the audioBufferList in process or bypass is populated, while it does report that the size() == 1, its pointer to audioBuferList[0] is nill...

Possibly there should be an additional check for this?

However, if instead of calling stop() on every node in your AudioManager.sleep() if you call engine.stop()

and conversely self.start() in your AudioManager.wake() instead of start on all your nodes... This avoids your error and should stop/start all nodes in the process.

  • Related