【資料壓縮11】Lab6 MPEG音頻編碼實驗
文章目錄
- 【資料壓縮11】Lab6 MPEG音頻編碼實驗
-
- 一、實驗目的
- 二、實驗原理
-
- 1. 感覺音頻編碼設計思想
-
- (1)基本思想
- (2)上下兩條線
- (3)時頻沖突
- (4)子產品組成
-
- - 多相濾波器組(Polyphase Filter Bank)
- - 心理聲學模型(Psychoacoustic Model)
- - 比特配置設定器(Bit Allocator)
- - 裝幀(Frame Creation)
- 2. 心理聲學模型實作過程
-
- (1)将樣本變換到頻域
- (2)确定聲壓級别
- (3)考慮安靜時門檻值
- (4)音頻信号分解
-
- 臨界頻帶(Critical Band):
- (5)音調和非音調掩蔽成分的消除
- (6)單個掩蔽門檻值的計算
-
- 隐蔽值計算:
- (7)全局掩蔽門檻值的計算
- (8)每個子帶的掩蔽門檻值
- (9)計算每個子帶信号掩蔽比(signal-to-[mask](https://so.csdn.net/so/search?q=mask&spm=1001.2101.3001.7020) ratio, SMR)
- 3. 碼率配置設定
-
- (1)在調整到固定的碼率之前
- (2)比特配置設定的過程
- 三、實驗内容
- 四、實驗結果
-
- 1. 輸出某一資料幀的各種資訊
-
- (1)`m2eanc.h`頭檔案中打開`FRAME_TRACE`
- (2)`m2eanc.c`的main函數中加入`FRAME_TRACE`
- 2. 三個不同特性的音頻檔案
-
- (1)音樂
- (2)噪聲
- (3)音樂+噪聲
- 4. 結論
- DEBUG
一、實驗目的
- 了解程式設計的整體架構
- 了解感覺音頻編碼的設計思想
- 兩條線
- 時-頻分析的沖突!
- 了解心理聲學模型的實作過程
- 臨界頻帶的概念
- 掩蔽值計算的思路
- 了解碼率配置設定的實作思路
二、實驗原理
1. 感覺音頻編碼設計思想
MPEG-1 Audio LayerII編碼器原理如下
- 輸入PCM碼流,采樣率為32,44.1或48kHz;
- 輸出為32kbps到384kbps。
(1)基本思想
基于人的生理和心理感覺特性(心理聲學模型),分析信号,對不被感覺的部分不編碼。聲音壓縮算法可以确立這種特性的模型來取消更多的備援資料。
(2)上下兩條線
- 上支線:子帶分解考慮時域。子帶分析濾波器組使信号具有高的時間分辨率,確定在短暫沖擊信号情況下,編碼的聲音信号具有足夠高的品質。
- 下支線:FFT和心理聲學模型考慮頻域。信号通過FFT運算具有高的頻率分辨率,因為掩蔽門檻值是從功率譜密度推出來的。
- 上支線為下支線的心理聲學模型提供比例因子;下支線為上支線的量化器提供比特配置設定。
(3)時頻沖突
由于傅裡葉變換的缺陷,變換結果隻表示了信号中存在哪些頻率,并不能表示某個頻率出現的時間,如果時域上不同時刻出現尖峰,在頻域上看兩者是一樣的。
(4)子產品組成
- 多相濾波器組(Polyphase Filter Bank)
将 PCM樣本變換到32個子帶的頻域信号。
如果輸入的采樣頻率為48kHz,那麼子帶的頻率寬度為48/(2*32)=0.75Hz
- 等帶寬的濾波器組與人類聽覺系統的臨界頻帶不對應 ;
- 濾波器組與其逆過程不是無失真的;
- 子帶間頻率有混疊 ,混疊:一個單頻正弦信号輸入可能在兩個子帶中産生非零信号。
- 心理聲學模型(Psychoacoustic Model)
計算信号中不可聽覺感覺的部分 (計算噪聲遮蔽效應)
- 比特配置設定器(Bit Allocator)
根據心理聲學模型的計算結果,為每個子帶信号配置設定比特數。
- 裝幀(Frame Creation)
2. 心理聲學模型實作過程
(1)将樣本變換到頻域
32個等分的子帶信号并不能精确地反映人耳的聽覺特性。 引入FFT補償頻率分辨率不足的問題。
(2)确定聲壓級别
(3)考慮安靜時門檻值
即絕對門檻值。在标準中有根據輸入PCM信号的采樣率編制的“頻率、臨界頻帶率和絕對門檻值”表。此表為多位科學家經多次心理聲學實驗所得。
(4)音頻信号分解
将音頻信号分解成“樂音(tones)” 和“非樂音/噪聲”部分:因為兩種信号的掩蔽能力不同。
臨界頻帶(Critical Band):
- 指當某個純音被以它為中心頻率、且具有一定帶寬的連續噪聲所掩蔽時,如果該純音剛好被聽到時的功率等于這一頻帶内的噪聲功率,這個帶寬為臨界頻帶寬度。通常認為從20Hz到16kHz有25個臨界頻帶,機關為
。bark
1 Bark = 一個臨界頻帶的寬度
- 研究窄帶噪聲對純音掩蔽量的規律時被發現的
- 使噪聲的中心頻率等于信号頻率,隻改變噪聲的帶寬同時保持噪聲的功率譜密度不變,測試純音聽阈随掩蔽噪聲帶寬變化的特性。
- 純音的聽阈随掩蔽噪聲帶寬的增大而增大,在帶寬增大到某一特定值之後聽阈保持恒定不變。
(5)音調和非音調掩蔽成分的消除
利用标準中給出的絕對門檻值消除被掩蔽成分;考慮在每個臨界頻帶内,小于0.5Bark的距離中隻保留最高功率的成分。
(6)單個掩蔽門檻值的計算
音調成分和非音調成分單個掩蔽門檻值根據标準中給出的算法求得。
隐蔽值計算:
Lutfi 對多個掩蔽音同時存在時的綜合掩蔽效果進行了研究:每個掩蔽音的掩蔽效果先獨立變換然後再線性相加。
(7)全局掩蔽門檻值的計算
(8)每個子帶的掩蔽門檻值
選擇出本子帶中最小的門檻值作為子帶門檻值
(9)計算每個子帶信号掩蔽比(signal-to-mask ratio, SMR)
SMR = 信号能量 / 掩蔽門檻值(SMR傳遞給編碼單元)
3. 碼率配置設定
算法:使整幀和每個子帶的總噪聲—掩蔽比MNR最小
(1)在調整到固定的碼率之前
先确定可用于樣值編碼的有效比特數。這個數值取決于比例因子、比例因子選擇資訊、比特配置設定資訊以及輔助資料所需比特數。
(2)比特配置設定的過程
- 對每個子帶計算
,是噪聲-掩蔽比MNR
與信掩比SMR之差
,其中SNR 由MPEG-I标準給定 (為量化水準的函數) ,信噪比SNR
表示波形誤差與感覺測量之間的誤差;噪聲掩蔽比NMR
N M R = S M R – S N R ( d B ) NMR = SMR– SNR (dB) NMR=SMR–SNR(dB)
- 對最高NMR的子帶配置設定比特,使獲益最大的子帶的量化級别增加一級,每提升1比特,信噪比就可以提升6dB;
- 重新計算配置設定了更多比特子帶的
。NMR
三、實驗内容
- 輸出音頻的采樣率和目标碼率
- 選擇三個不同特性的音頻檔案
- 噪聲(持續噪聲、突發噪聲)
- 音樂
- 混合
- 某個資料幀,輸出
- 該幀所配置設定的比特數
- 該幀的比例因子
- 該幀的比特配置設定結果
四、實驗結果
1. 輸出某一資料幀的各種資訊
采樣率: 44.1 kHz
目标碼率:bitrate = 192.000 kbps
(1) m2eanc.h
頭檔案中打開 FRAME_TRACE
m2eanc.h
FRAME_TRACE
m2eanc.c
的print_config函數中加入
FRAME_TRACE
輸出音頻的采樣率和目标碼率
#if FRAME_TRACE
FILE* output;
output = fopen("output.txt", "a");
fprintf(output, "========== 基本資訊 ==========\n");
fprintf(output, "輸入檔案:%s\n", inPath);
fprintf(output, "輸出檔案:%s\n", outPath);
fprintf(output, "采樣頻率:%.1f kHz\n", s_freq[header->version][header->sampling_frequency]);
fprintf(output, "目标碼率:%d kbps\n", bitrate[header->version][header->bitrate_index]);//輸出檔案碼率
fclose(output);
#endif // FRAME_TRACE
(2) m2eanc.c
的main函數中加入 FRAME_TRACE
m2eanc.c
FRAME_TRACE
輸出某個資料幀所配置設定的比特數、比例因子和比特配置設定結果
#if FRAME_TRACE
FILE* output;
output = fopen("output.txt", "a");
if (frameNum == 2) {
fprintf(output, "聲道數:%d\n", nch);
fprintf(output, "目前觀測第 %d 幀\n", frameNum);
fprintf(output, "本幀比特預算:%d bits\n", adb);
fprintf(output, "\n");
fprintf(output, "========== 比例因子 ==========\n");
for (ch = 0; ch < nch; ch++) // 每個聲道單獨輸出
{
fprintf(output, "------ 聲道%2d ------\n", ch + 1);
for (sb = 0; sb < frame.sblimit; sb++) // 每個子帶
{
fprintf(output, "子帶[%2d]:\t", sb + 1);
for (int gr = 0; gr < 3; gr++) {
fprintf(output, "%2d\t", scalar[ch][gr][sb]);
}
fprintf(output, "\n");
}
}
fprintf(output, "\n");
fprintf(output, "========== 比特配置設定表 ==========\n"); //輸出比特配置設定結果
for (ch = 0; ch < nch; ch++) {
fprintf(output, "------ 聲道%2d ------\n", ch + 1); //按聲道配置設定
for (sb = 0; sb < frame.sblimit; sb++) {
fprintf(output, "子帶[%2d]:\t%2d\n", sb + 1, bit_alloc[ch][sb]);
}
fprintf(output, "\n");
}
}
fclose(output);
#endif // FRAME_TRACE
2. 三個不同特性的音頻檔案
(1)音樂
test.wav
========== 基本資訊 ==========
輸入檔案:test.wav
輸出檔案:test.mp2
采樣頻率:44.1 kHz
目标碼率:192 kbps
聲道數:1
目前觀測第 2 幀
本幀比特預算:5016 bits
========== 比例因子 ==========
------ 聲道 1 ------
子帶[ 1]: 9 11 10
子帶[ 2]: 14 14 14
子帶[ 3]: 19 17 19
子帶[ 4]: 25 23 24
子帶[ 5]: 29 28 28
子帶[ 6]: 23 25 23
子帶[ 7]: 22 22 24
子帶[ 8]: 22 22 21
子帶[ 9]: 29 27 27
子帶[10]: 30 30 32
子帶[11]: 30 29 28
子帶[12]: 27 28 28
子帶[13]: 25 24 28
子帶[14]: 26 27 23
子帶[15]: 23 23 21
子帶[16]: 26 23 25
子帶[17]: 28 31 30
子帶[18]: 30 33 31
子帶[19]: 30 30 29
子帶[20]: 28 29 29
子帶[21]: 29 31 28
子帶[22]: 32 30 30
子帶[23]: 40 39 41
子帶[24]: 54 50 50
子帶[25]: 53 52 55
子帶[26]: 55 53 54
子帶[27]: 51 53 55
子帶[28]: 53 53 52
子帶[29]: 53 53 54
子帶[30]: 53 52 52
========== 比特配置設定表 ==========
------ 聲道 1 ------
子帶[ 1]: 8
子帶[ 2]: 8
子帶[ 3]: 6
子帶[ 4]: 8
子帶[ 5]: 7
子帶[ 6]: 8
子帶[ 7]: 8
子帶[ 8]: 6
子帶[ 9]: 5
子帶[10]: 6
子帶[11]: 6
子帶[12]: 7
子帶[13]: 6
子帶[14]: 6
子帶[15]: 6
子帶[16]: 5
子帶[17]: 5
子帶[18]: 5
子帶[19]: 4
子帶[20]: 6
子帶[21]: 3
子帶[22]: 3
子帶[23]: 0
子帶[24]: 0
子帶[25]: 0
子帶[26]: 0
子帶[27]: 0
子帶[28]: 0
子帶[29]: 0
子帶[30]: 0
(2)噪聲
生成高斯白噪聲
noise_yyx.wav
Number = 100000;
noise_guass= 1*randn(1,Number);
audiowrite('noise_yyx.wav',noise_guass,44100);
========== 基本資訊 ==========
輸入檔案:noise_yyx.wav
輸出檔案:noise_yyx.mp2
采樣頻率:44.1 kHz
目标碼率:192 kbps
聲道數:1
目前觀測第 2 幀
本幀比特預算:5016 bits
========== 比例因子 ==========
------ 聲道 1 ------
子帶[ 1]: 8 8 9
子帶[ 2]: 10 9 9
子帶[ 3]: 9 7 10
子帶[ 4]: 9 7 8
子帶[ 5]: 10 10 8
子帶[ 6]: 8 9 8
子帶[ 7]: 9 8 10
子帶[ 8]: 10 8 9
子帶[ 9]: 9 9 10
子帶[10]: 8 10 8
子帶[11]: 7 7 8
子帶[12]: 8 10 7
子帶[13]: 8 10 8
子帶[14]: 9 9 10
子帶[15]: 9 7 9
子帶[16]: 8 9 10
子帶[17]: 11 9 10
子帶[18]: 8 8 8
子帶[19]: 8 9 9
子帶[20]: 9 9 9
子帶[21]: 9 10 8
子帶[22]: 10 7 7
子帶[23]: 9 9 9
子帶[24]: 9 9 9
子帶[25]: 9 9 11
子帶[26]: 8 8 10
子帶[27]: 9 10 9
子帶[28]: 8 9 8
子帶[29]: 10 10 8
子帶[30]: 10 9 7
========== 比特配置設定表 ==========
------ 聲道 1 ------
子帶[ 1]: 5
子帶[ 2]: 5
子帶[ 3]: 4
子帶[ 4]: 5
子帶[ 5]: 5
子帶[ 6]: 5
子帶[ 7]: 5
子帶[ 8]: 4
子帶[ 9]: 4
子帶[10]: 5
子帶[11]: 4
子帶[12]: 5
子帶[13]: 3
子帶[14]: 3
子帶[15]: 4
子帶[16]: 3
子帶[17]: 4
子帶[18]: 4
子帶[19]: 3
子帶[20]: 3
子帶[21]: 2
子帶[22]: 3
子帶[23]: 3
子帶[24]: 3
子帶[25]: 2
子帶[26]: 1
子帶[27]: 2
子帶[28]: 3
子帶[29]: 2
子帶[30]: 2
(3)音樂+噪聲
[y,~]=audioread('test.wav');
[noise_guass,fs]=audioread('test.wav');
mix=y + noise_guass;
audiowrite('mix_yyx.wav',mix,fs);
========== 基本資訊 ==========
輸入檔案:mix_yyx.wav
輸出檔案:mix_yyx.mp2
采樣頻率:44.1 kHz
目标碼率:192 kbps
聲道數:1
目前觀測第 2 幀
本幀比特預算:5016 bits
========== 比例因子 ==========
------ 聲道 1 ------
子帶[ 1]: 6 8 7
子帶[ 2]: 11 11 11
子帶[ 3]: 16 14 16
子帶[ 4]: 22 20 21
子帶[ 5]: 26 25 25
子帶[ 6]: 20 22 20
子帶[ 7]: 19 19 21
子帶[ 8]: 19 19 18
子帶[ 9]: 26 24 24
子帶[10]: 27 27 29
子帶[11]: 27 26 25
子帶[12]: 24 25 25
子帶[13]: 22 21 25
子帶[14]: 23 24 20
子帶[15]: 20 20 18
子帶[16]: 23 20 22
子帶[17]: 25 28 27
子帶[18]: 27 30 28
子帶[19]: 27 27 26
子帶[20]: 25 26 26
子帶[21]: 26 28 25
子帶[22]: 29 27 27
子帶[23]: 37 36 38
子帶[24]: 51 47 47
子帶[25]: 50 49 52
子帶[26]: 52 50 51
子帶[27]: 48 50 52
子帶[28]: 50 50 49
子帶[29]: 50 50 51
子帶[30]: 50 49 49
========== 比特配置設定表 ==========
------ 聲道 1 ------
子帶[ 1]: 8
子帶[ 2]: 7
子帶[ 3]: 6
子帶[ 4]: 7
子帶[ 5]: 6
子帶[ 6]: 7
子帶[ 7]: 7
子帶[ 8]: 6
子帶[ 9]: 4
子帶[10]: 5
子帶[11]: 5
子帶[12]: 7
子帶[13]: 7
子帶[14]: 6
子帶[15]: 6
子帶[16]: 4
子帶[17]: 4
子帶[18]: 4
子帶[19]: 3
子帶[20]: 5
子帶[21]: 3
子帶[22]: 3
子帶[23]: 0
子帶[24]: 0
子帶[25]: 0
子帶[26]: 0
子帶[27]: 0
子帶[28]: 0
子帶[29]: 0
子帶[30]: 0
4. 結論
- 噪聲:各子帶都配置設定到的比特數相對比較均勻,這說明了這種信源分布比較均勻,對于每種頻率上的音頻都超過掩蔽曲線不少;
- 音樂:比特數集中在前面幾個子帶,後面的子帶配置設定到的比特數較少,這主要是因為人發聲範圍有限,高頻分量較少。基于感覺編碼,聲音信号在時域上非均勻分布,小幅度的樣值比大幅度的樣值出現的機率高;在頻域上功率譜密度非均勻,低頻能量高、高頻能量低。