仅在 MacOS Sierra 上调用 AudioConverterFillComplexBuffer 导致 CrashIfClientProvidedBogusAudioBufferList
Call to AudioConverterFillComplexBuffer results in CrashIfClientProvidedBogusAudioBufferList only on MacOS Sierra
我有一个音频程序使用以下代码调用 AudioConverterFillComplexBuffer:
OSStatus error = AudioConverterFillComplexBuffer(recorderObj->audioConverter,
MyAudioConverterCallback,
(__bridge void *)playerLocal,
&ioOutputDataPackets,
convertedData,
&streamDesc);
当此代码在 10.6-10.11 上运行时,它工作正常。当代码在 10.12 上运行时,它会崩溃并显示以下消息
Crashed Thread: 16 com.apple.audio.IOThread.client
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [0]
调用堆栈在 CrashIfClientProvidedBogusAudioBufferList 中结束。
大多数文章、文档和邮件列表都会说我的输出缓冲区不好,但就我的生活而言,我不知道我会做错什么,但我的代码仍然可以在所有版本的 MacOS 上运行,但最新的。这是我设置缓冲区的方式:
AudioBufferList *convertedData = (AudioBufferList*)malloc(sizeof(AudioBufferList) * 2);
convertedData->mNumberBuffers = 1;
convertedData->mBuffers[0].mNumberChannels = 2;
convertedData->mBuffers[0].mDataByteSize = 64 * 1024;
convertedData->mBuffers[0].mData = (UInt8 *)malloc(sizeof(UInt8) * 64 * 1024);
这是崩溃时的完整堆栈
Thread 16 Crashed:: com.apple.audio.IOThread.client
0 com.apple.audio.toolbox.AudioToolbox 0x00007fff89b9a330 CADebuggerStop() + 4
1 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a21e71 CrashIfClientProvidedBogusAudioBufferList + 97
2 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f710 AudioConverterChain::CallInputProc(unsigned int) + 646
3 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f386 AudioConverterChain::FillBufferFromInputProc(unsigned int*, CABufferList*) + 130
4 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f2ee BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) + 178
5 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f1b2 CBRConverter::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) + 106
6 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
7 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f2c3 BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) + 135
8 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a9369b Resampler2Wrapper::RenderOutput(CABufferList*, unsigned int, unsigned int&) + 183
9 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
10 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f2c3 BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) + 135
11 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f1b2 CBRConverter::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) + 106
12 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
13 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2253f AudioConverterChain::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) + 99
14 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
15 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a21d2f AudioConverterFillComplexBuffer + 282
16 com.pc-intercom.Intercom 0x0000000107a52803 0x107a4a000 + 34819
17 com.apple.audio.units.Components 0x000000010a38c97c AUHAL::AUIOProc(unsigned int, AudioTimeStamp const*, AudioBufferList const*, AudioTimeStamp const*, AudioBufferList*, AudioTimeStamp const*, void*) + 2324
18 com.apple.audio.CoreAudio 0x00007fff8a71f951 HALC_ProxyIOContext::IOWorkLoop() + 4369
19 com.apple.audio.CoreAudio 0x00007fff8a71e667 HALC_ProxyIOContext::IOThreadEntry(void*) + 131
20 com.apple.audio.CoreAudio 0x00007fff8a71e38b HALB_IOThread::Entry(void*) + 75
21 libsystem_pthread.dylib 0x0000000108134aab _pthread_body + 180
22 libsystem_pthread.dylib 0x00000001081349f7 _pthread_start + 286
23 libsystem_pthread.dylib 0x0000000108134221 thread_start + 13
如果有人对我如何调试此问题有任何建议,我将不胜感激。
在 MyAudioConverterCallback
中,ioDataPacketCount
应该是 LPCM 的 return 帧(我猜数据包 是未压缩音频的 帧),所以将其设置为:
*ioDataPacketCount = recorderObj->inputBuffer->mBuffers[0].mDataByteSize/recorderObj->streamFormat.mBytesPerFrame;
将 NULL
AudioStreamPacketDescription
传递给 AudioConverterFillComplexBuffer
而不是 1 的数组(这导致我在 10.11 上崩溃)。您的目标格式是 LPCM,因此不需要数据包描述,因为您的 "packets" 都是相同的大小。
同样,您的源格式也是 LPCM,因此您可以删除 MyAudioConverterCallback
中 return 数据包描述的代码 - 它也是错误的。
在我的机器上,我得到 streamFormat
的非交错立体声,这意味着 MyAudioConverterCallback
也必须填写 ioData->mBuffers[1]
。
设置 convertedData
AudioBufferList
时,sizePerPacket
使用源格式数据包大小而不是目标数据包大小。应该是:
sizePerPacket = mOutputFormat.mBytesPerPacket;
最后,即使它没有崩溃,这段代码也不正确,因为你正在从麦克风录制(比如说)512 帧,然后要求音频转换器转换 16384 - 这将为你提供音频故障。
我有一个音频程序使用以下代码调用 AudioConverterFillComplexBuffer:
OSStatus error = AudioConverterFillComplexBuffer(recorderObj->audioConverter,
MyAudioConverterCallback,
(__bridge void *)playerLocal,
&ioOutputDataPackets,
convertedData,
&streamDesc);
当此代码在 10.6-10.11 上运行时,它工作正常。当代码在 10.12 上运行时,它会崩溃并显示以下消息
Crashed Thread: 16 com.apple.audio.IOThread.client
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [0]
调用堆栈在 CrashIfClientProvidedBogusAudioBufferList 中结束。
大多数文章、文档和邮件列表都会说我的输出缓冲区不好,但就我的生活而言,我不知道我会做错什么,但我的代码仍然可以在所有版本的 MacOS 上运行,但最新的。这是我设置缓冲区的方式:
AudioBufferList *convertedData = (AudioBufferList*)malloc(sizeof(AudioBufferList) * 2);
convertedData->mNumberBuffers = 1;
convertedData->mBuffers[0].mNumberChannels = 2;
convertedData->mBuffers[0].mDataByteSize = 64 * 1024;
convertedData->mBuffers[0].mData = (UInt8 *)malloc(sizeof(UInt8) * 64 * 1024);
这是崩溃时的完整堆栈
Thread 16 Crashed:: com.apple.audio.IOThread.client
0 com.apple.audio.toolbox.AudioToolbox 0x00007fff89b9a330 CADebuggerStop() + 4
1 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a21e71 CrashIfClientProvidedBogusAudioBufferList + 97
2 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f710 AudioConverterChain::CallInputProc(unsigned int) + 646
3 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f386 AudioConverterChain::FillBufferFromInputProc(unsigned int*, CABufferList*) + 130
4 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f2ee BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) + 178
5 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f1b2 CBRConverter::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) + 106
6 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
7 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f2c3 BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) + 135
8 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a9369b Resampler2Wrapper::RenderOutput(CABufferList*, unsigned int, unsigned int&) + 183
9 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
10 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f2c3 BufferedAudioConverter::GetInputBytes(unsigned int, unsigned int&, CABufferList const*&) + 135
11 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2f1b2 CBRConverter::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) + 106
12 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
13 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2253f AudioConverterChain::RenderOutput(CABufferList*, unsigned int, unsigned int&, AudioStreamPacketDescription*) + 99
14 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a2225d BufferedAudioConverter::FillBuffer(unsigned int&, AudioBufferList&, AudioStreamPacketDescription*) + 281
15 com.apple.audio.toolbox.AudioToolbox 0x00007fff89a21d2f AudioConverterFillComplexBuffer + 282
16 com.pc-intercom.Intercom 0x0000000107a52803 0x107a4a000 + 34819
17 com.apple.audio.units.Components 0x000000010a38c97c AUHAL::AUIOProc(unsigned int, AudioTimeStamp const*, AudioBufferList const*, AudioTimeStamp const*, AudioBufferList*, AudioTimeStamp const*, void*) + 2324
18 com.apple.audio.CoreAudio 0x00007fff8a71f951 HALC_ProxyIOContext::IOWorkLoop() + 4369
19 com.apple.audio.CoreAudio 0x00007fff8a71e667 HALC_ProxyIOContext::IOThreadEntry(void*) + 131
20 com.apple.audio.CoreAudio 0x00007fff8a71e38b HALB_IOThread::Entry(void*) + 75
21 libsystem_pthread.dylib 0x0000000108134aab _pthread_body + 180
22 libsystem_pthread.dylib 0x00000001081349f7 _pthread_start + 286
23 libsystem_pthread.dylib 0x0000000108134221 thread_start + 13
如果有人对我如何调试此问题有任何建议,我将不胜感激。
在 MyAudioConverterCallback
中,ioDataPacketCount
应该是 LPCM 的 return 帧(我猜数据包 是未压缩音频的 帧),所以将其设置为:
*ioDataPacketCount = recorderObj->inputBuffer->mBuffers[0].mDataByteSize/recorderObj->streamFormat.mBytesPerFrame;
将 NULL
AudioStreamPacketDescription
传递给 AudioConverterFillComplexBuffer
而不是 1 的数组(这导致我在 10.11 上崩溃)。您的目标格式是 LPCM,因此不需要数据包描述,因为您的 "packets" 都是相同的大小。
同样,您的源格式也是 LPCM,因此您可以删除 MyAudioConverterCallback
中 return 数据包描述的代码 - 它也是错误的。
在我的机器上,我得到 streamFormat
的非交错立体声,这意味着 MyAudioConverterCallback
也必须填写 ioData->mBuffers[1]
。
设置 convertedData
AudioBufferList
时,sizePerPacket
使用源格式数据包大小而不是目标数据包大小。应该是:
sizePerPacket = mOutputFormat.mBytesPerPacket;
最后,即使它没有崩溃,这段代码也不正确,因为你正在从麦克风录制(比如说)512 帧,然后要求音频转换器转换 16384 - 这将为你提供音频故障。