2013年10月22日 星期二

linux要享受高品質的聲音...取樣率要和windows一樣要斤斤計較(lubuntu的alsa修改預設音效取樣率)

2015/05/01更新:新的改法(適用deadbeef player),感謝MEEEEE大

首先要提一下ac97和hdaudio,不過我只簡單提一下取樣率的那些事

ac97規定音效卡的取樣率是48khz,深度16bits,遵守就對了...你做更多功能ac97也不會多支援的
hdaudio除了48k/16bits之外,可以支援到96k/24bits,似乎允許混搭(例如工作在96k/16bits)

問題來了,cd用的44.1khz從來沒被支援過。

於是市場上有不少稍微講究點的卡片就這樣冒出來,同時支援了ac97、hdaudio用的48k和96k取樣,還額外支援了cd的44.1k取樣,只要你的播放程式支援,就能夠在不做重新取樣的情況直接輸出cd品質的聲音

至於內建音效嘛...雖然spec寫說晶片有支援,可是往下翻幾頁就會看到支援方式...把44.1k塞幾個重複的取樣點變成48khz,難怪不好聽。

於是高品質的軟體重取樣就登場了。

高品質的軟體重取樣技術,是基於傅立葉的數學公式,使用sinc放在每個紀錄點上面加總,藉此有限的重建出更細密的原始訊號波形...當然還是要遵守取樣限制啦,就是取樣率最高只能紀錄到取樣率一半頻率的那個限制...

既然可以重建出細密的訊號波形,那就可以用正確的速度和符合硬體限制的取樣率再重新取樣一次,然後輸出...是的,基本上就是作白工繞遠路,不過差異是聽得出來的。

