自己相関のグラフに見られる極値の周期は、元の信号の周期と合致する。
Octaveでは、findpeaks関数を使用して、極値のリストを得ることができる。
[pks, locs] = findpeaks(S,"DoubleSided", "MinPeakHeight", 0.3);と実行すると、pksに±0.3以上の極値(極大値&極小値)のリストが返され、locsに極値のインデクスが返される。
隣接する3つの極致のインデクスの差分を求めれば、周期が求まる。周波数は周期の逆数。
以下、極値の座標を求めて、周波数を求める関数の例
---- findCorrHz.m ----
function [WsHzVector, HzVector] = findCorrHz(R, Ws, Fs)
if(nargin == 0)
disp("usage: [WsHzVector, HzVector] = findCorrHz(R, Ws, Fs)");
return
end
Thresh = 0.3;
HzVector = [];
WsHzVector = [];
len=size(R)(1,1);
for k = [1:Ws:len]
if k+Ws > len
break
endif
Sub=R(k:k+Ws-1);
[pks, locs] = findpeaks(Sub,"DoubleSided", "MinPeakHeight", Thresh);
locs_len = size(locs)(1,1);
if locs_len <= 1
Ts = -Ws;
Hz = 0;
else
Ts = abs(locs(2,1) - locs(1,1));
if locs_len == 2
Ts += Ts;
else
Ts += abs(locs(3,1) - locs(2,1));
endif
Hz = Fs/Ts;
endif
HzVector=vertcat(HzVector, Hz);
WsHzVector=vertcat(WsHzVector, repmat(Hz,1,Ws)');
endfor
endfunction
----------------
HzVectorには、自己相関をWsサンプルの区間ごとに求めた周波数が返る(長さR/Wsのベクトル)。
WsHzVectorには、求めた周波数を各サンプル区間ごとにWs個ずつ複製した、長さWsのベクトルが返る。
[y, Fs] =audioread('Ongen2/egypt_charmera.wav');
Ws=1024, R=corrWs(y, Ws);
[WsHzVector, HzVector] = findCorrHz(R, Ws, Fs);
findpeaks 極大値の検出
Octave - Forge - findpeaks
0 件のコメント:
コメントを投稿