【数据压缩】MPEG音频编码实验

一、MPEG-1 Audio LayerII编码器原理

1、MPEG-1音频编码器框架图

在这里插入图片描述

(1)编码流程的两条线

整个编码流程分为两条线:
第一条线是主线,输入的PCM码流经过多相滤波器组分成32个子带信号。经过块形成后,对每个子带数据进行线性量化,对部分量化级别采用颗粒优化以增大压缩比,最后装帧输出。
第二条线是对应人耳特性,进行FFT变换,经过心理声学模型去除信号中被掩蔽的部分,提取出比例因子后进行动态比特分配:对人耳听觉敏感的低频成分分配较多比特,对高频噪声分配较少的比特,以增大压缩比。比例因子经过选择后,数据编码装帧输出。

(2)时域分析的矛盾

在时-频分析中也存在“测不准原理”,即时域分辨力和频域分辨力不可兼得,增大频域分辨力的同时时域分辨力便相应减小,反之亦然。
根据这一矛盾,MPEG-1音频编码采用了一系列方法来尽可能地兼顾时域分辨力和频域分辨力:

  1. 通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量。
  2. 使信号通过FFT运算具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来 的。

2、多相滤波器组

在这里插入图片描述其中,512个输入样本空间的FIFO缓冲区:新输入的32个样本在最低端。
数字音频信号通过一个多相滤波器组,变换成32个等宽频带子带,使得信号具有较高的时间分辨率,确保在短暂冲击信号的情况下,编码的声音信号具有足够高的质量。
缺点是等带宽的滤波器组与人类听觉系统的临界频带不对应,在低频区域,单个子带会覆盖多个临界频带。在这种情况下,量化比特数不能兼每个临界频带;滤波器组与其逆过程不是无失真的,但滤波器组引入的误差差很小,且听不到;子带间频率有混叠,滤波后的相邻子带有频率混叠现象,一个子带中的信号可以影响相邻子带的输出。
滤波器组的输出是临界频带经过量化的系数样值。若一个子带覆盖多个临界频带,则选择具有最小NMR的临界频带来计算分配给子带的比特数。

3、MPEG-I 心理声学模型

通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量。同时,令信号通过多点FFT运算具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来的。在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数,即分配较多的位数来表示样本值。而话音中的摩擦音和类似噪声的声音,通常出现在高频子带中,对它分配较少的位数。而具体如何分配,则是要参考码率和心理声学模型。
心理声学模型的实现过程如下所示。

(1)将样本变换到频域

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)中较小的一个。

(2)确定声压级别

子带n中的声压级别 L s b L_{s b} Lsb计算如下:
L s b ( n ) = MAX ⁡ [ X ( k ) , 20 × log ⁡ 10 ( s c f max ⁡ ( n ) × 32768 ) − 10 ] d B L_{s b}(n)=\operatorname{MAX}\left[\mathrm{X}(\mathrm{k}), 20 \times \log _{10}\left(\mathrm{scf}_{\max }(\mathrm{n}) \times 32768\right)-10\right] \mathrm{dB} Lsb(n)=MAX[X(k),20×log10(scfmax(n)×32768)10]dB
其中, X ( k ) \mathrm{X}(\mathrm{k}) X(k)是在子带n中的频谱线的声压级别, s c f max ⁡ ( n ) {scf}_{\max }(\mathrm{n}) scfmax(n)是在一帧中子带的三个缩放因子中最大的一个。

(3)考虑安静时阈值

也即绝对阈值。在标准中有根据输入PCM信号的采样率编制的“频率、临界频带率和绝对阈值”表。此表为多位科学家经多次心理声学实验所得

(4)分解音频信号

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

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

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

(6)单个掩蔽阈值的计算

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

(7)全局掩蔽阈值的计算

