精華區beta Audiophile 關於我們 聯絡資訊
看完這篇討論串, 我也很好奇為什麼會有這樣子的差距, 所以決定 對播放軟體做一點研究, 另外也對Sound Forge Pro 10.0的程式 做一些分析. 本篇對於非電資主修的朋友可能不是那麼容易理解, 所以建議從結論 那邊開始看. 由於在作業系統裡面, 所有的應用程式都跑在使用者模式(Usermode, a.k.a Ring 3 on x86), 基於安全考量, 及確保系統安定, 使用者 模式內不能跟硬體溝通. 而跟可以跟硬體溝通的程式, 也就是驅動程式 都在核心模式(Kernelmode, a.k.a Ring 0 on x86)下面運行. 因此, 所有播放聲音的動作都需要透過核心模式的驅動程式. 在Windows作業系統下面, 由於時常有不同的程式會需要輸出聲音, 作業系統就內建有mixer, 他會將不同程式丟出來的聲音混合起來, 並且在需要的時候(硬體不支援時), 執行Sample Rate Conversion, 或是Bitrate Conversion. 當然, 剛剛提到Kernelmode跟Usermode的概念, 也就是說SoundForge, Foobar2000之類的軟體不能之接跟硬體溝通, 他們需要透過一些方法 跟核心的驅動程式溝通, 才能夠播放聲音. 常見的方法有: - WaveOut: 這種方式是最常見的, 一般來說沒有特別需求的程式都使用種方式. WaveOut的輸出會到核心裡面的mixer, 做混音的動作. 使用這種方法 的程式會載入winmm.dll, 並且呼叫裡面的函數. - DirectSound: 比起WaveOut, 這種方式題供較多的功能, 但他在舊版的Windows上面 (Windows NT, 98, 95... etc)的支援比較差. DirectSound是DirectX 的一部分, 他原本的設計是用於遊戲上面. DirectSound的輸出也是 到核心的mixer, 使用這種方法的程式會載入dsound.dll, 並呼叫裡面 的函數. - WASAPI: 在Windows Vista/7下面, 由於微軟認為有DirectSound跟WaveOut兩個 API很麻煩, 所以微軟開發了WASAPI. WASAPI只被Vista/7支援, 而且 Vista/7下面, DirectSound/WaveOut都是透過WASAPI來運作的. WASAPI 的輸出也是到核心的mixer. - ASIO: 前面三種方法都有一個共同的問題, 就是他們透過系統的mixer. 系統的 mixer可能會改變音訊資料, 而且也會延長程式送資料到硬體收到資料的 時間(latency). ASIO解決了這個問題, 他直接將軟體的資料, 沒有處理的丟給 硬體. 這樣延遲就會減少, 而且音訊資料不會被更改. 再來我們研究Sound Forge的主程式, forge100.exe. 首先我們檢查程式的 PE Header, 發現這支程式是Microsoft Visual C++ 2008寫的, 而且沒有加殼. 另外我們查看他們Import Address Table, 裡面有導入WinMM.dll的函數, 但是沒有發現dsound.dll. 此時我們再用OllyDbg載入主程式forge100.exe. 在CreateFileA()/ CreateFileW()上面下Log斷點, 這樣可以看這支程式存取了哪些東西. 一般 來說, 如果程式有自己的驅動程式, 他會先存取那個.sys, 並且將那個 .sys載入系統, 然後CreateFile()那個.sys的Device Name. 我們在 CreateFile()上面下斷點的用意就是要確認這個程式是否有自己的 驅動程式. 經過檢查, forge100.exe並沒有自己的驅動程式, 所以他應該 是透過上述的四種方法來播放音訊. 當然過程中我們也發現一些有趣的 事情, 例如說forge100.exe有存取一個叫做lsarpc的pipe, 這個pipe是 用來存取系統帳號密碼管理程式的, 當然forge100.exe要存取他來幹麻 就不知道了. 再來, 由於我們之前檢查IAT發現沒有dsound.dll, 但是, 這個DLL模組 仍然可能在程式執行的時候載入, 因此我們斷點在LoadLibraryA()/ LoadLibraryW()上面. 執行後發現, dsound.dll在sfdsound.dll載入之後 就被載入了. 因此Sound Forge有可能是使用Direct Sound. 為了確定, 我們斷點在DirectSoundCreate()跟waveOutOpen()上面, 執行之後, 都沒有break, 但是當我們開啟檔案並且播放時, 發現waveOutOpen() 被執行了, 此時我們Log斷點在waveOutWrite()上面, 在播放的過程中, waveOutWrite()被重複的呼叫, 直到播放暫停為止. 因此我們可以確定 Sound Forge 也是使用waveOut API. 當然, Sound Forge的資料匣內有看到一個資料匣叫做"Audio Hardware Drivers" 裡面有兩個檔案sfasio.dll跟sfdsound.dll, 他們的功用到目前無法 被確認, 或許在經過設定之後這兩個檔案就會被使用了. ----------------------------- 結論 --------------------------------- 經研究發現, Sound Forge使用waveOut系列的API來播放音訊, 這種方法很普遍, 一般的應用程式都是使用他, 而其他播放程式 也有不少有支援waveOut, 或是預設使用waveOut. 所以, Sound Forge在輸出音訊方面並無過人之處. 對於那些聽到差別的, 我認為有下列解釋: - 軟體設定: 大多播放軟體都有插件的功能, 甚至有一些內建有預設就啟用的插件, 這些插件會造成聲音的差別. 另外音量也是很重要的, 一般來說較大的 音量會比較好聽. - Mixer設定: Mixer對於不同的輸入有不同的音量控制, 所以當設定不一制時, 會造成 音量的差距. Sound Forge預設waveOut, foobar2000預設Direct Sound, 因此 有可能會有這樣的問題. - SRC ( Sample Rate Conversion ): 這個晚一點解釋. - 心理作用: 這個時常發生, 因此我建議使用ABX盲測來確認. 實際方法在兩頁之後. 接下來我要講有關Sample Rate Conversion, 但在這之前, 我要建議非 電資主修的朋友們先看一下我上一篇文. Sample Rate Conversion 就是 將音訊從一個採樣率轉換成另一個採樣率, 也就是說, 我們音訊裡面 原本是每秒有n個資料, 我們把他變成每秒有m個資料, 而且之前跟之後的 資料在轉換成類比訊號之後應該要相同. 當然, 這是理想狀況下面, 有許多寫的不好, 或是不想要使用太多CPU的SRC程式在轉換之後, 會讓之前 跟之後的類比訊號有差別. 一般來說, 一個SRC程式在撰寫的時候, 會於到一個抉擇, 就是你要輸出品質好(跟原本的訊號差異小), 還是 執行速度快. 一般驅動程式跟核心Mixer裡面的SRC都是選擇後者, 因為如果一個驅動程式就佔你90%的CPU, 一般的使用者當然會不爽. 再來, 為什麼我們需要SRC? 其實, 大多時候我們不需要. 當我們的 DAC可以接受原始音訊的採樣率時, 我們可以直接將音訊交給DAC, 不需要轉換. 但是當我們的DAC不支援這個採樣率的時候, 我們就 需要做SRC, 這樣DAC才能接受這些音訊資料. 所以對於SRC, 重點在於, 如果可以不用, 那就盡量不用, 但是如果需要, 就要做到好. --------------------------------- ABX 盲測 ------------------------------- ABX盲測其實就是在當你聽過A跟B之後, 隨便從A跟B之中選一個(X), 然後在 你不知道的情況下給你聽, 要你判定是A還是B. 一般這種測試會重複幾次 (通常來說12~20), 然後用統計學的方法計算出你用猜的可能性. 由於我目前沒有看到可以ABX兩套軟體的程式, 所以我就順手寫了一個小程式, 載點如下: ( 原始碼+執行檔, 直接執行ABXClick.exe即可 ) http://stashbox.org/796583/ABXClick.zip 這支程式會幫你亂數選軟體A或是軟體B, 然後幫你按下"播放"鍵. 使用步驟: 1. 先將兩個程式(Sound Forge, Foobar2000)開啟, 然後開啟ABXClick.exe 2. 在兩個程式中開啟待測的音樂. 3. 將Sound Forge跟Foobar2000的視窗縮小並且同時放在螢幕上面, 確保兩個程式的撥放按鈕都可以被看的到. 如圖一. 圖一: http://stashbox.org/796596/ss1.JPG
4. 回到ABXClick視窗, 但是將滑鼠移到Foobar2000的播放按鈕上面, 並且按下F1, 此時, A Position欄位中會出現Foobar2000播放按鈕的螢幕座標, 5. 將滑鼠移到Sound Forge的播放按鈕, 按下F2. B Position欄位中 會出現Sound Forge播放按鈕的座標. 6. 關閉你的螢幕. 7. 此時按下F3, 程式會隨機將滑鼠移到A或是B的位置, 然後按下去, 因此音樂會開始播放. 8. 判定是Sound Forge還是Foobar2000, 並將他寫下. 9. 打開螢幕, 看哪一個程式正在播音樂. 10. 停止播放音樂, 並且回到ABXClick視窗. 11. 重複第六步數次. (建議: 16次) 12. 統計總共幾次測驗中, 有多少次是正確的. 另外你可以從以下Excel檔案中查出你在猜測的可能性: (縱軸是測試數目, 橫軸是正確數目) http://www.kikeg.arrakis.es/winabx/bino_dist.zip 一般來說, 猜測可能性在1%(0.01)以內就是真的聽的出來. 當然, 那些很明顯的差異, 幾乎都會導致全對. 我之前有ABX過一個 MP3 320 cbr vs. FLAC, 由於那MP3有Transient Smearing的 問題, 所以ABX出來就25/25全對. 不過我自己測試Foobar2000 vs. Sound Forge是16/11, 猜測可能性為10.5%, 這代表說我 聽不出來. (大概是太木耳) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.68.68
jacky2523555:未看先推大大認真分享 夜深了= =明天再讀XD 02/16 00:48
sent3:推專業 02/16 00:50
rayzart:你真有實驗精神! 02/16 00:51
djo:太過專業只能END推@@ 02/16 01:06
jikanson:哇靠 這超強的 XDD 02/16 01:14
capri75:這一篇文章值 1000 元 超強! 02/16 01:29
greenguy:推薦這一篇屌文 還是懶人好用foobar最棒了XD 02/16 01:31
levine21:推啊 超強大的!! 想請問有辦法弄出同一套軟體 02/16 01:56
levine21:然後不同的輸出(例如音效卡或是KS DS這類的) 02/16 01:57
levine21:有辦法用類似的方式"關螢幕盲測"嗎? 02/16 01:57
我建議你可以將一個支援多輸出選項的軟體連續開兩次, 然後兩個視窗 用不同的輸出選項, 然後同上述方法做ABX.
lyokuhana:專業推 02/16 03:17
sadowsky:好文:D 02/16 04:35
sifun:推專業好文 輸出的部分跟我試用的判斷的吻合 02/16 05:03
wylscott:看無只能end推 02/16 08:40
motokare:推ABX 看音響板長知識!! 02/16 08:44
wumin0304:推認真與專業!! 02/16 08:53
pai74424:不推怎麼行... 02/16 09:31
sweshi:推。不過音響這東西,靠理論是說不清的...XD 02/16 10:27
edcrfvm45:這個軟體不支援ASIO嗎? 但我輸出選項可以選LYNX ASIO 02/16 11:55
我對Sound Forge這個軟體不熟, 文中也提到發現有兩個類似輸出插件的DLL, 但是這兩個DLL並沒有被程式使用, 我當時也沒有發現有什麼方法可以使用 這兩個DLL. 如果你知道如何設定Sound Forge使他使用不同的輸出方法, 我希望你可以跟大家分享, 因為我也很想知道.
edcrfvm45:A和B我覺得差異不大,不排除是心理作用 02/16 11:56
edcrfvm45:但C就很明顯 02/16 11:56
如果驅動程式沒有做好SRC, 那確實會差很多. 如果你發現SRC造成你音質變差, 那我建議用Sound Forge的SRC, 然後重新存檔. 之後再用你覺得方便的播放程式 來播放, 這樣就可以得到方便性跟音質.
aalaya:這太專業了! 02/16 12:46
blackstyler:先推~另外想問問題 WASAPI也會過mixer囉? 02/16 12:47
blackstyler:有看過WASAPI也是直接跟硬體溝通的方法 02/16 12:48
blackstyler:還是說過不過mixer跟有沒有直接跟硬體溝通沒有關係呢? 02/16 12:49
我是沒有寫過或是研究過使用WASAPI的程式, 不過我剛剛去MSDN了解一下. WASAPI有兩種運作模式: - Shared Mode: 這種模式是一般程式使用的, 會透過Mixer, 所以可以讓很多程式同時 播放聲音, 也可以做音量控制. - Exclusive Mode: 這種模式類似ASIO, 他直接跳過Mixer, 以降低Latency, 他也不會 對你的音訊做任何處理, 因此無法透過一般的方法調整音量, 而且同時也只能有一個程式使用Exclusive Mode.
blackstyler:另外想請問KS的運作方式是什麼呢? 02/16 12:49
blackstyler:所以這樣看來要得到最原始的資訊還是需要用ASIO? 02/16 12:51
KS跟ASIO很類似. ASIO是由一間叫做Steinberg的公司開發的, 而 Kernel Streaming是微軟開發的. 基本上來說他們解決的問題是一樣的, 他們都穿越mixer, 而且有低Latency.
bear0418:對於流程的概念受益良多 想棄物理改電資了(誤 02/16 13:07
物理是電資的基礎, 而且大學入學分數物理還比資工高, 說真的我當時也很想去唸物理.
bear0418:請問如果想多了解此類知識可以看什麼書籍呢? 02/16 13:17
如果對Windows作業系統有興趣的, 有一本叫做Windows Internal的書, 寫的很詳細. 當然如果只是要多了解API, 那去MSDN上面找一找即可.
artf08:專業+1 02/16 13:42
※ 編輯: john0312 來自: 114.32.68.68 (02/16 14:42)
gloryhzw:GJ 02/16 14:25
wayne0411:電資是從物理分出來的...抓著物理好好念比較猛拉XD 02/16 14:44
LittleKuu:推專業文! 02/16 15:32
levine21:專業回答 再推!! 02/16 18:25
bear0418:= =好吧 我繼續把我的物理唸完 不過這領域還真有趣xd 02/16 19:08
bear0418:感謝你推荐的書籍 我會找找看的@@希望會看的懂 02/16 19:09
lastfantasy:高手!! 02/16 19:12
edcrfvm45:個人是無法判斷它到底使用哪個API 02/16 19:12
edcrfvm45:但是preference->輸出選項中 有ASIO選項可以選 02/16 19:13
edcrfvm45:我的AES16應該是沒有SRC的問題 02/16 19:14
louis0407:John 你弄不出asio會不會是因為你的音效裝置不支援啊 02/16 19:28
louis0407:這類專業軟體應該會自動偵測音效裝置是否支援asio 02/16 19:28
edcrfvm45:XD 有可能 那以上都白講了... 02/16 20:12
f9999:應該沒有自動偵測自動設定這麼神,預設還是會用WDM 02/17 00:17
f9999:ASIO都要另外設定 02/17 00:18
davidbright:不推不行.. 02/17 13:12
scfty:帥強阿!! 實在太誇張惹!! 02/18 22:50
Zender:樓上你好阿 02/19 00:09
tubahorn:太專業!不推不行,找時間慢慢研究,感謝! 03/06 19:03