我正在撰寫一個程式,它使用 PortAudio 將音頻輸入從計算機獲取到我的程式中。PortAudio 在他們的撰寫回呼教程中說回呼是作為 觸發的Interrupt Handler,并解釋了在回呼中撰寫的代碼不需要這樣做:
記憶體分配/釋放、I/O(包括檔案 I/O 以及控制臺 I/O,例如 printf())、背景關系切換(例如 exec() 或 yield())、互斥操作或任何其他可能依賴于作業系統
我遇到的問題是弄清楚我將如何處理來自回呼的音頻而無法使用malloc. 我當前的(和作業的)回呼看起來像這樣。
int Audio::paCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) {
// Cast data passed through stream to our structure.
auto *in = (uint16_t *) inputBuffer;
// Get number of audio channels, for instance stereo would be two
int numberOfChannels = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->maxInputChannels;
for (int i = 0; i < numberOfChannels; i ) {
auto storedStream = (uint16_t *) malloc(sizeof(uint16_t) * (framesPerBuffer 2));
storedStream[0] = uint16_t(i);
storedStream[1] = uint16_t(framesPerBuffer);
for (int j = 0; j < storedStream[1]; j ) {
storedStream[j 2] = in[numberOfChannels*j i];
}
audioQueue->push(&storedStream);
}
return 0;
}
我知道我不應該使用malloc,那么我將如何解決這個問題?
在尋找代碼示例時,我發現免費的音頻編輯軟體 Audacity 使用了 PortAudio。我查看了Audacity 的 PortAudio 回呼(第 2391 行AudioIO.cpp),他們所做的只是呼叫兩個函式。在第二個函式中,他們呼叫alloca分配記憶體。
是否可以從中斷處理程式呼叫函式然后進行記憶體分配,或者這些函式也可以在中斷背景關系中執行?
uj5u.com熱心網友回復:
通常,為了避免動態分配記憶體,我們將使用各種“靜態容器”。諸如預先分配和保留資料的回圈緩沖區,或 blit 緩沖區(兩個靜態緩沖區,其中新資料添加到一個緩沖區,而先前添加的資料從第二個緩沖區處理。它們的角色定期“交換”當“處理”緩沖區中的所有資料為空時)。在這兩種情況下,了解您可能需要的“最大”資料量并預先分配那么多資料都會有所幫助。
是否可以從中斷處理程式呼叫函式然后進行記憶體分配,或者這些函式也可以在中斷背景關系中執行?
這實際上取決于您的目標平臺。有時避免動態記憶體分配非常重要,而有時在現代嵌入式平臺上,這種擔憂有些過分了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/477239.html
