2

私は Tim Boldstad http://timbolstad.com/2010/03/16/core-audio-getting-started-pt2/によって提供されたコードを変更し(神の祝福がありますように)、変更できるように小さなスライダーを追加しました。出力トーン周波数は 40hz ~ 200000hz です。生成されたトーンに LPF を使用できるようにしたいと考えています。

まず第一に、これを行う方法を説明する詳細なガイドがありますか。単純に間にノードを追加しようとしましたが、機能しません。明らかに、オーディオ サンプル入力をフィルターに与える前に、16 ビット整数サンプルを浮動 8.24 形式に変換する必要があり、それを変換する必要があります。 16 ビット整数に戻ります。これが問題ですか?または、ノードを間違って接続しましたか? フィルターのカットオフ周波数やその他のパラメーターはどこで設定すればよいですか?

AudioUnitGetProperty の機能を説明できる人はいますか? これらのトピックに関するAppleのドキュメントは非常に断片的で、まったく価値がありません:(

-(void) initializeAUGraph
{

OSStatus result= noErr;

    result = NewAUGraph(&mGraph);

    AUNode outputNode;
    AUNode mixerNode;
    AUNode effectsNode;

    AudioComponentDescription effects_desc;
    effects_desc.componentType = kAudioUnitType_Effect;
    effects_desc.componentSubType = kAudioUnitSubType_LowPassFilter;
    effects_desc.componentFlags = 0;
    effects_desc.componentFlagsMask = 0;
    effects_desc.componentManufacturer = kAudioUnitManufacturer_Apple;

    AudioComponentDescription mixer_desc;
    mixer_desc.componentType=kAudioUnitType_Mixer;
    mixer_desc.componentSubType=kAudioUnitSubType_MultiChannelMixer;
    mixer_desc.componentFlags=0;
    mixer_desc.componentFlagsMask=0;
    mixer_desc.componentManufacturer=kAudioUnitManufacturer_Apple;

    AudioComponentDescription output_desc;
    output_desc.componentType = kAudioUnitType_Output;
    output_desc.componentSubType = kAudioUnitSubType_RemoteIO;
    output_desc.componentFlags = 0;
    output_desc.componentFlagsMask = 0;
    output_desc.componentManufacturer = kAudioUnitManufacturer_Apple;

   result= AUGraphAddNode(mGraph, &output_desc, &outputNode);
   result= AUGraphAddNode(mGraph, &mixer_desc, &mixerNode);
    result=AUGraphAddNode(mGraph, &effects_desc, &effectsNode);

    result=AUGraphConnectNodeInput(mGraph, mixerNode, 0, effectsNode, 0);
    result=AUGraphConnectNodeInput(mGraph, effectsNode, 0, outputNode, 0);

    result=AUGraphOpen(mGraph);

    //getting mixxer

    result = AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer);
    result = AUGraphNodeInfo(mGraph, effectsNode, NULL, &mEffects);

    UInt32 numbuses = 1;
    UInt32 size = sizeof(numbuses);
    result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &numbuses, size);


    //=====

    CAStreamBasicDescription desc;

    // Loop through and setup a callback for each source you want to send to the mixer.
    // Right now we are only doing a single bus so we could do without the loop.
    for (int i = 0; i < numbuses; ++i) 
    {

        // Setup render callback struct
        // This struct describes the function that will be called
        // to provide a buffer of audio samples for the mixer unit.
        AURenderCallbackStruct renderCallbackStruct;
        renderCallbackStruct.inputProc = &renderInput;
        renderCallbackStruct.inputProcRefCon = self;

        // Set a callback for the specified node's specified input
        result = AUGraphSetNodeInputCallback(mGraph, mixerNode, i, &renderCallbackStruct);

        // Get a CAStreamBasicDescription from the mixer bus.
        size = sizeof(desc);
        result = AudioUnitGetProperty(  mMixer,
                                      kAudioUnitProperty_StreamFormat,
                                      kAudioUnitScope_Input,
                                      i,
                                      &desc,
                                      &size);
        // Initializes the structure to 0 to ensure there are no spurious values.
        memset (&desc, 0, sizeof (desc));                               

        // Make modifications to the CAStreamBasicDescription
        // We're going to use 16 bit Signed Ints because they're easier to deal with
        // The Mixer unit will accept either 16 bit signed integers or
        // 32 bit 8.24 fixed point integers.

        desc.mSampleRate = kGraphSampleRate; // set sample rate
        desc.mFormatID = kAudioFormatLinearPCM;
        desc.mFormatFlags      = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
        desc.mBitsPerChannel = sizeof(AudioSampleType) * 8; // AudioSampleType == 16 bit signed ints
        desc.mChannelsPerFrame = 1;
        desc.mFramesPerPacket = 1;
        desc.mBytesPerFrame = ( desc.mBitsPerChannel / 8 ) * desc.mChannelsPerFrame;
        desc.mBytesPerPacket = desc.mBytesPerFrame * desc.mFramesPerPacket;

        printf("Mixer file format: "); desc.Print();
        // Apply the modified CAStreamBasicDescription to the mixer input bus
        result = AudioUnitSetProperty(  mMixer,
                                      kAudioUnitProperty_StreamFormat,
                                      kAudioUnitScope_Input,
                                      i,
                                      &desc,
                                      sizeof(desc));
    }

    // Apply the CAStreamBasicDescription to the mixer output bus
    result = AudioUnitSetProperty(   mMixer,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &desc,
                                  sizeof(desc));

    //************************************************************
    //*** Setup the audio output stream ***
    //************************************************************

    // Get a CAStreamBasicDescription from the output Audio Unit
    result = AudioUnitGetProperty(  mMixer,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &desc,
                                  &size);

    // Initializes the structure to 0 to ensure there are no spurious values.
    memset (&desc, 0, sizeof (desc));

    // Make modifications to the CAStreamBasicDescription
    // AUCanonical on the iPhone is the 8.24 integer format that is native to the iPhone.
    // The Mixer unit does the format shifting for you.
    desc.SetAUCanonical(1, true);
    desc.mSampleRate = kGraphSampleRate;

    // Apply the modified CAStreamBasicDescription to the output Audio Unit
    result = AudioUnitSetProperty(  mMixer,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &desc,
                                  sizeof(desc));

    // Once everything is set up call initialize to validate connections
    result = AUGraphInitialize(mGraph);
}
4

