Mpeg音频分析

实验原理

在这里插入图片描述
注意这两条线是不同的处理方向
1.子带滤波 提高时间分辨率
2.fft转变为频域方面进行分析
3.心理声学模型,依据人耳听觉阈值和听觉掩蔽特性建立
4.比例因子提取、选择,每个子带的12个样点为一个数据块,则一个子带含有3个数据块,将这三个数据块的比例因子进行提取并比较
5.动态比特分配,根据码率和心理声学模型,为子带分配最合理的量化比特数,使整帧和每个子带的噪掩比NMR最小的算法

心理声学模型理解

1.频域掩蔽 一个强纯音会掩蔽在其频域上附近同时发声的弱纯音,这称为频域掩蔽
2.时域掩蔽效应 时间上相邻的声音也会有掩蔽现象,即一个时域上强音对附近的其他弱音有掩蔽效应。分为超前掩蔽和滞后掩蔽。
3.对每个子带计算掩蔽-噪声比MNR,是信噪比SNR与信掩比SMR之差,
MNR = SNR–SMR
噪声-掩蔽比(noise-to-mask ratio, NMR):NMR = SMR – SNR (dB),每次给掩噪比最小的子带增加bit数

代码分析

1.输出音频的采样率和目标码率

void print_config (frame_info * frame, int *psy, char *inPath,
		   char *outPath)
{
  frame_header *header = frame->header;

  if (glopts.verbosity == 0)
    return;

  fprintf (stderr, "--------------------------------------------\n");
  fprintf (stderr, "Input File : '%s'   %.1f kHz\n",
	   (strcmp (inPath, "-") ? inPath : "stdin"),
	   s_freq[header->version][header->sampling_frequency]);
  fprintf (stderr, "Output File: '%s'\n",
	   (strcmp (outPath, "-") ? outPath : "stdout"));
  fprintf (stderr, "%d kbps ", bitrate[header->version][header->bitrate_index]);
  fprintf (stderr, "%s ", version_names[header->version]);
  if (header->mode != MPG_MD_JOINT_STEREO)
    fprintf (stderr, "Layer II %s Psycho model=%d  (Mode_Extension=%d)\n",
	     mode_names[header->mode], *psy, header->mode_ext);
  else
    fprintf (stderr, "Layer II %s Psy model %d \n", mode_names[header->mode],
	     *psy);
  fprintf (stderr, "[De-emph:%s\tCopyright:%s\tOriginal:%s\tCRC:%s]\n",
	   ((header->emphasis) ? "On" : "Off"),
	   ((header->copyright) ? "Yes" : "No"),
	   ((header->original) ? "Yes" : "No"),
	   ((header->error_protection) ? "On" : "Off"));

  fprintf (stderr, "[Padding:%s\tByte-swap:%s\tChanswap:%s\tDAB:%s]\n",
	   ((glopts.usepadbit) ? "Normal" : "Off"),
	   ((glopts.byteswap) ? "On" : "Off"),
	   ((glopts.channelswap) ? "On" : "Off"),
	   ((glopts.dab) ? "On" : "Off"));

  if (glopts.vbr == TRUE)
    fprintf (stderr, "VBR Enabled. Using MNR boost of %f\n", glopts.vbrlevel);
  fprintf(stderr,"ATH adjustment %f\n",glopts.athlevel);

  fprintf (stderr, "--------------------------------------------\n");
}

2.输出某数据帧的相关内容

int frameNum = 0;
int spec_frameNum = 1;//newly added 指定的帧数
int main (int argc, char **argv)
......

 FILE* result;
 result = fopen("output_result.txt", "w");
 if (result == NULL){
	 printf("error opening txt file.");
	 system("pause");
	 exit(-1);}//newly added
 	if(frameNum == spec_frameNum)
		fprintf (stderr, "[%4u]\r", frameNum);
      while (get_audio (musicin, buffer, num_samples, nch, &header) > 0) {
        if (glopts.verbosity > 1)
          if (++frameNum % 10 == 0)
        fprintf (stderr, "[%4u]\r", frameNum);
        fflush (stderr);
        output = (frameNum == spec_frame);
        win_buf[0] = &buffer[0][0];
        win_buf[1] = &buffer[1][0];
        adb = available_bits (&header, &glopts);//number of available bits
  	    //输出可用比特数
        if(output)
            fprintf(result,"可用比特数:%d\n",adb);//newly added
......
    	scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit);//计算比例因子scalar
    pick_scale (scalar, &frame, max_sc);
    if (frame.actual_mode == MPG_MD_JOINT_STEREO) {
      /* this way we calculate more mono than we need */
      /* but it is cheap */
      combine_LR (*sb_sample, *j_sample, frame.sblimit);//各个子带左右声道结合,结合后的为j_sample
      scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit);//计算比例因子j_scale
    }
	if (frameNum == spec_frameNum)
		{
			//输出比例因子
			fprintf(result, "比例因子:\n");
			for (int k = 0; k < nch; k++)//声道
			{
				fprintf(result, "声道:%d:\n", k + 1);
				for (int i = 0; i < SBLIMIT; i++)//子带三个比例因子
				{
					fprintf(result, "子带:%d:\t", i);
					for (int j = 0; j < 3; j++)
					{
						fprintf(result, "%d\t", scalar[k][j][i]);
					}
					fprintf(result, "\n");
				}
			}
		}
......
        transmission_pattern (scalar, scfsi, &frame);
        main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
        //输出比特分配结果
        if (frameNum == spec_frameNum)
            {
                fprintf(result, "比特分配结果\n");
                for (int k = 0; k < nch; k++)//声道
                {
                    fprintf(result, "声道%d:\n", k + 1);
                    for (int i = 0; i < SBLIMIT; i++)//每个子带有一个比特分配结果
                    {
                        fprintf(result, "子带%d:\t", i);
                        fprintf(result, "%d\n", bit_alloc[k][i]);
                    }
                }
            }
......
fclose(result);

在这里插入图片描述

结果分析

频带频率越高分配到的比特数越少,与实验原理一致

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值