实验原理:
本次实验对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");
}