MPEG-1 Audio LayerII编码器原理
![](https://img-blog.csdn.net/20170709204433826?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE3MTg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
MPEG-I 心理声学模型
通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量又可以使信号通过FFT运算具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来的。在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数,即分配较多的位数来表示样本值。而话音中的摩擦音和类似噪声的声音,通常出现在高频子带中,对它分配较少的位数
比例因子的取值和编码
对各个子带每12个样点进行一次比例因子计算。先定出12个 样点中绝对值的最大值。查比例因子表中比这个最大值大的 最小值作为比例因子。用6比特表示。
- 第2层的一帧对应36个子带样值,是第1层的三倍,原 则上要传三个比例因子。为了降低比例因子的传输码率, 采用了利用人耳时域掩蔽特性的编码策略。
- 每帧中每个子带的三个比例因子被一起考虑,划分成 特定的几种模式。根据这些模式,1个、2个或3个比例因 子和比例因子选择信息(每子带2比特)一起被传送。如 果一个比例因子和下一个只有很小的差别,就只传送大 的一个,这种情况对于稳态信号经常出现。
- 使用这一算法后,和第1层相比,第2层传输的比例因 子平均减少了2个,即传输码率由22.5Kb/s降低到了 7.5Kb/s。
比特分配及编码
在调整到固定的码率之前
- 先确定可用于样值编码的有效比特数
- 这个数值取决于比例因子、比例因子选择信息、比特分配信息 以及辅助数据所需比特数
比特分配的过程 :
- 对每个子带计算掩蔽-噪声比MNR,是信噪比SNR – 信掩比 SMR,即:MNR = SNR – SMR。
- 使整个一帧和每个子带的总噪声-掩蔽比最 小。这是一个循环过程,每一次循环使获益 最大的子带的量化级别增加一级,当然所用 比特数不能超过一帧所能提供的最大数目 。
- 第1层一帧用4比特给每个子带的比特分配信 息编码;而第2层只在低频段用4比特,高频 段则用2比特。
代码
m2aenc.c
FILE *output_txt;
char temp[50] = "frame_info.txt";
output_txt = fopen(temp, "w");
if (output_txt == NULL)
printf("Creating output txt file failed.\n");
......
scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit);
pick_scale (scalar, &frame, max_sc);
//add by susu
int sb,gr,ch;
if (frameNum == 200)
{
fprintf(output_txt, "sampling rate=%d kHz. \nbit rate=%d kbps.\n ",
header.sampling_frequency,bitrate[header.version][header.bitrate_index]);
fprintf(output_txt, "\nOutput the %d th frame.\n", frameNum);
fprintf(output_txt, "available bits number=%d\n", adb);
fprintf(output_txt, "\nScale_Factor:\n");
for (ch = 0; ch < nch; ch++)
{
fprintf(output_txt, "channel[%d] \n", ch + 1);
for (sb = 0; sb < frame.sblimit; sb++)
{
fprintf(output_txt, "subband[%d]: ", sb + 1);
for (gr = 0; gr < 3; gr++)
{
fprintf(output_txt, "%d\t", scalar[ch][gr][sb]);
}
fprintf(output_txt, "\n");
}
}
}
//end
......
transmission_pattern (scalar, scfsi, &frame);
main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
//add by susu
if (frameNum == 200)
{
fprintf(output_txt, "\nBits_Allocation:\n");
int ch, sb;
for (ch = 0; ch < nch; ch++)
{
fprintf(output_txt, "channel[%d] \n", ch + 1);
for (sb = 0; sb < frame.sblimit; sb++)
{
fprintf(output_txt, "subband[%d]:%d\n", sb, bit_alloc[ch][sb]);
}
}
}
//end
实验结果
![](https://img-blog.csdn.net/20170709210704672?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE3MTg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20170709210726692?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzc2NDE3MTg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)