2016-05-10 23 views
1

AVAudioEngine(OS X)をすべてのサンプルレートでうまく再生するのに問題があります。AVAudioUnit(OS X)レンダリングブロックは、特定のサンプルレートでのみ呼び出されます。

はここでの接続を構築するための私のコードです:私のオーディオインターフェイスで

- (void)makeAudioConnections { 

    auto hardwareFormat = [self.audioEngine.outputNode outputFormatForBus:0]; 
    auto format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:hardwareFormat.sampleRate channels:2]; 
    NSLog(@"format: %@", format); 

    @try { 
    [self.audioEngine connect:self.avNode to:self.audioEngine.mainMixerNode format:format]; 
    [self.audioEngine connect:self.audioEngine.inputNode to:self.avNode format:format]; 
    } @catch(NSException* e) { 
    NSLog(@"exception: %@", e); 
    } 
} 

、レンダリングコールバックが44.1、48、および176.4kHzのために呼ばれています。それは96と192 kHzのために呼び出されません。ビルトインオーディオでは、コールバックは44.1,48,88では呼び出されず、96では呼び出されません。

私のAUのallocateRenderResourcesAndReturnErrorが96kHzで呼び出されています。エラーは返されません。

- (instancetype)initWithComponentDescription:(AudioComponentDescription)componentDescription options:(AudioComponentInstantiationOptions)options error:(NSError **)outError { 

    self = [super initWithComponentDescription:componentDescription options:options error:outError]; 

    if (self == nil) { 
    return nil; 
    } 

    // Initialize a default format for the busses. 
    AVAudioFormat *defaultFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:44100. channels:2]; 

    // Create the input and output busses. 
    _inputBus.init(defaultFormat, 8); 
    _outputBus = [[AUAudioUnitBus alloc] initWithFormat:defaultFormat error:nil]; 

    // Create the input and output bus arrays. 
    _inputBusArray = [[AUAudioUnitBusArray alloc] initWithAudioUnit:self busType:AUAudioUnitBusTypeInput busses: @[_inputBus.bus]]; 
    _outputBusArray = [[AUAudioUnitBusArray alloc] initWithAudioUnit:self busType:AUAudioUnitBusTypeOutput busses: @[_outputBus]]; 

    self.maximumFramesToRender = 256; 

    return self; 

} 

を簡単にするために、私はアプリを起動する前に、サンプルレートを設定しています:

- (BOOL) allocateRenderResourcesAndReturnError:(NSError * _Nullable *)outError { 

    if(![super allocateRenderResourcesAndReturnError:outError]) { 
    return NO; 
    } 

    _inputBus.allocateRenderResources(self.maximumFramesToRender); 
    _sampleRate = _inputBus.bus.format.sampleRate; 

    return YES; 
} 

ここでは主にちょうどAppleのAUv3デモから&ペーストを切断して、私のAUのinitメソッドは、です。

これを追跡する場所がわかりません。

Xcode project to reproduce issue

あなたは、特定のサンプルレートで入力から引っ張っエラーを取得します:

アップデートは

ここに私がいる問題を再現する小さなプロジェクトです。

96kHzで動作するビルトインオーディオで、511と513のフレームカウントとエラー-10863(kAudioUnitErr_CannotDoInCurrentContext)と-10874(kAudioUnitErr_TooManyFramesToProcess)を交互に使用して、レンダリングブロックが呼び出されます。 maximumFramesToRenderを増やすことは役に立たないようです。

アップデート2

私はダウンだけで、メインのミキサーに入力を接続する私のテストを簡素化:

[self.audioEngine connect:self.audioEngine.inputNode to:self.audioEngine.mainMixerNode format:nil]; 

を私は明示的にフォーマット引数を設定してみました。

これは96kHzで再生されません。だから私はこれがAVAudioEngineのバグかもしれないと思っています。

+0

再生するには、オーディオMIDIセットアップでハードウェアサンプルレートを設定するか、コード内の何かを変更する必要がありますか? –

+0

@RhythmicFistman申し訳ありませんが、明確ではありません。 Audio MIDI Setupでサンプルレートを変更する必要があります。 – Taylor

+0

これで、エラーが発生しました。私の 'AURenderPullInputBlock'は' kAudioUnitErr_TooManyFramesToProcess' = -10874を返しています。なぜならそこにサンプルレートコンバーターがあり、512の代わりに514フレームを引っ張るからです。ストリームを512フレームのチャンクに分割するとどうなりますか?なぜレート変換が私にとって謎なのか、私の出力デバイスは実際には96kHzをサポートしていないかもしれません。 –

答えて

1

AVAudioEngineでのプレイスルーの場合、入出力ハードウェアフォーマットとすべての接続フォーマットは同じサンプルレートでなければなりません。だから次のように動作するはずです。

AVAudioFormat *outputHWFormat = [self.audioEngine.outputNode outputFormatForBus:0]; 
AVAudioFormat *inputHWFormat = [self.audioEngine.inputNode inputFormatForBus:0]; 

if (inputHWFormat.sampleRate == outputHWFormat.sampleRate) { 
    [self.audioEngine connect:self.audioEngine.inputNode to:self.audioEngine.mainMixerNode format:inputHWFormat]; 
    [self.audioEngine connect:self.audioEngine.mainMixerNode to:self.audioEngine.outputNode format:inputHWFormat]; 

} 
+0

なぜif文ですか?サンプルレートが合わないケースを処理したいと思うでしょう。 – Taylor

関連する問題