MATLAB变声器程序

clear;clc;
[s,fs,] = audioread(‘61.m4a’); % 载入语音s
s(1:3000)=s(1:3000)+randn(3000,1)*eps;
s = s/max(s); %归一化
L = length(s); % 读入语音长度
figure(1);
subplot(211);plot(s);title(‘原始语音信号波形’)
subplot(212);plot(abs(s));title(‘原始语音信号频谱’)
sound(s,fs)
%定义常数
FL = 80; % 帧长
WL = 240; % 窗长
% P = 10; % 预测系数个数
FN = floor(L/FL)-2; % 计算帧数

% 预测和重建滤波器
exc = zeros(L,1); % 激励信号(预测误差)
zi_pre = [0;0;0;0;0;0;0;0;0;0]; % 预测滤波器的状态
s_rec = zeros(L,1); % 重建语音
zi_rec = [0;0;0;0;0;0;0;0;0;0];

%变调不变速滤波器
exc_syn_t = zeros(L,1); % 合成的激励信号(脉冲串)
s_syn_t = zeros(L,1); % 合成语音
last_syn_t = 0; %存储上一个(或多个)段的最后一个脉冲的下标
zi_syn_t = zeros(10,1); % 合成滤波器的状态
hw = hamming(WL); % 汉明窗
% 依次处理每帧语音
for n = 3:FN
s_w = s(nFL-WL+1:nFL).hw; %汉明窗加权后的语音
[A,E] = lpc(s_w,10); %用线性预测法计算P个预测系数
% A是预测系数,E会被用来计算合成激励的能量
s_f = s((n-1)FL+1:nFL); % 本帧语音,下面就要对它做处理
% (4) 用filter函数s_f计算激励,注意保持滤波器状态
[exc1,zi_pre] = filter(A,1,s_f,zi_pre);
exc((n-1)FL+1:nFL) = exc1; %计算得到的激励
% (5) 用filter函数和exc重建语音,注意保持滤波器状态
[s_rec1,zi_rec] = filter(1,A,exc1,zi_rec);
s_rec((n-1)FL+1:nFL) = s_rec1; %计算得到的重建语音
% 注意下面只有在得到exc后才会计算正确
s_Pitch = exc(n
FL-222:nFL);
PT = findpitch(s_Pitch); % 计算基音周期PT
G = sqrt(E
PT); % 计算合成激励的能量G
% (13) 将基音周期减小一半,将共振峰频率增加7000Hz,重新合成语音(男声变童声)
PT1 =floor(PT/2); %减小基音周期
poles = roots(A);
deltaOMG =0.0052pi/fs;
for p=1:10 %增加共振峰频率,实轴上方的极点逆时针转,下方顺时针转
if imag(poles§)>0 poles§ = poles§exp(1ideltaOMG);
elseif imag(poles§)<0 poles§ = poles§exp(-1ideltaOMG);
end
end
A1=poly(poles);
tempn_syn_t = [1:nFL-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:nFL-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:nFL) = exc_syn1_t; %计算得到的合成激励
s_syn_t((n-1)FL+1:nFL) = s_syn1_t; %计算得到的合成语音
last_syn_t = last_syn_t+PT1
floor((n*FL-last_syn_t)/PT1);
end

figure;
subpot(211),plot(exc_syn_t),xlabel(‘n(samples)’);ylabel(‘Amplitude’),title(‘合成高调激励信号’);
XLim([0,length(exc_syn_t)]);
subplot(212);plot(abs(s));title(‘合成高调语音信号频谱’);
XLim([0,length(exc_syn_t)]);
sound(s_syn_t);

[s,fs,] = audioread(‘61.m4a’); % 载入语音s
sound(s,0.5*fs);%改变播放频率声音好像也变了。

注:语音最好把开头没用的裁剪一下,要不然会出错。

  • 5
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值