2016-06-16 3 views
1

私はkAudioUnitSubType_LowPassFilterAUGraphに追加しようとしていますが、それには成功しません。AUGraphにkAudioUnitSubType_LowPassFilterを追加するには?

私は、次のコードを実装:

// create a new AUGraph 
[Utilities checkError:NewAUGraph(&self.info->mGraph) 
      operation: "Couldn't create a new AUGraph"]; 

AUNode rioNode; 
AUNode lpfNode; 

// Create filter audio unit 
AudioComponentDescription lpfAU_description; 
lpfAU_description.componentType = kAudioUnitType_Effect; 
lpfAU_description.componentSubType = kAudioUnitSubType_LowPassFilter; 
lpfAU_description.componentFlags = 0; 
lpfAU_description.componentFlagsMask = 0; 
lpfAU_description.componentManufacturer = kAudioUnitManufacturer_Apple; 


// Create RemoteIO audio unit 
AudioComponentDescription rioAU_description; 
rioAU_description.componentType = kAudioUnitType_Output; 
rioAU_description.componentSubType = kAudioUnitSubType_RemoteIO; 
rioAU_description.componentManufacturer = kAudioUnitManufacturer_Apple; 
rioAU_description.componentFlags = 0; 
rioAU_description.componentFlagsMask = 0; 

[Utilities checkError:AUGraphAddNode(self.info->mGraph, &rioAU_description, &rioNode) 
      operation: "Couldn't add Graph Node"]; 
[Utilities checkError:AUGraphAddNode(self.info->mGraph, &lpfAU_description, &lpfNode) 
      operation: "Couldn't add Graph Node"]; 

// Open graph 
[Utilities checkError:AUGraphOpen(self.info->mGraph) 
      operation: "Couldn't open graph"]; 

// Get audio units 
[Utilities checkError:AUGraphNodeInfo(self.info->mGraph, lpfNode, NULL, &self.info->lpfUnit) 
      operation: "Couldn't link node to audio unit"]; 

[Utilities checkError:AUGraphNodeInfo(self.info->mGraph, rioNode, NULL, &self.info->rioUnit) 
      operation: "Couldn't link node to audio unit"]; 

// Make connections 
[Utilities checkError:AUGraphConnectNodeInput(self.info->mGraph, rioNode, 1, lpfNode, 1) 
      operation: "Couldn't connect remoteIO output scope bus 1 to filter input scope bus 1"];// input -> filter 

[Utilities checkError: AUGraphConnectNodeInput(self.info->mGraph, lpfNode, 0, rioNode, 0) 
      operation: "Couldn't connect filter output scope bus 0 to remoteIO input scope bus 0"]; // filter -> output 

// Enable IO for input and output (recording and playing) 
AudioUnitElement kRemoteIOInputScopeMic = 1; 
AudioUnitElement kRemoteIOOutputScopeSpeaker = 0; 

UInt32 enableInput = 1; 
[Utilities checkError:AudioUnitSetProperty (self.info->rioUnit, 
              kAudioOutputUnitProperty_EnableIO, 
              kAudioUnitScope_Input, 
              kRemoteIOInputScopeMic, 
              &enableInput, 
              sizeof(enableInput)) 
      operation: "Couldn't enable RIO input"]; 

// set up the rio unit for playback 
UInt32 enableOutput = 1; 
[Utilities checkError:AudioUnitSetProperty (self.info->rioUnit, 
              kAudioOutputUnitProperty_EnableIO, 
              kAudioUnitScope_Output, 
              kRemoteIOOutputScopeSpeaker, 
              &enableOutput, 
              sizeof(enableOutput)) 
      operation: "Couldn't enable RIO output"]; 

// Set property to low-pass filter 
AudioUnitSetParameter(self.info->lpfUnit, 
         kLowPassParam_CutoffFrequency, 
         kAudioUnitScope_Global, 
         0, 
         1000, 
         0); 



// Set callbacks 
// Callback for input 
AURenderCallbackStruct callbackStruct; 
callbackStruct.inputProc = recordingCallback; 
callbackStruct.inputProcRefCon = (__bridge void*) self; 


[Utilities checkError: AudioUnitSetProperty(self.info->rioUnit, 
              kAudioOutputUnitProperty_SetInputCallback, 
              kAudioUnitScope_Global, 
              1, // Input bus 
              &callbackStruct, 
              sizeof(AURenderCallbackStruct)) 
      operation: "AudioUnitSetProperty set RenderCalback"]; 

// Callback to render data 
callbackStruct.inputProc = renderCallback; 
callbackStruct.inputProcRefCon = (__bridge void*) self; 


[Utilities checkError: AudioUnitSetProperty(self.info->rioUnit, 
              kAudioUnitProperty_SetRenderCallback, 
              kAudioUnitScope_Input, //kAudioUnitScope_Global, ???? 
              0, // Output bus 
              &callbackStruct, 
              sizeof(AURenderCallbackStruct)) 
      operation: "AudioUnitSetProperty set RenderCalback"]; 

[Utilities checkError: AUGraphInitialize(self.info->mGraph) 
      operation: "Couldn't initialize graph"]; 


// Input ASBD 
AudioStreamBasicDescription inputasbd; 
UInt32 propSize = sizeof(inputasbd); 
[Utilities checkError:AudioUnitGetProperty(self.info->rioUnit, 
              kAudioUnitProperty_StreamFormat, 
              kAudioUnitScope_Input, 
              1, 
              &inputasbd, 
              &propSize) 
      operation:"Failed to get stream format of microphone input scope"]; 

