【实验六】MPEG音频编码器

一、实验目的

掌握MPEG编解码系统的基本原理。初步掌握复杂的数据压缩算法实现,并能根据理论分析需要实现所对应数据的输出。

二、实验原理

(一)MPEG音频编码原理

MPEG音频编码框图

1.1 基本思想

感知编码的基本思想是:基于人耳的听觉特性,分析信号,去掉不能被感知的部分

1.1.1 时域
  • 多相滤波器组:将PCM样本变换到32个子带的频域信号。

  • 块形成:每输入32个样本,每个子带滤波器产生1个样本输出,每12个样本作为一个块。Layer1以32*12=384个样本作为一帧,Layer2和Layer3以3*32*12=1152个样本作为一帧。

    数据帧形成

  • 线性量化器:比特分配信息告诉解码器每个样本由几位表示,比例因子用6比特表示,解码器使用这个6比特的比例因子乘逆量化器的每个输出样本值,以恢复被量化的子带值。

1.1.2 频域
  • FFT:使信号具有高的频率分辨率。
  • 心理声学模型:计算信号中不可听觉感知的部分。
  • 比特分配器:根据心理声学模型的计算结果,为每个子带信号分配比特数。
  • 装帧:产生MPEG-I兼容的比特流。
1.1.3 比例因子

对各个子带每12个样点进行一次比例因子计算,查表选择比例因子。

  • 第2层的一帧对应36个子带样值,三个比例因子根据一定的模式和比例因子选择信息一起传送。例如,对于稳态信号,只传送比例因子最大的一个。

1.2 心理声学模型

MPEG-I 标准定义了两个模型。

  • 心理声学模型1

计算复杂度低,但对假设用户听不到的部分压缩太严重。

(1)将样本变换到频域
32个等分的子带信号并不能精确地反映人耳的听觉特性。引入FFT补偿频率分辨率不足的问题。
(2)确定声压级别
子带n中的声压级别L_{sb}计算如下:
L_{sb}(n)=MAX[X(k),20*log_{10}(scf_{max}(n)*32678)-10]dB
其中X(K)是在子带n中的频谱线的声压级别,scf_{max}(n)是在一帧中子带n的三个缩放因子中最大的一个。
(3)考虑安静时阈值
在标准中有根据输入PCM信号的采样率编制的“频率、临界频带率和绝对阈值”表。
(4)将音频信号分解成“乐音(tones)” 和“非乐音/噪声”部分
因为两种信号的掩蔽能力不同,将音频信号分解成“乐音(tones)” 和“非乐音/噪声”部分。
模型1是这样做的:局部峰值为乐音,然后将本临界频带内的剩余频谱合在一起,组成一个代表噪声频率。
(5)音调和非音调掩蔽成分的消除
利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率的成分。
(6)单个掩蔽阈值的计算音调成分和非音调成分单个掩蔽阈值根据标准中给出的算法求得。
(7)全局掩蔽阈值的计算

(8)每个子带的掩蔽阈值
掩蔽扩散:一个掩蔽信号会对其它频带上的信号产生掩蔽效应。
选择出本子带中最小的阈值作为子带阈值。
(9)计算每个子带信号掩蔽比
SMR = 信号能量 / 掩蔽阈值,将SMR传递给编码单元。

  • 心理声学模型2

提供了适合Layer III编码的更多特征。

实际实现的模型复杂度取决所需要的压缩因子

1.3 码率分配

1.3.1 在调整到固定的码率之前

先确定可用于样值编码的有效比特数(取决于比例因子、比例因子选择信息、比特分配信息以及辅助数据所需比特数)。

1.3.2 比特分配的过程
  • 对每个子带计算掩蔽-噪声比MNR,是信噪比SNR–信掩比SMR,即:MNR = SNR–SMR。
  • 计算噪掩比NMR=SMR-SNR,使整帧和每个子带的总噪声—掩蔽比最小。

三、实验步骤

1.对整个算法流程逐步调试

  • 命令行输入-h查看用法
MPEG Audio Layer II encoder

usage:
        m2aenc.exe [options] <input> <output>

