MPEG-1 Audio Layer II原理
流程图如下
输入声音信号经过一个多相滤波器组,变换到多个子带。同时经过“心理声学模型”计算以频率为自变量的噪声掩蔽阈值。量化和编码部分用信掩比SMR决定分配给子带信号的量化位数,使量化噪声<掩蔽域值。最后通过数据帧包装将量化的子带样本和其它数据按照规定的帧格式组装成比特数据流。
总结一下,各部分作用如下
- 多相滤波器组:将样本信号变换到32个子带
- 心理声学模型:计算信号中听不到的部分
- 比特分配器:为每个子带分配比特位数
- 最后装帧
多项滤波器组
512个输入样本空间的FIFO缓冲区,这里32个最新输入的样本在最低端
- (i=0~511)计算窗口内的样本:Z[i]=C[i]*X[i]
- 样本点分组,计算64个Yk的值:Y[k]= ∑ j = 0 7 \sum_{j=0}^7 ∑j=07Z[k+64*j]
- 计算32 个自带样本S[i]= ∑ k = 0 63 \sum_{k=0}^{63} ∑k=063Y[k] ·M[i][k] 其中M[i][k]=cos((2*i+1)(k-16)*pi/64)
缺点:
- 等带宽的滤波器组与人类听觉系统的临界频带 不对应
- 在低频区域,单个子带会覆盖多个临界频带。在这 种情况下,量化比特数不能兼每个临界频带
- 滤波器组与其逆过程不是无失真的
- 但滤波器组引入的误差差很小,且听不到
- 子带间频率有混叠
- 滤波后的相邻子带有频率混叠现象,一个子带中的 信号可以影响相邻子带的输出
滤波器组与临界频带比较
一个子带的频率响应
心理声学模型
- 通过子带分析滤波器组使信号具有更高的时间分辨率, 确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量
- 又可以使信号通过FFT运算具有高的频率分辨率, 因为掩蔽阈值是从功率谱密度推出来的。
- 在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数,即分配较 多的位数来表示样本值。而话音中的摩擦音和类似 噪声的声音,通常出现在高频子带中,对它分配较 少的位数
MPEG-1标准定义了两个心理声学模型
第一种:
- 计算复杂度低
- 对假设用户听不到的部分压缩太严重
第二种: - 提供适合layer III编码的更多特征
不过实际上实现的时候,模型复杂度取决于需要的压缩因子,如大的压缩因子不重要,则可以完全不用心理声学模型。此时分配算法可以不使用SMR,使用SNR。
计算步骤如下
- 将样本转换到频域
-
32个等分的子带信号并不能精确地反映人耳的听觉特性。 引入FFT补偿频率分辨率不足的问题。
可以采用Hann加权和DFT- Hann加权减少频域中的边界效应
- 此变换不同于多相滤波器组,因为模型需要更精细 的频率分辨率,而且计算掩蔽阈值也需要每个频率 的幅值
模型 1 :采用 512 (Layer I)或 1024 (Layers II and III)样本窗口
- Layer I:每帧384个样本点,512个样本点足够覆盖
- Layer II和Layer III:每帧1152个样本点,每帧两次 计算,模型1选择两个信号掩蔽比(SMR)中较小的 一个
- 确定声压级别
- 子带n中的声压级别计算如下:Lsb(n)= MAX[x(k),20· log10scfmax(n)· 32768)-10]dB
- 其中X(k)是在子带n中的频谱线的声压级别,scU(n)在是一帧中子带n 的三个缩放因子中最大的一个。
- 考虑安静时阈值
- 也即绝对阈值。在标准中有根据输入PCM信号的采 样率编制的“频率、临界频带率和绝对阈值”表。 此表为多位科学家经多次心理声学实验所得。
- 4、将音频信号分解成“乐音(tones)”和“非乐音/噪声” 部分:因为两种信号的掩蔽能力不同
- 模型1:根据音频频谱的局部功率最大值确定乐音成分
- 局部峰值为乐音,然后将本临界频带内的剩余频谱合在一 起,组成一个代表噪声频率(无调成份)
- 区分有无调:
(1) 标明局部最大。如果x (k)比相邻的两个谱线都大,则
(k)为局部最大值;
(2) 列出有调成份,计算声压级。如果x(k)-x(k+j)>=7dB,则 x(k)列为有调成份。j随谱线的位置不同。
(3) 列出无调成分,计算功率。在每个临界频带内将所有余 留谱线的功率加起来形成临界频带内无调成分的声压级。并 列出以下参数:最接近临界频带几何平均值的谱线标记k,声 压级以及无调指示。
- 音调和非音调掩蔽成分的消除
- 利用标准中给出的绝对阈值消除被掩蔽成分; 考虑在每个临界频带内,小于0.5Bark的距离 中只保留最高功率的成分
- 单个掩蔽阈值的计算
- 音调成分和非音调成分单个掩蔽阈值根据标 准中给出的算法求得。
- 全局掩蔽阈值的计算
某一频率点i的总掩蔽阙值可通过该点的绝对掩蔽阚值与单独掩蔽阈值相
加得到
LTg(i) = 10 lg(10LTq(i)/10+ ∑ j = 1 m \sum_{j=1}^m ∑j=1m 10LTtm(z(j),z(i))/10+ ∑ j = 1 n \sum_{j=1}^n ∑j=1n 10LTnm(z(j),z(i))/10 )
- 其中,LTq(i)是频率点i的绝对掩蔽阈值;
- LTtm(z(j),z(i))是第j个音调掩蔽成分对频率点i的掩蔽阈值,对频率点i有掩蔽效应的音调掩蔽成分共m个;
- LTnm(z(j)),z(i))是第j个非音调掩蔽成分对频率点i的掩蔽阈值,对频率点i有 掩蔽效应的非音调掩蔽成分共n个.
- 还要考虑别的临界频带的影响。一个掩蔽信号会对其它频带上的信号产生掩蔽效应,即掩蔽扩散。
- SFdB(x)=15.81+7.5(x+0.474)-17.5 · 1 + ( x + 0.474 ) 2 \sqrt{1+(x+0.474)^{2}} 1+(x+0.474)2dB
- 每个子带的掩蔽阈值
- 选择出本子带中最小的阈值作为子带阈值
- 对高频不正确——高频区的临界频带很宽, 可能跨越多个子带,从而导致模型1将临界带 宽内所有的非音调部分集中为一个代表频率, 当一个子带在很宽的频带内却远离代表频率 时,无法得到准确的非音调掩蔽值。但计算 量低。
- 选择出本子带中最小的阈值作为子带阈值
- 计算每个子带信号掩蔽比(signal-to-mask ratio, SMR)
SMR =信号能量/掩蔽阈值 并将SMR传递给编码单元
编码
码率分配
先确定可用于样值编码的有效比特数,这个数值取决于比例因子、比例因子选择信息、比特分配信息以及辅助数据所需比特。
- 比特分配的过程
对每个子带计算掩蔽-噪声比MNR,是信噪比 SNR—信掩比SMR,即:MNR = SNR-SMR
算法:循环,直到没有比特可用:
- NMR = SMR- SNR (dB)
- 对最高NMR的子带分配比特,使获益最大的子带的 量化级别增加一级
- 重新计算分配了更多比特于带的NMR
装帧
帧头
实验内容
程序设计框架:
- 通过多项滤波器组获得子带
- 判断是否是立体声
- 计算比例因子
- 计算比例因子选择信息
- 利用心理声学模型计算频域掩蔽电平
- 比特分配
- 将比特分配,比例因子等关键信息打包,输出比特流
- 量化并输出比特流
音频编码主要分为两条线
上面那一条线,即多个箭头平行的那条线,可以看到,将信号分成32个子带,然后量化,使用颗粒减小数据量。
下面的线则是利用了心理声学,来进行比特分配,减小总数据量。
值得一提的是,频域分辨力和时域分辨力不可兼得,时域分辨力增大,频域分辨力会受一定的影响。滤波器组是信号具有高的时域分辨率,FFT运算可以使信号具有高的频率分辨率。
输出内容
1.输出音频的采样率和目标码率
fprintf(info, "sampling frequency:%.2fkHz\n", s_freq[header.version][header.sampling_frequency]);
fprintf(info,"target bit rate:%dMbps\n",bitrate[header.version][header.bitrate_index]);
- 输出数据帧的信息
fprintf(info, "scale factor\n");
for (int i = 0; i < nch; i++)
{
fprintf(info,"sound track%d\n",i);
fprintf(info,"subband\tGroup1\tGroup2\tGroup3\t\n");
for (int count = 0; count < frame.sblimit; count++)
{
fprintf(info,"%4d\t",count);
for (int j = 0; j < 3; j++)
{
fprintf(info,"%3d\t",scalar[i][j][count]);
}
fprintf(info, "\n");
}
}
fprintf(info, "frame bit allocation:\n");
for (int i = 0; i < nch; i++)
{
fprintf(info,"sound track%d\n",i);
for (int count = 0; count < frame.sblimit; count++)
{
fprintf(info,"subband%2d:\t",count);
fprintf(info, "%2d\n", bit_alloc[i][count]);
}
输出结果如下
比例因子
分配比特数