某一频率点i的总掩蔽阈值可通过该点的绝对掩蔽阈值与单独掩蔽阈值相加来获得。即:
LTg ⁡ ( i ) = 10 lg ⁡ ( 1 0 L T q ( i ) / 10 + ∑ j = 1 m 1 0 L h m ( { z ( j ) , z ( i ) ) / 10 + ∑ j = 1 n 1 0 L T m m ( z ( j ) , z ( i ) ) / 10 ) \operatorname{LTg}(i)=10 \lg \left(10^{L T_{q}(i) / 10}+\sum_{j=1}^{m} 10^{L h_{m}(\{z(j), z(i)) / 10}+\sum_{j=1}^{n} 10^{L T m m(z(j), z(i)) / 10}\right) LTg(i)=10lg(10LTq(i)/10+j=1m10Lhm({z(j),z(i))/10+j=1n10LTmm(z(j),z(i))/10)
其中, LTg ⁡ ( i ) \operatorname{LTg}(i) LTg(i)是频率点i的绝对掩蔽阚值, L h m ( z ( j ) , z ( i ) ) {L h_{m}(z(j), z(i)) } Lhm(z(j),z(i))是第j个音调掩蔽成分对频率点i的掩蔽阈值,对频率点i有掩蔽效应的音调掩蔽成分共m个; L h m ( z ( j ) , z ( i ) ) {L h_{m}(z(j), z(i)) } Lhm(z(j),z(i))是第j个非音调掩蔽成分对频率点i的掩蔽阈值,对频率点i有掩蔽效应的非音调掩蔽成分共n个。
还要考虑别的临界频带的影响。一个掩蔽信号会对其它频带上的信号产生掩蔽效应。这种掩蔽效应称为掩蔽扩散。

(8)每个子带的掩蔽阈值

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

(9)计算每个子带信号掩蔽比(signal-to-mask ratio, SMR)

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

4、码率分配

使整帧和每个子带的总噪声—掩蔽比最小,
计算噪声-掩蔽比(noise-to-mask ratio, NMR):NMR = SMR – SNR (dB),
其中SNR 由MPEG-I标准给定 (为量化水平的函数),NMR:表示波形误差与感知测量之间的误差。
算法:循环,直到没有比特可用:
对最高NMR的子带分配比特,使获益最大的子带的量化级别增加一级,
重新计算分配了更多比特子带的NMR。
在这里插入图片描述
Layer2的码率分配与Layer1基本一致,其量化在Layer1的基础上进行了改进:
根据采样和码率量化,不同子带可以从不同的量化器集合中选择,由此以来某些(高频)子带的比特数可能为0 。
对量化级别在3、5、9级时,采用“颗粒” 优化。

5、装帧

Layer2帧结构:3 组/帧 x 12个样本/子带 x 32个子带/帧 = 1152个样本/帧;每个样本的overhead更少、
缩放因子:每个子带的3个组尽可能共用缩放因子 , Layer 2: 1个/(24/36)个样本,
1/2/3个缩放因子和缩放因子选择信息(scale factor selection information, SCFSI) (每子带2比特)一起传送 .
若缩放因子和下一个只有很小的差别,就只传送大的一个,
若三个缩放因子差别比较大,则全部传送。

二、实验过程

1、实验要求

(1)理解程序设计的基本框架、感知音频编码的设计思想、心理声学模型的实现过程和码率分配的实现思路。
(2)输出音频的采样率和目标码率。
(3)选择三个不同特性的音频文件:噪声、乐音和混合声,对某个数据帧输出该帧所分配的比特数、该帧的比例因子和该帧的比特分配结果。

2、编码器的分析与调试

(1)多相滤波器,分成32个子带
{  
	int gr, bl, ch;  
    /* New polyphase filter 
	Combines windowing and filtering. Ricardo Feb'03 */  
	for( gr = 0; gr < 3; gr++ )  
 		for ( bl = 0; bl < 12; bl++ )  
   		for ( ch = 0; ch < nch; ch++ )  
     		 WindowFilterSubband( &buffer[ch][gr * 12 * 32 + 32 * bl], ch,  
         		&(*sb_sample)[ch][gr][bl][0] );  //滑动窗口滤波的函数
}  
(2)计算比例因子及比例因子选择信息
scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit);  
pick_scale (scalar, &frame, max_sc);  
(3)心理声学模型
    if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) {
      /* We're using quick mode, so we're only calculating the model every
         'quickcount' frames. Otherwise, just copy the old ones across */
      for (ch = 0; ch < nch; ch++) {
	for (sb = 0; sb < SBLIMIT; sb++)
	  smr[ch][sb] = smrdef[ch][sb];
      }
    } else {
      /* calculate the psymodel */
      switch (model) {
      case -1:
	psycho_n1 (smr, nch);
	break;
      case 0:	/* Psy Model A */
	psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000);	
	break;
      case 1:
	psycho_1 (buffer, max_sc, smr, &frame);
	break;
      case 2:
	for (ch = 0; ch < nch; ch++) {
	  psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	}
	break;
      case 3:
	/* Modified psy model 1 */
	psycho_3 (buffer, max_sc, smr, &frame, &glopts);
	break;
      case 4:
	/* Modified Psycho Model 2 */
	for (ch = 0; ch < nch; ch++) {
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	}
	break;	
      case 5:
	/* Model 5 comparse model 1 and 3 */
	psycho_1 (buffer, max_sc, smr, &frame);
	fprintf(stdout,"1 ");
	smr_dump(smr,nch);
	psycho_3 (buffer, max_sc, smr, &frame, &glopts);
	fprintf(stdout,"3 ");
	smr_dump(smr,nch);
	break;
      case 6:
	/* Model 6 compares model 2 and 4 */
	for (ch = 0; ch < nch; ch++) 
	  psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32,
		    (FLOAT) s_freq[header.version][header.sampling_frequency] *
		    1000, &glopts);
	fprintf(stdout,"2 ");
	smr_dump(smr,nch);
	for (ch = 0; ch < nch; ch++) 
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	fprintf(stdout,"4 ");
	smr_dump(smr,nch);
	break;
      case 7:
	fprintf(stdout,"Frame: %i\n",frameNum);
	/* Dump the SMRs for all models */	
	psycho_1 (buffer, max_sc, smr, &frame);
	fprintf(stdout,"1");
	smr_dump(smr, nch);
	psycho_3 (buffer, max_sc, smr, &frame, &glopts);
	fprintf(stdout,"3");
	smr_dump(smr,nch);
	for (ch = 0; ch < nch; ch++) 
	  psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32,
		    (FLOAT) s_freq[header.version][header.sampling_frequency] *
		    1000, &glopts);
	fprintf(stdout,"2");
	smr_dump(smr,nch);
	for (ch = 0; ch < nch; ch++) 
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	fprintf(stdout,"4");
	smr_dump(smr,nch);
	break;
      case 8:
	/* Compare 0 and 4 */	
	psycho_n1 (smr, nch);
	fprintf(stdout,"0");
	smr_dump(smr,nch);

	for (ch = 0; ch < nch; ch++) 
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	fprintf(stdout,"4");
	smr_dump(smr,nch);
	break;
      default:
	fprintf (stderr, "Invalid psy model specification: %i\n", model);
	exit (0);
      }
