Ios 停止AudioUnit录制后出错

Ios 停止AudioUnit录制后出错,ios,objective-c,iphone,core-audio,audiounit,Ios,Objective C,Iphone,Core Audio,Audiounit,我正在尝试使用以下代码从iPhone的麦克风获取音频输入: @property (nonatomic) AudioUnit rioUnit; @property (nonatomic) CAStreamBasicDescription outputCASBD; (...) // set our required format - LPCM non-interleaved 32 bit floating point CAStreamBasicDescription outFormat = CA

我正在尝试使用以下代码从iPhone的麦克风获取音频输入:

@property (nonatomic) AudioUnit rioUnit;
@property (nonatomic) CAStreamBasicDescription outputCASBD;

(...)

// set our required format - LPCM non-interleaved 32 bit floating point
CAStreamBasicDescription outFormat = CAStreamBasicDescription(44100, // sample rate
                                                              kAudioFormatLinearPCM, // format id
                                                              4, // bytes per packet
                                                              1, // frames per packet
                                                              4, // bytes per frame
                                                              1, // channels per frame
                                                              32, // bits per channel
                                                            kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved);

try {
    // Open the output unit
    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;

    AudioComponent comp = AudioComponentFindNext(NULL, &desc);

    AudioComponentInstanceNew(comp, &_rioUnit);

    UInt32 one = 1;
    XThrowIfError(AudioUnitSetProperty(_rioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, sizeof(one)), "couldn't enable input on the remote I/O unit");

    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = renderInput;
    callbackStruct.inputProcRefCon = (__bridge void*)self;
    XThrowIfError(AudioUnitSetProperty(_rioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callbackStruct, sizeof(callbackStruct)), "couldn't set remote i/o render callback");

    XThrowIfError(AudioUnitSetProperty(_rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outFormat, sizeof(outFormat)), "couldn't set the remote I/O unit's output client format");
    XThrowIfError(AudioUnitSetProperty(_rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &outFormat, sizeof(outFormat)), "couldn't set the remote I/O unit's input client format");

    XThrowIfError(AudioUnitInitialize(_rioUnit), "couldn't initialize the remote I/O unit");
    XThrowIfError(AudioOutputUnitStart(_rioUnit), "couldn't start the remote I/O unit");
}
catch (CAXException &e) {
    char buf[256];
    fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
}
catch (...) {
    fprintf(stderr, "An unknown error occurred\n");
}

// Allocate our own buffers (1 channel, 16 bits per sample, thus 16 bits per frame, thus 2 bytes per frame).
// Practice learns the buffers used contain 512 frames, if this changes it will be fixed in processAudio.
// will need float for accellerate fft (input is 16 bit signed integer) so make space...
_tempBuffer.mNumberChannels = outFormat.mChannelsPerFrame;
_tempBuffer.mDataByteSize = 512 * outFormat.mBytesPerFrame * 2;
_tempBuffer.mData = malloc( self.tempBuffer.mDataByteSize );
一切都很好,直到我想停止听麦克风输入

我正在这样做:

    AudioOutputUnitStop(_rioUnit);
    AudioUnitUninitialize(_rioUnit);
    AudioComponentInstanceDispose(_rioUnit);
    _rioUnit = nil;
但是我从为
kAudioOutputUnitProperty\u SetInputCallback
定义的回调函数中得到一个错误

错误是:
AURemoteIO::IOThread(14):EXC\u BAD\u访问(code=1,地址=0x800000c)

在我看来,AudioUnit的InputCallback仍然在被调用,即使我正在停止它,对其实例进行单元化和处理


为什么会发生这种情况,以及如何防止在停止、统一化和处置其实例后调用InputCallback?

首先,确保“rioUnit”在停止时的值与在开始时的值相同


正在另一个异步线程中调用音频输入回调。因此,在取消初始化或处理音频单元或任何其他所需的数据结构之前,您可能需要等待线程也停止(这通常发生在不到2个音频缓冲区持续时间内,因此等待的时间可能是合理的)

\u rioUnit=nil;//导致EXC\u坏访问错误

nil
更改为
NULL
解决了问题:

\u rioUnit=NULL;//工作平稳

我从这篇文章中得到了这个想法:


此外,还概述了
Objective-C

nil
NULL
之间的区别。您使用的是曲线图吗?如果是,您是否正在调用AUGraphStop()?我不是。结果是
\u rioUnit=nil是导致问题的原因。将其更改为
\u rioUnit=NULL解决了它。谢谢你的想法,我还认为它没有初始化错误的
\u rioUnit
。然而,事实证明,它实际上并没有正确地对其进行初始化。必须将其设置为
NULL
,而不是
nil
。请参阅我的答案以了解更多详细信息。