0

私は Core Audio を初めて使用するので、明らかなことはわからないかもしれません… 私の目的は、以前に録音されたオーディオ信号を処理することです。ただし、これらの信号は最初にフィルタリングする必要があります。オーディオを再生する必要はありません。記録して処理するだけです。

私のグラフは次のようになります: RemoteIO --> HighPassFilter --> コールバック (プロセス オーディオ)

そして、私はそれを次のように設定しました:

LBAudioDetectiveGetDefaultFormat(&detective->streamFormat);

// Create new AUGraph
OSStatus error = NewAUGraph(&detective->graph);
LBErrorCheck(error);

// Initialize AUNodes
AudioComponentDescription rioCD = {0};
rioCD.componentType = kAudioUnitType_Output;
rioCD.componentSubType = kAudioUnitSubType_RemoteIO;
rioCD.componentManufacturer = kAudioUnitManufacturer_Apple;

AUNode rioNode;
error = AUGraphAddNode(detective->graph, &rioCD, &rioNode);
LBErrorCheck(error);

AudioComponentDescription filterCD = {0};
filterCD.componentType = kAudioUnitType_Effect;
filterCD.componentSubType = kAudioUnitSubType_HighPassFilter;
filterCD.componentManufacturer = kAudioUnitManufacturer_Apple;

AUNode filterNode;
error = AUGraphAddNode(detective->graph, &filterCD, &filterNode);
LBErrorCheck(error);

// Open the graph so I can modify the AudioUnits
error = AUGraphOpen(detective->graph);

// Adapt rioUnit
error = AUGraphNodeInfo(detective->graph, rioNode, NULL, &detective->rioUnit);
LBErrorCheck(error);

UInt32 onFlag = 1;
AudioUnitElement bus1 = 1;
UInt32 propertySize = sizeof(UInt32);    
error = AudioUnitSetProperty(detective->rioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, bus1, &onFlag, propertySize);
LBErrorCheck(error);

propertySize = sizeof(AudioStreamBasicDescription);
error = AudioUnitSetProperty(detective->rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, bus1, &detective->streamFormat, propertySize);
LBErrorCheck(error);

// Adapt filterUnit
error = AUGraphNodeInfo(detective->graph, filterNode, NULL, &detective->filterUnit);
LBErrorCheck(error);

AURenderCallbackStruct callback = {0};
callback.inputProc = _LBAudioDetectiveFilterOutput;
callback.inputProcRefCon = detective;
propertySize = sizeof(AURenderCallbackStruct);
error = AudioUnitSetProperty(detective->filterUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback, propertySize);
LBErrorCheck(error);

// Connect the two units
AudioUnitElement bus0 = 0;
error = AUGraphConnectNodeInput(detective->graph, rioNode, bus1, filterNode, bus0);
LBErrorCheck(error);

AUGraphInitialize(detective->graph);

コールバックを設定しようとすると、コードがエラー -10879 で失敗します。フィルタ オーディオ ユニットがこのプロパティをサポートしていないと仮定しています。では、録音された音はどのように取得すればよいのでしょうか。私の知る限り、2 番目の汎用出力ユニットは許可されていません。

事前にご協力いただきありがとうございます

4

1 に答える 1

3

(フィルター ユニットまたは入力バスではなく) RemoteIO オーディオ ユニットの出力 (バス 0) でコールバックを構成しますが、その RemoteIO コールバックでは、フィルター ユニットからプル (レンダリング) します。次に、フィルタ ユニットが呼び出され、RemoteIO 入力 (バス 1) から利用可能なデータを取得して処理します。

また、音を鳴らしたくない場合は、出力バッファをゼロで埋めてください。

基本的に、スピーカーからサウンドを再生したくない場合でも、RemoteIO のスピーカー側は、RemoteIO のマイク側のデータに対するコールバックのタイミングを提供します。これは、Audio Unit チェーン全体がプル モデルに基づいている (ADC がデータを API にプッシュする場所がない) ためですが、入力と出力のハードウェア サンプル レートがたまたま同じであるためです。そのため、オーディオ ユニット チェーンがマイク入力バッファからプルするのにちょうどいいタイミングで出力が呼び出されます。

于 2013-04-22T16:08:12.370 に答える