实验原理
下图为MPEG音频编码layerII流程图: 32个子带滤波器组: 通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量。 将PCM样本变换到32个子带的频域信号:如果输入的采样频率为48kHz ,那么子带的频率宽度为48/ (2*32 )=0.75Hz 该多相滤波器组为如下图: 心理声学模型: 计算信号中不可听觉感知的部分。 时频分析的矛盾: 1、通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量 2、又可以使信号通过FFT运算具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来的。
在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数,即分配较多的位数来表示样本值。而话音中的摩擦音和类似噪声的声音,通常出现在高频子带中,对它分配较少的位数。
步骤: 将样本变换到频域->确定声压级别->考虑安静时阈值->将音频信号分解成“乐音(tones)” 和“非乐音/噪声”部分:因为两种信号的掩蔽能力不同->音调和非音调掩蔽成分的消除->单个掩蔽阈值的计算->全局掩蔽阈值的计算->每个子带的掩蔽阈值->计算每个子带信号掩蔽比(signal-to-maskratio, SMR)
比特分配过程: 使整帧和每个子带的总噪声—掩蔽比最小。 算法:循环,直到没有比特可用: 1、对每个子带计算掩蔽-噪声比MNR,MNR = SNR –SMR (dB) 2、对最低MNR的子带分配比特,使获益最大的子带的量化级别增加一级 3、重新计算分配了更多比特子带的MNR
实验流程
理解程序设计的整体框架 理解感知音频编码的设计思想 两条线 时-频分析的矛盾! 理解心理声学模型的实现过程 临界频带的概念 掩蔽值计算的思路 理解码率分配的实现思路 输出音频的采样率和目标码率 选择某个数据帧,输出 该帧所分配的比特数 该帧的比例因子 该帧的比特分配结果
主要代码
[csharp] view plain copy
sf_transmission_pattern (
scalar, scfsi, &frame);
main_bit_allocation_new (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
//main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
if (error_protection)
CRC_calc (&frame, bit_alloc, scfsi, &crc);
write_header (&frame, &bs);
//encode_info (&frame, &bs);
if (error_protection)
putbits (&bs, crc,
16);
write_bit_alloc (bit_alloc, &frame, &bs);
//encode_bit_alloc (bit_alloc, &frame, &bs);
write_scalefactors(bit_alloc, scfsi,
scalar, &frame, &bs);
//encode_scale (bit_alloc, scfsi,
scalar, &frame, &bs);
subband_quantization_new (
scalar,
*sb_sample, j_scale,
*j_sample, bit_alloc,
*subband, &frame);
//subband_quantization (
scalar,
*sb_sample, j_scale,
*j_sample, bit_alloc,
// *subband, &frame);
write_samples_new(
*subband, bit_alloc, &frame, &bs);
//sample_encoding (
*subband, bit_alloc, &frame, &bs);
/
*add by yangyulan
*/
if(frameNum==
200)
{
int k,t,i;
fprintf(result,
"采样率=%.1f khz\n",s_fre
q[header.version][header.sampling_frequency]);
fprintf(result,
"目标码率=%d kbps\n", bitrate[header.version][header.bitrate_index]);
fprintf(result,
"第%d帧\n",frameNum);
fprintf(result,
"可用比特数=%d\n",adb);
fprintf(result,
"比例因子:\n");
for(k=
0;k<nch;k++)
{
fprintf(result,
"声道[%d]\n",k);
for(i=
0;i<frame.sblimit;i++)
{
fprintf(result,
"子带[%d]:",i);
for(t=
0;t<
3;t++)
{
fprintf(result,
"%d\t",
scalar[k][t][i]);
}
fprintf(result,
"\n");
}
}
}
/
*end by yangyulan
*/
transmission_pattern (
scalar, scfsi, &frame);
main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
/*add by yangyulan*/
if(frameNum==
200)
{
int k,i;
fprintf(result,
"比特分配:\n");
for(k=
0;k<nch;k++)
{
fprintf(result,
"声道[%d]\n",k);
for(i=
0;i<frame.sblimit;i++)
{
fprintf(result,
"子带[%d]:%d\n",i,bit_alloc[k][i]);
}
}
}
/
*end by yangyulan
*/
if (error_protection)
CRC_calc (&frame, bit_alloc, scfsi, &crc);
encode_info (&frame, &bs);
if (error_protection)
encode_CRC (crc, &bs);
encode_bit_alloc (bit_alloc, &frame, &bs);
encode_scale (bit_alloc, scfsi,
scalar, &frame, &bs);
subband_quantization (
scalar,
*sb_sample, j_scale,
*j_sample, bit_alloc,
*subband, &frame);
sample_encoding (
*subband, bit_alloc, &frame, &bs);
实验结果及其分析