(4)计算NMR并进行动态比特分配
transmission_pattern (scalar, scfsi, &frame);  
main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts); 
(5)CRC检验
if (error_protection)  
  CRC_calc (&frame, bit_alloc, scfsi, &crc);  
encode_info (&frame, &bs);  
if (error_protection)  
  encode_CRC (crc, &bs);  
(6)量化装帧送至比特流
    subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc,
			  *subband, &frame);
    sample_encoding (*subband, bit_alloc, &frame, &bs);
#endif


    /* If not all the bits were used, write out a stack of zeros */
    for (i = 0; i < adb; i++)
      put1bit (&bs, 0);
    if (header.dab_extension) {
      /* Reserve some bytes for X-PAD in DAB mode */
      putbits (&bs, 0, header.dab_length * 8);
      
      for (i = header.dab_extension - 1; i >= 0; i--) {
	CRC_calcDAB (&frame, bit_alloc, scfsi, scalar, &crc, i);
	/* this crc is for the previous frame in DAB mode  */
	if (bs.buf_byte_idx + lg_frame < bs.buf_size)
	  bs.buf[bs.buf_byte_idx + lg_frame] = crc;
	/* reserved 2 bytes for F-PAD in DAB mode  */
	putbits (&bs, crc, 8);
      }
      putbits (&bs, 0, 16);
    }

    frameBits = sstell (&bs) - sentBits;

    if (frameBits % 8) {	/* a program failure */
      fprintf (stderr, "Sent %ld bits = %ld slots plus %ld\n", frameBits,
	       frameBits / 8, frameBits % 8);
      fprintf (stderr, "If you are reading this, the program is broken\n");
      fprintf (stderr, "email [mfc at NOTplanckenerg.com] without the NOT\n");
      fprintf (stderr, "with the command line arguments and other info\n");
      exit (0);
    }

    sentBits += frameBits;
  }

  close_bit_stream_w (&bs);

3、准备工作

  1. matlab生成高斯白噪音并添加至乐音生成混合音。代码如附件所示。
  2. 命令行为“输入文件 输出文件”,示例:
test.wav  test.mp2

4、输出音频的采样率和目标码率

在print_config()函数中添加输出音频的采样率和目标码率的代码:

  FILE* infoFp;
  infoFp = fopen("text.txt", "w");
  fprintf(infoFp, "========== 基本信息 ==========\n");
  fprintf(infoFp, "输入文件:%s\n", inPath);
  fprintf(infoFp, "输出文件:%s\n", outPath);
  fprintf(infoFp, "采样频率:%.1f kHz\n", s_freq[header->version][header->sampling_frequency]);
  fprintf(infoFp, "输出文件码率:%d kbps\n", bitrate[header->version][header->bitrate_index]);

5、输出某帧所分配的比特数、比例因子和比特分配结果

在main()函数中添加输出某个数据帧所分配的比特数、比例因子和比特分配结果的代码:

FILE* infoFp;
infoFp = fopen("text.txt", "at+");
if (frameNum == 2) {
	fprintf(infoFp, "声道数:%d\n", nch);
	fprintf(infoFp, "目前观测第 %d 帧\n", frameNum);
	fprintf(infoFp, "本帧比特预算:%d bits\n", adb);
	fprintf(infoFp, "\n");

	/* 比例因子 */
	fprintf(infoFp, "========== 比例因子 ==========\n");
	for (ch = 0; ch < nch; ch++)	// 每个声道单独输出
	{
		fprintf(infoFp, "------ 声道%2d ------\n", ch + 1);
		for (sb = 0; sb < frame.sblimit; sb++)	// 每个子带
		{
			fprintf(infoFp, "子带[%2d]:\t", sb + 1);
			for (int gr = 0; gr < 3; gr++) {
				fprintf(infoFp, "%2d\t", scalar[ch][gr][sb]);
			}
			fprintf(infoFp, "\n");
		}
	}
	fprintf(infoFp, "\n");

	/* 比特分配表 */
	fprintf(infoFp, "========== 比特分配表 ==========\n");  //输出比特分配结果
	for (ch = 0; ch < nch; ch++) {
		fprintf(infoFp, "------ 声道%2d ------\n", ch + 1); //按声道分配
		for (sb = 0; sb < frame.sblimit; sb++) {
			fprintf(infoFp, "子带[%2d]:\t%2d\n", sb + 1, bit_alloc[ch][sb]);
		}
		fprintf(infoFp, "\n");
	}
}

三、实验结果

(1)乐音
========== 基本信息 ==========
输入文件:model.wav
输出文件:model.mp2
采样频率:44.1 kHz
输出文件码率:192 kbps
声道数:2
目前观测第 2 帧
本帧比特预算:5016 bits

========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]:	22	16	15	
子带[ 2]:	23	16	16	
子带[ 3]:	23	18	20	
子带[ 4]:	31	22	20	
子带[ 5]:	30	27	26	
子带[ 6]:	38	31	32	
子带[ 7]:	40	35	36	
子带[ 8]:	56	49	49	
子带[ 9]:	56	58	58	
子带[10]:	57	57	57	
子带[11]:	55	57	56	
子带[12]:	57	58	57	
子带[13]:	60	57	55	
子带[14]:	55	55	58	
子带[15]:	56	57	56	
子带[16]:	58	59	59	
子带[17]:	60	58	57	
子带[18]:	58	57	60	
子带[19]:	58	58	57	
子带[20]:	57	58	57	
子带[21]:	59	57	57	
子带[22]:	59	57	55	
子带[23]:	55	53	53	
子带[24]:	53	51	50	
子带[25]:	59	56	58	
子带[26]:	59	57	57	
子带[27]:	58	60	56	
子带[28]:	59	58	61	
子带[29]:	59	57	58	
子带[30]:	57	57	58	
------ 声道 2 ------
子带[ 1]:	21	16	14	
子带[ 2]:	23	16	17	
子带[ 3]:	23	18	20	
子带[ 4]:	28	21	21	
子带[ 5]:	30	28	26	
子带[ 6]:	41	32	32	
子带[ 7]:	37	35	35	
子带[ 8]:	56	50	48	
子带[ 9]:	57	57	57	
子带[10]:	58	57	58	
子带[11]:	58	56	57	
子带[12]:	56	57	56	
子带[13]:	57	57	59	
子带[14]:	57	59	58	
子带[15]:	55	58	57	
子带[16]:	60	59	59	
子带[17]:	58	57	58	
子带[18]:	58	57	56	
子带[19]:	59	57	59	
子带[20]:	58	57	58	
子带[21]:	59	56	57	
子带[22]:	58	56	55	
子带[23]:	56	54	55	
子带[24]:	53	51	51	
子带[25]:	58	56	56	
子带[26]:	59	57	59	
子带[27]:	57	58	58	
子带[28]:	59	57	57	
子带[29]:	61	58	58	
子带[30]:	57	57	60	

========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]:	 4
子带[ 2]:	 4
子带[ 3]:	 3
子带[ 4]:	 6
子带[ 5]:	 5
子带[ 6]:	 4
子带[ 7]:	 5
子带[ 8]:	 4
子带[ 9]:	 4
子带[10]:	 5
子带[11]:	 4
子带[12]:	 5
子带[13]:	 4
子带[14]:	 4
子带[15]:	 5
子带[16]:	 5
子带[17]:	 4
子带[18]:	 4
子带[19]:	 4
子带[20]:	 4
子带[21]:	 4
子带[22]:	 3
子带[23]:	 3
子带[24]:	 1
子带[25]:	 0
子带[26]:	 0
子带[27]:	 0
子带[28]:	 0
子带[29]:	 0
子带[30]:	 0

------ 声道 2 ------
子带[ 1]:	 4
子带[ 2]:	 5
子带[ 3]:	 4
子带[ 4]:	 6
子带[ 5]:	 5
子带[ 6]:	 4
子带[ 7]:	 5
子带[ 8]:	 4
子带[ 9]:	 4
子带[10]:	 5
子带[11]:	 4
子带[12]:	 5
子带[13]:	 4
子带[14]:	 4
子带[15]:	 5
子带[16]:	 5
子带[17]:	 4
子带[18]:	 4
子带[19]:	 4
子带[20]:	 4
子带[21]:	 4
子带[22]:	 3
子带[23]:	 3
子带[24]:	 1
子带[25]:	 0
子带[26]:	 0
子带[27]:	 0
子带[28]:	 0
子带[29]:	 0
子带[30]:	 0

(2)噪声
========== 基本信息 ==========
输入文件:noise.wav
输出文件:noise.mp2
采样频率:44.1 kHz
输出文件码率:192 kbps
声道数:2
目前观测第 2 帧
本帧比特预算:5016 bits

========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]:	27	26	25	
子带[ 2]:	28	26	25	
子带[ 3]:	26	28	29	
子带[ 4]:	27	28	27	
子带[ 5]:	27	27	27	
子带[ 6]:	26	25	27	
子带[ 7]:	28	28	27	
子带[ 8]:	27	26	27	
子带[ 9]:	28	26	26	
子带[10]:	30	26	25	
子带[11]:	26	26	26	
子带[12]:	27	27	25	
子带[13]:	28	28	27	
子带[14]:	27	27	26	
子带[15]:	27	29	29	
子带[16]:	25	27	26	
子带[17]:	29	27	25	
子带[18]:	27	27	27	
子带[19]:	27	27	27	
子带[20]:	25	27	27	
子带[21]:	28	27	28	
子带[22]:	28	27	27	
子带[23]:	26	28	26	
子带[24]:	26	28	27	
子带[25]:	29	25	25	
子带[26]:	26	26	27	
子带[27]:	28	28	26	
子带[28]:	27	26	29	
子带[29]:	28	27	26	
子带[30]:	25	26	26	
------ 声道 2 ------
子带[ 1]:	28	27	29	
子带[ 2]:	27	28	28	
子带[ 3]:	28	26	26	
子带[ 4]:	28	25	27	
子带[ 5]:	27	27	26	
子带[ 6]:	28	28	30	
子带[ 7]:	27	29	25	
子带[ 8]:	27	26	28	
子带[ 9]:	26	28	27	
子带[10]:	28	27	27	
子带[11]:	28	29	28	
子带[12]:	26	26	27	
子带[13]:	25	26	28	
子带[14]:	25	27	27	
子带[15]:	28	27	27	
子带[16]:	28	25	26	
子带[17]:	28	26	27	
子带[18]:	28	27	26	
子带[19]:	26	28	26	
子带[20]:	25	26	24	
子带[21]:	27	27	28	
子带[22]:	25	27	28	
子带[23]:	28	28	27	
子带[24]:	27	27	27	
子带[25]:	27	27	27	
子带[26]:	26	28	25	
子带[27]:	26	29	28	
子带[28]:	28	27	26	
子带[29]:	26	26	24	
子带[30]:	28	29	27	

