资源简介
超强语音合成程序,包括变速不变调和变调不变速等内容。作者系清华大学电子工程系学生。
代码片段和文件信息
function speechproc()
% 定义常数
Fs=8000;
FL = 80; % 帧长
WL = 240; % 窗长
P = 10; % 预测系数个数
s = readspeech(‘voice.pcm‘100000); % 载入语音s
L = length(s); % 读入语音长度
FN = floor(L/FL)-2; % 计算帧数
% 预测和重建滤波器
exc = zeros(L1); % 激励信号(预测误差)
zi_pre = zeros(P1); % 预测滤波器的状态
s_rec = zeros(L1); % 重建语音
zi_rec = zeros(P1);
% 合成滤波器
exc_syn = zeros(L1); % 合成的激励信号(脉冲串)
s_syn = zeros(L1); % 合成语音
% 变调不变速滤波器
exc_syn_t = zeros(L1); % 合成的激励信号(脉冲串)
s_syn_t = zeros(L1); % 合成语音
% 变速不变调滤波器(假设速度减慢一倍)
exc_syn_v = zeros(2*L1); % 合成的激励信号(脉冲串)
s_syn_v = zeros(2*L1); % 合成语音
hw = hamming(WL); % 汉明窗
%%初始化各滤波器状态
zi_pre=s(2*FL-P+1:2*FL);
zi_rec=s(2*FL-P+1:2*FL);
zi_syn=s(2*FL-P+1:2*FL);
zi_syn_v=s(2*FL-P+1:2*FL);
zi_syn_t=s(2*FL-P+1:2*FL);
% 依次处理每帧语音
for n = 3:FN
% 计算预测系数(不需要掌握)
s_w = s(n*FL-WL+1:n*FL).*hw; %汉明窗加权后的语音
[A E] = lpc(s_w P); %用线性预测法计算P个预测系数
% A是预测系数,E会被用来计算合成激励的能量
if n == 27
% (3) 在此位置写程序,观察预测系统的零极点图
figure; zplane(1 A);
end
s_f = s((n-1)*FL+1:n*FL); % 本帧语音,下面就要对它做处理
% (4) 在此位置写程序,用filter函数s_f计算激励,注意保持滤波器状态
% exc((n-1)*FL+1:n*FL) = ... 将你计算得到的激励写在这里
[ exc((n-1)*FL+1:n*FL) zi_pre] = filter(A1s_fzi_pre);
% (5) 在此位置写程序,用filter函数和exc重建语音,注意保持滤波器状态
[s_rec((n-1)*FL+1:n*FL)zi_rec]=filter([1]Aexc((n-1)*FL+1:n*FL)zi_rec);
% s_rec((n-1)*FL+1:n*FL) = ... 将你计算得到的重建语音写在这里
% 注意下面只有在得到exc后才会计算正确
s_Pitch = exc(n*FL-222:n*FL);
PT = findpitch(s_Pitch); % 计算基音周期PT(不要求掌握)
G = sqrt(E*PT); % 计算合成激励的能量G(不要求掌握)
% (10) 在此位置写程序,生成合成激励,并用激励和filter函数产生合成语音
% exc_syn((n-1)*FL+1:n*FL) = ... 将你计算得到的合成激励写在这里
% s_syn((n-1)*FL+1:n*FL) = ... 将你计算得到的合成语音写在这里
if (n==3) %初始化合成位置
pos=(n-1)*FL+1-PT;
end
pos=pos+PT; %本段第一个激励与上一段最后一个相差PT
while (pos exc_syn(pos)=G;
pos=pos+PT;
end
pos=pos-PT; %本段最后一个激励位置
[ s_syn((n-1)*FL+1 : n*FL)zi_syn] = filter(1AG* exc_syn((n-1)*FL+1:n*FL)zi_syn);
% (11) 不改变基音周期和预测系数,将合成激励的长度增加一倍,再作为filter
% 的输入得到新的合成语音,听一听是不是速度变慢了,但音调没有变。
% exc_syn_v((n-1)*FL_v+1:n*FL_v) = ... 将你计算得到的加长合成激励写在这里
% s_syn_v((n-1)*FL_v+1:n*FL_v) = ... 将你计算得到的加长合成语音写在这里
FL_v=FL*2; %帧长加倍,合成类似上一问
if (n==3) %初始化合成位置
pos_v=(n-1)*FL_v+1-PT;
end
pos_v=pos_v+PT;
while (pos_v exc_syn_v(pos_v)=G;
pos_v=pos_v+PT;
end
pos_v=pos_v-PT;
[s_syn_v((n-1)*FL_v+1:n*FL_v)zi_syn_v]=filter([1]Aexc_syn_v((n-1)*FL_v+1:n*FL_v)zi_syn
评论
共有 条评论