基于FFT算法的数字变声器
发布时间:2024-11-02
发布时间:2024-11-02
【摘要】本数字变声器是实现男声变女声和女声变男声以及变成童声的系统。设计本数字变声器的目的是锻炼自己的学习实践能力。通过matlab编写程序修改语音参数来实现男声女声之间的变换。
【关键词】变音算法数字滤波器语音信号数字滤波器频谱分析 MATLAB
1 引言
变声器在现实生活中应用广泛,变声器是通过改变输入音频的音色、音调,并将变声后的音频输出的工具。根据变声器材质不同,变声器分为变声器硬件和变声器软件。变声器硬件,即通过硬件实现变声的工具;变声器软件,即通过软件实现变声的工具,软件类变声器,运行平台皆为电脑系统。无论是硬件变声器,还是软件变声器,其原理都是,通过改变输入声音频率,进而改变声音的音色、音调,使输出声音在感官上与原声音不同。我们每个人的声音不同,源于我们的每个人的音色和音调不同,我们所说的男中音、男高音,就是音调的不同,而即便音调一致,我们依然能区分出两个不同人的声音,或不同乐器的声音,这就是音色的不同。变声器,正是借助对声音音色和音调的双重复合改变,实现输出声音的改变。我们这里的变声器就是matlab来实现变声。
2 数字变声器的原理和算法
发音方法,发音时,喉头、口腔、鼻腔节制气流的方式和状态,包括发音时构成阻碍和克服阻碍的方式,气流强弱的情况及声带是否振动等几个方面。人类语音可分为有380声语音和无声语音,前者是由声带振动激励的脉冲信号经声腔调制变成不同的音,它是人类语言中元音的基础,声带振动的频率称为基频。无声语音则是声带保持开启状态,禁止振动引发的。一般来说,由声门振动决定的基频跟说话人的性别特征有关,如下表,而无声语音则没有体现这个特征。说话人的个性化音色和语音的另外一个声学参数——共振峰频率的分布有关。儿童由于声道短,其共振峰频率高于成年人,成年女性的声道一般短于成年男性,所以女性的共振峰频率一般高于男性。本实验是基于男生录制的声音进行相关参数提取,修改接近于女声、童声、老人声,并实现了音调的高低与速度的快慢1.变声原理在进行性别变声时,主要考虑基音周期、基频和共振峰频率的变化。基音周期改变时,基频、共振峰同时变化,若伸展既有男变女、女变童,反之亦可。本实验是基于男生录制的声音进行相关参数提取,修改接近于女声,实现男声到女声的变换。
●音段特征:描述的是语音的音色特征。特征参数主要包括基音频率、
共振峰位置、共振峰带宽、基音频率、能量等。
●超音段特征:描述的是语音的韵律特征。特征参数主要包括因素的时
长、基音频率的变化(音调)、能量等
●语言特征:包括习惯用语、方言、口音等。基音是指发浊音时声带振
动所引起的周期性,而基音周期是指声带振动频率的倒数。基音周期是语音信号最重要的参数之一,它描述了语音激励源的一个重要特征。不同的人以及同一个人在不同的年龄时期有不同的基音周期。人唱歌时,其基音频率范围大约是:童声高音频率范围为260-880Hz ,低音频率范围为 196-700Hz ,女声高音频率范围为 220-1.1KHz, 低音频率范围为 200-700Hz ,男声高音频率范围为 160-523Hz 低音频率范围为 80-358Hz 。此外,基音的变化模式称为声调,它携带着非常重要的具有辨意作用的信息。先就如何实时地通过基音频率的变化来实现语声变声,进行讨论, Matlab实现算法。
男声基频分布(hz):50~180 共振峰频率分布:偏低
人群
女声基频分布(hz):160~380 共振峰频率分布:中提取参数
(1 )语音时变傅里叶变换为:∑∞
-∞
=-
=
n jwn
jw e
n
x
e
X)
(
)
(
在低通滤波时,采用巴特沃斯滤波器。
(2)构建巴特沃斯低通滤波器
根据人的说话特征设定相应指标参数,对本段语音设计算出巴特沃斯模拟滤波器的阶数,截止频率,归一化低通原型系统函数。
本段语音设计算出巴特沃斯模拟滤波器的阶数N为5,3dB截止频率,
,算出为0.175,归一化低通原型系统函数为:
其中
将带人中,得到低通滤波器,
各种理想数字滤波器的幅度频率响应
流程图
3 数字变声器的软件实现与仿真结果
代码部分
选择音频文件
[filename,pathname]=uigetfile({'*.wav','ALL FILES'},'select voice file');
if isequal([filename pathname],[0,0]) return;
end
str=[pathname filename];
[temp,Fs]=audioread(str);
temp1=resample(temp,80,441);
handles.y1=temp;
handles.y=temp1;
handles.Fs=Fs;
guidata(hObject,handles);
原音播放
c=handles.Fs;
sound(handles.y1,c);
plot(handles.axes1,handles.y1)
title(handles.axes1,'时域图');
ysize=size(handles.y1);
y1=fft(handles.y,length(handles.y1)); ysize=size(y1);
plot(handles.axes2,abs(y1(1:ysize/2))); xlabel(handles.axes2,'频率');
ylabel(handles.axes2,'幅度');
title(handles.axes2,'频率特性');
男声变女声
FL=80;
WL=240;
P=10;
x1=handles.y;
fs=handles.Fs;
x1=resample(x1(:,1),8000,fs);
fs=8000;
x1=x1+0.000001*randn(length(x1),1);
x1=x1/max(x1);
L=length(x1);
FN=floor(L/FL)-2;
exc=zeros(L,1);
zi_pre=zeros(P,1);
x1_rec=zeros(L,1);
zi_rec=zeros(P,1);
exc_syn=zeros(L,1);
x1_syn=zeros(L,1);
last_syn=0;
zi_syn=zeros(P,1);
exc_syn_t=zeros(L,1);
x1_syn_t=zeros(L,1);
last_syn_t=0;
zi_syn_t=zeros(P,1);
hw=hamming(WL);
for n=3:FN
x1_w=x1(n*FL-WL+1:n*FL).*hw;
[A E]=lpc(x1_w,P);
x1_f=x1((n-1)*FL+1:n*FL);
[exc1,zi_pre]=filter(A,1,x1_f,zi_pre);
exc((n-1)*FL+1:n*FL)=exc1;
[x1_rec1,zi_rec]=filter(1,A,exc1,zi_rec);
x1_rec((n-1)*FL+1:n*FL)=x1_rec1;
x1_Pitch=exc(n*FL-222:n*FL);
PT=findpitch(x1_Pitch);
G=sqrt(E*PT);
PT1=floor(PT/2);
poles=roots(A);
deltaOMG=190*2*pi/8000;
for p=1:10
if imag(poles(p))>0 poles(p)=poles(p)*exp(j*deltaOMG);
elseif imag(poles(p))<0 poles(p)=poles(p)*exp(-j*deltaOMG); end
end
A1=poly(poles);
tempn_syn_t=[1:n*FL-last_syn_t]';
exc_syn1_t=zeros(length(tempn_syn_t),1);
exc_syn1_t(mod(tempn_syn_t,PT1)==0)=G;
exc_syn1_t=exc_syn1_t((n-1)*FL-last_syn_t+1:n*FL-last_syn_t); [x1_syn1_t,zi_syn_t]=filter(1,A1,exc_syn1_t,zi_syn_t);
exc_syn_t((n-1)*FL+1:n*FL)=exc_syn1_t;
x1_syn_t((n-1)*FL+1:n*FL)=x1_syn1_t;
last_syn_t=last_syn_t+PT1*floor((n*FL-last_syn_t)/PT1);
end
sound(x1_syn_t,fs)
plot(handles.axes1,x1_syn_t);
title(handles.axes1,'时域图');
grid on;
ysize=size(x1_syn_t);
y=fft(x1_syn_t,length(x1_syn_t));
ysize=size(y);
plot(handles.axes2,abs(y(1:ysize)))
xlabel(handles.axes2,'频率 ');
ylabel(handles.axes2,'幅度');
title(handles.axes2,'频率特征');
女声变男声
FL = 80; %帧长
WL = 240; % 窗长
P = 10; % 预测系数个数
c=handles.Fs;
Fs=c;
s=handles.y;
s = resample(s(:,1),8000,Fs);
Fs = 8000;
s = s + 0.000001*randn(length(s),1);
s = s/max(s); %归一化¯
L = length(s); % 读入语音长度
FN = floor(L/FL)-2; %计算帧数
% 预测和重建滤波器
exc = zeros(L,1); %激励信号
zi_pre = zeros(P,1); % 预测滤波器状态¬
s_rec = zeros(L,1); % 重建语音
zi_rec = zeros(P,1);
% 变调不变速滤波器
exc_syn_t = zeros(L,1); % 合成的激励信号
s_syn_t = zeros(L,1); % 合成语音
last_syn_t = 0; %储存上一个或多个段的最后一个脉冲的下标
zi_syn_t = zeros(P,1); % 合成滤波器状态
hw = hamming(WL); %依次处理语音
for n = 3:FN
%计算预测系数
s_w = s(n*FL-WL+1:n*FL).*hw; %汉明窗加权后的语音
[A, E] = lpc(s_w, P);
s_f = s((n-1)*FL+1:n*FL); % 本帧语音
% 计算激励
[exc1,zi_pre] = filter(A,1,s_f,zi_pre);
exc((n-1)*FL+1:n*FL) = exc1; %计算得到的重建语音
[s_rec1,zi_rec] = filter(1,A,exc1,zi_rec);
s_rec((n-1)*FL+1:n*FL) = s_rec1;
·s_Pitch = exc(n*FL-222:n*FL);
PT = findpitch(s_Pitch); % 计算基音周期pt
G = sqrt(E*PT); % 计算合成激励的能量
PT1 =floor(PT/0.50);
poles = roots(A);
deltaOMG = 80*2*pi/8000;
for p=1:10 if imag(poles(p))>0 ,poles(p) = poles(p)*exp(1i*deltaOMG);
elseif imag(poles(p))<0 ,poles(p) = poles(p)*exp(-1i*deltaOMG); end
end
A1=poly(poles);
tempn_syn_t = (1:n*FL-last_syn_t)';
exc_syn1_t = zeros(length(tempn_syn_t),1);
exc_syn1_t(mod(tempn_syn_t,PT1)==0) = G; %算出脉冲
exc_syn1_t = exc_syn1_t((n-1)*FL-last_syn_t+1:n*FL-last_syn_t);
[s_syn1_t,zi_syn_t] = filter(1,A1,exc_syn1_t,zi_syn_t);
exc_syn_t((n-1)*FL+1:n*FL) = exc_syn1_t; %计算得到的合成激励
s_syn_t((n-1)*FL+1:n*FL) = s_syn1_t; %计算得到的合成语音
last_syn_t = last_syn_t+PT1*floor((n*FL-last_syn_t)/PT1);
end
sound(s_syn_t,Fs);
plot(handles.axes1,s_syn_t)
title (handles.axes1,'时域');
ysize=size(s_syn_t);
y=fft(s_syn_t,length(s_syn_t));
ysize=size(y);
plot(handles.axes2,abs(y));
xlabel(handles.axes2,'频率');
ylabel(handles.axes2,'振幅');
title(handles.axes2,'频域');
仿真图形
(1)男原声播放
女原声播放
(2)男声变女声
(3)女声变男声
4结束语
经过对数字变声器的设计,我收获很多。自己也感觉到数字信号处理的应用和matlab的强大,同时网络是学习的重要工具,能在网络上获得好多资料。在这里非常感谢曹老师给我的这次机会,也感谢老师和同学们的热心的帮助。
参考文献
[1] 程佩青.数字信号处理教程。清华大学出版社,2007.2
[2] 张威 MATLAB基础与编程入门(第二版)西安电子科技大学出版社,2008.1
[3] 陈垚光等.精通MATLAB GUI设计.北京:电子工业出版社,2011.1
[4] 高西全,丁玉美.数字信号处理(第三版)[M].西安电子科技大学出版社,2011.
[5]陈生潭,郭宝龙,李学武,高建宁.信号与系统(第三版)[M].西安电子科技大学出版社,2008.
[6] 张雪英.数字语音处理及MATLAB仿真.北京:电子工业出版社,2010.7
[7] 郑阿奇.MATLAB实用教程。北京:电子工业出版社,2007.8
上一篇:基础写作-地点介绍