11764


AudioUnitを用いてマイク入力信号を色々編集するプログラムを書こうとしたのですが、一向に上手く行かないので質問させていただきます。

やりたいこと  
マイク入力信号→LPF→コールバック関数（ AUNode は二つになるのでしょうか？）

確認済なこと  
マイク入力信号→コールバック関数( AUNode は変数名 inNode １つです)

環境  
iOS 7.1.1

バグ  
以下のソースの直後のAuGraphStart(mAuGraph)でプログラムが落ちる。  
エラーすら出ないときと、OSStatusのエラーコード10863が得られるときがある。

質問内容  
上記バグを修正するにはどのように変更したら良いのでしょうか

ソース

[code]

    OSStatus status;
    
    NewAUGraph(&mAuGraph);
    AUGraphOpen(mAuGraph);
    
    AUNode inNode;
    //AudioUnit inUnit;
    AudioComponentDescription acd;
    acd.componentType = kAudioUnitType_Output;
    acd.componentSubType = kAudioUnitSubType_RemoteIO;
    acd.componentManufacturer = kAudioUnitManufacturer_Apple;
    acd.componentFlags = testAcd.componentFlagsMask = 0;
    AUGraphAddNode(mAuGraph, &acd, &inNode);
    AUGraphNodeInfo(mAuGraph, inNode, NULL, &_inUnit);
    
    //LPF設定
    AUNode lpfNode;
    //AudioUnit lpfUnit;
    acd.componentType = kAudioUnitType_Effect;
    acd.componentSubType = kAudioUnitSubType_kAudioUnitSubType_LowPassFilter;
    AUGraphAddNode(mAuGraph, &acd, &lpfNode);
    AUGraphNodeInfo(mAuGraph, lpfNode, NULL, &_lpfUnit);
    AudioUnitSetParameter(_lpfUnit,
                          kLowPassParam_CutoffFrequency,
                          kAudioUnitScope_Global,
                          0,
                          300,
                          0),
    
    
    
    //マイク入出力設定
    UInt32 flag = 1;
    AudioUnitSetProperty(_inUnit,
                         kAudioOutputUnitProperty_EnableIO,
                         kAudioUnitScope_Input,
                         1,
                         &flag,
                         sizeof(UInt32));
    status = AudioUnitSetProperty(_inUnit,
                                  kAudioOutputUnitProperty_EnableIO, 
                                  kAudioUnitScope_Output,
                                  kOutputBus,
                                  &flag,
                                  sizeof(flag));
    
    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate       = 22050;
    audioFormat.mFormatID         = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags      = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
    audioFormat.mBitsPerChannel     = 16;
    audioFormat.mChannelsPerFrame   = 1;
    audioFormat.mBytesPerFrame      = 2;
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mBytesPerPacket     = 2;
    AudioUnitSetProperty(_inUnit,
                         kAudioUnitProperty_StreamFormat,
                         kAudioUnitScope_Output,
                         1,
                         &audioFormat,
                         sizeof(audioFormat));
    
    //接続
    AUGraphConnectNodeInput(mAuGraph, inNode, 1, lpfNode, 0);
    
    //コールバック設定
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = callbackfunc;
    callbackStruct.inputProcRefCon = (__bridge void *)(self);
    status = AudioUnitSetProperty(_lpfUnit,
                                 kAudioOutputUnitProperty_SetInputCallback,
                                  kAudioUnitScope_Global,
                                  kInputBus,
                                  &callbackStruct,
                                  sizeof(callbackStruct));
    
    flag = 0;
    
    status = AudioUnitSetProperty(_lpfUnit,
                                  kAudioUnitProperty_ShouldAllocateBuffer,
                                  kAudioUnitScope_Output,
                                  kInputBus,
                                  &flag,
                                  sizeof(flag));
    
    status = AudioUnitInitialize(_inUnit);
    status = AudioUnitInitialize(_lpfUnit);
    AUGraphInitialize(mAuGraph);
    CAShow(mAuGraph);
    
[/code]

以上、ご教授ください。


CC BY-SA 3.0
2015-06-25T10:18:50.600
11719
2015-06-26T06:18:41.833
2015-06-25T11:24:07.930
10065
10065
question
ios objective-c iphone
iOS)AudioUnitを用いてマイク入力にLPFをかける方法について


iOS8 ですが以下のコードで動作確認しました。

ポイントは

  * マイク > エフェクト > スピーカ の流れではコールバック関数は必要ない
  * `kAudioUnitType_Effect` に設定できるオーディオのフォーマットは `float` でなければいけない（環境依存？）
  * `AudioGraph` を使用する場合は `AudioUnitInitialize` の関数で `AudioUnit` の初期化は必要ない。今回のコードには含まれていなですが破棄等も同様に必要なし。

* * *
[code]

    @interface MicInput ()
    {
        AUGraph _processingGraph;
    
        AUNode    _ioNode;
        AudioUnit _ioUnit;
        AUNode    _filterNode;
        AudioUnit _filterUnit;
    }
    
    @end
    
    @implementation MicInput
    
    - (void)start
    {
        OSStatus status;
    
        status = NewAUGraph(&self->_processingGraph);
        NSAssert(status == noErr, @"NewAUGraph fail : %@", @(status));
        status = AUGraphOpen(self->_processingGraph);
        NSAssert(status == noErr, @"AUGraphOpen fail : %@", @(status));
    
        {// AUNode の登録
            {// io
                AudioComponentDescription cd;
                cd.componentType         = kAudioUnitType_Output;
                cd.componentSubType      = kAudioUnitSubType_RemoteIO;
                cd.componentManufacturer = kAudioUnitManufacturer_Apple;
                cd.componentFlags        = 0;
                cd.componentFlagsMask    = 0;
    
                status = AUGraphAddNode(self->_processingGraph, &cd, &self->_ioNode);
                NSAssert(status == noErr, @"AUGraphAddNode fail : %@", @(status));
            }
            {// filter
                AudioComponentDescription cd;
                cd.componentType         = kAudioUnitType_Effect;
                cd.componentSubType      = kAudioUnitSubType_LowPassFilter;
                cd.componentManufacturer = kAudioUnitManufacturer_Apple;
                cd.componentFlags        = 0;
                cd.componentFlagsMask    = 0;
    
                status = AUGraphAddNode(self->_processingGraph, &cd, &self->_filterNode);
                NSAssert(status == noErr, @"AUGraphAddNode fail : %@", @(status));
            }
        }
    
        {// AudioUnit の取得
            // io
            status = AUGraphNodeInfo(self->_processingGraph, self->_ioNode, NULL, &self->_ioUnit);
            NSAssert(status == noErr, @"AUGraphNodeInfo fail : %@", @(status));
            // filter
    
            status = AUGraphNodeInfo(self->_processingGraph, self->_filterNode, NULL, &self->_filterUnit);
            NSAssert(status == noErr, @"AUGraphNodeInfo fail : %@", @(status));
        }
    
        {// processingGraph 内のフォーマットを統一する
    
            AudioStreamBasicDescription description;
            description.mSampleRate       = 44100;
            description.mFormatID         = kAudioFormatLinearPCM;
            description.mFormatFlags      = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
            description.mChannelsPerFrame = 1;
            description.mBytesPerPacket   = sizeof(Float32);
            description.mBytesPerFrame    = sizeof(Float32);
            description.mFramesPerPacket  = 1;
            description.mBitsPerChannel   = 8 * sizeof(Float32);
            description.mReserved         = 0;
    
            // mic out
            status = AudioUnitSetProperty(self->_ioUnit,
                                          kAudioUnitProperty_StreamFormat,
                                          kAudioUnitScope_Output,
                                          1,
                                          &description,
                                          sizeof(description));
            NSAssert(status == noErr, @"AudioUnitSetProperty fail : %@", @(status));
    
            // filter in
            status = AudioUnitSetProperty(self->_filterUnit,
                                          kAudioUnitProperty_StreamFormat,
                                          kAudioUnitScope_Input,
                                          0,
                                          &description,
                                          sizeof(description));
            NSAssert(status == noErr, @"AudioUnitSetProperty fail : %@", @(status));
    
            // filter out
            status = AudioUnitSetProperty(self->_filterUnit,
                                          kAudioUnitProperty_StreamFormat,
                                          kAudioUnitScope_Output,
                                          0,
                                          &description,
                                          sizeof(description));
            NSAssert(status == noErr, @"AudioUnitSetProperty fail : %@", @(status));
    
            // speaker in
            status = AudioUnitSetProperty(self->_ioUnit,
                                          kAudioUnitProperty_StreamFormat,
                                          kAudioUnitScope_Input,
                                          0,
                                          &description,
                                          sizeof(description));
            NSAssert(status == noErr, @"AudioUnitSetProperty fail : %@", @(status));
        }
    
        {// マイク入力を有効化
            UInt32 flag = 1;
            AudioUnitSetProperty(self->_ioUnit,
                                 kAudioOutputUnitProperty_EnableIO,
                                 kAudioUnitScope_Input,
                                 1,
                                 &flag,
                                 sizeof(UInt32));
            NSAssert(status == noErr, @"AudioUnitSetProperty fail : %@", @(status));
        }
    
        {// filter の設定
            AudioUnitSetParameter(self->_filterUnit,
                                  kLowPassParam_CutoffFrequency,
                                  kAudioUnitScope_Global,
                                  0,
                                  300,
                                  0);
            NSAssert(status == noErr, @"AudioUnitSetProperty fail : %@", @(status));
        }
    
        // ioNode(mic out) -> filterNode -> ioNode(speaker in)
        status = AUGraphConnectNodeInput(self->_processingGraph,
                                         self->_ioNode, 1,
                                         self->_filterNode, 0);
        NSAssert(status == noErr, @"AUGraphConnectNodeInput fail : %@", @(status));
    
        status = AUGraphConnectNodeInput(self->_processingGraph,
                                         self->_filterNode, 0,
                                         self->_ioNode, 0);
        NSAssert(status == noErr, @"AUGraphConnectNodeInput fail : %@", @(status));
    
        status = AUGraphInitialize(self->_processingGraph);
        NSAssert(status == noErr, @"AUGraphInitialize fail : %@", @(status));
    
        AUGraphStart(self->_processingGraph);
        NSAssert(status == noErr, @"AUGraphStart fail : %@", @(status));
    }
    
    @end
    
[/code]


CC BY-SA 3.0
2015-06-26T06:18:41.833
11764
2015-06-26T06:18:41.833
5106
11719
answer