7

次のコンテキストで、AudioUnitRender からエラー -50 (無効なパラメーター) が発生します。このPitch Detectorサンプル アプリを出発点として使用していますが、問題なく動作します。私のプロジェクトの唯一の大きな違いは、オーディオ出力にもリモート I/O ユニットを使用していることです。オーディオ出力は正常に機能します。入力コールバックと初期化コードを次に示します (簡潔にするためにエラー チェックを削除しています)。たくさんあることはわかっていますが、エラー -50 からは、問題がどこにあるのかについてほとんど情報が得られません。

入力コールバック:

OSStatus inputCallback( void* inRefCon, 
                            AudioUnitRenderActionFlags  *ioActionFlags, 
                            const AudioTimeStamp        *inTimeStamp, 
                            UInt32                      inBusNumber, 
                            UInt32                      inNumberFrames, 
                            AudioBufferList             *ioData) {

    WBAudio* audioObject= (WBAudio*)inRefCon;

    AudioUnit rioUnit = audioObject->m_audioUnit;
    OSStatus renderErr;
    UInt32 bus1 = 1;

    renderErr = AudioUnitRender(rioUnit, ioActionFlags, 
                                inTimeStamp, bus1, inNumberFrames, audioObject->m_inBufferList );
    if (renderErr < 0) {
        return renderErr; // breaks here
    }

    return noErr;
} // end inputCallback()

初期化:

- (id) init {

    self= [super init];
    if( !self ) return nil;

    OSStatus result;

    //! Initialize a buffer list for rendering input
    size_t bytesPerSample;
    bytesPerSample = sizeof(SInt16);
    m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer));
    m_inBufferList->mNumberBuffers = 1;
    m_inBufferList->mBuffers[0].mNumberChannels = 1;
    m_inBufferList->mBuffers[0].mDataByteSize = 512*bytesPerSample;
    m_inBufferList->mBuffers[0].mData = calloc(512, bytesPerSample);

    //! Initialize an audio session to get buffer size
    result = AudioSessionInitialize(NULL, NULL, NULL, NULL);

    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
    result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);

    // Set preferred buffer size
    Float32 preferredBufferSize = static_cast<float>(m_pBoard->m_uBufferSize) / m_pBoard->m_fSampleRate;
    result = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize);

    // Get actual buffer size
    Float32 audioBufferSize;
    UInt32 size = sizeof (audioBufferSize);
    result = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &size, &audioBufferSize);

    result = AudioSessionSetActive(true);

    //! Create our Remote I/O component description
    AudioComponentDescription desc;
    desc.componentType= kAudioUnitType_Output;
    desc.componentSubType= kAudioUnitSubType_RemoteIO;
    desc.componentFlags= 0;
    desc.componentFlagsMask= 0;
    desc.componentManufacturer= kAudioUnitManufacturer_Apple;

    //! Find the corresponding component
    AudioComponent outputComponent = AudioComponentFindNext(NULL, &desc);

    //! Create the component instance
    result = AudioComponentInstanceNew(outputComponent, &m_audioUnit);

    //! Enable audio output
    UInt32 flag = 1;
    result = AudioUnitSetProperty( m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));

    //! Enable audio input
    result= AudioUnitSetProperty( m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));

    //! Create our audio stream description
    m_audioFormat.mSampleRate= m_pBoard->m_fSampleRate;
    m_audioFormat.mFormatID= kAudioFormatLinearPCM;
    m_audioFormat.mFormatFlags= kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    m_audioFormat.mFramesPerPacket= 1;
    m_audioFormat.mChannelsPerFrame= 1;
    m_audioFormat.mBitsPerChannel= 16;
    m_audioFormat.mBytesPerPacket= 2;
    m_audioFormat.mBytesPerFrame= 2;

    //! Set the stream format
    result = AudioUnitSetProperty( m_audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &m_audioFormat, sizeof(m_audioFormat));

    result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, 
                               kAudioUnitScope_Output, 
                               kInputBus, &m_audioFormat, sizeof(m_audioFormat));

    //! Set the render callback
    AURenderCallbackStruct renderCallbackStruct= {0};
    renderCallbackStruct.inputProc= renderCallback;
    renderCallbackStruct.inputProcRefCon= m_pBoard;
    result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &renderCallbackStruct, sizeof(renderCallbackStruct));

    //! Set the input callback
    AURenderCallbackStruct inputCallbackStruct = {0};
    inputCallbackStruct.inputProc= inputCallback;
    inputCallbackStruct.inputProcRefCon= self;
    result= AudioUnitSetProperty( m_audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Input, kOutputBus, &inputCallbackStruct, sizeof( inputCallbackStruct ) );

    //! Initialize the unit
    result = AudioUnitInitialize( m_audioUnit );

    return self;
}
4

3 に答える 3

0

開発ドキュメントのエラー -50 はパラメーター エラーを意味します。AudioUnitRender で正しいパラメーターを渡していることを確認してください。ストリーム形式とユニットを確認してください

于 2013-09-01T11:45:02.147 に答える
0

m_inBufferList を次のように割り当てています。

m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer));

これは次のようになります。

m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * numberOfBuffers);   //numberOfBuffers in your case is 1

多分これはあなたの問題を解決することができます。

于 2012-04-30T11:24:10.427 に答える