========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]:	 3
子带[ 2]:	 3
子带[ 3]:	 3
子带[ 4]:	 4
子带[ 5]:	 5
子带[ 6]:	 3
子带[ 7]:	 4
子带[ 8]:	 3
子带[ 9]:	 3
子带[10]:	 3
子带[11]:	 2
子带[12]:	 3
子带[13]:	 1
子带[14]:	 2
子带[15]:	 2
子带[16]:	 1
子带[17]:	 3
子带[18]:	 3
子带[19]:	 1
子带[20]:	 1
子带[21]:	 1
子带[22]:	 1
子带[23]:	 0
子带[24]:	 0
子带[25]:	 0
子带[26]:	 0
子带[27]:	 0
子带[28]:	 0
子带[29]:	 0
子带[30]:	 0

------ 声道 2 ------
子带[ 1]:	 3
子带[ 2]:	 3
子带[ 3]:	 3
子带[ 4]:	 4
子带[ 5]:	 4
子带[ 6]:	 3
子带[ 7]:	 4
子带[ 8]:	 3
子带[ 9]:	 3
子带[10]:	 3
子带[11]:	 2
子带[12]:	 3
子带[13]:	 2
子带[14]:	 2
子带[15]:	 3
子带[16]:	 1
子带[17]:	 2
子带[18]:	 2
子带[19]:	 2
子带[20]:	 1
子带[21]:	 1
子带[22]:	 1
子带[23]:	 0
子带[24]:	 0
子带[25]:	 0
子带[26]:	 0
子带[27]:	 0
子带[28]:	 0
子带[29]:	 0
子带[30]:	 0
(3)混合音
========== 基本信息 ==========
输入文件:sound.wav
输出文件:sound.mp2
采样频率:44.1 kHz
输出文件码率:192 kbps
声道数:2
目前观测第 2 帧
本帧比特预算:5016 bits

========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]:	15	15	13	
子带[ 2]:	15	18	18	
子带[ 3]:	19	19	19	
子带[ 4]:	21	19	21	
子带[ 5]:	25	24	23	
子带[ 6]:	27	25	28	
子带[ 7]:	27	27	27	
子带[ 8]:	27	26	27	
子带[ 9]:	28	26	26	
子带[10]:	30	26	25	
子带[11]:	26	26	26	
子带[12]:	27	27	25	
子带[13]:	28	28	27	
子带[14]:	27	27	26	
子带[15]:	27	29	29	
子带[16]:	25	27	26	
子带[17]:	29	27	25	
子带[18]:	27	27	27	
子带[19]:	27	27	27	
子带[20]:	25	27	27	
子带[21]:	28	27	28	
子带[22]:	28	27	27	
子带[23]:	26	28	26	
子带[24]:	26	28	27	
子带[25]:	29	25	25	
子带[26]:	26	26	27	
子带[27]:	28	28	26	
子带[28]:	27	26	29	
子带[29]:	28	27	26	
子带[30]:	25	26	26	
------ 声道 2 ------
子带[ 1]:	15	15	14	
子带[ 2]:	15	18	19	
子带[ 3]:	20	19	19	
子带[ 4]:	21	19	21	
子带[ 5]:	25	25	23	
子带[ 6]:	27	27	29	
子带[ 7]:	27	28	25	
子带[ 8]:	27	26	28	
子带[ 9]:	26	28	27	
子带[10]:	28	27	27	
子带[11]:	28	29	28	
子带[12]:	26	26	27	
子带[13]:	25	26	28	
子带[14]:	25	27	27	
子带[15]:	28	27	27	
子带[16]:	28	25	26	
子带[17]:	28	26	27	
子带[18]:	28	27	26	
子带[19]:	26	28	26	
子带[20]:	25	26	24	
子带[21]:	27	27	28	
子带[22]:	25	27	28	
子带[23]:	28	28	27	
子带[24]:	27	27	27	
子带[25]:	27	27	27	
子带[26]:	26	28	25	
子带[27]:	26	29	28	
子带[28]:	28	27	26	
子带[29]:	26	26	24	
子带[30]:	28	29	27	

