1. 程式人生 > >Windows上的音訊採集技術

Windows上的音訊採集技術

前一段時間接到一個任務,需要採集到音效卡的輸出訊號,以便與麥克風的輸入訊號進行混音。

之前一直沒有研究過音訊的相關技術,這次就順便抽出一點時間去了解了一下Windows上採集音訊的相關技術。

對於音訊處理的技術,主要有如下幾種:

  • 採集麥克風輸入
  • 採集音效卡輸出
  • 將音訊資料送入音效卡進行播放
  • 對多路音訊輸入進行混音處理

1.Windows上音訊處理的API

在Windows作業系統上,常用的音訊處理技術主要包括:Wave系列API函式、DirectSound、Core Audio。

其中,Core Audio只可以在Vista以上(包括Vista)的作業系統中才能使用,主要用來取代Wave系列API函式和DirectSound。

Core Audio實現的功能也比較強大,能實現對麥克風的採集、音效卡輸出的採集、控制聲音的播放。

而Wave系列的API函式主要是用來實現對麥克風輸入的採集(使用WaveIn系列API函式)和控制聲音的播放(使用後WaveOut系列函式)。

DirectSound能夠實現的功能估計和Wave系列API差不多,可能會更強一些(由於沒有使用過DirectSound,不太肯定!)。

為了實現採集模組對作業系統的相容性更好,基本上對麥克風輸入的採集使用WaveIn系列API函式比較多;

在Windows XP系統中,沒有直接提供對音效卡輸出進行採集的API,因此,在Windows XP要實現對音效卡輸出的採集會比較麻煩。 通常可選用支援混音的音效卡,然後通過使用音效卡的混音模組來實現採集,但並不是所有的音效卡都支援混音的功能,這樣的方案不具備通用性。

要實現通用性,可以採用虛擬音效卡的方式來實現,從驅動層獲取音效卡的輸出資料,但這種方案實現難度會比較大。

而在Vista以上的系統中,如Win7,則可以使用Core Audio中的API函式來實現採集音效卡輸出的功能。

對於混音模組的實現,目前基本是使用自定義的混音演算法來完成功能,系統沒有直接的API函式可供呼叫。

2.使用WaveIn系列API函式實現麥克風輸入採集

涉及的API函式:

  • waveInOpen

    開啟音訊採集裝置,成功後會返回裝置控制代碼,後續的API都需要使用該控制代碼

    呼叫模組需要提供一個回撥函式(waveInProc),以接收採集的音訊資料

  • waveInClose

    關閉音訊採集模組

    成功後,由waveInOpen返回的裝置控制代碼將不再有效 

  • waveInPrepareHeader

    準備音訊採集資料快取的空間

  • waveInUnprepareHeader

    清空音訊採集的資料快取

  • waveInAddBuffer

    將準備好的音訊資料快取提供給音訊採集裝置

    在呼叫該API之前需要先呼叫waveInPrepareHeader

  • waveInStart

    控制音訊採集裝置開始對音訊資料的採集

  • waveInStop

    控制音訊採集裝置停止對音訊資料的採集

音訊採集裝置採集到音訊資料後,會呼叫在waveInOpen中設定的回撥函式。

其中引數包括一個訊息型別,根據其訊息型別就可以進行相應的操作。

如接收到WIM_DATA訊息,則說明有新的音訊資料被採集到,這樣就可以根據需要來對這些音訊資料進行處理。

(示例以後補上)

3.使用Core Audio實現對音效卡輸出的捕捉

涉及的介面有:

  • IMMDeviceEnumerator

  • IMMDevice

  • IAudioClient

  • IAudioCaptureClient

主要過程:

  • 建立多媒體裝置列舉器(IMMDeviceEnumerator)

  • 通過多媒體裝置列舉器獲取音效卡介面(IMMDevice)

  • 通過音效卡介面獲取音效卡客戶端介面(IAudioClient)

  • 通過音效卡客戶端介面(IAudioClient)可獲取音效卡輸出的音訊引數、初始化音效卡、獲取音效卡輸出緩衝區的大小、開啟/停止對音效卡輸出的採集

  • 通過音效卡採集客戶端介面(IAudioCaptureClient)可獲取採集的音效卡輸出資料,並對內部緩衝區進行控制

(示例以後補上)

4.常用的混音演算法

混音演算法就是將多路音訊輸入訊號根據某種規則進行運算(多路音訊訊號相加後做限幅處理),得到一路混合後的音訊,並以此作為輸出的過程。

我目前還做過這一塊,搜尋了一下基本有如下幾種混音演算法:

  • 將多路音訊輸入訊號直接相加取和作為輸出

  • 將多路音訊輸入訊號直接相加取和後,再除以混音通道數,防止溢位

  • 將多路音訊輸入訊號直接相加取和後,做Clip操作(將資料限定在最大值和最小值之間),如有溢位就設最大值

  • 將多路音訊輸入訊號直接相加取和後,做飽和處理,接近最大值時進行扭曲

  • 將多路音訊輸入訊號直接相加取和後,做歸一化處理,全部乘個係數,使幅值歸一化

  • 將多路音訊輸入訊號直接相加取和後,使用衰減因子限制幅值

(完)