matlab 变调器,个人改动后的语音变速变调的程序
function ct3
% 定義常數(shù)
FL = 80;? ?? ?? ?? ?? ? % 幀長
WL = 240;? ?? ?? ?? ?? ?% 窗長
P = 10;? ?? ?? ?? ?? ???% 預(yù)測系數(shù)個數(shù)
hw = hamming(WL);? ?? ? % 漢明窗
%%%%%%
[sl,Fs] = wavread('sunday_2.wav');? ?? ?? ?? ? % 載入語音s
load('mtlb.mat');
sl=mtlb;
s=buffer(sl,FL);
[~,FN] = size(s);? ?? ???% 計算幀數(shù)
% 預(yù)測和重建濾波器
exc = zeros(FL,FN);? ?? ? % 激勵信號(預(yù)測誤差)
s_rec = exc;? ?? ?? ?? ???% 重建語音
zi_pre = zeros(P,1);? ?? ?% 預(yù)測濾波器的狀態(tài)
zi_rec = zeros(P,1);? ?? ?% 重建濾波器的狀態(tài)
% 合成濾波器
exc_syn =exc;? ?? ?? ?? ? % 合成的激勵信號(脈沖串)
s_syn = exc;? ?? ?? ?? ???% 合成語音
last_syn = [];? ?? ?? ?? ? % 存儲上一個幀的最后一個脈沖在下一幀結(jié)束的位置
zi_syn = zeros(P,1);? ?? ?% 合成濾波器的狀態(tài)
% 變速不變調(diào)濾波器
FL_v = 2*FL;? ?? ?? ?? ???% 假設(shè)速度減慢一倍
exc_syn_v = zeros(FL_v,FN);??% 合成的激勵信號
s_syn_v = exc_syn_v;? ?? ?% 合成語音
last_syn_v = [];
zi_syn_v = zeros(P,1);? ? % 合成濾波器的狀態(tài)
% 變調(diào)不變速濾波器
exc_syn_t = zeros(FL,FN);
s_syn_t = exc_syn_t;
last_syn_t = [];
zi_syn_t = zeros(P,1);
% 記錄中間參數(shù)
A=zeros(P+1,FN);? ? %記錄每幀提取的預(yù)測系數(shù)
E=zeros(1,FN);
PT_sf=zeros(1,FN);
PT_rf=zeros(1,FN);? ???%記錄每幀提取的基音周期
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[S,F,T,Psd]=spectrogram(sl,240,160,2048,1);
Pe=pow2db(abs(Psd));
figure;surf(T,F*2048,Pe,'edgecolor','none')
% figure;surf(T,F(1:200)*2048,Pe(1:200,:),'edgecolor','none')
axis tight;
view(0,90);
xlabel('Time'); ylabel('sample');
[w,ind]=max(bsxfun(@minus,Pe(1:200,:),1.03.^(1:200)'));
PT_sf=round(2048./ind);
pind=w
PT_sf(pind)=FL-1; %基音周期置為幀長
figure;hold on;
plot(PT_sf,'r')
% 依次處理每幀語音
for n = 2:FN-1
% 計算預(yù)測系數(shù)(建立聲道的系統(tǒng)模型)
s_f = s(:,n-1:n+1);? ?? ?? ?? ?? ?? ???%漢明窗加權(quán)后的語音
[A(:,n) Et] = lpc(s_f(:).*hw, P);? ?? ?? ?? ?%用線性預(yù)測法計算P個預(yù)測系數(shù)
E(n)=Et*WL/sum(hw);
% A是預(yù)測系數(shù),E會被用來計算合成激勵的能量
% 提取激勵,并用激勵重建語音
[exc(:,n),zi_pre] = filter(A(:,n),1,s(:,n),zi_pre);% 計算激勵
[s_rec(:,n),zi_rec] = filter(1,A(:,n),exc(:,n),zi_rec);% 重建語音
end
for n = 2:FN-1
ex_f=exc(:,n-1:n+1);
ex_f=ex_f(:);
% 提取基音周期,用于人工合成激勵
R=xcorr(ex_f,1.5*FL);
Rh=filter(hamming(16),1,R(1.5*FL+1:end));
[~,PT]=findpeaks(Rh(9:end),'s','descend','n',1);
PT_rf(:,n)=PT;
G = sqrt(E(n)*PT);? ?? ?? ???% 計算合成激勵的能量G(不要求掌握)
[~,m]=findpeaks(ex_f(81:160),'s','descend','n',1);
if isempty(m),m=121;end
m=80+m;
a=ceil(PT/2)-1;
b=floor(PT/2);
excf=[ex_f(m-b:m+a)];
excfh=excf(1+mod(b,2):2:end);
% 合成語音
%n
kt=ceil((FL-length(last_syn))/PT);
GG=[last_syn;repmat(excf,kt,1)];
exc_syn(:,n) = GG(1:80);? ?? ???% 人工生成本幀激勵
last_syn=GG(81:end);
%if length(exc_syn)>80,n,end
[s_syn(:,n),zi_syn] = filter(1,A(:,n),exc_syn(:,n),zi_syn); %通過人造激勵合成語音
% 合成速度慢,但音調(diào)不變的語音。
kt=ceil((FL_v-length(last_syn_v))/PT);? ?% (不改變基音周期和預(yù)測系數(shù),將合成激勵的長度增加一倍)
GG=[last_syn_v;repmat(excf,kt,1)];
exc_syn_v(:,n) = GG(1:160); % 人工生成本幀激勵
last_syn_v=GG(161:end);
[s_syn_v(:,n),zi_syn_v] = filter(1,A(:,n),exc_syn_v(:,n),zi_syn_v);
% 合成變調(diào)不變速的語音
poles = roots(A(:,n));
deltaOMG = 150*2*pi/8000; % 將共振峰頻率增加150Hz
A1=poly(poles.*exp(sign(imag(poles))*1j*deltaOMG)); %生成新的聲道模型
PT1 =length(excfh);? ?% 將基音周期減小一半
kt=ceil((FL-length(last_syn_t))/PT1);
GG=[last_syn_t;repmat(excfh,kt,1)];
exc_syn_t(:,n) = GG(1:80); % 人工生成本幀激勵
last_syn_t=GG(81:end);
[s_syn_t(:,n),zi_syn_t] = filter(1,A1,exc_syn_t(:,n),zi_syn_t);
end
plot(PT_rf);title('受頻域分辨率的影響,70到80幀的精度很差')
xlabel('提高精度可以增加短時傅立葉變換的樣點數(shù)目(當(dāng)前是2048)')
%return
xx=reshape(1:FL*FN,FL,FN);
splot(s,exc,s_rec,xx,'重建',Fs)
splot(s,exc_syn,s_syn,xx,'合成',Fs)
xx2=reshape(1:FL_v*FN,FL_v,FN);
splot(s,exc_syn_v,s_syn_v,xx2,'合成慢速',Fs)
splot(s,exc_syn_t,s_syn_t,xx,'合成高調(diào)',Fs)
function splot(s,ex,re,x,str,Fs)
figure;
ax(3)=subplot(3,1,1);
plot(s(:));??title('原語音信號')
ax(2)=subplot(3,1,2);
plot(x,ex);??title([str,'激勵信號'])
ax(1)=subplot(3,1,3);
plot(re(:));??title([str,'語音信號'])
linkaxes(ax,'xy')
sound(s(:),Fs);
sound(ex(:),Fs);
sound(re(:),Fs);
總結(jié)
以上是生活随笔為你收集整理的matlab 变调器,个人改动后的语音变速变调的程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dr.Web(大蜘蛛) 下载
- 下一篇: [转贴]史上最强科幻 经典科幻电影100