工作中有個需求是關于抓取揚聲器的聲音, 為什么會有這個需求?
試想我們在共享遠程桌面時,如果能夠把本地桌面應用程序的聲音也一起發給對方, 用戶體驗該是多么棒。
在考慮如何實現這個需求前,我們先討論下電腦聲音的三種模式:
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的聲音是我們自己播放的,所以我們有該聲音樣本, 理論上我們可以通過噪聲消除從混音里過濾掉與會者的聲音,當然這塊知識太高深,需要專門的人才能做了。
posted on 2014-08-21 23:34
Richard Wei 閱讀(14964)
評論(5) 編輯 收藏 引用 所屬分類:
windows desktop