程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 實時錄音並顯示波形、頻譜

實時錄音並顯示波形、頻譜

編輯:.NET實例教程

本文講述如何實時錄音,以及將錄音波形頻譜實時顯示的方法。Windows提供了一個多媒體控制接口(MCI),用它可以錄音,很方便。但是這種方法不能實時給出錄音的原始數據,因此要顯示波形和頻譜都是不可能實現的。要達到實時的效果,就要使用Windows提供的另一套函數,即低級音頻函數。其中和錄音有關的是以waveIn開頭的一組函數。

    低級音頻函數的使用比較繁瑣,大致要有以下幾個步驟。

  1. 用waveInOpen打開設備,並設置回調。因為要保證實時性,所以不能用查詢的方式,而必須設置回調。
  2. 為設備分配足夠的內存做緩沖區,動態分配或靜態數組都可以。為了保證實時性,程序用了雙緩沖技術,在處理一個緩沖區數據的同時另一個緩沖區用於錄音。為了便於說明寫成Buffer1、Buffer2。
  3. 將Buffer1關聯到設備上去,waveInPrepareBuffer、waveInAddBuffer。
  4. 開始錄音,waveInStart
  5. 當驅動程序填滿這個緩沖區(Buffer1)時就會產生回調(消息為WIM_DATA),這時立刻將Buffer2關聯到設備上繼續錄音,然後處理Buffer1,當驅動程序填滿Buffer2時又會產生回調,這是再將Buffer1關聯到設備上,而去處理Buffer2,如此反復就使得錄音能夠實時的進行下去。
  6. 停止錄音,waveInStop
  7. 關閉設備,waveInClose

    上面就是實時錄音的一個基本流程,產生回調時,其lParam就是一個指向WAVEHDR結構的指針,通過這個指針就可以得到原始數據(注意了:我這個程序只是單聲道8位的PCM格式,因此正好一個字節就是一個采樣點的值,對於其他格式的我就不知道了)。有了原始數據就可以很容易的畫出波形了,而頻譜也就是多一次FFT變換而已,沒什麼太難的。

    這裡是我用LCC寫的例子,非常簡單,而且相信大家都可以很容易的移植到BCB上來。另外,我偷了一下懶,FFT用了我以前封裝到DLL中的函數(現在已經忘了怎麼寫了^_^),可以在此下載 (不要覺得奇怪,就是這個時鐘,將其中的DEMO.DLL拿來用就是了)。當然你也可以自己寫一個FFT放到程序裡去。

-*-*-PATCH-*-*-2002-06-11

    上次那個程序還不好,原因是雙緩沖還不能滿足實時的要求,因此這次用了8緩沖循環技術。新的程序也是用LCC寫的。
    開始時依次將0-6號緩沖區關聯到設備上,而7號緩沖區不關聯,然後開始錄音,這是驅動程序開始向0號緩沖區輸出數據,當0號緩沖區數據滿時產生回調,這時驅動程序會自動向1號緩沖區輸出數據,但這時應將7號緩沖區關聯到設備上去,然後處理0號緩沖區的數據。然後當1號緩沖區數據滿時又會產生回調,這時驅動程序會自動向2號緩沖區輸出數據,而將0號緩沖區關聯到設備上去。這樣如此反復,始終保持1個緩沖區用於驅動輸出數據,1個緩沖區用於處理數據,6個緩沖區處於等待狀態。
    而如果只有兩個緩沖區,就只能一個用於驅動輸出,一個用於處理數據。這樣在產生回調的時候就會出現沒有處於等待狀態的緩沖區的情況,這樣驅動程序就不能自動向緩沖區輸出數據。而要等waveInPrepareBuffer、waveInAddBuffer調用之後,這樣就會出現一個小小的間隙,而導致錄音不連續。

-*-*-PATCH-*-*-2002-06-11

    只是我的個人觀點,有什麼不對的地方,還望指教。

-*-*-PATCH-*-*-2003-04-07

    程序中有一個錯誤,在WIM_DATA的處理過程裡。

 case WIM_DATA:
  waveInUnprepareHeader(hwi,pwhi,sizeof(WAVEHDR));//釋放錯誤。
  nextWavHdr=(currWavHdr-1+MAX_INQUE
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved