0

バッファを読み取るオーディオ ユニットがあり、コールバック関数でメモリが増加しています。うまく機能しますが、このリークを解決するために多くの時間を費やしています。

問題を解決した後、Apple によって記述された基本的な構成コードがメモリの増加 (1 秒あたり 100k) を引き起こしていることがわかりました。

これは、問題のある他のすべてのものを取得した後の私のコールバックです:

AudioComponentInstance audioUnit;


static OSStatus recordingCallback(void *inRefCon, 
                                  AudioUnitRenderActionFlags *ioActionFlags, 
                                  const AudioTimeStamp *inTimeStamp, 
                                  UInt32 inBusNumber, 
                                  UInt32 inNumberFrames, 
                                  AudioBufferList *ioData) 
{
    AudioBuffer buffer;
    buffer.mNumberChannels = 1;
    buffer.mDataByteSize = inNumberFrames * 2;
    buffer.mData = malloc( inNumberFrames * 2 );

    // Put buffer in a AudioBufferList
    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0] = buffer;


    OSStatus status;

// problematic block   ******

    status = AudioUnitRender(audioUnit, 
                              ioActionFlags, 
                             inTimeStamp, 
                              inBusNumber, 
                             inNumberFrames, 
                              &bufferList); 


//end of problem block    ******


   free(buffer.mData); 
}

そのブロックを削除すると問題が解決します。

audioUnit にはプロパティが必要ですか? ここで私の基本的な問題は何ですか?ありがとう。

4

2 に答える 2

4

他の質問 (http://stackoverflow.com/questions/10278516/memory-is-growing-in-audio-buffer-code) で尋ねたように、レンダー コールバック内で malloc するべきではありません。外部で malloc し、バッファへの参照を保存し、各サンプルをゼロに設定してバッファをクリアします。2 for() ループは、malloc() よりもはるかに高速です。

メモリ管理の仕組みがわかりにくいため、(誤って) AudioUnitRender() の実際の呼び出しが問題の原因であると信じるようになりました。そうではありません。これは上記の malloc() 呼び出しであり、次のレンダリング コールバックが行われるまでにこのメモリを効率的に再利用できないという事実と相まってです。したがって、参照が保持され、メモリがリークされます。

一般的に言えば、オーディオ プログラミングのパフォーマンス戦略は、レンダー コールバックの外で必要なだけ多くの作業を行うことです。この関数は 10 ミリ秒以下で完了する必要があることを考慮してください。そうしないと、オーディオ ストリームでドロップアウトが聞こえます。

デスクトップ用にプログラミングしている場合は、初期化中に大量のメモリを貪欲に malloc() し、データへの参照を保存して、レンダリング中に割り当てる必要がないように、データからすばやく読み取る必要があります。同様に、定数などを計算する必要がある場合は、レンダリングを開始する前に実行する必要があります。

モバイルを使用している場合、戦略は似ていますが、おそらく malloc() を積極的に使用したくないでしょう。それでも、携帯電話 (または iPad) の CPU パワーとメモリの量は限られているため、レンダリング コールバックの長さには細心の注意を払う必要があります。短いほど良い。

于 2012-04-24T09:32:28.190 に答える
2

独自のオーディオ バッファーを割り当てまたは malloc() する場合 (これはAudio Unit コールバックので行う必要があります)、Audio Unit の初期化またはセットアップのどこかで自動バッファー割り当てを無効にしてみてください。

// Disable buffer allocation for the recorder
UInt32 myDisable = 0;
err = AudioUnitSetProperty(audioUnit,
                           kAudioUnitProperty_ShouldAllocateBuffer,
                           kAudioUnitScope_Output,
                           kInputBus,
                           &myDisable,
                           sizeof(myDisable));
于 2012-04-24T18:46:59.617 に答える