1 に答える 1

0

AudioUnitGetProperty の機能を説明できる人はいますか?

さて、Audio Unit からプロパティの値を取得します。「プロパティ」は通常、プログラマーとして扱うもの (オーディオ ストリーム形式、接続状態など) であり、「パラメーター」は通常、ユーザーに公開するもの (ローパス カットオフ周波数、ミキサー ボリュームなど) です。AudioUnitGetParameterandAudioUnitSetParameter関数を補完するAudioUnitGetPropertyand関数があることに注意してくださいAudioUnitSetProperty

基本的に、Audio Unit のプロパティ/パラメータが何であるか、およびそれらが期待する値を「知っている」ことが期待されます。これに関するドキュメントの最良のソースは、AudioUnit.framework の 2 つのヘッダーです。つまり、AudioUnitProperties.hAudioUnitParameters.h. 次善のソースは、Xcode のオートコンプリートです。たとえば、AULowPass のパラメーターはkLowPassParam_CutoffFrequencyandkLowPassParam_Resonanceであるため、入力するだけkLowPassParamで Xcode が使用可能なものを表示します。他の AU は通常、このスキームに従います。

...しかし、どうやらうまくいきません

もっと情報が必要です。聞き分けがつかないということですか?AULowPass は非常に高いカットオフ周波数で開始されるため、それを低く設定しない限り、おそらくまったく違いが聞こえないでしょう。

カットオフ周波数を非常に低い値 (500hz など) に設定してみてください。次のようにします。

AudioUnitSetParameter(mEffects,
                      kLowPassParam_CutoffFrequency,
                      kAudioUnitScope_Global,
                      0,
                      500,
                      0);
于 2012-10-11T15:06:32.413 に答える