【发布时间】:2019-09-19 19:14:13
【问题描述】:
我们在我们的应用程序中使用了“无皮肤”版本的 AK SynthOne(即,只是引擎,带有一组预设),并且在从后台返回时看到一致的崩溃。为了在序列不播放时节省用户的电池电量,如果用户进入后台,我们调用AudioKit.stop()。这允许 CPU 使用率降至零(客户满意!),但在返回时,当 SynthOne 尝试处理其第一个音符时,我们会看到一致的崩溃:
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;
...
回溯:
* 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
我们尝试了从刚启动 AudioKit 到完全重新初始化 SynthOne 的所有方法,但总是一样。
我们已经在这个问题上停留了一段时间,所以任何想法都非常感谢。
更新:实际上,恐怕我必须重新提出这个问题。尽管我在下面的回答中的.pause() 方法适用于往返后台,但我们也有一个用例,我们可以转为离线渲染模式来导出音频。该过程确实确实需要我们停止引擎(以便切换模式),并且在处理AudioKit.start() 之后的第一个事件时,我们会遇到与 SynthOne 相关的相同崩溃。有谁明白为什么我们在返回时会点击EXC_BAD_ACCESS?我猜内存已经以某种方式被错误地重新分配/回收(?),但我该如何防止呢?
我想,更广泛地说,问题是:使用 SynthOne 时如何安全地启动/停止 AudioKit 引擎。
【问题讨论】: