【作业】MPEG音频编码实验

本文详细介绍了MPEG音频编码的实验,包括MPEG编码的整体框架、心理声学模型的实现过程、码率分配的基本思路,并给出了程序测试的步骤。重点讲解了临界频带、掩蔽阈值的计算以及子带信号掩蔽比(SMR)的计算方法。
摘要由CSDN通过智能技术生成

实验要求

根据给出的MPEG编码程序

  1. 理解程序设计的整体框架
  2. 理解感知音频编码的设计思想
    1. 两条线
    2. 时-频分析的矛盾
  3. 理解心理声学模型的实现过程
    1. 临界频带的概念
    2. 掩蔽值计算的思路
  4. 理解码率分配的实现思路
  5. 输出音频的采样率和目标码率
  6. 选择三个不同特性的音频文件
    • 噪声
    • 音乐
    • 混合
  7. 某个数据帧,输出
    1. 该帧所分配的比特数
    2. 该帧的比例因子
    3. 该帧的比特分配结果

MPEG编码整体框架

MPEG-1 Audio Layer Ⅱ编码器框图
在这里插入图片描述MPEG的基本编码思路(感知编码的基本思路)
分析信号,去掉不能被感知的部分:

  1. 人耳对于不同频率的声音的感知能力不同(生理感知极限),因此对于人耳感知力度更低的信号,可以分配更少的比特位。在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数。
    在这里插入图片描述
  2. 听觉掩蔽特性,一种声音可以对另一种声音产生掩蔽效应(纯音对纯音,纯音对噪音,噪音对纯音),对于经计算确认被掩蔽的声音成分,可以不编码。

两条线

PCM码流分别输入到上下两条线,上方最终作为编码的源数据形成MPEG编码结果。下方使用FFT对信号进行分析,经过心理声学模型计算信号中听觉无法感知的部分(计算噪声掩蔽效应)。为编码提供比特分配的信息。

时-频分析的矛盾

较高的时间分辨率和较高的频率分辨率时不可兼得的。为了实现较高的时间分辨率,势必要减少采样长度,确保在短暂冲击信号的情况下,编码的声音信号具有足够高的质量(尽量少地受到前后信号的影响),因此编码中以32个样本(框图中的上方部分)为一组通过多相滤波器(分离出32个频率范围下的幅度值)。
但是32个样本不足以提供足够的频率分辨率,无法精确地反映人耳的听觉特性,因此引入FFT补偿频率分辨率不足的问题。将32个样本经过滤波器得到的32个频点上的每个值,前后共12次滤波形成一组值(称为子带)共享缩放因子(从),因而每组子带有12x32=384个样本,3组子带称为一帧(Layer Ⅱ/Ⅲ)。这样一帧内共用3x12x32 = 1152样本,。
LayerⅠ中,384个样本就是一帧,需要做512点FFT
Layer Ⅱ/Ⅲ中,1152个样本为一帧,需要做两次1024点FFT,选择其中信号掩蔽比较小者(心理声学模型1)。

心理声学模型的实现过程

MPEG-I标准定义了两个心理声学模型
模型1计算复杂度低,但对假设用户听不到的部分压缩太严重
模型2提供了适合LayerⅢ编码的更多特征。

临界频带

临界频带是指当某个纯音被以它为中心频率、且具有一定带宽的连续噪声所掩蔽时,如果该纯音刚好被听到时的功率等于这一频带内噪声功率,这个带宽为临界频带宽度。
临界频带的意义在于人耳与之相关的特性:纯音的听阈随掩蔽噪声带宽的增大而增大,在带宽增大到某一特定值之后听阈保持恒定不变
噪声掩蔽纯音时,只有以纯音频率为中心的、一定频带宽度内的噪声能量起掩蔽作用。

掩蔽阈值的计算思路

1. 将样本变换到频域

这点在前面描述”两条线“时已经讲到。

2. 确定声压级别

子带n的生涯级别 L s b L_{sb} Lsb计算如下:
L s b ( n ) = M A X [ X ( k ) , 20 × log ⁡ 10 ( s c f m a x ( n ) × 32768 ) − 10 ] d B L_{sb}(n) = MAX[X(k), 20\times \log_{10}(scf_{max}(n)\times 32768) -10] \rm dB Lsb(n)=MAX[X(k),20×log10(scfmax(n)×32768)10]dB
其中 X ( k ) X(k) X(k)时子带n中频谱线的声压级别, s c f m a x ( n ) scf_{max}(n) scfmax(n)时一帧中子带n三个缩放因子中最大的一个。

3. 考虑安静时阈值

即绝对阈值。根据心理声学实验得到的“频率、临界频率和绝对阈值”表。

4. 区分“乐音”和“非乐音/噪声”

因为两种信号的掩蔽能力不同,因此将音频信号分解为“乐音”和“非乐音/噪声”部分。
在这里插入图片描述
模型1根据音频频谱的局部功率最大值确定乐音成分:局部峰值为乐音,然后将本临界频带内的剩余频谱合在一起,组成一个代表噪音频率。

5. 音调和非音调掩蔽成分的消除

利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率的成分。

6. 单个掩蔽阈值的计算

音调成分和非音调成分单个掩蔽阈值根据标准中给出的算法求得。

7. 全局掩蔽阈值的计算

某一频率点的

8. 每个子带的掩蔽阈值