========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]:	 5
子带[ 2]:	 4
子带[ 3]:	 5
子带[ 4]:	 5
子带[ 5]:	 4
子带[ 6]:	 3
子带[ 7]:	 3
子带[ 8]:	 3
子带[ 9]:	 3
子带[10]:	 3
子带[11]:	 2
子带[12]:	 3
子带[13]:	 1
子带[14]:	 2
子带[15]:	 2
子带[16]:	 1
子带[17]:	 3
子带[18]:	 3
子带[19]:	 2
子带[20]:	 1
子带[21]:	 1
子带[22]:	 1
子带[23]:	 0
子带[24]:	 0
子带[25]:	 0
子带[26]:	 0
子带[27]:	 0
子带[28]:	 0
子带[29]:	 0
子带[30]:	 0

------ 声道 2 ------
子带[ 1]:	 5
子带[ 2]:	 5
子带[ 3]:	 5
子带[ 4]:	 4
子带[ 5]:	 4
子带[ 6]:	 3
子带[ 7]:	 3
子带[ 8]:	 3
子带[ 9]:	 3
子带[10]:	 3
子带[11]:	 2
子带[12]:	 3
子带[13]:	 2
子带[14]:	 2
子带[15]:	 3
子带[16]:	 1
子带[17]:	 3
子带[18]:	 3
子带[19]:	 2
子带[20]:	 1
子带[21]:	 1
子带[22]:	 1
子带[23]:	 0
子带[24]:	 0
子带[25]:	 0
子带[26]:	 0
子带[27]:	 0
子带[28]:	 0
子带[29]:	 0
子带[30]:	 0

四、实验问题

(1)解决“错误 D8016 “/ZI”和“/Gy-”命令行选项不兼容 ”问题

出现此问题,我们需要手动改变/ZI命令行选项 或者 /Gy命令行选项。
进入“项目”—>“属性”—>“C/C++—>“常规”—>“调试信息格式”—>选择“程序数据库(/Zi)”或“无”即可解决问题。
在这里插入图片描述

附件

[y,fs] = audioread('D:\\30s_trained_model.wav');%读入语音数据
%% 高斯白噪声信号
snr=10;%设定信噪比,单位db
[data,noise]=Gnoisegen(y,snr);%输出参数data是乐音混合噪声,noise是加在信号上的白噪声
audiowrite('noise.wav',noise,fs)
audiowrite('sound.wav',data,fs)
function [y,noise] = Gnoisegen(x,snr)

noise=randn(size(x));              % 用randn函数产生高斯白噪声
Nx=length(x);                      % 求出信号x长
signal_power = 1/Nx*sum(x.*x);     % 求出信号的平均能量
noise_power=1/Nx*sum(noise.*noise);% 求出噪声的能量
noise_variance = signal_power / ( 10^(snr/10) );    % 计算出噪声设定的方差值
noise=sqrt(noise_variance/noise_power)*noise;       % 按噪声的平均能量构成相应的白噪声
y=x+noise;                         % 合成带噪语音
end

参考

解决“错误 D8016 “/ZI”和“/Gy-”命令行选项不兼容 ”问题
MPEG-1 Audio Layer II编码原理及编码器调试
MPEG-1音频编码原理与实验

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值