MPEG音频编码分析
目录
- 基本流程
- 设计框架
- 变量设置
- 音频读入
- 多相滤波器结合窗函数和滤波
- 计算比例因子
- 心理声学模型
- 比特分配
- 量化与装帧
- 实验要求
- 输出音频的采样率和目标码率
- 对于某个数据帧,输出该帧所分配的比特数,该帧的比例因子,该帧的比特分配结果
基本流程
重点关注代码中如何实现双线流程的结合,多项滤波器之后提取比例因子给下面的心理声学模型线。比特分配后利用比特数完成上面流程的线性量化。
设计框架
变量设置
typedef double SBS[2][3][SCALE_BLOCK][SBLIMIT];SBS *sb_sample;//子带样本12*32*3*2(立体声)typedef double JSBS[3][SCALE_BLOCK][SBLIMIT];JSBS *j_sample;typedef double IN[2][HAN_SIZE];//2*512,FFTIN *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];//快速算法中存放SNR
音频读入
get_audio
unsigned long
get_audio (FILE * musicin, short buffer[2][1152], unsigned long num_samples,int nch, frame_header *header)//读取音频并返回读取长度
{int j;short insamp[2304];unsigned long samples_read;if (nch == 2) { /* stereo判断是立体声 */samples_read =read_samples (musicin, insamp, num_samples, (unsigned long) 2304);if (glopts.channelswap == TRUE) {//为false则切换通道for (j = 0; j < 1152; j++) {buffer[1][j] = insamp[2 * j];buffer[0][j] = insamp[2 * j + 1];}} else {for (j = 0; j < 1152; j++) {buffer[0][j] = insamp[2 * j];buffer[1][j] = insamp[2 * j + 1];}}} else if (glopts.downmix == TRUE) {//低音混合samples_read =read_samples (musicin, insamp, num_samples, (unsigned long) 2304);for (j = 0; j < 1152; j++) {buffer[0][j] = 0.5 * (insamp[2 * j] + insamp[2 * j + 1]);}} else { /* 单声道 */samples_read =read_samples (musicin, insamp, num_samples, (unsigned long) 1152);for (j = 0; j < 1152; j++) {buffer[0][j] = insamp[j];/* buffer[1][j] = 0; don't bother zeroing this buffer. MFC Nov 99 */}}return (samples_read);
}
read_samples
unsigned long
read_samples (FILE * musicin, short sample_buffer[2304],unsigned long num_samples, unsigned long frame_size)//读取音频文件到buffer里
{unsigned long samples_read;static unsigned long samples_to_read;static char init = TRUE;if (init) {samples_to_read = num_samples;init = FALSE;//确定读取长度}if (samples_to_read >= frame_size)samples_read = frame_size;//最多读取不超过2304elsesamples_read = samples_to_read;if ((samples_read =fread (sample_buffer, sizeof (short), (int) samples_read,musicin)) == 0)fprintf (stderr, "Hit end of audio data\n");//读完/*Samples are big-endian. If this is a little-endian machinewe must swap*/if (NativeByteOrder == order_unknown) {NativeByteOrder = DetermineByteOrder ();if (NativeByteOrder == order_unknown) {fprintf (stderr, "byte order not determined\n");exit (1);}}if (NativeByteOrder != order_littleEndian || (glopts.byteswap == TRUE))SwapBytesInWords (sample_buffer, samples_read);if (num_samples != MAX_U_32_NUM)samples_to_read -= samples_read;if (samples_read < frame_size && samples_read > 0) {/* fill out frame with zeros */for (; samples_read < frame_size; sample_buffer[samples_read++] = 0);samples_to_read = 0;samples_read = frame_size;}return (samples_read);
}
available_bits函数:计算出可用比特数
多相滤波器结合窗函数和滤波
WindowFilterSubband函数:对buffer里数据分解进行子带滤波
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] );//
计算比例因子
scale_factor_calc函数:使用二分法查找比例因子
pick_scale:每个字带3个样本选择三个比例因子
如果是立体声,则使用combine_LR函数结合左右声道后,查找比例因子
transmission_pattern函数:决定发送几个比例因子,并根据此填写比例因子选择信息
心理声学模型
根据model选择心理声学模型并计算SMR
以模型0为例
void psycho_0(double SMR[2][SBLIMIT], int nch, unsigned int scalar[2][3][SBLIMIT], FLOAT sfreq)//通过子带内最低ATH值和比例因子结合的方法,以简单方式计算出SMR
{int ch, sb, gr;int minscaleindex[2][SBLIMIT]; /* scale越小尺度因子越大 Smaller scale indexes mean bigger scalefactors */static FLOAT ath_min[SBLIMIT];int i;static int init=0;if (!init) {FLOAT freqperline = sfreq/1024.0;for (sb=0;sb<SBLIMIT;sb++) {ath_min[sb] = 1000; /* set it huge */}/* 找到每个子带中最小的ATH */for (i=0;i<512;i++) {FLOAT thisfreq = i * freqperline;FLOAT ath_val = ATH_dB(thisfreq, 0);if (ath_val < ath_min[i>>4])ath_min[i>>4] = ath_val;}init++;}/* 找到最小的比例因子index for each ch/sb */for (ch=0;ch<nch;ch++) for (sb=0;sb<SBLIMIT;sb++) minscaleindex[ch][sb] = scalar[ch][0][sb];for (ch=0;ch<nch;ch++) for (gr=1;gr<3;gr++) for (sb=0;sb<SBLIMIT;sb++) if (minscaleindex[ch][sb] > scalar[ch][gr][sb])minscaleindex[ch][sb] = scalar[ch][gr][sb];/* Oh yeah. Fudge the hell out of the SMR calculations by combining the scalefactor table index and the min ATH in that subbandThere are probably more elegant/correct ways of combining these values,but who cares? It works pretty well MFC Mar 03 */for (ch=0;ch<nch;ch++)for (sb=0;sb<SBLIMIT;sb++)SMR[ch][sb] = 2.0 * (30.0 - minscaleindex[ch][sb]) - ath_min[sb];
}
比特分配
根据心理声学模型和码率限制进行比特分配
main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);
“动态比特分配”:根据信号掩蔽比(SMR)确定子
带的量化级数(比特数,对总数据率进行比特分配。
原则:(1)SMR(dB) = SNRmax(dB) – MNRmin(dB)
(2)使各子带的量化信噪比SNR>最小信掩蔽比SMR,
将允许数据率分配给音频帧,再分给子带。音频帧的总
的供使用的数据率扣除用于传送比例因子、比例因子选
择信息、动态比特分配(BAL)、数据帧头与必要的差错
检测和考虑附加数据后,分配给音频取样值。
量化与装帧
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 (frameNum == random_frame_number){fprintf(trace_file, "采样率为:%.1fkhz \r\n", s_freq[header.version][header.sampling_frequency]);fprintf(trace_file, "目标码率为:%dMbps \r\n", bitrate[header.version][header.bitrate_index]);fprintf(trace_file, "可获得比特数为:%dbits\r\n", adb);}
这一步在滤波前即可输出,此时音频读入后这些参数都已经算出
输出结果:
采样率为:48.0khz
目标码率为:192Mbps
可获得比特数为:4608bits
对于某个数据帧,输出该帧所分配的比特数,该帧的比例因子,该帧的比特分配结果
这一步在比特分配后可以输出
if (frameNum == random_frame_number){fprintf(trace_file, "选择的数据帧为:%d \r\n", frameNum);for (int k = 0; k < nch; k++){fprintf(trace_file, "声道[%d] \r\n", k + 1);for (int j = 0; j < frame.sblimit; j++)//子带总数{fprintf(trace_file, "子带[%d]: ", j + 1);for (int m = 0; m < 3; m++)//每个子带有3个比例因子{fprintf(trace_file, "%d\t", scalar[k][m][j]);}fprintf(trace_file, "\r\n");}}}
输出结果:代码中提示多余bit自动补0
声道[1]
子带[1]: 14 14 19
子带[2]: 27 27 27
子带[3]: 27 27 27
子带[4]: 31 31 31
子带[5]: 33 33 33
子带[6]: 34 34 34
子带[7]: 37 37 37
子带[8]: 37 37 37
子带[9]: 37 37 37
子带[10]: 39 39 39
子带[11]: 37 39 39
子带[12]: 39 41 41
子带[13]: 42 42 42
子带[14]: 41 41 41
子带[15]: 42 42 42
子带[16]: 42 42 42
子带[17]: 42 45 45
子带[18]: 44 44 44
子带[19]: 43 43 43
子带[20]: 44 44 44
子带[21]: 46 46 46
子带[22]: 46 46 46
子带[23]: 45 46 46
子带[24]: 46 46 46
子带[25]: 44 44 44
子带[26]: 47 47 47
子带[27]: 45 45 45
子带[28]: 0 0 0
子带[29]: 0 0 0
子带[30]: 0 0 0
子带[31]: 0 0 0
子带[32]: 0 0 0
声道[2]
子带[1]: 14 14 19
子带[2]: 26 26 26
子带[3]: 27 27 27
子带[4]: 30 30 30
子带[5]: 33 33 33
子带[6]: 34 34 34
子带[7]: 37 37 37
子带[8]: 37 37 37
子带[9]: 37 37 37
子带[10]: 39 39 39
子带[11]: 37 39 39
子带[12]: 39 39 39
子带[13]: 41 41 41
子带[14]: 41 41 41
子带[15]: 42 42 42
子带[16]: 43 43 43
子带[17]: 44 44 44
子带[18]: 45 45 45
子带[19]: 42 44 44
子带[20]: 44 44 44
子带[21]: 45 45 45
子带[22]: 46 46 46
子带[23]: 46 46 44
子带[24]: 45 45 45
子带[25]: 44 44 44
子带[26]: 43 43 43
子带[27]: 47 43 46
子带[28]: 0 0 0
子带[29]: 0 0 0
子带[30]: 0 0 0
子带[31]: 0 0 0
子带[32]: 0 0 0
MPEG音频编码分析相关推荐
- MPEG音频编码 基本原理和C语言代码分析
背景 MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准. MPEG 音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它 ...
- MPEG音频编码及分析
一.MPEG音频编码思想 1.整体概述 (1)基本思想 分析信号,去掉不能被感知的部分 (2)MPEG-1声音的主要性能 输入为PCM信号,采样率为32,44.1或48kHz,输出为32kbps到38 ...
- MPEG音频编码三十年
▲扫描图中二维码了解音视频技术大会更多信息▲ 作者:Leonardo Chiariglione 翻译:Alex 技术审校:冯建元 视 野 #011# 前言 很明显,声音信息的电子格式要早于视觉信息的电 ...
- Lab6 MPEG音频编码实验——C++代码实现
Lab6 MPEG音频编码实验--C++代码实现 一.MPEG音频编码实现框架及思路 1.MPEG音频编码实现框图: MPEG音频编码的实现主要分为上下两条线,上方红色框中的部分属于时域分析(粗细节) ...
- MPEG音频编码原理及编码器调试
一 MPEG音频编码 1 基本原理 基本思想:去掉音频信号中的冗余.其中,冗余主要来自:声音信号中本身存在的冗余:不被人耳感知的部分. 1.1 MPEG-1 Audio Layer2 编码器原理 该编 ...
- 实验六 MPEG音频编码
一.MPEG音频编码原理 1.1 基本思想 分析信号,去掉不能被感知的部分[声音压缩算法可以确立这种特性的模型来取消更多的冗余数据] 子带分析滤波器组:使信号具有高的时间分辨率[短暂冲击信号情况下,编 ...
- 【数据压缩】第八次作业——MPEG音频编码
MPEG音频编码实验 文章目录 MPEG音频编码实验 MPEG介绍 MPEG-1声音的主要性能 心理声学模型 人耳听觉特性 临界频带 掩蔽值 心理声学模型Ⅰ MPEG-1 编码原理 基本思想 整体框架 ...
- 数据压缩(十三)——MPEG音频编码原理及编码器调试
文章目录 一.MPEG音频编码原理 1.1 基本思想 1.2 心理声学模型(Psychoacoustic model) 1.2.1 听觉阈值 1.2.2 频域掩蔽 1.3 临界频带(Critical ...
- 第八次作业——MPEG音频编码
MPEG介绍 MPEG标准主要有以下五个,MPEG-1.MPEG-2.MPEG-4.MPEG-7及MPEG-21等.该专家组建于1988年,专门负责为CD建立视频和音频标准,而成员都是视频.音频及系统 ...
最新文章
- dwr消息推送和tomcat集群
- CTF(pwn)攻防世界warmup
- YY/T 0664—2020《医疗器械软件 软件生存周期过程》 相关
- 自动生成网络拓扑图开源_为视频自动生成字幕,一款神奇的开源工具!
- 佳鑫诺计算机模拟卷答案,微机原理练习册答案佳鑫诺).docx
- mybatis依赖_Spring Boot2 系列教程(二十一)整合 MyBatis
- CISC与RISC的区别?
- python怎么控制小数点位数_谈谈关于Python里面小数点精度控制的问题
- 在Linux系统下初始化COM组件,Linux操作系统的引导和初始化.doc
- 那些让老板赞不绝口的可视化大屏,附模板和教程
- Springboot接收ajax提交JSON数组
- 工作是工作,爱好是爱好,理想是另外一回事
- [阅读笔记]Modern C++ Programming with Test-Driven Develpment chp2
- UE4导入字体 ttf
- (二)UDPSocket 客户端编写(超详细)
- 服务器上Dll文件读取失败,解决开机出现dll文件加载失败的方法
- maven deploy 时报错-repository element was not specified in the POM inside distributionManagement eleme
- 击败26个硕士,本科生“歪门邪道”月薪过万
- 别用老派交易员眼光看市场回调
- 石家庄程序员创业高级QQ群186813809
热门文章
- python 闭包_Python 闭包
- minio分布式存储系列(一)__介绍及开箱使用
- java实习生面试题_java实习生面试题(含答案)
- 深度学习——残差神经网络ResNet在分别在Keras和tensorflow框架下的应用案例
- 关于Codewarrior 中的 .prm 文件
- 小学计算机专业知识试题及答案,小学信息技术教师专业知识测试题
- 旧书交易系统——第二次报告(UML图)
- 从零开始手把手搭建Vision Transformers(Pytorch版本)
- c语言中求字节的运算符是,初学者单片机C语言运算符
- 关于输入输出流的学习总结