选择出本子带中最小的阈值作为子带阈值(对高频不正确——高频区的临界频带很宽,可能跨越多个子带,从而导致模型1将临界带宽内所有的非音调部分集中为一个代表频率,当一个子带在很宽的频带内却远离代表频率时,无法得到准确的非音调掩蔽值。但计算量低。)

9. 计算每个子带信号掩蔽比(SMR)

SMR = 信号能量/掩蔽阈值
将SMR传递给编码单元

以下是心理声学模型1(Layer Ⅱ)的代码摘选

/**********************************************************************

        This module implements the psychoacoustic model I for the
 MPEG encoder layer II. It uses simplified tonal and noise masking
 threshold analysis to generate SMR for the encoder bit allocation
 routine.

**********************************************************************/
// buffer PCM样本; scale 缩放因子; ltmin SMR; 
void psycho_1 (short buffer[2][1152], double scale[2][SBLIMIT],
	       double ltmin[2][SBLIMIT], frame_info * frame)
{
  frame_header *header = frame->header;
  int nch = frame->nch;
  int sblimit = frame->sblimit;
  int k, i, tone = 0, noise = 0;
  static char init = 0;
  static int off[2] = { 256, 256 };
  double sample[FFT_SIZE];
  double spike[2][SBLIMIT];
  static D1408 *fft_buf;
  static mask_ptr power;
  static g_ptr ltg;
  FLOAT energy[FFT_SIZE];

  /* call functions for critical boundaries, freq. */
  if (!init) {			/* bands, bark values, and mapping */
    fft_buf = (D1408 *) mem_alloc ((long) sizeof (D1408) * 2, "fft_buf");
    power = (mask_ptr) mem_alloc (sizeof (mask) * HAN_SIZE, "power");
    if (header->version == MPEG_AUDIO_ID) {
      psycho_1_read_cbound (header->lay, header->sampling_frequency);
      psycho_1_read_freq_band (&ltg, header->lay, header->sampling_frequency);
    } else {
      psycho_1_read_cbound (header->lay, header->sampling_frequency + 4);
      psycho_1_read_freq_band (&ltg, header->lay, header->sampling_frequency + 4);
    }
    psycho_1_make_map (power, ltg);
    for (i = 0; i < 1408; i++)
      fft_buf[0][i] = fft_buf[1][i] = 0;

    psycho_1_init_add_db ();		/* create the add_db table */

    init = 1;
  }
  for (k = 0; k < nch; k++) {
    /* check pcm input for 3 blocks of 384 samples */
    /* sami's speedup, added in 02j
       saves about 4% overall during an encode */
    int ok = off[k] % 1408;
    for (i = 0; i < 1152; i++) {
      fft_buf[k][ok++] = (double) buffer[k][i] / SCALE;
      if (ok >= 1408)
	ok = 0;
    }
    ok = (off[k] + 1216) % 1408;
    for (i = 0; i < FFT_SIZE; i++) {
      sample[i] = fft_buf[k][ok++];
      if (ok >= 1408)
	ok = 0;
    }
    off[k] += 1152;
    off[k] %= 1408;

    // 加hanning窗fft,计算能量密度谱
    psycho_1_hann_fft_pickmax (sample, power, &spike[k][0], energy);
    // 确定乐音成分
    psycho_1_tonal_label (power, &tone);
    // 确定噪音成分
    psycho_1_noise_label (power, &noise, ltg, energy);
    //psycho_1_dump(power, &tone, &noise) ;
    // 消除掩蔽成分
    psycho_1_subsampling (power, ltg, &tone, &noise);
    // 计算单个掩蔽阈值并根据绝对阈值得到总掩蔽阈值
    psycho_1_threshold (power, ltg, &tone, &noise,
	       bitrate[header->version][header->bitrate_index] / nch);
    // 选出本子带中最小的阈值作为子带阈值
    psycho_1_minimum_mask (ltg, &ltmin[k][0], sblimit);
    // 计算每个子带信号掩蔽比
    psycho_1_smr (&ltmin[k][0], &spike[k][0], &scale[k][0], sblimit);
  }

}

码率分配的基本思路

再调整固定的码率之前,先确定可用于样值编码的有效比特数,这个数值取决于比例因子、比例因子选择信息、比特分配信息

比特分配过程:
对每个子带计算掩蔽-噪声比NMR(NMR=SMR-SNR),SNR是信噪比,由MPEG-Ⅰ标准给定(根据量化水平计算的得到)。

信掩比减去信噪比,得到的是考虑噪声和掩蔽后剩余的信号强度。

对最高NMR的子带分配比特,使获益最大的子带量化级别增加一级
重新计算分配了更多比特子带的NMR(SNR发生了改变)。

程序测试

编译执行示例程序,对test.wav进行编码
在这里插入图片描述
输入音频采样率为44.1kHz,输出比特率为192kbps。

打印帧信息

修改程序,打印出一帧的总可用比特数、缩放因子、最终比特分配结果:

Avalable bits: 5016
Scale(0): 0.099213 0.004922 0.003906 0.000775 0.004922 0.002461 0.001953 0.002461 0.003100 0.001230 0.000977 0.000615 0.000388 0.000308 0.000388 0.000194 0.000194 0.000154 0.000010 0.000012 0.000010 0.000010 0.000012 0.000010 0.000008 0.000010 0.000008 0.000010 0.000015 0.000010 0.000000 0.000000
Scale(1): 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Allocate bits
Bit alloc(0): 9 8 7 8 10 8 8 8 9 8 7 7 6 6 6 6 6 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Bit alloc(1): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值