实验原理

MPEG简介

MPEG-1

MPEG组织制定的第一个视频和音频有损压缩标准,也是最早推出及应用在市场上的MPEG技术,其原来的主要目标是在CD光盘上记录影像,后来被广泛应用在VCD光盘。视频压缩算法于1990年定义完成。1992年底,MPEG-1正式被批准成为国际标准。其中的音讯压缩的第三级(MPEG-1 Layer 3)简称MP3,成为比较流行的音讯压缩格式。

MPEG-2

1994年发布,广播质量的视讯、音讯和传输协议。被用于无线数位电视-ATSC、DVB以及ISDB、数字卫星电视(例如DirecTV)、数字有线电视信号,以及DVD视频光盘技术中。AAC 的音频编码就出现在MPEG-2中。

MPEG-1声音的主要性能

        输入为PCM信号,采样率为32,44.1或48kHz,输出为32kbps到384kbps。
三个独立的压缩层次
        Layer1:编码器最简单,384kbps(4:1,用于小型数字盒带DCC,Compact Cassette)
        Layer2:编码器复杂程度中等,256kbps~192kbps(6:1~8:1, 用于DAB、CD-I和VCD)
        Layer3:编码器最为复杂,64kbps,用于ISDN,网络音频

MPEG音频压缩

MPEG-1 Audio LayerII编码器原理

        输入声音信号经过一个多相滤波器组,变换到多个子带。 同时经过“心理声学模型”计算以频率为自变量的噪声掩蔽阈值。量化和编码部分用信掩比SMR决定分配给子带信号的量化位数,使量化噪声<掩蔽域值。最后通过数据帧包装将量化的子带样本和其它数据按照规定的帧格式组装成比特数据流。

两条线

时间的瞬时特性

频域分析

时-频分析的矛盾

在低频部分,LayerI/II的带宽明显大于临界带宽

解决方法:提高频域分辨率(更多子带),同时保证向后兼容

(1)多相滤波器组,用来分割子带
(2)量化和编码 – 比例因子的取值和编码
(3)数据帧包装

MPEG-I 心理声学模型

通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量。

又可以使信号通过FFT运算具有高的频率分辨率,因为掩蔽阈值是从功率谱密度推出来的。

在低频子带中,为了保护音调和共振峰的结构,就要求用较小的量化阶、较多的量化级数,即分配较多的位数来表示样本值。而话音中的摩擦音和类似噪声的声音,通常出现在高频子带中,对它分配较少的位数。

        听觉系统中存在一个听觉阈值电平,低于这个电平的声音信号就听不到。
        ·听觉阈值的大小随声音频率的改变而改变。
        ·一个人是否听到声音取决于声音的频率,以及声音的幅度是否高于这种频率下的听觉阈值
        听觉掩蔽特性。即听觉阈值电平是自适应的,会随听到的不同频率声音而发生变化。
MPEG-I 标准定义了两个模型
        心理声学模型1: 计算复杂度低 但对假设用户听不到的部分压缩太严重
        心理声学模型2 : 提供了适合Layer III编码的更多特征

心理声学模型1

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、确定声压级别

3、考虑安静时阈值

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

4、将音频信号分解成“乐音(tones)” 和“非乐音/噪声”部分:因为两种信号的掩蔽能力不同

4、将音频信号分解成“乐音(tones)” 和“非乐音/噪声”部分:因为两种信号的掩蔽能力不同

模型1:根据音频频谱的局部功率最大值确定乐音成分 局部峰值为乐音,然后将本临界频带内的剩余频谱合在一起,组成一个代表噪声频率(无调成份)

要列出谱线x(k)的有调和无调,需执行下面三个步骤:

(1)标明局部最大。如果x(k)比相邻的两个谱线都大,则x(k)为局部最大值;

(2)列出有调成份,计算声压级。如果x(k)-x(k+j)>=7dB,则x(k)列为有调成份。j随谱线的位置不同。

