数据压缩原理实验6_MPEG音频编码

一、实验原理

这里写图片描述
子带编码:将原始信号分解为若干个子频带,对其分别进行编码处理后再合成为全频带信号

时域与频域的矛盾:要感知时域的变化,就要增加时域的分辨力,但同时就会对频域的分辨力有所限制,反之亦然,因此要在两者之间找到一个协调。

1.时域分析

1.1 滤波器划分子带
  • 人耳听觉系统
    人类听觉系统大致等效于一个在0Hz到20KHz频率范围内由25个重叠的带通滤波器组成的滤波器组。
    人耳不能区分同一频带内同时发生的不同声音
    人耳频带被称为临界频带(critical band);
    500Hz以下每个临界频带的带宽大约是100Hz,从500Hz起,临界频带带宽线性增加。

    这里写图片描述

  • 多相滤波器
    Layer1每次进去32个点,分12次进入系统,按理说时域每次进去的32个点经过频域的32个子带后应该出来时域的32*32个点,但经过多相滤波器后只需出来32个点就可以表示32*32个点的内容。而Layer2每次进去96个点,每32个点为一组,共三组,因此需要后面的比例因子选择部分。
    下图为多相滤波器的示意图
    这里写图片描述
    但该滤波器有如下缺点:
    (1)等带宽的滤波器组与人类听觉系统的临界频带不对应。因为在低频区域,单个子带会覆盖多个临界频带。在这种情况下,量化比特数不能兼每个临界频带
    (2)滤波器组与其逆过程不是无失真的。但滤波器组引入的误差差很小,且听不到
    (3)子带间频率有混叠。滤波后的相邻子带有频率混叠现象,一个子带中的信号可以影响相邻子带的输出

2.频域分析

2.1 心理声学模型

32个等分的子带信号并不能精确地反映人耳的听觉特性。引入FFT补偿频率分辨率不足的问题。
(1)系统中存在一个听觉阈值电平,低于这个电平的声音信号就听不到。听觉阈值的大小随声音频率的改变而改变。一个人是否听到声音取决于声音的频率,以及声音的幅度是否高于这种频率下的听觉阈值
(2)听觉掩蔽特性。即听觉闽值电平是自适应的,会随听到的不同频率声音而发生变化
下图为频域掩蔽域随声压级变化曲线,可以看出听力阈会随声音频率而发生变化,以及不同声音频率造成的听力阈也有所不同
这里写图片描述
下图为掩蔽效果的加和
这里写图片描述
下图为不同掩蔽类型的讨论
这里写图片描述
掩蔽音与被掩蔽音的组合方式有四种,它们分别可以是乐音信号或者窄带噪声。乐音信号和窄带噪声信号作为掩蔽音时产生的掩蔽效果有很大的不同。从上图可以看出:(1)在相同条件下,乐音掩蔽噪声比噪声掩蔽乐音要难 (2)在一个固定的频率下的音信号易被比该频率低的信号掩蔽

2.2**比例因子取值和编码**

对各个子带每12个样点进行一次比例因子计算。先定出12个样点中绝对值的最大值。查比例因子表中比这个最大值大的最小值作为比例因子。用6比特表示。

  • 第2层的一帧对应36个子带样值,是第1层的三倍,原则上要传三个比例因子。为了降低比例因子的传输码率,采用了利用人耳时域掩蔽特性的编码策略。
  • 每帧中每个子带的三个比例因子被一起考虑,划分成特定的几种模式。根据这些模式,1个、2个或3个比例因子和比例因子选择信息(每子带2比特)一起被传送。如果一个比例因子和下一个只有很小的差别,就只传送大的一个,这种情况对于稳态信号经常出现。
  • 使用这一算法后,和第1层相比,第2层传输的比例因子平均减少了2个,即传输码率由22.5Kb/s降低到了7.5Kb/s。
2.3**比特分配及编码**

比特分配的过程

  • 对每个子带计算掩蔽–噪声比MNR,是信噪比SNR–信掩比SMR,即:MNR=SNR-SMR
  • 使整个一帧和每个子带的总噪声-掩蔽比最小。这是一个循环过程,每一次循环使获益最大的子带的量化级别增加一级,当然所用比特数不能超过一帧所能提供的最大数目
  • 第1层一帧用4比特给每个子带的比特分配信息编码;而第2层只在低频段用4比特,高频段则用2比特

下图为SMR的计算示意图
这里写图片描述

2.4**子带样值的量化和编码**
  • 输入以12个样本为一组,每组样本经过时间一频率变换之后进行一次比特分配并记录一个比例因子(scale factor)
  • 比特分配信息告诉解码器每个样本由几位表示,比例因子用6比特表示,解码器使用这个6比特的比例因子乘逆量化器的每个输出样本值,以恢复被量化的子带值。比例因子的作用是充分利用量化器的量化范围,通过比特分配和比例因子相配合,可以表示动态范围超过120dB的样本
  • 第2层中,量化级别的数目随子带的不同而不同,但量化等级仍然覆盖了365535的范围,同时子带不被分配给比特的概率增加了,没有分配给比特的子带就不被量化。低频段的量化等级有15级,中频段7级,高频段只有3级

二、代码及结果

1.代码分析

m2aenc.c

//add by zx
FILE *output_txt;
char temp[100] = "info.txt"; //info.txt为存储数据帧信息的文件
//end
...
int main (int argc, char **argv)
{
    //add by zx
    output_txt = fopen(temp, "w");
    if (output_txt == NULL)
        printf("Creating output txt file failed.\n");
    //end
    ...
}
#ifdef NEWENCODE
    ...
#else
    scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit);
    pick_scale (scalar, &frame, max_sc);
    //add by zx
    int sb, gr, ch;
    if (frameNum == 100)   //选择第100个数据帧
    {
        //输出采样率 
        fprintf(output_txt, "采样频率为 %d kHz. \n 目标码率为 %d kbps.\n",
            header.sampling_frequency, bitrate[header.version][header.bitrate_index]);
        fprintf(output_txt, "输出的为第 %d 帧\n", frameNum); //输出数据帧
        fprintf(output_txt, "分配的比特数为 %d\n", adb);
        fprintf(output_txt, "比例因子为:\n");  //输出比例因子
        for (ch = 0; ch < nch; ch++)//声道
        {
            fprintf(output_txt, "channel[%2d] \n", ch + 1); 
            for (sb = 0; sb < frame.sblimit; sb++) //子带
            {
                fprintf(output_txt, "subband[%2d]:    ", sb + 1);  
                for (gr = 0; gr < 3; gr++) 
                {
                    fprintf(output_txt, "%2d\t", scalar[ch][gr][sb]);
                }
                fprintf(output_txt, "\n");
            }
        }
    }
    //end 
    ...
  }
#endif
...
    //add by zx
    if (frameNum == 100)
    {
        fprintf(output_txt, "\n分配的比特数为:\n");  //输出比特分配结果
        int ch, sb;
        for (ch = 0; ch < nch; ch++)
        {
            fprintf(output_txt, "channel[%2d] \n", ch + 1); //按声道分配
            for (sb = 0; sb < frame.sblimit; sb++)
            {
                fprintf(output_txt, "subband[%2d]:%2d\n", sb, bit_alloc[ch][sb]);
            }
        }
    }
    //end

2.结果显示

这里写图片描述
这里写图片描述
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值