* 区間ごとに異なる周波数の正弦波を生成する
「Octaveレッスン(11) - 自己相関から周波数を求める」で区間ごとに周波数(HzVector)を求めた。以下、HzVectorで与えられる周波数情報を元に、区間ごと正弦波を生成する例
---- genWsSin.m ----
function WsSin = genWsSin(HzVector, Ws, Fs)
if(nargin == 0)
disp("usage: WsSin = genWsSin(HzVector, Ws, Fs)");
return
endif
len=size(HzVector)(1,1);
preHz=-1;
dur=0;
WsSin=[];
for k = [1:len-1]
crrHz=HzVector(k,1);
if crrHz==preHz
dur += Ws;
else
if dur > 0
WsSin = horzcat(WsSin, gen_pre_sin(preHz, dur, Fs));
endif
preHz=crrHz;
dur=Ws;
endif
endfor
if dur > 0
WsSin = horzcat(WsSin, gen_pre_sin(preHz, dur, Fs));
endif
endfunction
function y = gen_pre_sin(preHz, dur, Fs)
x=[0:dur-1];
y=sin(2*pi*preHz/Fs*x);
endfunction
if(nargin == 0)
disp("usage: WsSin = genWsSin(HzVector, Ws, Fs)");
return
endif
len=size(HzVector)(1,1);
preHz=-1;
dur=0;
WsSin=[];
for k = [1:len-1]
crrHz=HzVector(k,1);
if crrHz==preHz
dur += Ws;
else
if dur > 0
WsSin = horzcat(WsSin, gen_pre_sin(preHz, dur, Fs));
endif
preHz=crrHz;
dur=Ws;
endif
endfor
if dur > 0
WsSin = horzcat(WsSin, gen_pre_sin(preHz, dur, Fs));
endif
endfunction
function y = gen_pre_sin(preHz, dur, Fs)
x=[0:dur-1];
y=sin(2*pi*preHz/Fs*x);
endfunction
----------------
実行例:
[y, Fs] =audioread('Ongen2/egypt_charmera.wav');
Ws=1024, R=corrWs(y, Ws);
[WsHzVector, HzVector] = findCorrHz(R, Ws, Fs);
WsSin = genWsSin(HzVector, Ws, Fs);
sound(WsSin,Fs)
⇒ 笛の音を録音した音声信号を1024サンプルの区間に分割して、区間ごとに周波数を検出。
genWsSin()関数を使用して、区間ごとに正弦波で再構成した音WinSinを再生すると、元の音色に近い音階が聞こえる