【实验】MPEG-1 Audio Layer II编码原理及编码器调试
目录
- 一、理解感知音频编码的设计思想
- 1.等响度曲线
- 2.频域掩蔽域随声压级变化曲线
- 二、理解心理声学模型的实现方法
- 1.临界频带(Critical Band)
- 2.掩蔽值计算的思路
- 三、人类听觉系统
- 四、 MPEG-1音频压缩编码
- (1)多相滤波器组,用来分割子带
- (2)量化和编码 – 比例因子的取值和编码
- (3)数据帧包装
- 五、 MPEG-1 Audio Layer II编码器编码流程
- 1.截取音乐片段,使用matlab生成高斯噪声片段,使用格式工厂将两段音频进行合并。
- 2.输出一帧的比例因子和比特分配表
- 六、实验结果
一、理解感知音频编码的设计思想
基本思想-------分析信号,去掉不能被感知的部分
1.等响度曲线
最下方的蓝色曲线代表人耳听阈,其下方的声音人耳无法听到。
两个声音响度级相同,但强度不一定相同,还与频率有关。
声压级越高,等响度曲线趋于平坦。
人耳对3-4khz的声音感觉最灵敏。
声压级(SPL):
2.频域掩蔽域随声压级变化曲线
一个较弱的声音(被掩蔽音)的听觉感受被另一个较强的声音(掩蔽音)影响的现象称为人耳的“掩蔽效应”。被掩蔽音单独存在时的听阈分贝值,或者说在安静环境中能被人耳听到的纯音的最小值称为绝对闻阈。实验表明,3kHz—5kHz绝对闻阈值最小,即人耳对它的微弱声音最敏感;而在低频和高频区绝对闻阈值要大得多。在800Hz–1500Hz范围内闻阈随频率变化最不显著,即在这个范围内语言可储度最高。在掩蔽情况下,提高被掩蔽弱音的强度,使人耳能够听见时的闻阈称为掩蔽闻阈(或称掩蔽门限),被掩蔽弱音必须提高的分贝值称为掩蔽量(或称阈移)。
二、理解心理声学模型的实现方法
1.临界频带(Critical Band)
临界频带是指当某个纯音被以它为中心频率、且具有一定带宽的连续噪声所掩蔽时,如果该纯音刚好被听到时的功率等于这一频带内的噪声功率,这个带宽为临界频带宽度。
研究窄带噪声对纯音掩蔽量的规律时被发现的:
使噪声的中心频率等于信号频率,只改变噪声的带宽同时保持噪声的功率谱密度不变,测试纯音听阈随掩蔽噪声带宽变化的特性。
纯音的听阈随掩蔽噪声带宽的增大而增大,在带宽增大到某一特定值之后听阈保持恒定不变。
通常认为从20Hz到16kHz有25个临界频带,单位为bark,1 Bark = 一个临界频带的宽度。
2.掩蔽值计算的思路
音乐与语音信号大都由一系列复杂的频谱分量构成 ,相应的这些多个掩蔽分量也会相互影响并最终获得一个整体的掩蔽阈值。对于多个掩蔽分量的综合掩蔽效果,目前有多种模型给出了描述方案 。
Lutfi 对多个掩蔽音同时存在时的综合掩蔽效果进行了研究:
每个掩蔽音的掩蔽效果先独立变换然后再线性相加。
将输入信号变换到频域,再将结果分解成一些尽量与临界频带尽可能相似的子带,然后对每个子带进行量化,量化方式应当使得量化噪声听不见。
三、人类听觉系统
人类听觉系统大致等效于一个信号通过一组并联的不同中心
频率的带通滤波器
➢ 中心频率与信号频率相同的滤波器具有最大响应;中心频率偏离信号频率较多的滤波器不会产生响应。
➢ 在0Hz到20KHz频率范围内由25个重叠的带通滤波器组成的滤波器组。
➢ 听音者在噪声中听某一纯音信号时,只启用中心频率与信号频率相同的那个听觉滤波器,纯音信号通过该滤波器,而噪声信号只有通带范围内的部分信号能通过,通带以外的频率成分则被抑制,只有通过该滤波器的噪声才对掩蔽起作用。
➢ 聆听复音时启动多个听觉滤波器。听觉能够计算各滤波器输出端的信噪比。当信噪比达到或者超过听阈因子时,即可听到该频率成分。
掩蔽声对被掩蔽声的掩蔽效应,取决于两者的频率与强度的关系。
➢ 噪声掩蔽纯音时,只有以纯音频率为中心的,一定频带宽度内的噪声能量起掩蔽作用,超出该频带的噪声能量无掩蔽效应,称掩蔽的临界带宽。掩蔽说明了频率选择性的极限。
➢ 掩蔽纯音信号,理论上使用带宽范围等于其临界带宽1/3倍频程的窄带噪声,这是因为掩蔽的临界带宽稍窄,听起来接近于纯音,患者常常混淆纯音与掩蔽噪声,而以纯音频率为中心频率的1/3倍频程噪声,宽度略大于临界带宽,同样可以起到很好的掩蔽效果。但实际应用中根据IEC645规定,临床听力计上常使用约4/10倍频程的窄带噪声。
掩蔽言语声和短声等宽频谱信号,则常用白噪声。因此,在听觉诱发反应测试中,往往在健侧耳施加白噪声作为掩蔽噪声。
四、 MPEG-1音频压缩编码
输入声音信号经过一个多相滤波器组,变换到多个子带。同时经过“心理声学模型”计算以频率为自变量的噪声掩蔽阈值。量化和编码部分用信掩比SMR决定分配给子带信号的量化位数,使量化噪声<掩蔽域值。最后通过数据帧包装将量化的子带样本和其它数据按照规定的帧格式组装成比特数据流。
(1)多相滤波器组,用来分割子带
划分子带的方法有两种:线性划分和非线性划分
➢ 线性划分可能一个子带覆盖好几个临界频带,以Layer 1为例,先分成32个相等的子带。
(2)量化和编码 – 比例因子的取值和编码
对各个子带每12个样点进行一次比例因子计算。先定出12个样点中绝对值的最大值。查比例因子表中比这个最大值大的最小值作为比例因子。用6比特表示。
◆第2层的一帧对应36个子带样值,是第1层的三倍,原则上要传三个比例因子。为了降低比例因子的传输码率,采用了利用人耳时域掩蔽特性的编码策略。
◆每帧中每个子带的三个比例因子被一起考虑,划分成特定的几种模式。根据这些模式,1个、2个或3个比例因子和比例因子选择信息(每子带2比特)一起被传送。如果一个比例因子和下一个只有很小的差别,就只传送大的一个,这种情况对于稳态信号经常出现。
◆使用这一算法后,和第1层相比,第2层传输的比例因子平均减少了2个,即传输码率由22.5Kb/s降低到了7.5Kb/s。
◼ 在调整到固定的码率之前
➢ 先确定可用于样值编码的有效比特数
➢ 这个数值取决于比例因子、比例因子选择信息、比特分配信息以及辅助数据所需比特数
◼ 比特分配的过程
➢ 对每个子带计算掩蔽-噪声比MNR,信噪比SNR–信掩比SMR,
即:MNR = SNR–SMR
◼ 比特分配的过程
➢ 使整个一帧和每个子带的总噪声-掩蔽比最小。这是一个循环过程,每一次循环使获益最大的子带的量化级别增加一级,当然所用比特数不能超过一帧所能提供的最大数目。
➢ 第1层一帧用4比特给每个子带的比特分配信息编码;而第2层只在低频段用4比特,高频段则用2比特。
(3)数据帧包装
◼码流结构的设计
➢ 有利于使用低复杂性和少延时的解码器,编码后的声音信号包含多个短且
恒定间隔的切入点
➢ 编码数据允许在编码码流中插入整数倍的切入点,以利记录、播放和编辑
短的声音序列,并能精确指定编辑点
五、 MPEG-1 Audio Layer II编码器编码流程
1.截取音乐片段,使用matlab生成高斯噪声片段,使用格式工厂将两段音频进行合并。
使用matlab生成噪声片段:
使用格式工厂合并:
2.输出一帧的比例因子和比特分配表
分别在main函数和print_config()函数中打开文件need.txt
在文件开头位置定义宏:#define FRAME_TRACE 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);elsefprintf (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");
#if FRAME_TRACEFILE* need;need = fopen("need.txt", "a");fprintf(need, "========== 基本信息 ==========\n");fprintf(need, "输入文件:%s\n", inPath);fprintf(need, "输出文件:%s\n", outPath);fprintf(need, "采样频率:%.1f kHz\n", s_freq[header->version][header->sampling_frequency]);fprintf(need, "输出文件码率:%d kbps\n", bitrate[header->version][header->bitrate_index]);fclose(need);
#endif // FRAME_TRACE}
int main (int argc, char **argv)
{typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT];SBS *sb_sample;typedef double JSBS[3][SCALE_BLOCK][SBLIMIT];JSBS *j_sample;typedef double IN[2][HAN_SIZE];IN *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], scfsi[2][SBLIMIT];static unsigned int scalar[2][3][SBLIMIT], 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;/* 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 */total_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);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 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] );}
#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_TRACEFILE* need;need = fopen("need.txt", "a");if (frameNum == 2) {fprintf(need, "声道数:%d\n", nch);fprintf(need, "目前观测第 %d 帧\n", frameNum);fprintf(need, "本帧比特预算:%d bits\n", adb);fprintf(need, "\n");/* 比例因子 */fprintf(need, "========== 比例因子 ==========\n");for (ch = 0; ch < nch; ch++) // 每个声道单独输出{fprintf(need, "------ 声道%2d ------\n", ch + 1);for (sb = 0; sb < frame.sblimit; sb++) // 每个子带{fprintf(need, "子带[%2d]:\t", sb + 1);for (int gr = 0; gr < 3; gr++) {fprintf(need, "%2d\t", scalar[ch][gr][sb]);}fprintf(need, "\n");}}fprintf(need, "\n");/* 比特分配表 */fprintf(need, "========== 比特分配表 ==========\n"); //输出比特分配结果for (ch = 0; ch < nch; ch++) {fprintf(need, "------ 声道%2d ------\n", ch + 1); //按声道分配for (sb = 0; sb < frame.sblimit; sb++) {fprintf(need, "子带[%2d]:\t%2d\n", sb + 1, bit_alloc[ch][sb]);}fprintf(need, "\n");}}fclose(need);
#endif // FRAME_TRACEif (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++) {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);}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);
#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);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");time(&end_time);total_time = end_time - start_time;printf("total time is %d\n", total_time);exit (0);
}
六、实验结果
music.wav
========== 基本信息 ==========
输入文件:music.wav
输出文件:1.mp2
采样频率:22.1 kHz
输出文件码率:96 kbps
声道数:2
目前观测第 2 帧
本帧比特预算:5016 bits========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]: 26 6 6
子带[ 2]: 24 14 12
子带[ 3]: 32 25 23
子带[ 4]: 41 25 23
子带[ 5]: 45 29 31
子带[ 6]: 46 26 26
子带[ 7]: 45 28 29
子带[ 8]: 51 37 31
子带[ 9]: 48 34 33
子带[10]: 52 37 36
子带[11]: 57 37 35
子带[12]: 57 33 32
子带[13]: 56 31 29
子带[14]: 49 22 22
子带[15]: 45 26 28
子带[16]: 54 51 39
子带[17]: 41 30 24
子带[18]: 41 29 27
子带[19]: 48 25 26
子带[20]: 42 28 25
子带[21]: 44 31 30
子带[22]: 56 47 47
子带[23]: 58 58 57
子带[24]: 57 57 57
子带[25]: 58 56 57
子带[26]: 61 57 58
子带[27]: 59 57 58
子带[28]: 57 57 58
子带[29]: 59 56 57
子带[30]: 59 57 57
------ 声道 2 ------
子带[ 1]: 27 7 6
子带[ 2]: 26 16 14
子带[ 3]: 34 27 22
子带[ 4]: 54 32 28
子带[ 5]: 49 33 32
子带[ 6]: 46 29 29
子带[ 7]: 44 31 28
子带[ 8]: 57 34 33
子带[ 9]: 53 37 33
子带[10]: 51 38 36
子带[11]: 53 34 34
子带[12]: 54 36 31
子带[13]: 51 33 30
子带[14]: 45 30 27
子带[15]: 44 31 31
子带[16]: 54 36 32
子带[17]: 52 30 27
子带[18]: 49 30 27
子带[19]: 43 31 26
子带[20]: 44 30 28
子带[21]: 57 33 31
子带[22]: 57 58 50
子带[23]: 62 56 58
子带[24]: 61 57 57
子带[25]: 60 58 58
子带[26]: 57 59 57
子带[27]: 59 57 58
子带[28]: 57 57 58
子带[29]: 59 56 56
子带[30]: 60 57 59 ========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]: 4
子带[ 2]: 5
子带[ 3]: 4
子带[ 4]: 4
子带[ 5]: 3
子带[ 6]: 3
子带[ 7]: 3
子带[ 8]: 3
子带[ 9]: 3
子带[10]: 3
子带[11]: 3
子带[12]: 2
子带[13]: 3
子带[14]: 2
子带[15]: 2
子带[16]: 3
子带[17]: 3
子带[18]: 3
子带[19]: 3
子带[20]: 3
子带[21]: 2
子带[22]: 3
子带[23]: 2
子带[24]: 2
子带[25]: 1
子带[26]: 2
子带[27]: 2
子带[28]: 3
子带[29]: 1
子带[30]: 2------ 声道 2 ------
子带[ 1]: 4
子带[ 2]: 5
子带[ 3]: 4
子带[ 4]: 4
子带[ 5]: 3
子带[ 6]: 3
子带[ 7]: 3
子带[ 8]: 3
子带[ 9]: 3
子带[10]: 3
子带[11]: 3
子带[12]: 2
子带[13]: 3
子带[14]: 2
子带[15]: 2
子带[16]: 3
子带[17]: 3
子带[18]: 3
子带[19]: 3
子带[20]: 3
子带[21]: 2
子带[22]: 3
子带[23]: 2
子带[24]: 2
子带[25]: 1
子带[26]: 2
子带[27]: 2
子带[28]: 3
子带[29]: 1
子带[30]: 2
noise.wav
========== 基本信息 ==========
输入文件:noise.wav
输出文件:2.mp2
采样频率:44.1 kHz
输出文件码率:192 kbps
声道数:1
目前观测第 2 帧
本帧比特预算:5016 bits========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]: 9 9 8
子带[ 2]: 11 11 9
子带[ 3]: 13 12 11
子带[ 4]: 9 10 12
子带[ 5]: 11 11 11
子带[ 6]: 12 11 11
子带[ 7]: 9 13 10
子带[ 8]: 11 9 8
子带[ 9]: 9 9 10
子带[10]: 10 11 11
子带[11]: 10 9 8
子带[12]: 9 11 10
子带[13]: 11 11 10
子带[14]: 10 8 11
子带[15]: 11 11 11
子带[16]: 9 11 13
子带[17]: 10 13 10
子带[18]: 11 13 10
子带[19]: 11 10 10
子带[20]: 10 13 10
子带[21]: 11 9 11
子带[22]: 12 11 10
子带[23]: 10 10 11
子带[24]: 11 12 10
子带[25]: 11 11 11
子带[26]: 11 12 12
子带[27]: 9 11 9
子带[28]: 10 11 9
子带[29]: 11 10 12
子带[30]: 12 11 10 ========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]: 6
子带[ 2]: 5
子带[ 3]: 5
子带[ 4]: 6
子带[ 5]: 6
子带[ 6]: 5
子带[ 7]: 6
子带[ 8]: 5
子带[ 9]: 6
子带[10]: 5
子带[11]: 4
子带[12]: 5
子带[13]: 5
子带[14]: 4
子带[15]: 4
子带[16]: 5
子带[17]: 5
子带[18]: 5
子带[19]: 5
子带[20]: 3
子带[21]: 3
子带[22]: 3
子带[23]: 3
子带[24]: 2
子带[25]: 3
子带[26]: 2
子带[27]: 2
子带[28]: 2
子带[29]: 2
子带[30]: 2
music+noise.wav
========== 基本信息 ==========
输入文件:music+noise.wav
输出文件:3.mp2
采样频率:22.1 kHz
输出文件码率:96 kbps
声道数:2
目前观测第 2 帧
本帧比特预算:5016 bits========== 比例因子 ==========
------ 声道 1 ------
子带[ 1]: 26 6 6
子带[ 2]: 24 14 12
子带[ 3]: 32 25 23
子带[ 4]: 41 25 23
子带[ 5]: 45 29 31
子带[ 6]: 46 26 26
子带[ 7]: 45 28 29
子带[ 8]: 51 37 31
子带[ 9]: 48 34 33
子带[10]: 52 37 36
子带[11]: 57 37 35
子带[12]: 57 33 32
子带[13]: 56 31 29
子带[14]: 49 22 22
子带[15]: 45 26 28
子带[16]: 54 51 39
子带[17]: 41 30 24
子带[18]: 41 29 27
子带[19]: 48 25 26
子带[20]: 42 28 25
子带[21]: 44 31 30
子带[22]: 56 47 47
子带[23]: 58 58 57
子带[24]: 57 57 57
子带[25]: 58 56 57
子带[26]: 61 57 58
子带[27]: 59 57 58
子带[28]: 57 57 58
子带[29]: 59 56 57
子带[30]: 59 57 57
------ 声道 2 ------
子带[ 1]: 27 7 6
子带[ 2]: 26 16 14
子带[ 3]: 34 27 22
子带[ 4]: 54 32 28
子带[ 5]: 49 33 32
子带[ 6]: 46 29 29
子带[ 7]: 44 31 28
子带[ 8]: 57 34 33
子带[ 9]: 53 37 33
子带[10]: 51 38 36
子带[11]: 53 34 34
子带[12]: 54 36 31
子带[13]: 51 33 30
子带[14]: 45 30 27
子带[15]: 44 31 31
子带[16]: 54 36 32
子带[17]: 52 30 27
子带[18]: 49 30 27
子带[19]: 43 31 26
子带[20]: 44 30 28
子带[21]: 57 33 31
子带[22]: 57 58 50
子带[23]: 62 56 58
子带[24]: 61 57 57
子带[25]: 60 58 58
子带[26]: 57 59 57
子带[27]: 59 57 58
子带[28]: 57 57 58
子带[29]: 59 56 56
子带[30]: 60 57 59 ========== 比特分配表 ==========
------ 声道 1 ------
子带[ 1]: 3
子带[ 2]: 5
子带[ 3]: 3
子带[ 4]: 4
子带[ 5]: 3
子带[ 6]: 3
子带[ 7]: 3
子带[ 8]: 3
子带[ 9]: 3
子带[10]: 3
子带[11]: 3
子带[12]: 3
子带[13]: 2
子带[14]: 2
子带[15]: 2
子带[16]: 3
子带[17]: 3
子带[18]: 2
子带[19]: 3
子带[20]: 3
子带[21]: 3
子带[22]: 3
子带[23]: 3
子带[24]: 3
子带[25]: 1
子带[26]: 2
子带[27]: 2
子带[28]: 2
子带[29]: 1
子带[30]: 2------ 声道 2 ------
子带[ 1]: 3
子带[ 2]: 5
子带[ 3]: 4
子带[ 4]: 4
子带[ 5]: 3
子带[ 6]: 3
子带[ 7]: 3
子带[ 8]: 3
子带[ 9]: 3
子带[10]: 3
子带[11]: 3
子带[12]: 3
子带[13]: 2
子带[14]: 2
子带[15]: 2
子带[16]: 3
子带[17]: 3
子带[18]: 2
子带[19]: 3
子带[20]: 3
子带[21]: 3
子带[22]: 3
子带[23]: 3
子带[24]: 3
子带[25]: 1
子带[26]: 2
子带[27]: 2
子带[28]: 2
子带[29]: 1
子带[30]: 2
文章一些内容参考自师哥师姐的实验报告!
【实验】MPEG-1 Audio Layer II编码原理及编码器调试相关推荐
- 数据压缩(十三)——MPEG音频编码原理及编码器调试
文章目录 一.MPEG音频编码原理 1.1 基本思想 1.2 心理声学模型(Psychoacoustic model) 1.2.1 听觉阈值 1.2.2 频域掩蔽 1.3 临界频带(Critical ...
- MPEG音频编码原理及编码器调试
一 MPEG音频编码 1 基本原理 基本思想:去掉音频信号中的冗余.其中,冗余主要来自:声音信号中本身存在的冗余:不被人耳感知的部分. 1.1 MPEG-1 Audio Layer2 编码器原理 该编 ...
- FFmpeg入门详解之20:视频编码原理简介
视频为何需要压缩? 原因:未经压缩的数字视频的数据量巨大 ● 存储困难 ○ 一G只能存储几秒钟的未压缩数字视频. ● 传输困难 ○ 1兆的带宽传输一秒的数字电视视频需要大约4分钟. 主要压缩了什么东西 ...
- 即时通讯音视频开发(七):音频基础及编码原理入门
前言 即时通讯应用中的实时音视频技术,几乎是IM开发中的最后一道高墙.原因在于:实时音视频技术 = 音视频处理技术 + 网络传输技术 的横向技术应用集合体,而公共互联网不是为了实时通信设计的. 系列文 ...
- MP3文件格式与编码原理解码流程详解
1 文件格式 MP3文件格式四部分,按顺序排列如下: ID3V2 包含了作者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量 Frame 音频帧序列 APEV2 包含了作者,作曲,专辑等 ...
- 音频基础知识及编码原理
一.基本概念 1 比特率:表示经过编码(压缩)后的音频数据每秒钟需要用多少个比特来表示,单位常为kbps. 2 响度和强度:声音的主观属性响度表示的是一个声音听来有多响的程度.响度主要随声音的强度而变 ...
- 音视频开发系列-H264编码原理
H264简介 来自百度百科的介绍: H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式. H.264是ITU-T以H.26x系列为名称命名的 ...
- 利用FFmpeg编码器将JPG图片进行H.264编码原理
利用FFmpeg编码器将JPG图片进行H.264编码原理 文章目录 利用FFmpeg编码器将JPG图片进行H.264编码原理 整体的编码流程 将JPG或BMP编码为YUV 利用FFmpeg将YUV格式 ...
- 建议收藏 | H.265编码原理入门
视频编码的目的是为了压缩原始视频,压缩的主要思路是从空间.时间.编码.视觉等几个主要角度去除冗余信息.由于 H.264 出色的数据压缩比率和视频质量,成为当前市场上最为流行的编解码标准.而 H.265 ...
最新文章
- select into mysql_MySQL select into 和 SQL select into
- 机器学习笔记六:K-Means聚类,层次聚类,谱聚类
- 配置yum源并与公网同步更新
- python list删除元素_python中List添加、删除元素的几种方法
- Android使用MPAndroidChat
- 2019.7.25锻炼逻辑思维9道题。
- HDOJ 2074 叠筐
- 磁盘管理,quota,RAID,LVM
- Thrift Server与Client
- pro缺点和不足 一加7t_看点满满,一用难忘:一加7T上手体验全方位测评
- Java实现常用的三种加密算法详解
- oracle dbv验证,ORACLE施用dbv工具检验数据文件是否有坏块
- 算法时间复杂度分析(一)
- 紫光视频平台服务器系统,紫光展锐打造操作系统生态,赋能万物互联智能时代...
- java 替换 ppt内容_Java 替换PPT文档中的文本和图片
- 配置OpenLDAP使用TLS通信
- bh1750采集流程图_基于BH1750的光照度检测)报告方案.doc
- 微信小店和微信小商店的区别?如何建立怎么开通?
- 超宽带 DW1000 API --- dwt_configure (频道,脉冲重复频率,数据速率等)
- 安装java8和tomcat_jdk1.8.0+tomcat8.0安装
热门文章
- 基于MATLAB的线激光三维彩色扫描仪
- vue+elementui实现非常好看的博客、网站首页,网站模板
- 关于5位编程高手涉嫌侵犯腾讯著作权被受审的一些看法
- ESP32 使用 ESP-AT 测试 MQTT WSS 连接和数据传输的流程
- curl采集 根据关键词 获取雅虎竞价排名
- IC验证培训——实战SV验证学习(lab6)
- 编程趣事 100元x100元是否等于10000分x10000分
- win10远程桌面连接计算机密码错误,win10远程桌面连接不上怎么办?windows10远程桌面连接不上的解决方法...
- QEMU零知识学习2 —— QEMU源码下载
- 【百度】 快速精准搜索