jbm
jbm

Reputation: 1318

AudioKit SynthOne crashes after returning from background

We're using a "skinless" version of AK SynthOne in our app (i.e., just the engine, with a collection of presets), and seeing a consistent crash when returning from background. In order to spare the user's battery when the sequence is not playing, if the user goes to background, we call AudioKit.stop(). This allows the CPU usage to fall to zero (happy customers!), but on returning we see a consistent crash when SynthOne tries to handle its first note:

void S1NoteState::startNoteHelper(int noteNumber, int velocity, float frequency) {
    oscmorph1->freq = frequency;    // <-- EXC_BAD_ACCESS here!
    oscmorph2->freq = frequency;
    subOsc->freq = frequency;
    fmOsc->freq = frequency;

    ...

The backtrace:

* thread #13, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000100fc5d78 Spliqs`S1NoteState::startNoteHelper(this=0x0000000108345500, noteNumber=56, velocity=54, frequency=207.652328) at S1NoteState.mm:105:21
    frame #1: 0x0000000100fd6764 Spliqs`S1DSPKernel::turnOnKey(this=0x00000001088a3790, noteNumber=56, velocity=54, frequency=207.652328) at S1DSPKernel+toggleKeys.mm:85:14
    frame #2: 0x0000000100fcabd0 Spliqs`S1DSPKernel::startNote(this=0x00000001088a3790, noteNumber=56, velocity=54, frequency=207.652328) at S1DSPKernel+startStopNotes.mm:45:9
    frame #3: 0x0000000100fc1298 Spliqs`::-[S1AudioUnit startNote:velocity:frequency:](self=0x00000001088a3600, _cmd="startNote:velocity:frequency:", note='8', velocity='6', frequency=207.652328) at S1AudioUnit.mm:98:13
    frame #4: 0x00000001014cf86c Spliqs`AKSynthOne.play(noteNumber=56, velocity=54, frequency=207.65233610331066, channel=0, self=0x0000000280de4a00) at AKSynthOne.swift:223:21
    frame #5: 0x00000001016dbda4 Spliqs`AudioKit.AKPolyphonicNode.play(noteNumber: Swift.UInt8, velocity: Swift.UInt8, channel: Swift.UInt8) -> () + 328
    frame #6: 0x000000010135a120 Spliqs`Conductor.handleMIDI(data1=146, data2=56, data3=54, self=0x000000010820efe0) at Conductor.swift:392:23
    frame #7: 0x00000001013597a4 Spliqs`Conductor.handle(event=AudioKit.AKMIDIEvent @ 0x000000016f488ba0, self=0x000000010820efe0) at Conductor.swift:374:26
    frame #8: 0x0000000101358de4 Spliqs`closure #1 in Conductor.setUpMIDIHandler(packetList=0x000000016f489e98, _0=nil, self=0x000000010820efe0) at Conductor.swift:326:30
    frame #9: 0x0000000101157f48 Spliqs`thunk for @escaping @callee_guaranteed (@unowned UnsafePointer<MIDIPacketList>, @unowned UnsafeMutableRawPointer?) -> () at <compiler-generated>:0
    frame #10: 0x00000001d42467b8 CoreMIDI`LocalMIDIReceiverList::HandleMIDIIn(unsigned int, unsigned int, void*, MIDIPacketList const*) + 164
    frame #11: 0x00000001d4246618 CoreMIDI`MIDIProcess::RunMIDIInThread() + 132
    frame #12: 0x00000001d425d1e8 CoreMIDI`XThread::RunHelper(void*) + 28
    frame #13: 0x00000001d4262624 CoreMIDI`CAPThread::Entry(CAPThread*) + 92
    frame #14: 0x00000001c3eef908 libsystem_pthread.dylib`_pthread_body + 132
    frame #15: 0x00000001c3eef864 libsystem_pthread.dylib`_pthread_start + 48
    frame #16: 0x00000001c3ef7dcc libsystem_pthread.dylib`thread_start + 4

We've tried everything from just starting AudioKit, through to completely re-initializing SynthOne, but it's always the same.

We've been stuck on this one for a while, so any thoughts greatly appreciated.

UPDATE: Actually, I'm afraid I have to resuscitate this question. Although the .pause() approach in my answer below worked for going to/from background we also have a use-case where we move to offline render mode to export audio. That process definitely does require us to stop the engine (in order to switch modes), and we're getting the same SynthOne-related crash when handling the first event after AudioKit.start(). Does anybody understand why we'd hit an EXC_BAD_ACCESS when returning? I'm guessing that memory has been incorrectly reallocated/reclaimed(?) somehow, but how can I prevent it? I suppose, more broadly, the question would be: how do I safely start/stop the AudioKit engine when using SynthOne.

Upvotes: 2

Views: 96

Answers (1)

jbm
jbm

Reputation: 1318

Erm... yikes... how about .stopEngine() and .startEngine()...? an rtfm moment, for sure.

For anyone who might face a similar problem, these use AudioKit.engine.pause() and AudioKit.engine.start(), as opposed to using stop().

Upvotes: 2

Related Questions