0

何度もあなたたちの邪魔をした後、私はアップルの人たちと話していました。

私はリアルタイムでオーディオを扱っており、バッファ、DSP(FFT) を読み取り、決定を下しています。その決定をメイン シーン (またはメイン スレッド) に送信して、並列処理を行う必要があります。そのため、オーディオ バッファを取得し、リアルタイムで決定を聞きます。

問題は、音声コールバック関数、objC 関数、または決定が下されたときに他のクラスに通知を投稿するなど、時間がかかるその他のものを入れることができないことです。

私がまだ試したこと:

  1. そのコールバックに NSNotification を入れて、新しいデータでメインスレッドに通知します-リークします。

  2. 決定をグローバル変数(シングルトーン)に入れてから、メインスレッドからその変数をスケジュールします-これは悪い考えのようです(そしてNSTimerは50ミリ秒を下回ることはできません)。

  3. コールバックから別のクラスの別の関数を呼び出すだけです-そこに何かを実装するには-リークを引き起こします-そこに何かをNSLOGしただけでも。

  4. 別の objC 関数で別のスレッドを作成し、それをオーディオ コールバック関数から呼び出しますが、それでもリークします (つまり、メモリが急速に増加しています!)

それを行う正しい方法を見つけることができません。

コールバック関数 (1 秒間に 1000 回呼び出される) を調べたい人向け

折り返し電話 :

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; //* sizeof(SInt16) ?
    buffer.mData = NULL;// malloc( inNumberFrames * 2 );

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


    OSStatus status;

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


    SInt16 *targetBuffer = (SInt16*)(&bufferList)->mBuffers[0].mData;

// got the buffer, here i have tried so many things to do with it ,in order to not leak the app. i need to send it somewhere to process the data, or save it somewhere else.

   [globals sharedGlobals].bufBuf=targetBuffer;

    return noErr;


}
4

1 に答える 1

2

UI 実行ループ内の NSTimer は、UI が更新されるのとほぼ同じ頻度で起動するため、決定が UI によって表示される場合は、繰り返しタイマー コールバックでフラグ変数をポーリングするだけです。別のスレッドが何かをより頻繁に更新する必要がある場合は、オーディオ コールバックの外でそのスレッドを開始し、そのスレッドをポーリングするか、ロックを待機させます。

于 2012-05-01T16:01:13.293 に答える