数据压缩实验八:MPEG音频压缩编码

一、MPEG编码概述

1.1 关于MPEG

1.1.1 整体框架

多相滤波器组:将PCM样本变换到32个子带的频域信号。如果输入的采样频率为48kHz,那么子带的频率宽度为48kHz/(2*32)=0.75kHz。

心理声学模型:计算信号中不可听觉感知的部分。

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

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

两条线:

① 以1152个样本为单位,输入到滤波器组中分解为32个子带,以32个样本为一个时间窗口形成36个样本,形成以12个样本为单位的3个块,再进行比例因子的提取,通过频域分析线路的辅助,进行后续的量化等工作。
② 对输入的PCM码流进行1024点FFT变换,经过心理声学模型去除信号中被掩蔽的部分,确定动态比特分配和比例因子,最后对码流进行边信息编码,一起封装成帧比特流进行传输。

时频分析的矛盾:

时域分解力与频域分解力互相矛盾,时域分解力高则频域分解力低,频域分解力高则时域分解力低。根据这一矛盾,MPEG-1音频编码采取措施:通过子带分析滤波器组使信号具有高的时间分辨率,确保在短暂冲击信号情况下,编码的声音信号具有足够高的质量又可以使信号通过FFT运算具有高的频率分辨率。

1.1.2  心理声学模型

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

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

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

临界频带的概念:当噪音掩蔽纯音时,起作用的是以纯音频率为中心频率的一定频带宽度内的噪声频率。如果频带内的噪声功率等于噪声中刚好能听见该纯音的功率,则这频带就称为临界频带。

通常认为从20Hz到16KHz有25个临界频带,单位为bark,1bark=一个临界频带宽度。

掩蔽值计算的思路:

将样本变换到频域
采用Hann加权和DFT,512 (Layer I) 或1024 (Layers II and III)样本窗口
确定声压级别
子带n的声压级别计算包含了子带n频谱线的声压级别及该子带最大缩放因子。
考虑安静时阈值
也即绝对阈值。在标准中有根据输入PCM信号的采样率编制的“频率、临界频带率和绝对阈值”表
将音频信号分解成“乐音(tones)” 和“非乐音/噪声”部分
因为两种信号的掩蔽能力不同,根据音频频谱的局部功率最大值确定乐音成分局部峰值为乐音,然后将本临界频带内的剩余频谱合在一起,组成一个代表噪声频率(无调成份)。
音调和非音调掩蔽成分的消除
利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率的成分。
单个掩蔽阈值的计算
音调成分和非音调成分单个掩蔽阈值根据标准中给出的算法求得。
全局掩蔽阈值的计算
某一频率点的总掩蔽值可通过该点的绝对掩蔽值与单独掩蔽阈值相加获得。
每个子带的掩蔽阈值
选择出本子带中最小的阈值作为子带阈值
计算每个子带信号掩蔽比(signal-to-mask ratio, SMR)
SMR = 信号能量 / 掩蔽阈值,并将SMR传递给编码单元
此时编码上线均匀32个子带,计算了每个子带的声压级,下线低频一个子带可能包含多个临界频带,高频一个临界频带可能包含多个子带。以临界频带为单位,低频密,高频疏。计算了掩蔽阈值。由此可计算出SMR。
 

1.1.3 码率分配的实现思路

使得所有频带和帧的总噪声-延毕NMR最小,此时首先舍去负dB,对最高NMR的子带分配比特,每提升1比特,信噪比提升6dB。

  • 每个子带计算噪声-掩蔽比MNR,信噪比SNR–信掩比SMR  NMR=SMR–SNR(dB)

 二、主要代码

2.1 main.c

int main(int argc, char** argv)
{
	/********************************参数初始化***************************************************/
	programName = argv[0];//argv[0]表示输入文件
	if (argc == 1)
		short_usage();
	else
		parse_args(argc, argv, &frame, &model, &num_samples, original_file_name,
			encoded_file_name);//解析命令行参数
	print_config(&frame, &model, original_file_name, encoded_file_name);//输出配置信息
 
	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);//在码率分配前首先要计算码率预算,把计算所得的该帧总分配比特数赋给了adb,在adb获得值以后直接进行输出。
		lg_frame = adb / 8;
		if (header.dab_extension) {
			if (header.sampling_frequency == 1)
				header.dab_extension = 4;
			if (frameNum == 1)
				minimum = lg_frame + MINIMUM;
			adb -= header.dab_extension * 8 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值