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数

Mpeg音频分析

文章插图
代码分析
1.输出音频的采样率和目标码率
【Mpeg音频分析】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");}
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 addedif(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);//计算比例因子scalarpick_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_samplescale_factor_calc (j_sample, &j_scale, 1, frame.sblimit);//计算比例因子j_scale}if (frameNum == spec_frameNum){//输出比例因子fprintf(result, "比例因子:\n");for (int k = 0; k