多线程,采样和基本软件问题

时间:2012-05-01 13:49:01

标签: objective-c c core-audio

在打扰了你们这么多次之后,我正在和苹果人谈话,我必须得到一个你可能比我更清楚的决定。

我正在处理实时音频,读取缓冲区,DSP(FFT)并做出决定。 我必须将该决定发送到主场景(或主线程),以并行执行。 所以,获取音频缓冲区,并实时听取决定。

问题是:您无法放入音频回调函数,objC函数或其他需要时间的事情,例如在做出决定时向其他类发布通知。

我还试过了什么:

  1. 在该回调中放置NSNotification以通知主线程新数据 - 它泄漏。

  2. 将决策放在一个全局变量(单线程)中,然后从主线程安排变量 - 这似乎是一个坏主意(并且NSTimer不能达到50ms)。

  3. 只需从回调调用到另一个类中的另一个函数 - 来实现其中的事情 - 导致泄漏 - 即使我只是NSLOG中的东西。

  4. 在另一个objC函数中创建另一个线程,从音频回调函数调用它,仍然是泄漏(这意味着内存正在快速增长!)

  5. 无法找到正确的方法。

    对于想要查看回调函数的人(每秒调用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;
    
    
    }
    

1 个答案:

答案 0 :(得分:2)

UI运行循环中的NSTimer将随着UI的更新而触发,因此如果要由UI显示决策,则只需在重复计时器回调中轮询标志变量。如果另一个线程需要更频繁地更新某些内容,请在音频回调之外启动该线程,然后进行该线程轮询或等待锁定。