轉自:http://shanewfx.github.io/blog/2013/08/14/caprure-audio-on-windows/ 前一段時間接到一個任務,須要採集到聲卡的輸出信號,以便與麥克風的輸入信號進行混音。git
以前一直沒有研究過音頻的相關技術,此次就順便抽出一點時間去了解了一下Windows上採集音頻的相關技術。github
對於音頻處理的技術,主要有以下幾種:算法
採集麥克風輸入 採集聲卡輸出 將音頻數據送入聲卡進行播放 對多路音頻輸入進行混音處理 1.Windows上音頻處理的APIwindows
在Windows操做系統上,經常使用的音頻處理技術主要包括:Wave系列API函數、DirectSound、Core Audio。緩存
其中,Core Audio只能夠在Vista以上(包括Vista)的操做系統中才能使用,主要用來取代Wave系列API函數和DirectSound。函數
Core Audio實現的功能也比較強大,能實現對麥克風的採集、聲卡輸出的採集、控制聲音的播放。操作系統
而Wave系列的API函數主要是用來實現對麥克風輸入的採集(使用WaveIn系列API函數)和控制聲音的播放(使用後WaveOut系列函數)。blog
DirectSound可以實現的功能估計和Wave系列API差很少,可能會更強一些(因爲沒有使用過DirectSound,不太確定!)。接口
爲了實現採集模塊對操做系統的兼容性更好,基本上對麥克風輸入的採集使用WaveIn系列API函數比較多;ip
在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操做(將數據限定在最大值和最小值之間),若有溢出就設最大值
將多路音頻輸入信號直接相加取和後,作飽和處理,接近最大值時進行扭曲
將多路音頻輸入信號直接相加取和後,作歸一化處理,所有乘個係數,使幅值歸一化
將多路音頻輸入信號直接相加取和後,使用衰減因子限制幅值
(完)