实验六:MPEG音频编码实验

来源:互联网 发布:青秀区人民法院淘宝网 编辑:程序博客网 时间:2024/05/29 07:25

一、MPEG-1音频编码整体框架


心理声学模型:通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量;又可以使信号通过FFT运算具有高的频率分辨率,因为掩蔽域值是从功率谱密度推出来的。在低频子带中为了保护音调和共振峰的结构,就要求用较小的量化阶、潍坊人    化阶数,即分配较多的位数。噪音多分布在高频子带,分配较少的位数。

多项滤波器组:把PCM信号变换到32个子带的频域信号。 做子带分解。

心理声学模型:计算信号中不可听觉感知的部分 (噪声遮蔽效应)

比特分配器:根据心理声学模型的计算结果,为每个子带信号分配比特数

装帧:产生MPEG-1兼容的比特流。

二 、实验要求

理解程序设计的整体  框架;

将PCM码流分成两条线进行处理,一条经多项滤波器组划分为32个子带,每个子带有12个样点,对每个子带计算一次比例因子,用来确定量化器。另一条线对PCM信号进行FFT,由心理声学模型计算以频率为自变量的掩噪比。使量化噪声小于掩蔽域值。由心理声学模型确定比例因子选择信息和动态比特分配,决定一个子带分配多少比特。最后通过帧包装将量化自带的样本和其他数据(采样率,比特率,比例因子信息,动态比特分配信息)组装成比特流。

理解感知音频编码的设计思想:两条线、时频分析的矛盾

两条线:

第一条线:心理声学模型:以临界频带为分析单位,分析的横坐标是频率。谱线间隔越小越好。

第二条线:信号的短时相关性,时域越短越好,这样能抓住瞬时变化率。

时频分析的矛盾:频域的频谱分辨率和时域的变化率是一对矛盾,时域信号取得越短,频域谱线间隔越大。

理解心理声学模型实现的过程:临界频带的概念;掩蔽值计算的思路

临界频带是指当某个纯音被以它为中心频率,且具有一定带宽的连续噪声所掩蔽时,如果该纯音刚好被听到时的功率等于这一频带内的噪声功率,这个带宽为临界频带的宽度。

掩蔽值计算:单个掩蔽域值:乐音和非乐音掩蔽域值

全局掩蔽域值:某一频率点的掩蔽阈值等于该点的绝对掩蔽阈值与的那个掩蔽域值相加

每个子带的掩蔽域值:选出这个子带内最小的阈值作为该子带阈值

理解码率分配的实现思路

使整帧和整个子带的总噪声掩蔽比最小:MNR(掩噪比)=SNR(信噪比)-SMR(信掩比)

对最低的MNR的子带分配比特,使获益最大的子带量化级数级别增加一级,重新计算分配了更多比特的MNR

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

选择某个数据帧输出该帧分配的比特数、比例因子、比特分配结果

三:代码

输入文件:match2.WAV 输出文件 match2.mp3 

在scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit);//计算比例因子之后即可输出以下内容:

#ifdef NEWENCODE    scalefactor_calc_new(*sb_sample, scalar, nch, frame.sblimit);//计算比例因子    find_sf_max (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_new (*sb_sample, *j_sample, frame.sblimit);      scalefactor_calc_new (j_sample, &j_scale, 1, frame.sblimit);    }#else    scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit);    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);      scale_factor_calc (j_sample, &j_scale, 1, frame.sblimit);    }#endif/*add by zsy  输出采样率,比特率,帧数,每一帧的比特数,以及32*3*12个比例因子*/if(frameNum==10)    {        fprintf(outinfotable,"samplingrate:%.1fkhz\n",s_freq[header.version][header.sampling_frequency]);        fprintf(outinfotable,"bitrate:%dMbps\n",bitrate[header.version][header.bitrate_index]);fprintf(outinfotable,"frame num:%d\n",frameNum);        fprintf(outinfotable,"bitnum of this frame:%d\n",adb); fprintf(outinfotable, "\nScale_Factor:\n");        for (a = 0; a< nch; a++)//声道数2个        {            fprintf(outinfotable, "channel[%d] \n", a + 1);            for (b = 0; b < frame.sblimit; b++)//子带数32个            {                fprintf(outinfotable, "subband[%d]:    ", b + 1);                for (c = 0; c < 3; c++)//每个子带有三个比例因子                {                    fprintf(outinfotable, "%d\t", scalar[a][c][b]);                }                fprintf(outinfotable, "\n");            }        }     }/*add by zsy */


在 main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);//用第四步得到的掩蔽值为子带进行迭代比特分配让掩噪比最低 之后输出每个子带的比特分配信息

#else    transmission_pattern (scalar, scfsi, &frame);    main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);//用第四步得到的掩蔽值为子带进行迭代比特分配让掩噪比最低/* add by zsy 输出每一个子带分配的比特数*/if (frameNum == 10)    {        fprintf(outinfotable, "\nBits_Allocation:\n");        //int a, b;        for (a = 0; a < nch; a++)        {            fprintf(outinfotable, "channel[%d] \n", a + 1);            for (b = 0; b < frame.sblimit; b++)            {                fprintf(outinfotable, "subband[%d]:%d\n", b, bit_alloc[a][b]);            }        }    }/*end*/
四、实验结果
  

    

五、结论

层2一帧对应36个子带样值,原则上每帧要传3个比例因子,由以上输出信息可得,每帧的三个比例因子相差不大,因此可以将三个比例因子进行合并,进行比例因子选择,决定3个用一个获两个。

由每个子带的比特分配可得,频率越高(子带序号越大),分配IDE比特数越少,16、17以上的子带基本都为0,符合人耳听觉特征:对低频对高频敏感。