Options:
Input
        -s sfrq  input smpl rate in kHz   (dflt 44.1)
        -a       downmix from stereo to mono
        -x       force byte-swapping of input
        -g       swap channels of input file
Output
        -m mode  channel mode : s/d/j/m   (dflt    j)
        -p psy   psychoacoustic model 0/1/2/3 (dflt    1)
        -b br    total bitrate in kbps    (dflt 192)
        -v lev   vbr mode
        -l lev   ATH level (dflt 0)
Operation
        -q num   quick mode. only calculate psy model every num frames
Misc
        -d emp   de-emphasis n/5/c        (dflt    n)
        -c       mark as copyright
        -o       mark as original
        -e       add error protection
        -r       force padding bit/frame off
        -D len   add DAB extensions of length [len]
        -t       talkativity 0=no messages (dflt 2)Files
        input    input sound file. (WAV,AIFF,PCM or use '/dev/stdin')
        output   output bit stream of encoded audio

        Allowable bitrates for 16, 22.05 and 24kHz sample input
        8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160

        Allowable bitrates for 32, 44.1 and 48kHz sample input
        32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384

2.实现以下输出

  1. 输出音频的采样率和目标码率
    parse_args函数中增加条件编译:
#if FRAME_TRACE
  FILE* output;
  output = fopen("out.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 

out.txt文件中输出如下:

========== 基本信息 ==========
输入文件:test.wav
输出文件:test.mp2
采样频率:44.1 kHz
目标码率:192 kbps
  1. 选择三个不同特性的音频文件某个数据帧,输出该帧所分配的比特数、该帧的比例因子、该帧的比特分配结果
  • 利用Audacity生成纯噪声音频和带有噪声的音乐


    纯噪声
噪声+音乐(噪声振幅0.2)
  • main函数增加代码
#if FRAME_TRACE
    FILE* output;
    output = fopen("out.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 
  • 三种特性音频的具体信息
  1. 音乐
========== 基本信息 ==========
输入文件:test.wav
输出文件:test.mp2
采样频率:44.1 kHz
目标码率:192 kbps
声道数:1
目前观测第 2 帧
本帧比特预算:5016 bits

========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]: 11  11  11  
子带[ 2]: 12  12  12  
子带[ 3]: 21  18  18  
子带[ 4]: 25  25  25  
子带[ 5]: 29  29  29  
子带[ 6]: 28  23  26  
子带[ 7]: 22  22  22  
子带[ 8]: 21  21  21  
子带[ 9]: 32  28  28  
子带[10]: 34  30  30  
子带[11]: 31  31  31  
子带[12]: 30  30  26  
子带[13]: 27  24  24  
子带[14]: 23  23  23  
子带[15]: 26  22  25  
子带[16]: 30  25  25  
子带[17]: 26  26  26  
子带[18]: 29  29  29  
子带[19]: 31  31  30  
子带[20]: 26  26  26  
子带[21]: 34  34  31  
子带[22]: 34  31  31  
子带[23]: 38  38  38  
子带[24]: 39  50  50  
子带[25]: 43  51  57  
子带[26]: 41  54  54  
子带[27]: 45  52  52  
子带[28]: 42  54  54  
子带[29]: 44  52  52  
子带[30]: 43  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

大部分子带的比例因子相差不大,这时可以利用平稳性,只传送一个比例因子,提高压缩效率。根据比特分配表可以看到,前部分子带(对应低频部分)分配的比特数较多,后部分子带(对应高频部分)分配的比特数较少,这是根据人耳的感知特性(高频部分感知能力差)对音频进行压缩编码的表现。

  1. 噪声
========== 基本信息 ==========
输入文件:noise.wav
输出文件:noise.mp2
采样频率:44.1 kHz
目标码率:192 kbps
声道数:1
目前观测第 2 帧
本帧比特预算:5016 bits

========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]: 62  62  62  
子带[ 2]: 62  62  62  
子带[ 3]: 62  62  62  
子带[ 4]: 62  62  62  
子带[ 5]: 62  62  62  
子带[ 6]: 62  62  62  
子带[ 7]: 62  62  62  
子带[ 8]: 60  60  60  
子带[ 9]: 58  58  58  
子带[10]: 62  57  57  
子带[11]: 59  56  56  
子带[12]: 56  56  56  
子带[13]: 55  55  55  
子带[14]: 57  53  53  
子带[15]: 53  53  53  
子带[16]: 56  56  56  
子带[17]: 57  57  57  
子带[18]: 59  59  59  
子带[19]: 58  58  58  
子带[20]: 58  53  53  
子带[21]: 51  51  51  
子带[22]: 50  50  50  
子带[23]: 53  50  50  
子带[24]: 49  49  49  
子带[25]: 47  50  46  
子带[26]: 47  47  47  
子带[27]: 45  45  45  
子带[28]: 46  46  46  
子带[29]: 50  45  45  
子带[30]: 45  45  45  

