如何抓取揚聲器的聲音

工做中有個需求是關於抓取揚聲器的聲音, 爲何會有這個需求? 
試想咱們在共享遠程桌面時,若是可以把本地桌面應用程序的聲音也一塊兒發給對方,而後播放出來, 用戶體驗該是多麼棒。

在考慮如何實現這個需求前,咱們先討論下電腦聲音的三種模式:
1) render模式
該方式實際上就是播放(output)聲音,常見的API如PlaySound, WaveOutXXX, DirectSound等

2) capture模式
該方式實際上就是錄入(input)聲音, 也就是咱們經過麥克風輸入聲音,常見API如WaveInXXX

3)loopback模式
該方式就是咱們須要實現的方式,即把揚聲器裏播放的聲音抓取下來。

對於上面3種方式,render和capture方式應該比較好理解, 也都是系統有API直接支持的方式, loopback方式就比較奇怪了,在XP上該方式系統實際都沒有正式支持, loopback的錄製方式實際上也涉及到CD的版權問題。

下面是XP時代的Audio架構圖, 該架構下audio的合成和壓縮都是在系統內核裏進行的:

在XP這種方式下,咱們要抓去聲卡播放的聲音沒有正規的方式, 通常來講只有2中: 
一種是虛擬聲卡,還有一種就是Hook audio 播放相關的API (不少時候咱們會發現API hook是沒有辦法時的全能辦法 ^_^)


可是在Vista以後,微軟修改了原來的媒體架構, 以COM的方式從新封裝了core audio API:
能夠看到原來Auido的API (waveXXX, mixerXXX和DirectSound)都依賴下層的新封裝的Core Audio APIs,並且這些APi都工做在用戶模式, 也就是說聲音的合成是在用戶模式下經過軟件實現的。在Vista以後, 能夠看到咱們能夠單獨控制每一個應用程序的聲音了, 由於每路Audio均可以工做在不一樣的Audio session了。經過新的Core Audio API, 咱們能夠很容易的實現聲卡聲音的抓取, 具體可參考這裏: http://msdn.microsoft.com/en-us/library/ms679146.aspx

可是很快咱們又發現了另一個問題, 在一個網絡會議裏面, 若是共享本身桌面的人加入了VOIP, 另外也有其餘與會者也加入了VOIP, 與會者說話的聲音會在共享桌面端播放出來,可是該聲音和共享的應用程序的聲音又被一塊兒被抓下來後發給了原來的與會者, 這樣就有回聲了。

這裏就涉及到抓取聲卡聲音時可否排除掉某個聲音,惋惜答案是系統WASAPI不支持這種方式。可是由於與會者VOIP的聲音是咱們本身播放的,因此咱們有該聲音樣本, 理論上咱們能夠經過噪聲消除從混音裏過濾掉與會者的聲音,固然這塊知識過高深,須要專門的人才能作了。

相關文章
相關標籤/搜索