[英]STFT / sliding FFT on real-time data
我最近選擇了一個項目,需要對傳入的麥克風數據執行實時滑動FFT分析。 我選擇執行此操作的環境是OpenGL和Cinder並使用C ++。
這是我第一次在音頻編程方面的經驗,我有些困惑。
這是我試圖在OpenGL應用程序中實現的目標:
因此,在每一幀中,都有一部分傳入數據。 在for循環中(因此需要多次通過),當前數據的窗口將被消耗,並對它執行FFT分析。 對於for循環的下一次迭代,窗口將在數據等中前進“跳躍大小”,直到到達數據末尾。
現在,此過程必須是連續的。 但是,如您在上圖中所看到的,當我當前的應用程序框架結束時,當下一幀的數據輸入時,我無法拾取離開上一幀的位置(因為數據已經消失)。 您可以在圖中看到它,其中藍色區域位於兩幀之間。
現在您可能會說,以一種永遠不會發生的方式選擇window-size / hop-size,但那是不可能的,因為這些參數應該在我的項目中由用戶配置。
也非常歡迎針對C ++ 11的此類處理建議!
謝謝!
不確定我100%理解您的情況,但聽起來您可能想使用循環緩沖區。 沒有“標准”循環緩沖區,但Boost中有一個 。
但是,如果您打算使用2個線程進行處理,則需要一個鎖。 例如,一個線程將等待音頻輸入,然后鎖定緩沖區,然后從音頻緩沖區復制到循環緩沖區。 如果該緩沖區中至少有k
可用,則第二個線程將定期獲取該緩沖區的鎖並讀取接下來的k
元素。
您需要適當地調整緩沖區的大小,並確保處理數據的速度始終快於傳入速率,以避免循環緩沖區中的數據丟失。
不知道為什么要提到緩沖區是無鎖的,以及是否有此要求,我會先嘗試使用帶鎖的循環緩沖區,因為從概念上看它很簡單,並且只有在必須時才使用鎖,因為數據結構在這種情況下可能會更復雜(但是“生產者-消費者”無鎖隊列可能會起作用)...
HTH。
感謝您發布圖形-很好地說明了問題。
您真正需要的只是一個大小為(window - 1)
的緩沖區,您可以在其中存儲零個或多個來自“上一個”幀的樣本,以便在“下一個”幀中進行處理。 在C ++中,這將是:
std::vector<Sample> interframeBuffer;
interframeBuffer.reserve(windowSize - 1);
然后,當您位於當前幀末尾的windowSize
樣本內時,而不是處理樣本,而是使用interframeBuffer.push_back(sample)
存儲。 當您開始處理下一幀時,首先需要執行以下操作:
for (const Sample& sample : interframeBuffer) {
process(sample);
}
interframeBuffer.clear();
您應該一直使用單個向量,清除它並根據需要重新填充它,以避免內存分配。 這就是為什么我們在頂部調用reserve()
的原因,以避免以后出現延遲。 調用clear()
不會釋放內存,只是將size()
重置為零。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.