2012-04-24 28 views
0

我們有一個讀取緩衝區的音頻單元,並且我在回調函數中增加了內存。它工作的很好,但我花了很多時間來解決這個泄漏。音頻單元Ostatus是否泄漏?

消除問題後,我發現基本配置代碼,由蘋果寫的,導致了內存增長(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

像你問你的其他問題(http://stackoverflow.com/questions/10278516/memory-is-growing-in-audio-buffer-code),你不應該在你的渲染回調內malloc'ing 。在外面的Malloc中,保存對緩衝區的引用,並通過將每個採樣設置爲零來清除緩衝區。 2 for()循環是比malloc()更快得多

由於內存管理工作令人困惑,因此您(錯誤地)認爲實際調用AudioUnitRender()會導致您的問題。不是。這是上面的malloc()調用,加上這個內存在下一次​​渲染回調完成時無法有效回收。因此,參考文件被保留,你的記憶被泄漏。

一般來說,任何音頻編程的性能策略都是根據需要在渲染回調之外完成儘可能多的工作。考慮到這個功能需要在~10ms或更短時間內完成,否則你會聽到音頻流中的droupout。

如果您正在爲桌面編程,您希望在初始化期間貪婪地使用malloc()噸內存,並保存對數據的引用以快速讀取數據,因此您無需在呈現期間進行分配。同樣,如果你需要計算任何常量或類似的東西,你想在渲染開始之前完成。

如果你在移動設備上,策略是類似的,但你可能不想malloc()積極。儘管如此,由於手機(或iPad)的CPU功率和內存數量有限,因此您需要非常小心您的渲染回調時間。越短越好。

+0

首先非常感謝。其次,這是非常奇怪的,因爲蘋果文檔和其他每一個好網站都在以這種方式設置緩衝區(前四行)並將其分配到回調函數內部。無論如何,做這件事的最佳方式是什麼?如果我將緩衝區列表作爲參數從回調中發送到另一個函數,那麼我將在那裏創建一個池並處理音頻(dsp)是否可以? – user1280535 2012-04-25 06:43:07

+0

忘記第二個回調 - 假裝它根本不存在。 :)現在,在您的代碼中有第一次機會時創建所需的緩衝區。如果你必須(認真)使用全局變量。現在,內作出(),只是零出緩衝器的內容,而不是重新分配。 – 2012-04-25 08:14:45

+0

非常感謝您的時間。所以我應該在初始化分配一次,免費在它的dealloc,還是沒有?爲什麼零緩衝區內容?無論如何,它填滿了新的數據是不是? – user1280535 2012-04-27 08:17:29

2

如果您爲自己的音頻緩衝區(應該在音頻單元回調之外完成)分配或malloc(),您可能需要嘗試禁用音頻單元初始化或設置中某處的自動緩衝區分配。

// Disable buffer allocation for the recorder 
UInt32 myDisable = 0; 
err = AudioUnitSetProperty(audioUnit, 
          kAudioUnitProperty_ShouldAllocateBuffer, 
          kAudioUnitScope_Output, 
          kInputBus, 
          &myDisable, 
          sizeof(myDisable)); 
+0

非常感謝!所以把我的init分配,會更好? – user1280535 2012-04-25 06:44:04