【数据压缩】MPEG音频编码实验

来源:互联网 发布:数据标准是什么 编辑:程序博客网 时间:2024/05/29 15:07

实验原理:

本次实验对MEPG-1 Audio LayerII的编码器原理进行分析:
这里写图片描述

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

  • 心理声学模型:计算信号中不可听觉感知的部分,计算出噪声的遮蔽效应,对这部分被掩蔽的听不见的信号不进行传输

  • 比特分配器:根据心理声学模型的计算结果,为每个子带信号分配比特数

  • 装帧:产生出一个数据帧,帧要求与MPEG-l兼容

心理声学模型的分析:

1.将样本变换到频域
模型1:采用512点或1024点DFT样本窗口。
应注意的是,MPEG音频编码的三个层每帧的样本数不同。Layer I:每帧有384样本点,512样本点足够覆盖;Layer II和Layer III:每帧1152个样本点,每帧计算两次,模型1选择两个信号掩蔽比(SMR)中较小的一个。

2.确定声压级别:
这里写图片描述

3.考虑安静时阈值
也即绝对阈值,安静时也没法听到的声压级

4.根据不同信号的掩蔽能力区别,将音频信号分解为“乐音(tones)”和“噪声”,如图为两种信号的掩蔽效果:
这里写图片描述

5.音调和非音调掩蔽成分的消除
利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率成分

6.单个掩蔽值的计算
根据标准中给出的算法求出音调成分和非音调成分的单个掩蔽阈值

7.全局掩蔽阈值的计算
这里写图片描述

8.选出本子带中最小的阈值作为该子带阈值

9.计算出每个子带的信号掩蔽比(SMR)
SMR = 信号能量/掩蔽阈值
最后将SMR传递给编码单元


实验过程:

实验要求:选择某个数据帧,输出

  • 该帧所分配的比特数
  • 该帧的比例因子
  • 该帧的比特分配结果

    在m2aenc工程资源下,m2aenc.cpp内的main():
    对实验所需的比特、比例因子等信息输出到指定文本文件中,从而记录相应实验数据。
    文本文件初始化代码:

    FILE *C_TRACE;    C_TRACE = fopen("C_trace.txt", "w");
  • 记录该帧所分配的总比特数:
    这里写图片描述
    输出结果:
    这里写图片描述
    由实验结果可知,第一个帧总计可以分配5008个比特给所有子带的样本。

  • 记录比特分配:

    if (frameNum == 1)    {        fprintf(C_TRACE, "下面输出比特分配:\n");        for (int i = 0; i < frame.sblimit; i++)            fprintf(C_TRACE, "ch[0].subband[%d]: %d bits\n",i,bit_alloc[0][i]);            //putbits(bs, bit_alloc[k][i], (*alloc)[i][0].bits);        fprintf(C_TRACE, "\n");    }

比特分配结果:
这里写图片描述
输出信息描述了每个自带所占用的bit数,由于输入文件类型为mono单声道类型,所以只输出了第一个频道的子带比特分配

  • 记录比例因子选择:
if (frameNum == 1)    {        fprintf(C_TRACE, "下面输出比例因子选择:\n");        for (int i = 0; i < frame.sblimit; i++)            fprintf(C_TRACE, "Ch[0].subband[%d] scfsi: %d\n",i,scfsi[0][i]);        fprintf(C_TRACE, "\n");    }

比例因子输出结果:
这里写图片描述

  • 记录每个子带的三个比例因子:
    if (frameNum == 1)    {        fprintf(C_TRACE, "下面输出比例因子:\n");        for (int i = 0; i < frame.sblimit; i++)        {            fprintf(C_TRACE, "Ch[0].subband[%d] scalar: %d\t %d\t %d\n", i, scalar[0][0][i], scalar[0][1][i], scalar[0][2][i]);        }        fprintf(C_TRACE, "\n");    }

这里写图片描述