(3)列出无调成分,计算功率。在每个临界频带内将所有余留谱线的功率加起来形成临界频带内无调成分的声压级。并列出以下参数:最接近临界频带几何平均值的谱线标记k,声压级以及无调指示。

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

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

6、单个掩蔽阈值的计算

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

7、全局掩蔽阈值的计算

还要考虑别的临界频带的影响。一个掩蔽信号会对其它频带上的信号产生掩蔽效应。这种掩蔽效应称为掩蔽扩散。

8、每个子带的掩蔽阈值

选择出本子带中最小的阈值作为子带阈值

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

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

SMR = 信号能量 / 掩蔽阈值

并将SMR传递给编码单元

听觉阈值

        ◼两个声音响度级相同,但强度不一定相同,还与频率有关;
        ◼ 声压级越高,等响度曲线趋于平坦;
        ◼ 人耳对3~4KHz的声音感觉最灵敏。 
        声压级(SPL): 

 ,零声级的参考声压值,为具有正常听力的年轻人对1 kHz的声音刚好能察觉的声压值

临界频带

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

        研究窄带噪声对纯音掩蔽量的规律时被发现的。
        ·使噪声的中心频率等于信号频率,只改变噪声的带宽同时保持噪声的功率谱密度不变,测试纯音听阈随掩蔽噪声带宽变化的特性。
        ·纯音的听阈随掩蔽噪声带宽的增大而增大,在带宽增大到某一特定值之后听阈保持恒定不变。
        通常认为从20Hz到16kHz有25个临界频带,单位为bark,1Bark = 一个临界频带的宽度。

人耳听觉系统

        人类听觉系统大致等效于一个信号通过一组并联的不同中心频率的带通滤波器。
        中心频率与信号频率相同的滤波器具有最大响应;中心频率偏离信号频率较多的滤波器不会产生响应。
        在0Hz到20KHz频率范围内由25个重叠的带通滤波器组成的滤波器组。
        听音者在噪声中听某一纯音信号时,只启用中心频率与信号频率相同的那个听觉滤波器,纯音信号通过该滤波器,而噪声信号只有通带范围内的部分信号能通过,通带以外的频率成分则被抑制,只有通过该滤波器的噪声才对掩蔽起作用。
        聆听复音时启动多个听觉滤波器。听觉能够计算各滤波器输出端的信噪比。当信噪比达到或者超过听阈因子时,即可听到该频率成分。

Layer I 编码

码率分配

在调整到固定的码率之前

·先确定可用于样值编码的有效比特数

·这个数值取决于比例因子、比例因子选择信息、比特分配信息以及辅助数据所需比特数

比特分配的过程

对每个子带计算掩蔽-噪声比MNR,是信噪比SNR–信掩比SMR,即:MNR = SNR–SMR

NMR=SMR-SNR

算法:使整帧和每个子带的总噪声—掩蔽比最小

计算噪声-掩蔽比(noise-to-mask ratio, NMR):         NMR = SMR – SNR          (dB)

其中SNR 由MPEG-I标准给定 (为量化水平的函数)

NMR:表示波形误差与感知测量之间的误差

算法:循环,直到没有比特可用:

NMR = SMR– SNR (dB)

对最高NMR的子带分配比特,使获益最大的子带的量化级别增加一级

重新计算分配了更多比特子带的NMR

装帧

Header:帧头格式

Layer II编码

与Layer I类似,但对Layer I有增强

装帧、缩放因子表示、量化 缩放因子(比例因子)一般从低频子带到高频子带出现连续下降

帧: 3 组/帧 x  12个样本/子带 x 32个子带/帧 = 1152个样本/帧 每个样本的overhead更少

缩放因子:每个子带的3个组尽可能共用缩放因子

Layer I: 1个/12个样本

Layer II: 1个/(24/36)个样本

1/2/3个缩放因子和缩放因子选择信息(scale factor selection information, SCFSI) (每子带2比特)一起传送

如果缩放因子和下一个只有很小的差别,就只传送大的一个,这种情况对于稳态信号经常出现

