To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / _beattracker / newtt_hmm_dp.m @ 8:b5b38998ef3b
History | View | Annotate | Download (3.85 KB)
| 1 |
function [beats,localscore,timesig,ppath] = newtt_hmm_dp(df,tempo) |
|---|---|
| 2 |
|
| 3 |
if nargin<2 |
| 4 |
tempo = 0; |
| 5 |
end |
| 6 |
|
| 7 |
beats = []; |
| 8 |
|
| 9 |
p = bt_parms; |
| 10 |
|
| 11 |
df = df(:)'; |
| 12 |
% |
| 13 |
% df = df/alpha_norm(9,df); |
| 14 |
df = qnormalise(df,9,2); |
| 15 |
|
| 16 |
% work out period track with viterbi decoding |
| 17 |
[ppath,obs,prob,wv]= tempo_hmm(df,p.step,tempo); |
| 18 |
|
| 19 |
% ppp=textread('home/studio/Desktop/path.txt');
|
| 20 |
% ppp = [ppp(:)' ppp(end)*ones(1,2)]; |
| 21 |
% ppath = ppp; |
| 22 |
|
| 23 |
ppath(ppath<20) = 20; |
| 24 |
dp = abs(diff(ppath)); |
| 25 |
dp = [0 dp(:)']; |
| 26 |
dp(dp>16) = 16; |
| 27 |
% plot(dp),pause(0.01); |
| 28 |
% now incorporate ellis' dynamic programming, |
| 29 |
% but for time-varying period....! |
| 30 |
|
| 31 |
|
| 32 |
tempmat = (ppath'*ones(1,p.step))'; |
| 33 |
pd = round(tempmat(:)); |
| 34 |
% length(pd) |
| 35 |
|
| 36 |
|
| 37 |
% df = abs(diff(df)); |
| 38 |
% prob = 0.5+0.5*prob/max(prob); |
| 39 |
% prob = 4*prob; |
| 40 |
|
| 41 |
% prob = 4*prob/max(prob); |
| 42 |
|
| 43 |
|
| 44 |
% a=ftacf(adapt_thresh(df)); |
| 45 |
% a=a(1:512); |
| 46 |
% [tmp,r]=getperiod(a,wv,0,128,1,0); |
| 47 |
% r=sunity(r); |
| 48 |
% val=max(r); |
| 49 |
% tightness = 100*val; |
| 50 |
tightness= [4]; % want to try and get a tightness out of the signal automatically... |
| 51 |
|
| 52 |
|
| 53 |
alpha=0.8; |
| 54 |
mpd = round(median(ppath)); |
| 55 |
templt = exp(-0.5*(([-mpd:mpd]/(mpd/32)).^2)); |
| 56 |
localscore = conv(templt,df); |
| 57 |
% this removes the offset imposed by the filtering... |
| 58 |
|
| 59 |
localscore = localscore(round(length(templt)/2)+[1:length(df)]); |
| 60 |
localscore = localscore/sum(localscore); |
| 61 |
|
| 62 |
|
| 63 |
aacf = ftacf(localscore); |
| 64 |
[timesig] = findmeter_mm(aacf(1:512),mpd); |
| 65 |
|
| 66 |
% % subplot(311); plot(localscore); |
| 67 |
% % al = localscore; |
| 68 |
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 69 |
% %%%% little bootstrap on phase |
| 70 |
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 71 |
% apin = 0; |
| 72 |
% awinlen=512; |
| 73 |
% astep = 128; |
| 74 |
% apend = length(localscore)-2*awinlen; |
| 75 |
% ak = 0; |
| 76 |
% while (apin<apend) |
| 77 |
% ak = ak+1; |
| 78 |
% align = getalignment2(localscore(apin+1:apin+awinlen),ones(1,pd(ak)),pd(ak),0); |
| 79 |
% try |
| 80 |
% localscore(apin+align-4:apin+align+4) = (1+gausswin(9)').*localscore(apin+align-4:apin+align+4); |
| 81 |
% catch |
| 82 |
% temp_a = 1; |
| 83 |
% end |
| 84 |
% apin=apin+astep; |
| 85 |
% end |
| 86 |
% |
| 87 |
% % subplot(312); plot(localscore); |
| 88 |
% % subplot(313); plot(al-localscore); |
| 89 |
backlink = zeros(1,length(localscore)); |
| 90 |
cumscore = zeros(1,length(localscore)); |
| 91 |
|
| 92 |
starting = 1; |
| 93 |
for i = 1:length(localscore) |
| 94 |
% pause; |
| 95 |
% i |
| 96 |
% search range for previous beat |
| 97 |
prange = round(-2*pd(i)):-round(pd(i))/2; |
| 98 |
|
| 99 |
% want to update tightness based on periodicity change.. |
| 100 |
% or as andrew does.. whether it's an important beat. |
| 101 |
% Skewed window |
| 102 |
mu = -pd(i); |
| 103 |
% tightness = prob(ceil(i/128)); |
| 104 |
% sigma = pd(i)/4; |
| 105 |
% txwt = exp(-0.5 * ((prange - mu)./sigma).^2) ./ (sqrt(2*pi) .* sigma); |
| 106 |
txwt = exp( -0.5* ( ( ( tightness - 1* log(1+dp(ceil(i/128))) ) * log(prange/-pd(i))).^2) ); |
| 107 |
% txwt = -(prange ./ mu.^ 2) .* exp(-prange .^ 2 ./ (2*mu .^ 2)); |
| 108 |
% txwt = txwt.^2; |
| 109 |
% keyboard |
| 110 |
timerange = i + prange; |
| 111 |
|
| 112 |
% Are we reaching back before time zero? |
| 113 |
zpad = max(0, min(1-timerange(1),length(prange))); |
| 114 |
% Search over all possible predecessors and apply transition |
| 115 |
% weighting |
| 116 |
scorecands = txwt .* [zeros(1,zpad),cumscore(timerange(zpad+1:end))]; |
| 117 |
% Find best predecessor beat |
| 118 |
[vv,xx] = max(scorecands); |
| 119 |
% Add on local score |
| 120 |
cumscore(i) = alpha*vv + (1-alpha)*localscore(i); |
| 121 |
|
| 122 |
% special case to catch first onset |
| 123 |
% if starting == 1 & localscore(i) > 100*abs(vv) |
| 124 |
if starting == 1 & localscore(i) < 0.01*max(localscore); |
| 125 |
backlink(i) = -1; |
| 126 |
else |
| 127 |
backlink(i) = timerange(xx); |
| 128 |
% prevent it from resetting, even through a stretch of silence |
| 129 |
starting = 0; |
| 130 |
end |
| 131 |
|
| 132 |
end |
| 133 |
|
| 134 |
|
| 135 |
%try |
| 136 |
% align = getalignment2(localscore(end-1024:end),ones(1,2*pd(end)),2*pd(end),0); |
| 137 |
%catch |
| 138 |
align = getalignment2(localscore(end-512:end),ones(1,1*pd(end)),1*pd(end),0); |
| 139 |
%end |
| 140 |
|
| 141 |
b = []; |
| 142 |
b = length(df) - align; |
| 143 |
|
| 144 |
% b = bestendx; |
| 145 |
|
| 146 |
while backlink(b(end)) > 0 |
| 147 |
b = [b,backlink(b(end))]; |
| 148 |
end |
| 149 |
|
| 150 |
|
| 151 |
b = fliplr(b); |
| 152 |
|
| 153 |
% return beat times in secs |
| 154 |
beats = (b*512); % seems to be an offset. |
| 155 |
beats(beats<1) = []; |
| 156 |
% |
| 157 |
% otherbeats{kk} = b;
|
| 158 |
% score(kk) = dfscore(b,df); |
| 159 |
% [val,ind] = max(score); |
| 160 |
% beats = otherbeats{ind};
|
| 161 |
% beats = 512*(length(df)-beats/512); |
| 162 |
% beats = sort(beats); |