一、实验原理
1、MPEG-1 Audio Layer II编码器原理框图
子带分析滤波器组:使信号具有高的时间分辨率;
FFT运算:使信号具有高的频率分辨率;
比特分配:低频子带分配较多的位数,高频自带分配较少的位数。
2、听觉阈值
听觉阈值的大小随声音频率的改变而改变;
一个人是否听到声音取决于声音的频率,以及声音的幅度是否高于这种频率下的听觉阈值。
3、频域掩蔽
如果有多个频率成分的复杂信号存在,那么频谱的总掩蔽阈值与频率的关系取决于各掩蔽音的强度、频率和它们之间的距离。
4、临界频带
通常认为从20Hz到16kHz有25个临界频带,单位为bark,1 Bark = 一个临界频带的宽度。
5、人耳听觉系统
中心频率与信号频率相同的滤波器具有最大响应;中心频率偏离信号频率较多的滤波器不会产生响应;
在0Hz到20KHz频率范围内由25个重叠的带通滤波器组成的滤波器组。
6、掩蔽效果的加和
Lutfi 对多个掩蔽音同时存在时的综合掩蔽效果进行了研究:每个掩蔽音的掩蔽效果先独立变换然后再线性相加;
当两个信号重叠并落在一个临界频带中时,二者的掩蔽分量可以线性相加;
对于复杂音频信号可将其频谱分割成一系列离散段,每段就是一个掩蔽信号。各掩蔽音互不重叠,即以一个临界带为单位。各掩蔽音的声压级则通过将对应的临界频带上的短时功率谱密度线性相加得到。
7、多相滤波器组
人类听觉系统大致等效于一个信号通过一组并联的不同中心频率的带通滤波器;
听音者在噪声中听某一纯音信号时,只启用中心频率与信号频率相同的那个听觉滤波器,纯音信号通过该滤波器,而噪声信号只有通带范围内的部分信号能通过,通带以外的频率成分则被抑制,只有通过该
滤波器的噪声才对掩蔽起作用;
聆听复音时启动多个听觉滤波器。听觉能够计算各滤波器输出端的信噪比。当信噪比达到或者超过听阈因子时,即可听到该频率成分。
二、代码调试
1、添加如下代码即可输出txt文件:
FILE* output = fopen("output.txt", "wb");
if (frameNum == 20)
{
fprintf(output, "输出音频的采样率为:%.1fkhz \r\n", s_freq[header.version][header.sampling_frequency]);
fprintf(output, "目标码率为:%dMbps \r\n", bitrate[header.version][header.bitrate_index]);
fprintf(output, "选择的数据帧为:%d \r\n", frameNum);
fprintf(output, "该帧所分配的比特数为:%dbits\r\n", adb);
for (int k = 0; k < nch; k++)
{
fprintf(output, "声道[%d] \r\n", k + 1);
for (int j = 0; j < frame.sblimit; j++)//子带总数
{
fprintf(output, "子带[%d]: ", j + 1);
for (int m = 0; m < 3; m++)//每个子带有3个比例因子
{
fprintf(output, "%d\t", scalar[k][m][j]);
}
fprintf(output, "\r\n");
}
}
}
if (frameNum == 20)
{
fprintf(output, "\n比特分配:\n");
for (int k = 0; k < nch; k++)
{
fprintf(output, "channel[%d] \r\n", k + 1);
for (int j = 0; j < frame.sblimit; j++)
{
fprintf(output, "subband[%d]:%d\r\n", j, bit_alloc[k][j]);
}
}
}
使用的输入文件为test.wav
2、代码运行后的命令行窗口:其中44.1kHz为采样率,192kbps为目标码率;
3、输出的txt文件