而我習慣的設定,則是完全倚重重取樣,將44.1khz取樣率的訊號「拉皮」用96khz輸出,至少在理論上能夠將sinc重建的訊號波形的所有細節,都盡可能的輸出。使用96khz的理由則是因為我周圍的機器都已經支援到96k的輸出能力了,偏不好好支援44.1k(嘆


有在windows用過foobar2000的使用者,應該都對那堆難搞的設定有印象,偏偏foobar2000又是windows上音質出名的播放程式,而他其中一個有梗的地方,是可以使用dsp做軟體重取樣來配合一般電腦不怎樣的內建音效晶片的聲音取樣率...當然不能讓一顆一塊美金的便宜音效晶片身價暴漲,但是至少可以讓他「演得像一點」,不至於被內建的簡易取樣率轉換毀掉音質。

我曾經讓同學盲聽測試,不開重取樣直接播放air原聲帶第一曲,那些鋼琴音銳得像是刀片,就連便宜的mp3都比較好聽;開了重取樣之後,聽起來就正常多了...當然不能和有點身價的音效卡pk,也算是聊勝於無啦...

當然,linux上的deadbeef,也有這樣的重取樣dsp能用,也可以設定重取樣到什麼頻率去...如果王子和公主真的幸福美滿那我就不用寫啦!那個重取樣設定最後還是要跟著你的系統音效處理跑啊!

我剛用linux不久,也只知道一個alsa音效層,這一層做了一件事情,一件軟體工程師會笑,音響工程師會哭的事情
他又重取樣了一次!對!他又重取樣了一次!有沒有很熟悉?windows也會這樣重取樣一次!所以foobar2000才要搞出核心音訊流和asio繞過win那層機車api,結果到了linux他又重取樣了一次!

也就是說,就算我在deadbeef用高品質的sinc重取樣「拉皮」到96k取樣,輸出之前經過alsa又要被alsa用內部設定拉...到設定值去。

我不清楚linux尤其是各發行版在安裝的時候會怎麼設定這個值,不過我用的lubuntu12.4看來是用了一個安全值,48k取樣,一個通吃ac97和hdaudio還有幾乎所有音效卡的設定,說不定對一些軟體來說也是個安全數值。

不過我想發揮全部的音效潛力...呃,我說的是升頻之後

所以,來改系統取樣率啦!

放個我自己也很悶的警告:lubuntu14.4.1照文章修改可能導致chromium裡youtube無聲音但是niconico有聲音(重開後才發生,超無言),有請高手分享解決辦法,感恩orz

參考資料,alsa的網頁:http://www.alsa-project.org/main/index.php/Asoundrc

alsa的網頁提到了一個alsa設定檔,只要修改這個設定檔,就能夠改變一些進階設定...

...再次聲明,玩掛了不要找我負責,因為我也不懂(炸

首先可以在終端機輸入cat /proc/asound/card0/pcm0p/sub0/hw_params看到你的alsa部份設定,其中就有關於取樣率的設定

參考資料,ubuntu的問答:http://unix.stackexchange.com/questions/74558/change-sampling-rate-in-alsa

rate這項就是目前的系統取樣率了。如果你想要把系統取樣率拉高到硬體的最高設定,那就打開那個alsa設定檔吧。以我的電腦為例,他在usr/share/alsa裡面,那個alsa.conf就是了

要注意的是,這個檔案的所有人是root,你必須用root權限才能修改這個設定檔

要修改的是這行

defaults.pcm.dmix.rate 48000

我的內建音效晶片最高可以工作到96k,那麼我就改他變成:

defaults.pcm.dmix.rate 96000

最後存檔

可惜目前還不知道有沒有辦法只在某軟體運作的時候用特定取樣率(例如有好音效卡的話,播放時使用44.1k,播放停止就回到系統設定)

接下來重開deadbeef,外掛裡面那個alsa輸出設定的「使用alsa再取樣」可以拿掉了,dsp裡那個resampler就讓他重取樣到你設定的,呃,像我就是96k。理論上這次他會乖乖的重取樣到96k並且輸出96k了。


釋疑:就算沒大費周章改alsa,重取樣還是可以設定成96k?

答:就算重取樣到96k,只要外掛那個alsa輸出設定的「使用alsa再取樣」沒拿掉,那96k會再被轉一次,使他和alsa輸出設定相同...就真的做白工了


釋疑:不改alsa設定,只把「alsa再取樣」取消會怎樣?

答:理論上重取樣的dsp應該要去跟alsa要一個96k輸出的通道來用(大概吧)不過載我的電腦顯然是沒去要來,反而讓音樂播放速度變成0.5倍速了orz(96k用48k播放剛好是半速)


釋疑:這麼麻煩,我插張好音效卡搞定他?

答:除非deadbeef哪天學foobar2000搞個核心音訊流什麼的方法繞過alsa重取樣,否則,換了卡片還是要去改alsa...只是這次你可以改成44100或者他的倍數了


釋疑:沒圖沒真相,我看不懂

答:我在逃避所以才跑來寫這個不能當論文發的鬼東西,寫寫又想睡啦,哪天有想到的話再考慮補圖吧...而且我也不知道要補啥w

7 則留言:

MEEEEE 提到...

請問,沒有更改預設取樣率,然後也去ALSA外掛設定那邊把ALSA再取樣取消

這樣播出來的就是音樂原本的取樣率了嗎?
(聲音沒有變快或變慢,內建音效晶片有支援到192khz)

MEEEEE 提到...

我查詢了一下,你那個會用半倍速播放應該是因為你選擇了有"default"的選項,所以他就會照預設的48khz播出

像我選擇"Front Speakers"就不會有問題

sean robot 提到...

啊抱歉現在才看到
通常...以我所知道的,alsa再取樣這個是要讓deadbeef不管用什麼格式出聲音,都會被alsa再取樣給規範成系統設定的格式
如果alsa再取樣這項關閉,那應該會變成deadbeef丟給dsp裡面的resampler做軟體升頻成指定取樣率以後再輸出

那如果把resampler也關了呢?

那應該就是聲音原始格式長怎樣就直接丟給音效晶片去處理!可是如果你是主機板內建音效,不管有沒有支援192khz,都應該避免選這項...以螃蟹音效晶片來說,他處理44.1khz音訊的方法就是塞點垃圾讓他膨脹成48khz,然後用48khz的硬體來輸出...這就是軟體再取樣為什麼存在的原因了。


另外你指的是輸出裝置這項嗎?如果說動這個可以跳過預設設定,在原理上也說的通,我卻從來沒想過w等下來玩玩看,感謝啦

sean robot 提到...

可以看看這份手冊的16到18頁,variable sample rates這節,有大概敘述怎麼處理44.1khz取樣的音訊(cd格式)
開頭先講hda通道是以48k和其倍數做設計,所以不是48k或倍數的都要先整形。根據計算,在44.1k取樣率跑147筆資料的時間,和48k跑160筆資料的時間一致,所以填充目標是每147筆資料要灌水到160筆,多做13筆假資料才能交出

http://www.hardwaresecrets.com/datasheets/ALC1150-CG_DataSheet_1.0.pdf

方法如下:

轉送12筆資料...共12筆
塞一張空白紙...共13筆
轉送11筆資料...共24筆
塞一張空白紙...共25筆
轉送11筆資料...共36筆
塞一張空白紙...共37筆
轉送12筆資料...共49筆
塞一張空白紙...共50筆
轉送11筆資料...共61筆
塞一張空白紙...共62筆
轉送11筆資料...共73筆
塞一張空白紙...共74筆
轉送12筆資料...共86筆
塞一張空白紙...共87筆
轉送11筆資料...共98筆
塞一張空白紙...共99筆
轉送11筆資料...共110筆
塞一張空白紙...共111筆
轉送12筆資料...共123筆
塞一張空白紙...共124筆
轉送11筆資料...共135筆
塞一張空白紙...共136筆
轉送11筆資料...共147筆
塞一張空白紙...共148筆
轉送11筆資料...共159筆
塞一張空白紙...共160筆

就完成一單位的假資料了。

可是這樣看起來好像只歪一點點,事實就是只歪這一點就造成了內建音效與獨立音效卡之間,無法挽回的鴻溝。一些音響系統為了確保資料在精準正確的時間送出,就這樣多做了一台時間精確的緩衝器放架子上。


那軟體的resampler呢?軟體根據不同的重建選項,會在時間軸上放上44.1khz的148個點的資料,連成一條線以後(點與點之間用直線連的是線性重取樣,用數學公式算出弧線狀的連線則是sinc處理。感謝傅立葉吧,公式他導的),再切成160等分,就變成48khz,而且波型比較連續的資料了。

這樣的重取樣方式的數學運算,是在每個輸入點的位置放一個弦波(其實是sinc波),最後加總,就會變成弧線狀的連線。牽涉到數學運算這種事情,要用硬體也是ok啦(聽說有音響廠真的去開這種ic...不過規格可以被軟體式的處理法輕鬆超車),不過還是軟體比較簡單低成本

扯遠了,總之內建音效除非不遵守hda規範和通道(早一點就是ac97,一樣48k設計),不然都是聲音裡面塞垃圾的設計。所以才說要好聽,不是開軟體重取樣就是買音效卡...

sean robot 提到...

然後,然後的然後,要同時對一大堆資料畫一個sinc,最後又加總還原成高解析度的波型之後,再降低解析度去配合音效輸出裝置...我覺得這工作超級適合用顯卡跑的xddd不過現在cpu都算夠快,所以好像沒看到有誰把這套算法寫到顯卡跑...

MEEEEE 提到...

什麼!原來主機板的音效晶片不能直接輸出44.1khz阿!之前都被windows下面顯示的44.1khz騙了。

再請教一下,您說非48khz倍數的資料都會被用演算法調整到48khz再輸出,那麼96khz和192khz是可以直接輸出的對嗎?

sean robot 提到...

to MEEEEE:

96k和192k硬體可以輸出,但是有可能經過作業系統的軟體混音器。可以考慮選擇讓軟體獨占裝置的選項來避開軟體混音。有正確避開的話,直接輸出96k/192k是沒有問題的。

軟體混音器的簡單例子:右下角的調音量,尤其是win7開始常見的各軟體獨立調整音量...因為如果只是調整體音量,系統是可以發指令給音效晶片叫他硬體調整;可是按軟體分別調音量就幾乎肯定是os的軟體混音處理的了