// Output ASBD 
AudioStreamBasicDescription outputasbd; 
UInt32 typeByteSize = sizeof(float); 
outputasbd.mBitsPerChannel = 8 * typeByteSize; 
outputasbd.mChannelsPerFrame = 1; 
outputasbd.mBytesPerFrame = typeByteSize * outputasbd.mChannelsPerFrame; 
outputasbd.mFormatFlags  = kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved; 
outputasbd.mFormatID   = kAudioFormatLinearPCM; 
outputasbd.mFramesPerPacket = 1; 
outputasbd.mBytesPerPacket = outputasbd.mFramesPerPacket * outputasbd.mBytesPerFrame; 
outputasbd.mSampleRate  = inputasbd.mSampleRate; 

// Set stream format to output scope of input bus 
[Utilities checkError:AudioUnitSetProperty (self.info->rioUnit, 
              kAudioUnitProperty_StreamFormat, 
              kAudioUnitScope_Output, 
              1, 
              &inputasbd, 
              sizeof (AudioStreamBasicDescription)) 
      operation: "Couldn't set ASBD for RIO on output scope/bus 1"]; 

// Set format on inputscope of output bus 
[Utilities checkError:AudioUnitSetProperty(self.info->rioUnit, 
              kAudioUnitProperty_StreamFormat, 
              kAudioUnitScope_Input, 
              0, 
              &outputasbd, 
              sizeof(AudioStreamBasicDescription)) 
      operation: "Couldn't set ASBD for RIO on input scope/bus 0"]; 


// Start AUGraph 
[Utilities checkError:AUGraphStart(self.info->mGraph) 
     operation: "Couldn't start AUGraph"]; 

をしかし残念ながらAUグラフは、このコード(OSStatus -10863)を開始できませんでした。 AUGraphConnectNodeInputメソッドをコメントアウトするか、remoteIO AUを使用してフィルタを削除すると、問題なくオーディオがマイクからスピーカに直接再生されます。

誰でも私の設定に間違いがあるかどうかヒントを教えてください。kAudioUnitSubType_LowPassFilter

+0

「kAudioUnitSubType_LowPassFilter」の設定に何か問題があったのはどういう意味ですか?あなたはそれについて何を確信していますか?別のサブタイプのユニットを接続しようとしましたか? – user3078414

+0

実際、私は問題がどこにあるのか本当にわからないことを意味しました。グラフに「kAudioUnitSubType_MultiChannelMixer」を入れようとしましたが(マイクからの入力は1つだけです)、同じエラーコードが表示されます。 – Taco

+0

'OSStatus -10863 = kAudioToolboxErr_CannotDoInCurrentContext'。あなたのレンダリングコールバックに問題があり、 'remoteIO' AUをプレイスルー設定にするようです。 'AUGraphConnectNodeInput()'接続を行ったときにコメントアウトし、何か起こるかどうか確認してください。 – user3078414

答えて

0

EDIT 2:

はステレオにあなたのASBDを変更し

。フィルタに必要です。

AUGraphConnectNodeInput(self.info->mGraph, rioNode, 1, lpfNode, 1)AUGraphConnectNodeInput(self.info->mGraph, rioNode, 1, lpfNode, 0)とします。 inDestInputNumber引数は本質的に入力バスであり、フィルタはただ1つのバスしか持たないので、引数はバス0でなければなりません。それでも問題が解決しない場合は、setStreamFormatWithInputASBDメソッドで何が起こっているのかを投稿してください(該当する場合)。いずれにせよ、私は通常、接続されているユニットの入力と一致するように、すべての出力ASBDを明示的に設定します。

(audioUnitGetPropertyとASBDためのsetPropertyための擬似コード)

unitB.outputASBD = outUnit.inputASBD; 
unitA.outputASBD = unitB.inputASBD; 
inUnit.outputASBD = unitA.inputASBD; 

時には、このISN」:inUnit-> unitA-> unitB->このパターンを使用してASBDsを設定outUnitこのようなグラフが与えられると

必要ではありますが、ときどきです!ほとんどのフィルタは入力として必須のステレオフロートASBDを使用します。

+0

残念ながら、私はiOSでは動作しませんが、私はOSX CoreAudio APIに精通しています。 RemoteIO AUはiOS専用で、そのAPIはMacのHAL AU、@Daveに似ています。レンダリングコールバックは入力バスと出力バスとの間の接続を定義するスルースルー構成を担当しますが、入力コールバックはおそらく無関係かもしれません。しかし、RemoteIO AUの入力バスの間に別のAUを接続すると、そうした方法で登録されたレンダリングコールバックは目的を果たさない可能性があります。 AUGraphにコールバックを登録するメカニズムには、APIを壊さないものがあります。 – user3078414

+0

さらに、 'inSource InputNumber'と 'inDestInputNumber'についてはまったく正確ではなく、基本的には入力チャンネルであり、フィルターにはただ1つのチャンネルしかありません" @Dave。これらはノード番号 のバス番号であり、ストリーム形式のフレームあたりの_audio_チャンネルの数と混同しないでください。 ( - : – user3078414

+0

私もバス番号を変更しようとしましたが、エラーコードは変わっていませんでしたが、user3078414のコメントに関しては、これらが正しいと思います。さらに、私の質問をASBDで編集しました。コールバック私はいくつかの分析(FIRフィルタリングを含む)を行い、循環バッファにオーディオを入れ、録音を行うことができました。私はバッファからオーディオをレンダリングし、オーディオを再生してプロットするためにレンダリングコールバックを使用します。 – Taco

関連する問題