该行AudioDeviceManager *manager = (__bridge AudioDeviceManager *)inRefCon;
导致 EXC_BAD_ACCESS(代码 1)。实际错误是 AudioUnitRender Failed: Unknown (-10863),它转换为 kAUGraphErr_CannotDoInCurrentContext。
这是它发生的回调:
static OSStatus playbackCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {
int i, j;
if(startedCallback && noInterrupt) {
//get a copy of the objectiveC class "self"
AudioDeviceManager *manager = (__bridge AudioDeviceManager *)inRefCon;
//data from input; 16 bit integer, one channel
short signed int * source= (short signed int *)bufferList->mBuffers[0].mData;
inNumberFrames= inNumberFrames<1025?inNumberFrames:1024;
//pre created data stores
float * inputbuf = manager->inputbuf;
// shift old audio data
memmove(inputbuf, inputbuf+inNumberFrames, sizeof(float)*(1024-inNumberFrames));
for (j = 0; j < inNumberFrames; j++) {
inputbuf[j+1024-inNumberFrames] = source[j]*3.0518509475997e-05f; //conversion from 16 bit integer (range up to 32767 either side of 0.0) to float (-1.0 to 1.0)
}
manager->seq_cb(inputbuf, NULL, inNumberFrames, inTimeStamp, manager->seq);
//loop through all the buffers that need to be filled ( in practice, will be one)
for (i = 0 ; i < ioData->mNumberBuffers; i++){
//get the buffer to be filled
AudioBuffer buffer = ioData->mBuffers[i];
//printf("which buf %d numberOfSamples %d channels %d countertest %d \n", i, buffer.mDataByteSize, buffer.mNumberChannels, g_countertest);
//if needed we can get the number of bytes that will fill the buffer using
// int numberOfSamples = ioData->mBuffers[i].mDataByteSize;
//get the buffer and point to it as an UInt32 (as we will be filling it with 32 bit samples)
//if we wanted we could grab it as a 16 bit and put in the samples for left and right seperately
//but the loop below would be for(j = 0; j < inNumberFrames * 2; j++) as each frame is a 32 bit number
//UInt32 *frameBuffer = buffer.mData;
short signed int *frameBuffer = (short signed int *)buffer.mData;
//loop through the buffer and fill the frames
for (j = 0; j < inNumberFrames; j++){
//interleaved stereo, left then right
frameBuffer[2*j] = 0; //mono output; later could have stereo effects
frameBuffer[2*j+1] = 0;
//++g_countertest;
}
}
} else {
//output zeroes while not ready to process input
for (i = 0 ; i < ioData->mNumberBuffers; i++){
AudioBuffer buffer = ioData->mBuffers[i];
short signed int *frameBuffer = (short signed int *)buffer.mData;
//loop through the buffer and fill the frames
for (j = 0; j < inNumberFrames; j++){
short signed int value = 0; //32767.0*0.0;
frameBuffer[2*j] = value;
frameBuffer[2*j+1] = value;
//++g_countertest;
}
}
}
return noErr;
}
您通常可以再次尝试该操作 - 通常是 NEXT 渲染周期
但是每次调用回调时都会引发相同的异常。
堆栈跟踪:
Thread 6 name: AURemoteIO::IOThread
Thread 6 Crashed:
0 libobjc.A.dylib 0x317bcf7a objc_retain + 10
1 Partyscape 0x0006cb36 _ZL16playbackCallbackPvPmPK14AudioTimeStampmmP15AudioBufferList (AudioDeviceManager.mm:80)
2 AudioToolbox 0x366a5326 AUInputElement::PullInput(unsigned long&, AudioTimeStamp const&, unsigned long, unsigned long) + 130
3 AudioToolbox 0x366aa6f6 AUInputFormatConverter2::InputProc(OpaqueAudioConverter*, unsigned long*, AudioBufferList*, AudioStreamPacketDescription**, void*) + 154
4 AudioToolbox 0x3668f31e AudioConverterChain::CallInputProc(unsigned long) + 354
5 AudioToolbox 0x3668f074 AudioConverterChain::FillBufferFromInputProc(unsigned long*, CABufferList*) + 72
6 AudioToolbox 0x3668f01e BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) + 122
7 AudioToolbox 0x366aa5c2 CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) + 74
8 AudioToolbox 0x3668ed4c BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) + 180
9 AudioToolbox 0x3668ee92 AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) + 86
10 AudioToolbox 0x3668ed4c BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) + 180
11 AudioToolbox 0x3668eb22 AudioConverterFillComplexBuffer + 350
12 AudioToolbox 0x367549b0 AUInputFormatConverter2::PullAndConvertInput(AudioTimeStamp const&, unsigned long&, AudioBufferList&, AudioStreamPacketDescription*, bool&) + 104
13 AudioToolbox 0x366aa518 AUConverterBase::RenderBus(unsigned long&, AudioTimeStamp const&, unsigned long, unsigned long) + 896
14 AudioToolbox 0x36745376 AURemoteIO::RenderBus(unsigned long&, AudioTimeStamp const&, unsigned long, unsigned long) + 42
15 AudioToolbox 0x36757d84 AUBase::DoRenderBus(unsigned long&, AudioTimeStamp const&, unsigned long, AUOutputElement*, unsigned long, AudioBufferList&) + 184
16 AudioToolbox 0x3669002e AUBase::DoRender(unsigned long&, AudioTimeStamp const&, unsigned long, unsigned long, AudioBufferList&) + 438
17 AudioToolbox 0x3674592a AURemoteIO::PerformIO(unsigned int, unsigned int, XAudioTimeStamp const&, XAudioTimeStamp const&, int&) + 870
18 AudioToolbox 0x36745a90 AURIOCallbackReceiver_PerformIO + 192
19 AudioToolbox 0x3673ca1e _XPerformIO + 178
20 AudioToolbox 0x366a5cdc mshMIGPerform + 368
21 AudioToolbox 0x36710b96 MSHMIGDispatchMessage + 22
22 AudioToolbox 0x367452ea AURemoteIO::IOThread::Run() + 58
23 AudioToolbox 0x36748f42 AURemoteIO::IOThread::Entry(void*) + 2
24 AudioToolbox 0x36685c9c CAPThread::Entry(CAPThread*) + 208
25 libsystem_c.dylib 0x3414172e _pthread_start + 314
26 libsystem_c.dylib 0x341415e8 thread_start + 0
实际上还有另一个AURemoteIO 线程,它看起来像这样:
Thread 9 name: AURemoteIO::IOThread
Thread 9:
0 libsystem_kernel.dylib 0x382dd004 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x382dd1fa mach_msg + 50
2 AudioToolbox 0x36745312 AURemoteIO::IOThread::Run() + 98
3 AudioToolbox 0x36748f42 AURemoteIO::IOThread::Entry(void*) + 2
4 AudioToolbox 0x36685c9c CAPThread::Entry(CAPThread*) + 208
5 libsystem_c.dylib 0x3414172e _pthread_start + 314
6 libsystem_c.dylib 0x341415e8 thread_start + 0