1

Audio Unit サービスを使用して出力レンダリング コールバックをセットアップし、合成オーディオをミックスできるようにしています。私が持っているコードは、私が持っているデバイス (iPod Touch、iPhone 3G、および iPad) では完全に機能するように見えますが、シミュレーターでは機能しません。

シミュレーターでは、AudioUnitInitialise 関数が失敗し、-10851 の値を返します (Apple のドキュメントによると kAudioUnitErr_InvalidPropertyValue)。

これが私の初期化コードです..私がここで間違っていることを見るよりも、このAPIの経験が豊富な人はいますか?

#define kOutputBus 0
#define kInputBus  1 

... 

static OSStatus playbackCallback(void *inRefCon, 
                             AudioUnitRenderActionFlags* ioActionFlags, 
                             const AudioTimeStamp*       inTimeStamp, 
                             UInt32                      inBusNumber, 
                             UInt32                      inNumberFrames, 
                             AudioBufferList*            ioData) 
{
    // Mix audio here - but it never gets here on the simulator
    return noErr;
}

...



{
    OSStatus status;

    // Describe audio component
    AudioComponentDescription desc;
    desc.componentType         = kAudioUnitType_Output;
    desc.componentSubType      = kAudioUnitSubType_RemoteIO;
    desc.componentFlags        = 0;
    desc.componentFlagsMask    = 0;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;

    // Get component
    AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

    // Get audio units
    status = AudioComponentInstanceNew(inputComponent, &m_audio_unit);
    if(status != noErr) {
        NSLog(@"Failed to get audio component instance: %d", status);
    }

    // Enable IO for playback
    UInt32 flag = 1;
    status = AudioUnitSetProperty(m_audio_unit, 
                                  kAudioOutputUnitProperty_EnableIO, 
                                  kAudioUnitScope_Output, 
                                  kOutputBus,
                                  &flag, 
                                  sizeof(flag));
    if(status != noErr) {
        NSLog(@"Failed to enable audio i/o for playback: %d", status);
    }

    // Describe format
    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate       = 44100.00;
    audioFormat.mFormatID         = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags      = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    audioFormat.mFramesPerPacket  = 1;      
    audioFormat.mChannelsPerFrame = 2;
    audioFormat.mBitsPerChannel   = 16;
    audioFormat.mBytesPerPacket   = 4;
    audioFormat.mBytesPerFrame    = 4;      

    // Apply format
    status = AudioUnitSetProperty(m_audio_unit, 
                                  kAudioUnitProperty_StreamFormat, 
                                  kAudioUnitScope_Input, 
                                  kOutputBus, 
                                  &audioFormat, 
                                  sizeof(audioFormat));
    if(status != noErr) {
        NSLog(@"Failed to set format descriptor: %d", status);
    }

    // Set output callback
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc       = playbackCallback;
    callbackStruct.inputProcRefCon = self;
    status = AudioUnitSetProperty(m_audio_unit, 
                                  kAudioUnitProperty_SetRenderCallback, 
                                  kAudioUnitScope_Global, 
                                  kOutputBus,
                                  &callbackStruct, 
                                  sizeof(callbackStruct));
    if(status != noErr) {
        NSLog(@"Failed to set output callback: %d", status);
    }

    // Initialize (This is where it fails on the simulator)
    status = AudioUnitInitialize(m_audio_unit);
    if(status != noErr) {
        NSLog(@"Failed to initialise audio unit: %d", status);
    }

}

XCode のバージョンは 3.2.2 (64 ビット) です。シミュレーターのバージョンは 3.2 です (ただし、3.1.3 のデバッグまたはリリースでも同じ問題が発生します)。

ありがとうございます!

4

3 に答える 3

1

デバイス用とシミュレータ用のコンパイルはまったく異なります。最も一般的なことは、同じ期待される結果をもたらします。たとえば、サウンドを再生するそれらの間にビュースイッチをロードするなどです。ただし、OpenAL を使用して 10 個のバッファーをロードしてサウンドを再生し、それらを切り替えるなどの他のことになると、シミュレーターはそれを処理できませんが、デバイスは処理できます。

私が気にするのは、デバイスで動作する限りです。デバイス上で正常に動作するアプリケーションをシミュレーター上で動作させるためだけに、髪を引っ張らないでください。

それが役立つことを願っています

ピーク

于 2010-09-29T15:50:01.317 に答える
0

RemoteIO 初期化コードを呼び出す前に、オーディオ セッションを構成して有効にしましたか?

于 2010-09-28T06:49:48.607 に答える
0

ストリーム プロパティを入力バスに設定するときはkOutputBus、入力スコープに使用しています。それはおそらく良くない。また、レンダー コールバックをグローバル スコープに適用する必要はおそらくありません。必要なのは出力のためだけだからです。さらに、あなたのkOutputBusとの定義kInputBusは間違っていると思います...動作中の iPhone オーディオ コードを見ると、入力バスに 0 を使用し、出力バスに 1 を使用しています。

また、AudioStreamBasicDescription に関していくつかの小さなことを考えることができますが、これらが大きな違いを生むとは思いません。

  1. kAudioFormatFlagsNativeEndianプロパティをフォーマット フラグに追加します。
  2. フィールドを明示的mReservedに 0 に設定します。
于 2010-09-28T09:10:00.390 に答える