如果要给瞬态信号编码,则要在瞬态的前、后沿传送两个或所有三个比例因子

量化

Layer I:每个子带从相同的量化集合中选择

每个子带取共14个量化器中的一个

Layer II:

根据采样和码率量化,不同子带可以从不同的量化器集合中选择

·某些(高频)子带的比特数可能为0

对量化级别在3、5、9级时,采用“颗粒” 优化

·颗粒= 3 个样本,根据颗粒选择量化水平

装帧

Layer III 编码

MDCT 

        正交变换通常分块进行,而每块的变换系数一般独立编码 ,相继块的量化误差未必相同。由于正交变换在边界处存在着不连续性,因此在这些块边界处就有可能产生很大的幅度差异,这就是常令人头痛的“块边界效应”
        各种边界去块效应滤波器
◼ MDCT:改进的离散余弦变换(Modified Discrete CosineTransform) – 解决块边缘失真问题
◼ MDCT变换是一个非正交变换,必须采用时域混叠抵消技术(TDAC)来完成信号的重建
◼ 在实际处理时需要先加窗,再进行MDCT变换

IMDCT:

         分析过程中引进的混叠失真,可以在综合过程中抵消。

重构信号
        保留10个最大的系数  频域的量化噪声将扩展到变换的整个数据。
        对尖锐的短声音,需采用更小的块,以控制QE的扩散。

实验要求

理解程序设计的整体框架

理解感知音频编码的设计思想

·两条线

·时-频分析的矛盾!

理解心理声学模型的实现过程

临界频带的概念

掩蔽值计算的思路

理解码率分配的实现思路

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

选择三个不同特性的音频文件

噪声(持续噪声、突发噪声) 音乐 混合

某个数据帧,输出

该帧所分配的比特数

该帧的比例因子

该帧的比特分配结果

实验结果

命令行参数设置

