現在一般常見的聲卡都只支持接收最高24bit的輸入,
因此要使用WASAPI/ASIO Renderer的話解碼輸出應該使用16~24bit的formats。
不過FFDShow有個詭異的邏輯,
全部輸出都勾選的情況下,它的選擇邏輯沒有問題。
但是只勾選16/24bit時,
由於FFDShow裡的EQ、Mixer、volume與Winamp2這四個filter不支持24bit的運算,
因此對24bit的輸入,如果開啟了上述四個filter中任何一個(例如很常用的Mixer),
內部運算輸出的是32bit interger,這種情況下輸出會按照32bit interger輸入的優先級來計算。
而32bit interger輸入時,不允許32bit 輸出的話輸出的優先選擇是16bit而不是24bit,導致較大的質量損失,無法發揮24bit聲卡的優勢。
要想輸出24bit,必須只勾選24bit輸出,而不能勾選16bit。
但是這樣的話不光24/32/float按24bit輸出了,連16bit輸入的也會輸出24bit,造成沒必要的帶寬浪費。
LAV Audio倒是沒這種混亂的問題,不過LAV目前還不支持channel up/downmix;
而且LAV內部需要降低bit depth的時候始終是直接bit shift的,不能像ffdshow那樣開啟dither/noise shaping(當然音頻一般也沒必要就是了…),
所以LAV很多時候還沒法單獨使用(我自己也是全部走LAV解碼,然後輸出原始bit depth的PCM交給ffdshow去進行必要的downmix處理的),
於是自己稍微修改了一下,把ffdshow那個混蛋output formats選擇邏輯改掉了。
下載(ICL12是指ICL12.1編譯的,在Intel的CPU上表現更好,部分filter甚至有30-50%的提速;未標記的是MSVC2010 SP1編譯的):
新版(也許是最後的版本):
ffdshow_rev4505_20130402_tMod_x86.7z
ffdshow_rev4505_20130402_tMod_x64.7z
ffdshow_rev4479_20120812_tMod_x86.7z: MediaFire、NMM-Mirror
ffdshow_rev4479_20120812_tMod_x64.7z: MediaFire、NMM-Mirror
ffdshow_rev4479_20120812_tMod_icl12.1_x86.7z: MediaFire、NMM-Mirror
ffdshow_rev4479_20120812_tMod_icl12.1_x64.7z: MediaFire、NMM-Mirror
這個修改版裡,完整的優先級順序是:
16bit interger輸入按照16bit interger>24bit interger>32bit interger>32bit float的優先級順序輸出;
24bit interger輸入按照24bit interger>32bit interger>32bit float>16bit interger的優先級順序輸出;
32bit interger輸入按照32bit interger>32bit float>24bit interger>16bit interger的優先級順序輸出;
32bit float的輸入按照32bit float>32bit interger>24bit interger>16bit interger的優先級順序輸出。
例如對目前常見的24bit聲卡只勾選16/24bit輸出的情況下,
16bit輸入時則輸出16bit,24/32/32float輸入則輸出24bit。
如果聲卡要求24bit必須pad到32bit,則應該只勾選16/32bit輸出,此時
16bit輸入則輸出16bit,24/32/32float輸入則輸出32bit。
當然如果勾選全部的輸出格式,則和原版一樣沒有影響。
總之原則是能不轉則不轉,在必須轉時優先進行無損的提升bit方式轉換,在必須降bit時優先輸出允許的最高bit depth。
不過正如前面說的,FFDShow裡的EQ、Mixer、volume與Winamp2這四個filter不支持24bit的運算,
因此對24bit的輸入,如果開啟了上述filter的話,內部運算輸出的是32bit interger,這種情況下輸出會按照32bit interger的優先級來計算。
即如果聲卡支持16/24/32bit輸入的話,同時勾選這三個,則
16bit輸入時輸出16bit;24bit輸入時如果不開啟上述四個filter,則輸出24bit,若開啟上述四個filter,則輸出32bit;32bit interger/float輸入時輸出為32bit。
順便貼一下official版ffdshow詭異而坑爹的邏輯下的完整優先級:
16bit interger輸入按照16bit interger>32bit interger>32bit float>24bit interger的優先級順序輸出;
24bit interger輸入按照24bit interger>32bit interger>16bit interger>32bit float的優先級順序輸出;
32bit interger輸入按照32bit interger>16bit interger>24bit interger>32bit float的優先級順序輸出;
32bit float的輸入按照32bit float>32bit interger>16bit interger>24bit interger的優先級順序輸出。