指標¶

關於一段音訊,可以問兩種問題。一是這段錄音本身好不好,任何音訊都能問;二是它離自己的乾淨版本有多近,這就得先有那個乾淨版本。面板上半部不需要任何參考訊號,回答第一種;下半部回答第二種;兩者下方共用一張表格,顯示最後執行的那一項。每個按鈕旁邊都有一行,寫著它背後的 kudio 呼叫。
這裡的每項量測都針對整段音訊,選取範圍不影響結果。
檢查這段音訊¶
「檢查這段音訊」對整段音訊執行 kudio.audio_report,並填入表格:
| 列 | 意義 |
|---|---|
| 峰值 | 最大的樣本值,單位 dBFS;全部為零時顯示「靜音」 |
| RMS | 平均音量,單位 dBFS |
| 響度(BS.1770) | 整合響度,單位 LUFS。沒有數字時會寫出原因:全部為零時顯示「靜音」;短於一個 400 ms 閘控區塊時顯示「不適用(短於 400 ms)」;含有 NaN 或 inf 的音訊,或小聲到每個區塊都在 BS.1770 的 −70 LUFS 閘門以下的音訊,顯示「不適用」 |
| 削波樣本數 | 停在滿刻度平頂上的樣本,連續三個以上才算,以及它們佔整段的比例 |
| DC 偏移 | 樣本的平均值;健康的錄音應該落在零 |
| 靜音 | 30 ms 幀中,比大聲的幀低 40 dB 以上的比例 |
| 底噪 | 最安靜那些幀的音量,取第 10 百分位數,單位 dBFS |
| 估計 SNR | 大聲的幀(第 95 百分位數)相對於底噪。這是從單一訊號估計出來的,不是拿乾淨訊號比對量到的 |
| 頻寬 | 內容實際延伸到多高,以及取樣率允許到多高 |
一兩個樣本碰到滿刻度不算削波;浮點音訊超過 1.0 但仍然描出完整波形,也不算。只有貼在上限的一段平頂,才是資訊真的已經丟失了。
按鈕下方列出錄音本身的問題,一行一個,以警示色顯示:
| 顯示的文字 | 出現的條件 |
|---|---|
有 … 個樣本不是有限值(NaN 或 inf) |
音訊已損壞。這時只會出現這一行,因為其他數字都沒有意義了 |
這段音訊是數位靜音 |
所有樣本都是零 |
有 … 個樣本削波(佔整段的 …%) |
只要有任何一段削波 |
峰值 … dBFS,超過滿刻度 |
浮點音訊超過 0 dBFS 但還沒削波。一寫成整數格式就會削波 |
峰值 … dBFS,緊貼上限 |
峰值高於 −0.5 dBFS |
峰值只有 … dBFS — 非常小聲 |
峰值低於 −30 dBFS |
DC 偏移 … |
偏移的絕對值超過 0.01 |
內容到 … Hz 就沒了,檔案卻標示 … Hz |
內容在取樣率一半的 90% 以下就結束,通常表示它是升頻而來的 |
整段有 …% 是靜音 |
靜音超過 60% |
估計 SNR 約 … dB |
估計 SNR 低於 10 dB |
一個都沒有時,那一行會寫:
「檢視」面板上的「音量」讀數隨時都在做同樣的檢查,並顯示最常看的那幾個數字。這張表格則是它們背後的數據,想知道底噪或 DC 偏移的確切數值時用得上。
DNSMOS¶
audio_report 回答的是錄音在技術上有沒有問題。聽起來好不好則是主觀判斷,沒有聽測小組時,唯一的辦法是用聽者評分訓練出來的模型。「預測主觀分數(DNSMOS)」透過 kudio.dnsmos 執行 DNSMOS(ITU-T P.835),在表格中填入三個 1 到 5 分的分數:
| 列 | 評的是什麼 |
|---|---|
| SIG(語音) | 語音本身,不管背景 |
| BAK(背景) | 背景有多不干擾 |
| OVRL(整體) | 整體品質 |
| 平均的視窗數 | 這些分數是幾個 9 秒視窗的平均 |
三個分數我都列出來,而不是只給一個平均,因為降噪時 SIG 與 BAK 會往相反方向走。壓得越用力,背景越乾淨,語音卻被吃掉,取平均正好會把你想判斷的那個取捨藏起來。
按鈕下方會有一行白話的結論。OVRL 4.0 以上叫「乾淨」,3.0 以上「可用」,2.0 以上「差」,更低則是「很差」;SIG 與 BAK 相差超過 0.7 時,還會補上一句說明:
反過來,SIG 明顯高於 BAK 時,那句說明是語音保住了,但背景仍然干擾。
模型是以 16 kHz、9.01 秒的視窗訓練的,所以音訊會先重新取樣到 16 kHz,再一個視窗一個視窗地評分,視窗之間相隔一秒。比一個視窗短的音訊會重複接起來直到填滿一個視窗,而不是補靜音,因為模型會把靜音評成被破壞的語音:2 秒的音訊會變成 16 秒、七個視窗。
DNSMOS 需要什麼¶
兩樣東西,基本安裝都不包含:
- onnxruntime,用
pip install "kudiostudio[dnsmos]"安裝; - 模型權重
sig_bak_ovr.onnx。它屬於 Microsoft 的 DNS-Challenge,也由那裡發布,所以 kudio 與 KudioStudio 都沒有隨附。請 clone https://github.com/microsoft/DNS-Challenge,並在啟動kudiostudio之前,把環境變數KUDIO_DNSMOS_DIR指向其中的DNSMOS資料夾。這個變數也可以直接指向模型檔本身。面板呼叫的是不帶model_dir的kudio.dnsmos(y, sr),所以這個變數是它找到權重的唯一途徑。
缺了任何一樣,面板會完整顯示 kudio 自己的訊息,因為那則訊息會告訴你缺的東西去哪裡拿。兩種訊息與對應的指令都在疑難排解。
與乾淨參考訊號比較¶
每個品質指標都是拿音訊與它的乾淨版本比較。合成資料集有乾淨版本,真實錄音永遠沒有:它的原始版本就是含噪的那一個,所以拿它來評分,量到的是你改動了音訊多少,而不是你有沒有改善它。
「參考訊號」決定要和什麼比較:
原始音訊(編輯之前)- 開啟或錄下時的音訊。只有當你開啟的本來就是乾淨的音訊時,它才算乾淨的參考訊號。先開一段乾淨的錄音,在效果加上雜訊或房間,再到增強降噪,這時按「評估」,評的就是降噪器相對於起點的表現。
檔案…- 在「檔案」欄選的檔案。它會以單聲道、以這段音訊的取樣率讀入,必要時重新取樣,所以取樣率不同的參考訊號照樣能逐樣本比較。
「評估」會先量測兩者之間的偏移(見下一節),再填入只靠 numpy 就能算的幾項:SNR、SI-SDR、「分段 SNR」,以及實際評分了多少樣本的「比較的樣本數」。PESQ、STOI 與 SDR 在背景工作中計算,完成後加進表格。缺少後端的那一項,會在該列說明原因(見下文)。
先對齊¶
這裡的每個指標,都是拿參考訊號的第 i 個樣本與這段音訊的第 i 個樣本比較。下面是一段錄音和它自己延遲 128 個樣本(16 kHz 下是 8 ms)的副本比較的結果:
光看第二個數字,分不出是「這兩段沒對齊」還是「處理把訊號毀了」,偏偏這兩者的意思正好相反。所以每次按「評估」,都會用 kudio.find_delay 量測偏移,並放在表格的第一列:
「落後」表示這段音訊比參考訊號晚,「超前」表示比較早;若其中一個上下顛倒,還會加上「極性相反」。反相的副本仍是同一段錄音,只是處理鏈中某處把它翻轉了,這本身就值得知道,所以只回報、不自動修正。
「先與參考訊號對齊」預設開啟,會在評分前去除偏移:兩個訊號都修剪到彼此重疊的那一段,所以「比較的樣本數」可能比整段音訊略少。狀態列會說去掉了多少:
關掉它,就照兩者原本的樣子評分。偏移仍然會被量測與回報,並多出一列警告:
在最佳偏移處的相關係數低於 0.5 時,兩者就不是同一段錄音,不論開關怎麼設:
這時面板會直接評分,不做對齊。互相關總是找得到某個最佳偏移,把兩個無關的訊號照它對齊,只會產生一個看起來很有把握、實際上毫無意義的數字,這比一個明顯很差的數字更糟。
哪個指標需要什麼¶
| 指標 | 需要 | 備註 |
|---|---|---|
| SNR、SI-SDR、分段 SNR | 不需要額外安裝;numpy | 隨時可用 |
| STOI | pip install "kudiostudio[eval]" |
去掉靜音後要有約 0.4 秒的語音 |
| SDR | pip install "kudiostudio[eval]" |
BSS-SDR,來自 mir_eval |
| PESQ | pip install "kudio[pesq]" |
要從原始碼編譯,需要 C 編譯器,Windows 上則是 MSVC Build Tools。只支援 8 或 16 kHz |
| DNSMOS | pip install "kudiostudio[dnsmos]" 與模型權重 |
見上文 |
PESQ 自成一個 extra,是因為它要編譯。若放進 [eval] 或 [all],沒有編譯器的機器連那兩組都裝不起來。
表格下方那一行說明哪些後端已經裝好,沒裝的則附上安裝指令:
這些指令寫的是 kudio 的 extra。kudiostudio[eval] 裝的東西與 kudio[eval] 相同,PESQ 則沒有對應的 KudioStudio extra。沒有分數的列會說明是三種情況中的哪一種,因為處理方式各不相同:
- 「未安裝」:缺少後端;
- 「在 44100 Hz 下沒有定義(PESQ 僅支援 8 或 16 kHz)」:PESQ 已安裝,但標準只涵蓋這兩種取樣率;
- 「這一對無法計算」:已安裝、也有定義,卻仍然在這兩個訊號上失敗,例如語音太少的 STOI。
若三種情況都寫成「未安裝」,就等於叫你去裝已經裝好的東西。後端只在每次啟動時檢查一次,所以裝好之後請重新啟動 kudiostudio。
PESQ:MOS-LQO 還是 raw¶
PESQ 有兩種尺度,「PESQ 尺度」決定表格顯示哪一種。該列的名稱會寫明是哪一種:PESQ (MOS-LQO) 或 PESQ (raw P.862)。
- MOS-LQO
- 預設值,也是 kudio 平常回報的:映射到兩份標準共同定義的 MOS 尺度上的分數。16 kHz 時是寬頻 PESQ(P.862.2),8 kHz 時是窄頻。
- raw P.862
- 經過 P.862.1 映射之前的窄頻分數,範圍 −0.5 到 4.5:ITU 參考程式印出的就是它,多數語音增強論文引用的也是它。在 16 kHz 下選它,PESQ 也會以窄頻模式執行,因為 P.862.2 沒有定義 raw 分數。
兩者是不同的尺度,不是不同的捨入方式。raw 2.03 大約等於 1.66 MOS-LQO,所以拿一份 raw 分數去和論文的 MOS-LQO 並列,或反過來,比的是兩個根本不能比的數字。把自己的結果放到論文旁邊之前,先確認那篇論文引用的是哪一種。