int main(int argc, char** argv)
{typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT];   // SCALE_BLOCK=12,SBLIMIT=32SBS* sb_sample;typedef double JSBS[3][SCALE_BLOCK][SBLIMIT];JSBS* j_sample;typedef double IN[2][HAN_SIZE];   //HAN_SIZE=512IN* win_que;typedef unsigned int SUB[2][3][SCALE_BLOCK][SBLIMIT];SUB* subband;frame_info frame;     frame_header header;    char original_file_name[MAX_NAME_SIZE];     char encoded_file_name[MAX_NAME_SIZE];      short** win_buf;static short buffer[2][1152];     static unsigned int bit_alloc[2][SBLIMIT];     static unsigned int scfsi[2][SBLIMIT];static unsigned int scalar[2][3][SBLIMIT];     static unsigned int j_scale[3][SBLIMIT];static double smr[2][SBLIMIT], lgmin[2][SBLIMIT], max_sc[2][SBLIMIT];    // FLOAT snr32[32];short sam[2][1344];       /* was [1056]; */int model, nch, error_protection;    static unsigned int crc;int sb, ch, adb;      unsigned long frameBits, sentBits = 0;unsigned long num_samples;int lg_frame;int i;FILE* result = NULL;result = fopen("result.txt", "wb");/* Used to keep the SNR values for the fast/quick psy models */static FLOAT smrdef[2][32];static int psycount = 0;extern int minimum;time_t start_time, end_time;int total_time;sb_sample = (SBS*)mem_alloc(sizeof(SBS), "sb_sample");j_sample = (JSBS*)mem_alloc(sizeof(JSBS), "j_sample");win_que = (IN*)mem_alloc(sizeof(IN), "Win_que");subband = (SUB*)mem_alloc(sizeof(SUB), "subband");win_buf = (short**)mem_alloc(sizeof(short*) * 2, "win_buf");    /* clear buffers */memset((char*)buffer, 0, sizeof(buffer));memset((char*)bit_alloc, 0, sizeof(bit_alloc));memset((char*)scalar, 0, sizeof(scalar));memset((char*)j_scale, 0, sizeof(j_scale));memset((char*)scfsi, 0, sizeof(scfsi));memset((char*)smr, 0, sizeof(smr));memset((char*)lgmin, 0, sizeof(lgmin));memset((char*)max_sc, 0, sizeof(max_sc));//memset ((char *) snr32, 0, sizeof (snr32));memset((char*)sam, 0, sizeof(sam));global_init();     header.extension = 0;frame.header = &header;frame.tab_num = -1;       /* no table loaded */frame.alloc = NULL;header.version = MPEG_AUDIO_ID;   /* Default: MPEG-1 */     //MPEG_AUDIO_ID=1total_time = 0;time(&start_time);programName = argv[0];if (argc == 1)       /* no command-line args */  short_usage();elseparse_args(argc, argv, &frame, &model, &num_samples, original_file_name,encoded_file_name);     print_config(&frame, &model, original_file_name, encoded_file_name);   /* this will load the alloc tables and do some other stuff */hdr_to_frps(&frame);nch = frame.nch;error_protection = header.error_protection;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);win_buf[0] = &buffer[0][0];win_buf[1] = &buffer[1][0];adb = available_bits(&header, &glopts);   //bit预算lg_frame = adb / 8;if (header.dab_extension) {/* in 24 kHz we always have 4 bytes */if (header.sampling_frequency == 1)header.dab_extension = 4;/* You must have one frame in memory if you are in DAB mode                 *//* in conformity of the norme ETS 300 401 http://www.etsi.org               *//* see bitstream.c            */if (frameNum == 1)minimum = lg_frame + MINIMUM;adb -= header.dab_extension * 8 + header.dab_length * 8 + 16;}int totalbit = adb;{int gr, bl, ch;/* New polyphase filterCombines 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]);     }if (frameNum == 5) {//输出提示信息fprintf(result, "第%d帧\n", frameNum);//输出可用比特数fprintf(result, "分配比特数:%d\n", totalbit);//输出比例因子fprintf(result, "比例因子:\n");for (int i = 0; i < nch; i++) {   fprintf(result, "声道[%d]:\n", i + 1);for (int j = 0; j < frame.sblimit; j++) {   if (j % 4 == 0 && j != 0) {fprintf(result, "\n");}fprintf(result, "子带%d:\t", j);for (int k = 0; k < 3; k++) {    fprintf(result, "%d\t", scalar[i][k][j]);}fprintf(result, "\t");}fprintf(result, "\n");}fprintf(result, "\n");//输出比特分配结果fprintf(result, "\n比特分配结果:\n");for (int i = 0; i < nch; i++) {   fprintf(result, "声道[%d]:\n", i + 1);for (int j = 0; j < frame.sblimit; j++) {   if (j % 4 == 0 && j != 0) {fprintf(result, "\n");}fprintf(result, "子带%d:\t%d\t", j, bit_alloc[i][j]);}fprintf(result, "\n");}fflush(result);}#ifdef REFERENCECODE{/* Old code. left here for reference */int gr, bl, ch;for (gr = 0; gr < 3; gr++)for (bl = 0; bl < SCALE_BLOCK; bl++)for (ch = 0; ch < nch; ch++) {window_subband(&win_buf[ch], &(*win_que)[ch][0], ch);filter_subband(&(*win_que)[ch][0], &(*sb_sample)[ch][gr][bl][0]);}}
#endif#ifdef NEWENCODEscalefactor_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);}
#elsescale_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);}
#endifif ((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++) {    //nch表示通道数for (sb = 0; sb < SBLIMIT; sb++)    //SBLIMIT=32smr[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);}if (glopts.quickmode == TRUE)/* copy the smr values and reuse them later */for (ch = 0; ch < nch; ch++) {for (sb = 0; sb < SBLIMIT; sb++)smrdef[ch][sb] = smr[ch][sb];}if (glopts.verbosity > 4)smr_dump(smr, nch);}#ifdef NEWENCODEsf_transmission_pattern(scalar, scfsi, &frame);main_bit_allocation_new(smr, scfsi, bit_alloc, &adb, &frame, &glopts);//main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);if (error_protection)CRC_calc(&frame, bit_alloc, scfsi, &crc);write_header(&frame, &bs);//encode_info (&frame, &bs);if (error_protection)putbits(&bs, crc, 16);write_bit_alloc(bit_alloc, &frame, &bs);//encode_bit_alloc (bit_alloc, &frame, &bs);write_scalefactors(bit_alloc, scfsi, scalar, &frame, &bs);//encode_scale (bit_alloc, scfsi, scalar, &frame, &bs);subband_quantization_new(scalar, *sb_sample, j_scale, *j_sample, bit_alloc,*subband, &frame);//subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc,//      *subband, &frame);write_samples_new(*subband, bit_alloc, &frame, &bs);//sample_encoding (*subband, bit_alloc, &frame, &bs);
#elsetransmission_pattern(scalar, scfsi, &frame);    main_bit_allocation(smr, scfsi, bit_alloc, &adb, &frame, &glopts);    if (error_protection)  CRC_calc(&frame, bit_alloc, scfsi, &crc);encode_info(&frame, &bs);   if (error_protection)encode_CRC(crc, &bs);encode_bit_alloc(bit_alloc, &frame, &bs);              encode_scale(bit_alloc, scfsi, scalar, &frame, &bs);    subband_quantization(scalar, *sb_sample, j_scale, *j_sample, bit_alloc,*subband, &frame);      sample_encoding(*subband, bit_alloc, &frame, &bs);     /* If not all the bits were used, write out a stack of zeros */for (i = 0; i < adb; i++)    //写码流put1bit(&bs, 0);     //剩余未分配比特数写入stackif (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);if ((glopts.verbosity > 1) && (glopts.vbr == TRUE)) {int i;
#ifdef NEWENCODEextern int vbrstats_new[15];
#elseextern int vbrstats[15];
#endiffprintf(stdout, "VBR stats:\n");for (i = 1; i < 15; i++)fprintf(stdout, "%4i ", bitrate[header.version][i]);fprintf(stdout, "\n");for (i = 1; i < 15; i++)
#ifdef NEWENCODEfprintf(stdout, "%4i ", vbrstats_new[i]);
#elsefprintf(stdout, "%4i ", vbrstats[i]);
#endiffprintf(stdout, "\n");}fprintf(stderr,"Avg slots/frame = %.3f; b/smp = %.2f; bitrate = %.3f kbps\n",(FLOAT)sentBits / (frameNum * 8),(FLOAT)sentBits / (frameNum * 1152),(FLOAT)sentBits / (frameNum * 1152) *s_freq[header.version][header.sampling_frequency]);if (fclose(musicin) != 0) {fprintf(stderr, "Could not close \"%s\".\n", original_file_name);exit(2);}fprintf(stderr, "\nDone\n");fclose(result);time(&end_time);total_time = end_time - start_time;printf("total time is %d\n", total_time);exit(0);
}

