用DFT对语音信号进行压缩
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用DFT对语音信号进行压缩处理
学生姓名:XXX 学号:XXXXX 指导老师:XXXXX
摘要:本文要解决的问题是如何对音频文件(本文仅研究了wav格式的文件)进行微失真压缩,文中使用DFT算法将对音频信号中部分对声音影响较小的部分给去除,以实现音频压缩的目的。
关键词:DFT,音频压缩。
1.DFT原理:
对于一个有限长信号,我们可以使用DTFT算法得到其频谱,但是一个有限长的信号,其频谱都是无限长的:
但是对于人耳而言,能听到的频率在10Hz到44,1KHz之间,这样频谱中大部分的成分都是不需要的,而且对于计算机而言,无法模拟出一段连续的频谱。这时候我们只能对频谱进行采样,在保证最大程度不失真的程度上模拟出频谱,但是对频谱进行采样后,对得到的频谱信号进行IDTFT,得到的语音信号被周期话,成为一个无限长的序列,这样计算机还是无法模拟。
DFT 算法就很好的解决了这个问题,时域中的N 点序列x[n]的DFT 定义为:
2
10
[][]N j
nk N
n X k x n e
π--==∑,k=0,1,…N-1
一个有限长信号序列,通过DFT 变换后得到的频谱为:
由上式可知n 个点的DFT 仍是n 点,这时候我们可以对得到的频谱序列进行裁剪,搬移等操作,得到我们所需要的频谱上的语音信号。
而对得到的频谱做IDFT 得到的信号不会成为无限长的一个序列,n 个点的IDFT 仍是n 点。这样我们就可以在计算机中得到自己想要的频段上的语音信号了。本文中所实现的就是这样的一个过程。
2.音频压缩的基本原理
Wav文件保存音频信息的基本原理为将音频信号的每一个采样点的时域数值用1个16bit数记录下来,对应的采样频率越高单位时内记录的数据就越多,音质也就越高。所以在不改变wav文件记录音频文件的基本格式的前提下只有降低采样频率才能实现文件的压缩,当然对采样频率的降低就会带来音质的损耗,所以该类压缩方法不是无失真的压缩方法。
在尽量保证源文件的音质效果的前提下有以下两种压缩思路:
1.在源文件的时域序列上间隔取点,再将取点之后的新序列以与取点间隔相对应的采
样频率重新写制成为wav文件,以达到压缩的目的。
2.将源文件的时域序列进行DFT后得到频谱,将频谱中能量较低的成分删除,在按
照新的频谱的长度做IDFT得到新的较源文件更短的时域序列,同样以相应的采
样频率重新写制wav文件。
2.1时域间隔采样法
在时域的间隔采样等效于将频谱中高频成分向低频搬移,而将低频成分去掉。可以用MATLAB读取一段wav文件并将其间隔1点采样后作DFT得到频谱与源文件的频谱比较如图2-1.
MATLAB代码如下:
[time1 fs1 bits1]=wavread('monsterkill.wav');
freq1=fft(time1);
m1=length(time1)
for i=1:m1/2
time2(i)=time1(2*i);
end
freq2=fft(time2);
subplot(2,1,1);
plot(abs(freq1));
subplot(2,1,2);
plot(abs(freq2));
图2-1
可以明显的看到高频成分向序列中段靠拢而幅值则缩小了一半,由此可以得到时域间
[time1 fs1 bits1]=wavread('monsterkill.wav');
freq1=fft(time1);
m1=length(time1);
time2=real(ifft(freq1,m1/2));
wavwrite(time2,fs1/2,'monsterkill2-1.wav');
freq2=fft(time2);
figure(1);
subplot(2,1,1);
plot(abs(freq1));
subplot(2,1,2);
plot(abs(freq2));
title('频谱成分');
figure(2);
subplot(2,1,1);
plot(time1);
subplot(2,1,2);
plot(time2);
title('时域序列');
运行结果如(图2-2)、(图2-3)。实际得到新wav文件见附件monsterkill2-1.wav
图2-2
该种方法的优点在于操作方便易于实现,并且能够较好的保留源文件的音质特点。但在压缩比例较大或者源音频文件以中低音为主时将会很大的破坏音质,失真度很高。
2.2去除低能频点法
频谱上各频点对应值的模长表示能量的分布,将能量较小的部分忽略掉即可以达到压缩的目的,其基本压缩流程如下:
以去掉小于平均能量20倍的频点为例MATLAB 代码如下:
[time1 fs1 bits1]=wavread('monsterkill.wav');
freq1=fft(time1);
m1=length(time1);
en=0;
for n=1:m1
en=en+abs(freq1(n));
end
d=en/m1;
n=1;
for i=1:m1
if d/abs(freq1(i))<20
freq2(n)=freq1(i);
n=n+1;
end
end
time2=real(ifft(freq2));
wavwrite(time2,n*fs1/m1,'monsterkill2-2.wav'); figure(1);
subplot(2,1,1);
plot(time1);
subplot(2,1,2);
plot(time2);
title('时域序列');
figure(2);