========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]:  3
子带[ 2]:  3
子带[ 3]:  4
子带[ 4]:  6
子带[ 5]:  6
子带[ 6]:  6
子带[ 7]:  6
子带[ 8]:  6
子带[ 9]:  7
子带[10]:  7
子带[11]:  7
子带[12]:  6
子带[13]:  7
子带[14]:  7
子带[15]:  7
子带[16]:  6
子带[17]:  4
子带[18]:  3
子带[19]:  2
子带[20]:  4
子带[21]:  2
子带[22]:  1
子带[23]:  0
子带[24]:  0
子带[25]:  0
子带[26]:  0
子带[27]:  0
子带[28]:  0
子带[29]:  0
子带[30]:  0

同样地,大部分子带的三个比例因子相差不大,与音乐不同的是,噪声的子带比例因子都比较大,而音乐的低频子带比例因子较小,随着子带频率增加比例因子也随之增大。根据比特分配表可以看到,随着子带频率的增加比特分配数并非随之减少,在中频的子带分配的比特殊较多,相较于音乐,噪声的比特分配更为均匀,这是因为噪声各个频率的概率分布近似均匀。

  1. 噪声+音乐
========== 基本信息 ==========
输入文件:music_noise.wav
输出文件:music_noise.mp2
采样频率:44.1 kHz
目标码率:192 kbps
声道数:1
目前观测第 2 帧
本帧比特预算:5016 bits

========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]: 11  11  11  
子带[ 2]: 12  12  12  
子带[ 3]: 21  18  18  
子带[ 4]: 25  25  25  
子带[ 5]: 29  29  29  
子带[ 6]: 28  23  26  
子带[ 7]: 22  22  22  
子带[ 8]: 21  21  21  
子带[ 9]: 32  28  28  
子带[10]: 34  30  30  
子带[11]: 31  31  31  
子带[12]: 30  30  26  
子带[13]: 27  24  24  
子带[14]: 23  23  23  
子带[15]: 26  22  25  
子带[16]: 30  25  25  
子带[17]: 26  26  26  
子带[18]: 29  29  29  
子带[19]: 31  31  30  
子带[20]: 26  26  26  
子带[21]: 34  34  31  
子带[22]: 31  31  31  
子带[23]: 37  37  37  
子带[24]: 39  46  46  
子带[25]: 43  46  46  
子带[26]: 41  46  46  
子带[27]: 44  47  47  
子带[28]: 42  47  47  
子带[29]: 45  45  45  
子带[30]: 44  47  47  

========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]:  7
子带[ 2]:  7
子带[ 3]:  6
子带[ 4]:  8
子带[ 5]:  6
子带[ 6]:  7
子带[ 7]:  7
子带[ 8]:  6
子带[ 9]:  5
子带[10]:  5
子带[11]:  5
子带[12]:  7
子带[13]:  7
子带[14]:  6
子带[15]:  6
子带[16]:  4
子带[17]:  4
子带[18]:  4
子带[19]:  4
子带[20]:  5
子带[21]:  3
子带[22]:  2
子带[23]:  0
子带[24]:  0
子带[25]:  0
子带[26]:  0
子带[27]:  0
子带[28]:  0
子带[29]:  0
子带[30]:  0

比例因子与比特分配特点与音乐类似。

3.梳理整个算法流程

  • 理解程序设计的整体框架
  • 理解感知音频编码的设计思想
  • 理解心理声学模型的实现过程
  • 理解码率分配的实现思路
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容