持续性噪声

突发性噪声

乐音

混合

数据对比

类型 分配的比特数 比例因子 比特分配结果 压缩比
突发噪声

4608

530/66.3=8
持续噪声

4608

588/63.9=7.99
音乐

4608

780/97.8=7.98
混合

4608

782/97.8=8

遇到的问题

“/ZI”和“/Gy-”命令行选项不兼容 ”问题

1."项目”—>“属性”—>“C/C++” “常规”—>“调试信息格式”—>选择“程序数据库(/Zi)”或“无”
2."项目”—>“属性”—>“C/C++” “代码生成”—>“启用函数集链接”—>选择“是 (/Gy)”

MPEG音频编码实验相关推荐

  1. Lab6 MPEG音频编码实验——C++代码实现

    Lab6 MPEG音频编码实验--C++代码实现 一.MPEG音频编码实现框架及思路 1.MPEG音频编码实现框图: MPEG音频编码的实现主要分为上下两条线,上方红色框中的部分属于时域分析(粗细节) ...

  2. 【实验6】MPEG音频编码实验

    文章目录 一.实验内容 1 .MPEG-1音频编码器框架 2 .理解感知音频编码的设计思想 3 .理解心理声学模型的实现过程 4 .理解码率分配的实现思路 二.理解程序设计的整体框架 三.实验步骤与实 ...

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

    一.MPEG-1 Audio LayerII编码器原理 1.MPEG-1音频编码器框架图 (1)编码流程的两条线 整个编码流程分为两条线: 第一条线是主线,输入的PCM码流经过多相滤波器组分成32个子 ...

  4. 综合编码——MPEG音频编码实验

    目录 一.程序设计整体框架 1.MPEG-1 Audio LayerII编码器原理 2.心理声学模型 (1)将样本变换到频域 (2)确定声压级别 (3)考虑安静时阈值 (4)音频信号分解 (5)音调和 ...

  5. 实验六|MPEG音频编码实验

    MPEG-1 Audio LayerII编码器原理 多相滤波器组(Polyphase Filter Bank):将PCM样本变换到32个子带的频域信号 心理声学模型(Psychoacoustic Mo ...

  6. 实验6_MPEG音频编码实验

    MPEG音频编码实验 一.MP2简介 1.什么是MP2 2.MP2优缺点 1)优点 2)缺点 3.与MP3对比 二.MPEG简介 1.什么是MPEG-1 2.音频分层 三.音频编码--人类听觉系统的感 ...

  7. 【数据压缩】第八次作业——MPEG音频编码

    MPEG音频编码实验 文章目录 MPEG音频编码实验 MPEG介绍 MPEG-1声音的主要性能 心理声学模型 人耳听觉特性 临界频带 掩蔽值 心理声学模型Ⅰ MPEG-1 编码原理 基本思想 整体框架 ...

  8. 实验六 MPEG音频编码

    一.MPEG音频编码原理 1.1 基本思想 分析信号,去掉不能被感知的部分[声音压缩算法可以确立这种特性的模型来取消更多的冗余数据] 子带分析滤波器组:使信号具有高的时间分辨率[短暂冲击信号情况下,编 ...

  9. MPEG音频编码 基本原理和C语言代码分析

    背景 MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准. MPEG 音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它 ...

最新文章

  1. 最小生成树实验报告c语言,算法与程序设计实验最小生成树(c语言).ppt
  2. 双十一风险暗藏危机 网络狂欢需谨慎
  3. JavaScript设计模式——单例模式的理解与应用
  4. ruby中的self
  5. 《C Traps and Pitfalls》 笔记
  6. 「2019纪中集训Day7」解题报告
  7. 数学建模学习笔记(十二)——奇异值分解
  8. ubuntu 下groovy 安装配置
  9. Laravel核心解读--Session源码解析
  10. jpushinterface.setalias的几个参数都是啥意思_很多电工老师傅都不知道,低压断路器基本参数,你懂几个?...
  11. URL Scheme获取帮助文档
  12. 传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(day01~day10)(2015年11月17日20:47:22)...
  13. 经典机器学习系列(五)【决策树详解】
  14. cf701B Cells Not Under Attack
  15. C语言数据结构——查找(检索)
  16. linux iometer安装教程,硬盘测试软件IOMETER安装配置指南
  17. VS2005 安装 WTL80
  18. 3.4.3 区域与图像的平均灰度值
  19. JavaScript 判断是否是数字 isFinite() Number.isFinite()
  20. 1010: 求圆的周长和面积 ZZULIOJ

热门文章

  1. 学习中如何建立自己的资源库?
  2. android推送弹窗,总被安卓通知“骚扰”?只需1招,教你屏蔽各种弹窗通知!
  3. 什么样的企业需要私有化部署?
  4. linux解压rar多层文件夹,linux rar 解压文件夹_rar文件夹
  5. android q 桌面模式,Android Q带来全新桌面模式
  6. java如何引用文件_java 中如何引用json文件
  7. Python 字典
  8. windows“运行”中的快捷命令
  9. Processing-当使用代码来绘画
  10. 字段私有制,属性方法