XAMP開發秘話01 音效輸出篇

有用過Foobar 2000的人因該多多少少聽過或用過WASAPI 輸出,這讓許多人認識到Windows也可以跟發燒搭的上邊。Windows 經歷多個過版本的演進之後,從早期waveOut和DirectSound 至WDM driver 的 Kernel Stream並到Windows Vista之後的WASAPI,低延遲與多種場景使用是Windows 改善的重點。

  1. 低延遲(等於原音重現):也許很多人認為低延遲對於撥放沒有幫助。低延遲其實考驗OS從用戶模式到 Mixer到音效卡時間,這之間如果資料經歷某些DSP處理,可能就沒辦法這麼快到達音效卡。
  2. 多種場景使用:低延遲代表的是對電量與系統負載越高,這對需要長時間使用時間的設備卻是一種負擔。
發燒友都知道Foobar 2000有一種特殊的獨佔WASAPI 輸出模式,可以讓系統所有音效都失效,如果有不知道的人還以為系統出現問題了~

Push 與 Event 傻傻分不清楚?
在Foobar 2000中獨佔WASAPI 輸出模式就是Event模式,另外一個Push 就是所謂共享模式。
接下來我們來細細描述一些細節。
Event模式如同它的名字一樣它需要等待某個系統發生事件之後,才能夠將聲音資料拷貝至系統提供的緩衝區,當然你不能夠讓你的撥放軟體去等待這個事件,需要讓某個服務該事件執行序(Thread)去等待,否則等待的期間你的撥放軟體無法接受用戶輸入的訊息。這個也是絕大部分的撥放器的音效輸出所做的事情。

這個等待事件執行序如同系統其他執行序相同,都需要經過排入系統調度器中,低延遲意味著需要更高的優先權,優先進出系統調度器中來保證低延遲。

大部的撥放器WASAPI輸出:一個執行序 + 調高系統對此執行序優先級(MCSS)。

窺探早期的foo_asio原始碼即可得知道,Foobar 2000為了改善舊版Windows對於系統負載變高之後導致提高執行序優先級失效的問題,採取子行程(Child Process)的方式並利用IPC進行通訊,這無疑的導致系統呼叫變多導致系統負擔變大。
XAMP 採用的Windows提供Microsoft Media Foundation 多序池,改善了傳統的做法中一個執行序需與系統搶資源的窘境。

除了輸出優化之外,還需要考慮解碼器與音效輸出資源競爭的問題。大部分的撥放器解碼後的資料結構設計均採用互斥鎖+環狀的SPSC柱列的來進行設計,互斥鎖會增加撥放延遲,最差的狀況就產生爆音。XAMP採用的是無鎖式(lock free)記憶體緩衝區,有效的降低降低撥放時的延遲。



留言

這個網誌中的熱門文章

升級電腦

[心血來潮的介紹] 在我心中滿分自動筆 STAEDTLER 925 25

使用spdlog的時候win32平台如何加速編譯?