annotate toolboxes/MIRtoolbox1.3.2/MIRToolbox/mironsets.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function varargout = mironsets(x,varargin)
wolffd@0 2 % o = mironsets(x) shows a temporal curve where peaks relate to the
wolffd@0 3 % position of note onset times, and estimates those note onset
wolffd@0 4 % positions.
wolffd@0 5 % Optional arguments:
wolffd@0 6 % mironsets(...,f) selects the strategy for the computation of the
wolffd@0 7 % onset detection function.
wolffd@0 8 % f = 'Envelope': Envelope of the audio signal. (Default choice).
wolffd@0 9 % With two methods for envelope extraction:
wolffd@0 10 % mironsets(...,'Spectro') (Default):
wolffd@0 11 % mironsets(...,'SpectroFrame',fl,fh) species the frame
wolffd@0 12 % length fl (in s.) and the hop factor fh (as a value
wolffd@0 13 % between 0 and 1)
wolffd@0 14 % Default values: fl = .1 s., fh = .1
wolffd@0 15 % the frequency reassigment method can be specified:
wolffd@0 16 % 'Freq' (default), 'Mel', 'Bark' or 'Cents' (cf. mirspectrum).
wolffd@0 17 % mironsets(...,'Filter'):
wolffd@0 18 % mironsets(...,'Filterbank',nc) specifies a preliminary
wolffd@0 19 % filterbank decomposition into nc channels. If nc = 0,
wolffd@0 20 % no decomposition is performed.
wolffd@0 21 % Default value: 40.
wolffd@0 22 % mironsets(...,'FilterbankType',ft) specifies the type of
wolffd@0 23 % filterbank (see mirfilterbank).
wolffd@0 24 % Default value: 'Gammatone';
wolffd@0 25 % Options associated to the mirenvelope function can be
wolffd@0 26 % passed here as well (see help mirenvelope):
wolffd@0 27 % 'FilterType','Tau','PreDecim'
wolffd@0 28 % mironsets(...,'Sum','no') does not sum back the channels at
wolffd@0 29 % the end of the computation. The resulting onset curve
wolffd@0 30 % remains therefore decomposed into several channels.
wolffd@0 31 % Options associated to the mirenvelope function can be
wolffd@0 32 % passed here as well (see help mirenvelope):
wolffd@0 33 % 'HalfwaveCenter','Diff','HalfwaveDiff','Center',
wolffd@0 34 % 'Smooth', 'Sampling','Log','Power','Lambda',
wolffd@0 35 % ,'PostDecim','UpSample'
wolffd@0 36 % f = 'SpectralFlux': Spectral flux of the audio signal.
wolffd@0 37 % Options associated to the mirflux function can be
wolffd@0 38 % passed here as well (see help mirflux):
wolffd@0 39 % 'Inc' (toggled on by default here),
wolffd@0 40 % 'Halfwave' (toggled on by default here),
wolffd@0 41 % 'Complex' (toggled off by default),
wolffd@0 42 % 'Median' (toggled on by default here)
wolffd@0 43 % f = 'Pitch ':computes a frame-decomposed autocorrelation function ,
wolffd@0 44 % of same default characteristics than those returned
wolffd@0 45 % by mirpitch, with however a range of frequencies set by
wolffd@0 46 % the following options:
wolffd@0 47 % 'Min' (set by default to 30 Hz),
wolffd@0 48 % 'Max' (set by default to 1000 Hz),
wolffd@0 49 % and subsequently computes the novelty curve of the
wolffd@0 50 % resulting similatrix matrix.
wolffd@0 51 % Option associated to the mirnovelty function can be
wolffd@0 52 % passed here as well (see help mirnovelty):
wolffd@0 53 % 'KernelSize' (set by default to 32 samples)
wolffd@0 54 % mironsets(...,'Detect',d) toggles on or off the onset detection,
wolffd@0 55 % which is based on the onset detection function.
wolffd@0 56 % (By default toggled on.)
wolffd@0 57 % Option associated to the mirpeaks function can be specified as
wolffd@0 58 % well:
wolffd@0 59 % 'Contrast' with default value c = .01
wolffd@0 60 % 'Threshold' with default value t = 0
wolffd@0 61 % mironsets(...,'Attack') (or 'Attacks') detects attack phases.
wolffd@0 62 % mironsets(...,'Release') (or 'Releases') detects release phases.
wolffd@0 63 % mironsets(...,'Gauss',o) estimate the attack and/or release
wolffd@0 64 % points using a gaussian envelope smoothing of order o of the
wolffd@0 65 % onset curve.
wolffd@0 66 % mironsets(...,'Frame',...) decomposes into frames, with default frame
wolffd@0 67 % length 3 seconds and hop factor .1
wolffd@0 68 % Preselected onset detection models:
wolffd@0 69 % mironsets(...,'Scheirer') corresponds to (Scheirer, 1998):
wolffd@0 70 % mironsets(...,'FilterBankType','Scheirer',...
wolffd@0 71 % 'FilterType','HalfHann','Sampling',200,...
wolffd@0 72 % 'HalfWaveDiff','Sum',0,'Detect',0)
wolffd@0 73 % mironsets(...,'Klapuri99') corresponds to most of (Klapuri, 1999).
wolffd@0 74
wolffd@0 75 %% options related to 'Envelope':
wolffd@0 76
wolffd@0 77 env.key = 'Envelope';
wolffd@0 78 env.type = 'Boolean';
wolffd@0 79 env.default = NaN;
wolffd@0 80 option.env = env;
wolffd@0 81
wolffd@0 82 envmethod.key = 'Method'; % optional
wolffd@0 83 envmethod.type = 'Boolean';
wolffd@0 84 option.envmethod = envmethod;
wolffd@0 85
wolffd@0 86 envmeth.type = 'String';
wolffd@0 87 envmeth.choice = {'Filter','Spectro'};
wolffd@0 88 envmeth.default = 'Spectro';
wolffd@0 89 option.envmeth = envmeth;
wolffd@0 90
wolffd@0 91 %% options related to 'Filter':
wolffd@0 92
wolffd@0 93 filter.key = 'FilterType';
wolffd@0 94 filter.type = 'String';
wolffd@0 95 filter.choice = {'IIR','HalfHann'};
wolffd@0 96 filter.default = 'IIR';
wolffd@0 97 option.filter = filter;
wolffd@0 98
wolffd@0 99 tau.key = 'Tau';
wolffd@0 100 tau.type = 'Integer';
wolffd@0 101 tau.default = .02;
wolffd@0 102 option.tau = tau;
wolffd@0 103
wolffd@0 104 fb.key = {'Filterbank','NbChannels'};
wolffd@0 105 fb.type = 'Integer';
wolffd@0 106 fb.default = 40;
wolffd@0 107 option.fb = fb;
wolffd@0 108
wolffd@0 109 filtertype.key = 'FilterbankType';
wolffd@0 110 filtertype.type = 'String';
wolffd@0 111 %filtertype.choice = {'Gammatone','2Channels','Scheirer','Klapuri'};
wolffd@0 112 filtertype.default = 'Gammatone';
wolffd@0 113 option.filtertype = filtertype;
wolffd@0 114
wolffd@0 115 decim.key = {'Decim','PreDecim'};
wolffd@0 116 decim.type = 'Integer';
wolffd@0 117 decim.default = 0;
wolffd@0 118 option.decim = decim;
wolffd@0 119
wolffd@0 120 %% options related to 'Spectro':
wolffd@0 121
wolffd@0 122 band.type = 'String';
wolffd@0 123 band.choice = {'Freq','Mel','Bark','Cents'};
wolffd@0 124 band.default = 'Freq';
wolffd@0 125 option.band = band;
wolffd@0 126
wolffd@0 127 specframe.key = 'SpectroFrame';
wolffd@0 128 specframe.type = 'Integer';
wolffd@0 129 specframe.number = 2;
wolffd@0 130 specframe.default = [.1 .1];
wolffd@0 131 option.specframe = specframe;
wolffd@0 132
wolffd@0 133 sum.key = 'Sum';
wolffd@0 134 sum.type = 'Boolean';
wolffd@0 135 sum.default = 1;
wolffd@0 136 option.sum = sum;
wolffd@0 137
wolffd@0 138 chwr.key = 'HalfwaveCenter';
wolffd@0 139 chwr.type = 'Boolean';
wolffd@0 140 chwr.default = 0;
wolffd@0 141 chwr.when = 'After';
wolffd@0 142 option.chwr = chwr;
wolffd@0 143
wolffd@0 144 mu.key = 'Mu';
wolffd@0 145 mu.type = 'Boolean';
wolffd@0 146 mu.default = 0;
wolffd@0 147 mu.when = 'After';
wolffd@0 148 option.mu = mu;
wolffd@0 149
wolffd@0 150 oplog.key = 'Log';
wolffd@0 151 oplog.type = 'Boolean';
wolffd@0 152 oplog.default = 0;
wolffd@0 153 oplog.when = 'After';
wolffd@0 154 option.log = oplog;
wolffd@0 155
wolffd@0 156 oppow.key = 'Power';
wolffd@0 157 oppow.type = 'Boolean';
wolffd@0 158 oppow.default = 0;
wolffd@0 159 oppow.when = 'After';
wolffd@0 160 option.power = oppow;
wolffd@0 161
wolffd@0 162 diffenv.key = 'DiffEnvelope'; % obsolete, replaced by 'Diff'
wolffd@0 163 diffenv.type = 'Boolean';
wolffd@0 164 diffenv.default = 0;
wolffd@0 165 option.diffenv = diffenv;
wolffd@0 166
wolffd@0 167 diff.key = 'Diff';
wolffd@0 168 diff.type = 'Integer';
wolffd@0 169 diff.default = 0;
wolffd@0 170 diff.keydefault = 1;
wolffd@0 171 diff.when = 'After';
wolffd@0 172 option.diff = diff;
wolffd@0 173
wolffd@0 174 diffhwr.key = 'HalfwaveDiff';
wolffd@0 175 diffhwr.type = 'Integer';
wolffd@0 176 diffhwr.default = 0;
wolffd@0 177 diffhwr.keydefault = 1;
wolffd@0 178 diffhwr.when = 'After';
wolffd@0 179 option.diffhwr = diffhwr;
wolffd@0 180
wolffd@0 181 lambda.key = 'Lambda';
wolffd@0 182 lambda.type = 'Integer';
wolffd@0 183 lambda.default = 1;
wolffd@0 184 lambda.when = 'After';
wolffd@0 185 option.lambda = lambda;
wolffd@0 186
wolffd@0 187 c.key = 'Center';
wolffd@0 188 c.type = 'Boolean';
wolffd@0 189 c.default = 0;
wolffd@0 190 c.when = 'After';
wolffd@0 191 option.c = c;
wolffd@0 192
wolffd@0 193 aver.key = 'Smooth';
wolffd@0 194 aver.type = 'Integer';
wolffd@0 195 aver.default = 0;
wolffd@0 196 aver.keydefault = 30;
wolffd@0 197 aver.when = 'After';
wolffd@0 198 option.aver = aver;
wolffd@0 199
wolffd@0 200 ds.key = {'Down','PostDecim'};
wolffd@0 201 ds.type = 'Integer';
wolffd@0 202 if isamir(x,'mirenvelope')
wolffd@0 203 ds.default = 1;
wolffd@0 204 else
wolffd@0 205 ds.default = NaN;
wolffd@0 206 end
wolffd@0 207 ds.when = 'After';
wolffd@0 208 ds.chunkcombine = 'During';
wolffd@0 209 option.ds = ds;
wolffd@0 210
wolffd@0 211 sampling.key = 'Sampling';
wolffd@0 212 sampling.type = 'Integer';
wolffd@0 213 sampling.default = 0;
wolffd@0 214 sampling.when = 'After';
wolffd@0 215 option.sampling = sampling;
wolffd@0 216
wolffd@0 217 up.key = {'UpSample'};
wolffd@0 218 up.type = 'Integer';
wolffd@0 219 up.default = 0;
wolffd@0 220 up.keydefault = 2;
wolffd@0 221 option.up = up;
wolffd@0 222
wolffd@0 223 %% options related to 'SpectralFlux'
wolffd@0 224 flux.key = 'SpectralFlux';
wolffd@0 225 flux.type = 'Boolean';
wolffd@0 226 flux.default = 0;
wolffd@0 227 option.flux = flux;
wolffd@0 228
wolffd@0 229 complex.key = 'Complex';
wolffd@0 230 complex.type = 'Boolean';
wolffd@0 231 complex.when = 'Both';
wolffd@0 232 complex.default = 0;
wolffd@0 233 option.complex = complex;
wolffd@0 234
wolffd@0 235 inc.key = 'Inc';
wolffd@0 236 inc.type = 'Boolean';
wolffd@0 237 inc.default = 1;
wolffd@0 238 option.inc = inc;
wolffd@0 239
wolffd@0 240 median.key = 'Median';
wolffd@0 241 median.type = 'Integer';
wolffd@0 242 median.number = 2;
wolffd@0 243 median.default = [.2 1.3];
wolffd@0 244 median.when = 'After';
wolffd@0 245 option.median = median;
wolffd@0 246
wolffd@0 247 hw.key = 'Halfwave';
wolffd@0 248 hw.type = 'Boolean';
wolffd@0 249 hw.default = 1;
wolffd@0 250 hw.when = 'After';
wolffd@0 251 option.hw = hw;
wolffd@0 252
wolffd@0 253 %% options related to 'Pitch':
wolffd@0 254 pitch.key = 'Pitch';
wolffd@0 255 pitch.type = 'Boolean';
wolffd@0 256 pitch.default = 0;
wolffd@0 257 option.pitch = pitch;
wolffd@0 258
wolffd@0 259 min.key = 'Min';
wolffd@0 260 min.type = 'Integer';
wolffd@0 261 min.default = 30;
wolffd@0 262 option.min = min;
wolffd@0 263
wolffd@0 264 max.key = 'Max';
wolffd@0 265 max.type = 'Integer';
wolffd@0 266 max.default = 1000;
wolffd@0 267 option.max = max;
wolffd@0 268
wolffd@0 269 kernelsize.key = 'KernelSize';
wolffd@0 270 kernelsize.type = 'Integer';
wolffd@0 271 kernelsize.default = 32;
wolffd@0 272 option.kernelsize = kernelsize;
wolffd@0 273
wolffd@0 274 %% options related to event detection
wolffd@0 275 detect.key = 'Detect';
wolffd@0 276 detect.type = 'String';
wolffd@0 277 detect.choice = {'Peaks','Valleys',0,'no','off'};
wolffd@0 278 detect.default = 'Peaks';
wolffd@0 279 detect.keydefault = 'Peaks';
wolffd@0 280 detect.when = 'After';
wolffd@0 281 option.detect = detect;
wolffd@0 282
wolffd@0 283 cthr.key = 'Contrast';
wolffd@0 284 cthr.type = 'Integer';
wolffd@0 285 cthr.default = NaN;
wolffd@0 286 cthr.when = 'After';
wolffd@0 287 option.cthr = cthr;
wolffd@0 288
wolffd@0 289 thr.key = 'Threshold';
wolffd@0 290 thr.type = 'Integer';
wolffd@0 291 thr.default = 0;
wolffd@0 292 thr.when = 'After';
wolffd@0 293 option.thr = thr;
wolffd@0 294
wolffd@0 295 attack.key = {'Attack','Attacks'};
wolffd@0 296 attack.type = 'Boolean';
wolffd@0 297 attack.default = 0;
wolffd@0 298 attack.when = 'After';
wolffd@0 299 option.attack = attack;
wolffd@0 300
wolffd@0 301 release.key = {'Release','Releases'};
wolffd@0 302 release.type = 'String';
wolffd@0 303 release.choice = {'Olivier','Valeri',0,'no','off'};
wolffd@0 304 release.default = 0;
wolffd@0 305 release.keydefault = 'Olivier';
wolffd@0 306 release.when = 'After';
wolffd@0 307 option.release = release;
wolffd@0 308
wolffd@0 309 gauss.key = 'Gauss';
wolffd@0 310 gauss.type = 'Integer';
wolffd@0 311 gauss.default = 0;
wolffd@0 312 gauss.when = 'After';
wolffd@0 313 option.gauss = gauss;
wolffd@0 314
wolffd@0 315 %% preselection
wolffd@0 316 presel.choice = {'Scheirer','Klapuri99'};
wolffd@0 317 presel.type = 'String';
wolffd@0 318 presel.default = 0;
wolffd@0 319 option.presel = presel;
wolffd@0 320
wolffd@0 321
wolffd@0 322 %% 'Frame' option
wolffd@0 323 frame.key = 'Frame';
wolffd@0 324 frame.type = 'Integer';
wolffd@0 325 frame.when = 'Both';
wolffd@0 326 frame.number = 2;
wolffd@0 327 frame.default = [0 0];
wolffd@0 328 frame.keydefault = [3 .1];
wolffd@0 329 option.frame = frame;
wolffd@0 330
wolffd@0 331 specif.option = option;
wolffd@0 332
wolffd@0 333 specif.eachchunk = 'Normal';
wolffd@0 334 specif.combinechunk = 'Concat';
wolffd@0 335 specif.extensive = 1;
wolffd@0 336
wolffd@0 337 specif.title = 'Onset curve'; %used for miroptions
wolffd@0 338
wolffd@0 339 varargout = mirfunction(@mironsets,x,varargin,nargout,specif,@init,@main);
wolffd@0 340
wolffd@0 341
wolffd@0 342 %% INIT
wolffd@0 343
wolffd@0 344 function [y type] = init(x,option)
wolffd@0 345 if iscell(x)
wolffd@0 346 x = x{1};
wolffd@0 347 end
wolffd@0 348 if ischar(option.presel)
wolffd@0 349 if strcmpi(option.presel,'Scheirer')
wolffd@0 350 option.filtertype = 'Scheirer';
wolffd@0 351 option.filter = 'HalfHann';
wolffd@0 352 option.envmeth = 'Filter';
wolffd@0 353 elseif strcmpi(option.presel,'Klapuri99')
wolffd@0 354 option.filtertype = 'Klapuri';
wolffd@0 355 option.filter = 'HalfHann';
wolffd@0 356 option.envmeth = 'Filter';
wolffd@0 357 option.decim = 180;
wolffd@0 358 end
wolffd@0 359 end
wolffd@0 360 if option.diffenv
wolffd@0 361 option.env = 1;
wolffd@0 362 end
wolffd@0 363 if isnan(option.env)
wolffd@0 364 if option.flux || option.pitch
wolffd@0 365 option.env = 0;
wolffd@0 366 else
wolffd@0 367 option.env = 1;
wolffd@0 368 end
wolffd@0 369 end
wolffd@0 370 if isamir(x,'miraudio')
wolffd@0 371 if option.env
wolffd@0 372 if strcmpi(option.envmeth,'Filter') && option.fb>1
wolffd@0 373 fb = mirfilterbank(x,option.filtertype,'NbChannels',option.fb);
wolffd@0 374 else
wolffd@0 375 fb = x;
wolffd@0 376 end
wolffd@0 377 y = mirenvelope(fb,option.envmeth,option.band,...
wolffd@0 378 'Frame',option.specframe(1),option.specframe(2),...
wolffd@0 379 'FilterType',option.filter,...
wolffd@0 380 'Tau',option.tau,'UpSample',option.up,...
wolffd@0 381 'PreDecim',option.decim,'PostDecim',0);
wolffd@0 382 type = 'mirenvelope';
wolffd@0 383 elseif option.flux
wolffd@0 384 x = mirframenow(x,option);
wolffd@0 385 y = mirflux(x,'Inc',option.inc,'Complex',option.complex);
wolffd@0 386 type = 'mirscalar';
wolffd@0 387 elseif option.pitch
wolffd@0 388 [unused ac] = mirpitch(x,'Frame','Min',option.min,'Max',option.max);
wolffd@0 389 y = mirnovelty(ac,'KernelSize',option.kernelsize);
wolffd@0 390 type = 'mirscalar';
wolffd@0 391 end
wolffd@0 392 elseif (option.pitch && not(isamir(x,'mirscalar'))) ...
wolffd@0 393 || isamir(x,'mirsimatrix')
wolffd@0 394 y = mirnovelty(x,'KernelSize',option.kernelsize);
wolffd@0 395 type = 'mirscalar';
wolffd@0 396 elseif isamir(x,'mirscalar') || isamir(x,'mirenvelope')
wolffd@0 397 y = x; %mirframenow(x,option);
wolffd@0 398 type = mirtype(x);
wolffd@0 399 else
wolffd@0 400 x = mirframenow(x,option);
wolffd@0 401 y = mirflux(x,'Inc',option.inc,'Complex',option.complex); %Not used...
wolffd@0 402 type = 'mirscalar';
wolffd@0 403 end
wolffd@0 404
wolffd@0 405
wolffd@0 406 %% MAIN
wolffd@0 407
wolffd@0 408 function o = main(o,option,postoption)
wolffd@0 409 if not(isempty(option)) && ischar(option.presel)
wolffd@0 410 if strcmpi(option.presel,'Scheirer')
wolffd@0 411 postoption.sampling = 200;
wolffd@0 412 postoption.diffhwr = 1;
wolffd@0 413 option.sum = 0;
wolffd@0 414 postoption.detect = 0;
wolffd@0 415 elseif strcmpi(option.presel,'Klapuri99')
wolffd@0 416 postoption.mu = 1;
wolffd@0 417 postoption.diffhwr = 1;
wolffd@0 418 option.sum = 0;
wolffd@0 419 postoption.ds = 0;
wolffd@0 420 o2 = o;
wolffd@0 421 end
wolffd@0 422 end
wolffd@0 423 if iscell(o)
wolffd@0 424 o = o{1};
wolffd@0 425 end
wolffd@0 426 if not(isempty(option)) && option.diffenv
wolffd@0 427 postoption.diff = 1;
wolffd@0 428 end
wolffd@0 429 if isa(o,'mirenvelope')
wolffd@0 430 if isfield(postoption,'sampling') && postoption.sampling
wolffd@0 431 o = mirenvelope(o,'Sampling',postoption.sampling);
wolffd@0 432 elseif isfield(postoption,'ds')
wolffd@0 433 if isnan(postoption.ds)
wolffd@0 434 if option.decim || strcmpi(option.envmeth,'Spectro')
wolffd@0 435 postoption.ds = 0;
wolffd@0 436 else
wolffd@0 437 postoption.ds = 16;
wolffd@0 438 end
wolffd@0 439 end
wolffd@0 440 if postoption.ds
wolffd@0 441 o = mirenvelope(o,'Down',postoption.ds);
wolffd@0 442 end
wolffd@0 443 end
wolffd@0 444 end
wolffd@0 445 if isfield(postoption,'cthr')
wolffd@0 446 if isa(o,'mirenvelope')
wolffd@0 447 if postoption.mu
wolffd@0 448 o = mirenvelope(o,'Mu');
wolffd@0 449 end
wolffd@0 450 if postoption.log
wolffd@0 451 o = mirenvelope(o,'Log');
wolffd@0 452 end
wolffd@0 453 if postoption.power
wolffd@0 454 o = mirenvelope(o,'Power');
wolffd@0 455 end
wolffd@0 456 if postoption.diff
wolffd@0 457 o = mirenvelope(o,'Diff',postoption.diff,...
wolffd@0 458 'Lambda',postoption.lambda,...
wolffd@0 459 'Complex',postoption.complex);
wolffd@0 460 end
wolffd@0 461 if postoption.diffhwr
wolffd@0 462 o = mirenvelope(o,'HalfwaveDiff',postoption.diffhwr,...
wolffd@0 463 'Lambda',postoption.lambda,...
wolffd@0 464 'Complex',postoption.complex);
wolffd@0 465 end
wolffd@0 466 if postoption.aver
wolffd@0 467 o = mirenvelope(o,'Smooth',postoption.aver);
wolffd@0 468 end
wolffd@0 469 if postoption.chwr
wolffd@0 470 o = mirenvelope(o,'HalfwaveCenter');
wolffd@0 471 end
wolffd@0 472 if postoption.c
wolffd@0 473 o = mirenvelope(o,'Center');
wolffd@0 474 end
wolffd@0 475 elseif isa(o,'mirscalar') && strcmp(get(o,'Title'),'Spectral flux')
wolffd@0 476 if postoption.median
wolffd@0 477 o = mirflux(o,'Median',postoption.median(1),postoption.median(2),...
wolffd@0 478 'Halfwave',postoption.hw);
wolffd@0 479 else
wolffd@0 480 o = mirflux(o,'Halfwave',postoption.hw);
wolffd@0 481 end
wolffd@0 482 end
wolffd@0 483 end
wolffd@0 484 if isfield(option,'sum') && option.sum
wolffd@0 485 o = mirsum(o,'Adjacent',option.sum);
wolffd@0 486 end
wolffd@0 487 if isfield(option,'presel') && ...
wolffd@0 488 ischar(option.presel) && strcmpi(option.presel,'Klapuri99')
wolffd@0 489 % o, already computed, corresponds to mirenvelope(o,'Mu','HalfwaveDiff');
wolffd@0 490 % o is the relative distance function W in (Klapuri, 99);
wolffd@0 491 o2 = mirenvelope(o2,'HalfwaveDiff');
wolffd@0 492 % o2 is the absolute distance function D in (Klapuri, 99);
wolffd@0 493 p = mirpeaks(o,'Contrast',.2,'Chrono');
wolffd@0 494 p2 = mirpeaks(o2,'ScanForward',p,'Chrono');
wolffd@0 495 o = combinepeaks(p,p2,.05);
wolffd@0 496 clear o2 p p2
wolffd@0 497 filtfreq = 44*[2.^ ([ 0:2, ( 9+(0:17) )/3 ]) ];% Center frequencies of bands
wolffd@0 498 o = mirsum(o,'Weights',(filtfreq(1:end-1)+filtfreq(2:end))/2);
wolffd@0 499 o = mirenvelope(o,'Smooth',12);
wolffd@0 500 end
wolffd@0 501 if not(isa(o,'mirscalar'))
wolffd@0 502 o = mirframenow(o,postoption);
wolffd@0 503 end
wolffd@0 504 if isfield(postoption,'detect') && ischar(postoption.detect)
wolffd@0 505 if isnan(postoption.cthr) || not(postoption.cthr)
wolffd@0 506 if ischar(postoption.detect) || postoption.detect
wolffd@0 507 postoption.cthr = .01;
wolffd@0 508 end
wolffd@0 509 elseif postoption.cthr
wolffd@0 510 if not(ischar(postoption.detect) || postoption.detect)
wolffd@0 511 postoption.detect = 'Peaks';
wolffd@0 512 end
wolffd@0 513 end
wolffd@0 514 if strcmpi(postoption.detect,'Peaks')
wolffd@0 515 o = mirpeaks(o,'Total',Inf,'SelectFirst',...
wolffd@0 516 'Threshold',postoption.thr,'Contrast',postoption.cthr,...
wolffd@0 517 'Order','Abscissa','NoBegin','NoEnd');
wolffd@0 518 elseif strcmpi(postoption.detect,'Valleys')
wolffd@0 519 o = mirpeaks(o,'Total',Inf,'SelectFirst',...
wolffd@0 520 'Threshold',postoption.thr,'Contrast',postoption.cthr,...
wolffd@0 521 'Valleys','Order','Abscissa','NoBegin','NoEnd');
wolffd@0 522 end
wolffd@0 523 nop = cell(size(get(o,'Data')));
wolffd@0 524 o = set(o,'AttackPos',nop,'ReleasePos',nop);
wolffd@0 525 end
wolffd@0 526 if (isfield(postoption,'attack') && postoption.attack) || ...
wolffd@0 527 (isfield(postoption,'release') && postoption.release)
wolffd@0 528 p = get(o,'PeakPos');
wolffd@0 529 pm = get(o,'PeakMode');
wolffd@0 530 d = get(o,'Data');
wolffd@0 531 if postoption.attack
wolffd@0 532 [st p pm] = mircompute(@startattack,d,p,pm);
wolffd@0 533 end
wolffd@0 534 if ischar(postoption.release) && ~strcmpi(postoption.release,'No') ...
wolffd@0 535 && ~strcmpi(postoption.release,'Off')
wolffd@0 536 [rl p pm st] = mircompute(@endrelease,d,p,pm,st,postoption.release);
wolffd@0 537 o = set(o,'ReleasePos',rl);
wolffd@0 538 end
wolffd@0 539 o = set(o,'AttackPos',st,'PeakPos',p,'PeakMode',pm);
wolffd@0 540 end
wolffd@0 541 title = get(o,'Title');
wolffd@0 542 if not(length(title)>11 && strcmp(title(1:11),'Onset curve'))
wolffd@0 543 o = set(o,'Title',['Onset curve (',title,')']);
wolffd@0 544 end
wolffd@0 545
wolffd@0 546
wolffd@0 547 function st = startattack(d,z,pm)
wolffd@0 548 z = sort(z{1});
wolffd@0 549 pm = pm{1};
wolffd@0 550 st = zeros(size(z));
wolffd@0 551 i = 1;
wolffd@0 552 dd = diff(d,1,1); % d'
wolffd@0 553 ddd = diff(dd,1,1); % d''
wolffd@0 554 dddd = diff(ddd,1,1); % d'''
wolffd@0 555 while i<=length(z)
wolffd@0 556 % Start attack is identified to previous peak in d''.
wolffd@0 557 p = find(dddd((z(i)-1)-1:-1:1)<0,1); % previous decreasing d''
wolffd@0 558 if isempty(p)
wolffd@0 559 st(i) = 1;
wolffd@0 560 else
wolffd@0 561 n = find(dddd((z(i)-1)-p-1:-1:1)>0,1); % previous increasing d''
wolffd@0 562 if isempty(n)
wolffd@0 563 st(i) = 1;
wolffd@0 564 else
wolffd@0 565 st(i) = ((z(i)-1)-p-(n-1))+1;
wolffd@0 566 end
wolffd@0 567 if i>1 && st(i-1)==st(i)
wolffd@0 568 if d(z(i))>d(z(i-1))
wolffd@0 569 del = i-1;
wolffd@0 570 else
wolffd@0 571 del = i;
wolffd@0 572 end
wolffd@0 573 st(del) = [];
wolffd@0 574 z(del) = [];
wolffd@0 575 pm(del) = [];
wolffd@0 576 i = i-1;
wolffd@0 577 end
wolffd@0 578 end
wolffd@0 579 i = i+1;
wolffd@0 580 end
wolffd@0 581 st = {{st} {z} {pm}};
wolffd@0 582
wolffd@0 583
wolffd@0 584 function rt = endrelease(d,z,pm,st,meth)
wolffd@0 585 z = sort(z{1});
wolffd@0 586 pm = pm{1};
wolffd@0 587 if not(isempty(st))
wolffd@0 588 st = st{1};
wolffd@0 589 end
wolffd@0 590 rt = zeros(size(z));
wolffd@0 591 i = 1;
wolffd@0 592 dd = diff(d,1,1); % d'
wolffd@0 593 ddd = diff(dd,1,1); % d''
wolffd@0 594 dddd = diff(ddd,1,1); % d'''
wolffd@0 595 while i<=length(z)
wolffd@0 596 if strcmpi(meth,'Olivier')
wolffd@0 597 % Release attack is identified to next (sufficiently positive) peak
wolffd@0 598 % in d''.
wolffd@0 599 l = find(ddd((z(i)-1):end)<min(ddd)/100,1);
wolffd@0 600 % next d'' sufficiently negative
wolffd@0 601 if isempty(l)
wolffd@0 602 rt(i) = length(d);
wolffd@0 603 else
wolffd@0 604 p = find(ddd((z(i)-1)+(l-1)+1:end)>max(ddd)/100,1); % next increasing d''
wolffd@0 605 if isempty(p)
wolffd@0 606 rt(i) = length(d);
wolffd@0 607 else
wolffd@0 608 n = find(dddd((z(i)-1)+(l-1)+p+1:end)<0,1); % next decreasing d''
wolffd@0 609 if isempty(n)
wolffd@0 610 rt(i) = length(d);
wolffd@0 611 else
wolffd@0 612 rt(i) = ((z(i)-1)+(l-1)+p+n)+1;
wolffd@0 613 end
wolffd@0 614 end
wolffd@0 615 end
wolffd@0 616 elseif strcmpi(meth,'Valeri')
wolffd@0 617 p = find(dd((z(i)-1)+1:end)>min(dd)/100,1); % find point nearest to min(dd)/100 from current peak.
wolffd@0 618 if isempty(p)
wolffd@0 619 rt(i) = length(d);
wolffd@0 620 elseif p<=3 %that means if p is less than 3 points away from the peak then it can not be considered as the end point of release.
wolffd@0 621 %Assumption is that the whole DSR(decay sustain release) section can not be shorter than 30 ms (sampling rate is 100 Hz), also, no successive note can be nearer than 30ms.
wolffd@0 622 rt(i) = z(i)+3;
wolffd@0 623 else
wolffd@0 624 rt(i) = (z(i)-1)+(p-1);
wolffd@0 625 end
wolffd@0 626 end
wolffd@0 627 if i>1 && rt(i-1)==rt(i)
wolffd@0 628 if d(z(i))>d(z(i-1))
wolffd@0 629 del = i-1;
wolffd@0 630 else
wolffd@0 631 del = i;
wolffd@0 632 end
wolffd@0 633 rt(del) = [];
wolffd@0 634 z(del) = [];
wolffd@0 635 pm(del) = [];
wolffd@0 636 if not(isempty(st))
wolffd@0 637 st(del) = [];
wolffd@0 638 end
wolffd@0 639 i = i-1;
wolffd@0 640 end
wolffd@0 641 i = i+1;
wolffd@0 642 end
wolffd@0 643 rt = {{rt} {z} {pm} {st}};