annotate toolboxes/MIRtoolbox1.3.2/MIRToolbox/@mirspectrum/mirspectrum.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function varargout = mirspectrum(orig,varargin)
Daniel@0 2 % s = mirspectrum(x) computes the spectrum of the audio signal x, showing
Daniel@0 3 % the distribution of the energy along the frequencies.
Daniel@0 4 % (x can be the name of an audio file as well.)
Daniel@0 5 % Optional argument:
Daniel@0 6 % mirspectrum(...,'Frame',l,h) computes spectrogram, using frames of
Daniel@0 7 % length l seconds and a hop rate h.
Daniel@0 8 % Default values: l = .05 s, h = .5.
Daniel@0 9 % mirspectrum(...,'Min',mi) indicates the lowest frequency taken into
Daniel@0 10 % consideration, expressed in Hz.
Daniel@0 11 % Default value: 0 Hz.
Daniel@0 12 % mirspectrum(...,'Max',ma) indicates the highest frequency taken into
Daniel@0 13 % consideration, expressed in Hz.
Daniel@0 14 % Default value: the maximal possible frequency, corresponding to
Daniel@0 15 % the sampling rate of x divided by 2.
Daniel@0 16 % mirspectrum(...,'Window',w): windowing method:
Daniel@0 17 % either w = 0 (no windowing) or any windowing function proposed
Daniel@0 18 % in the Signal Processing Toolbox (help window).
Daniel@0 19 % default value: w = 'hamming'
Daniel@0 20 %
Daniel@0 21 % mirspectrum(...,'Cents'): decomposes the energy in cents.
Daniel@0 22 % mirspectrum(...,'Collapsed'): collapses the spectrum into one
Daniel@0 23 % octave divided into 1200 cents.
Daniel@0 24 % Redistribution of the frequencies into bands:
Daniel@0 25 % mirspectrum(...,'Mel'): Mel bands.
Daniel@0 26 % (Requires the Auditory Toolbox.)
Daniel@0 27 % mirspectrum(...,'Bark'): Bark bands.
Daniel@0 28 % (Code based on Pampalk's MA toolbox).
Daniel@0 29 % If the audio signal was frame decomposed, the output s is a
Daniel@0 30 % band-decomposed spectrogram. It is then possible to compute
Daniel@0 31 % the spectrum of the temporal signal in each band,
Daniel@0 32 % using the following syntax:
Daniel@0 33 % mirspectrum(s,'AlongBands')
Daniel@0 34 % This corresponds to fluctuation (cf. mirfluctuation).
Daniel@0 35 % mirspectrum(...,'Mask'): Models masking phenomena in each band.
Daniel@0 36 % (Code based on Pampalk's MA toolbox).
Daniel@0 37 % mirspectrum(...,'Normal'): normalizes with respect to energy.
Daniel@0 38 % mirspectrum(...,'NormalInput'): input signal is normalized from 0 to 1.
Daniel@0 39 % mirspectrum(...,'Power'): squares the energy.
Daniel@0 40 % mirspectrum(...,'dB'): represents the spectrum energy in decibel scale.
Daniel@0 41 % mirspectrum(...,'dB',th): keeps only the highest energy over a
Daniel@0 42 % range of th dB.
Daniel@0 43 % mirspectrum(...,'Terhardt'): modulates the energy following
Daniel@0 44 % (Terhardt, 1979) outer ear model. (Code based on Pampalk's MA
Daniel@0 45 % toolbox).
Daniel@0 46 % mirspectrum(...,'Resonance',r): multiplies the spectrum with a
Daniel@0 47 % resonance curve. Possible value for r:
Daniel@0 48 % 'ToiviainenSnyder': highlights best perceived meter
Daniel@0 49 % (Toiviainen & Snyder 2003)
Daniel@0 50 % (default value for spectrum of envelopes)
Daniel@0 51 % 'Fluctuation': fluctuation strength (Fastl 1982)
Daniel@0 52 % (default value for spectrum of band channels)
Daniel@0 53 % mirspectrum(...,'Prod',m): Enhances components that have harmonics
Daniel@0 54 % located at multiples of range(s) m of the signal's fundamental
Daniel@0 55 % frequency. Computed by compressing the signal by the list of
Daniel@0 56 % factors m, and by multiplying all the results with the original
Daniel@0 57 % signa (Alonso et al, 2003).
Daniel@0 58 % mirspectrum(...,'Sum',s): Similar option using summation instead of
Daniel@0 59 % product.
Daniel@0 60 %
Daniel@0 61 % mirspectrum(...,'MinRes',mr): Indicates a minimal accepted
Daniel@0 62 % frequency resolution, in Hz. The audio signal is zero-padded in
Daniel@0 63 % order to reach the desired resolution.
Daniel@0 64 % If the 'Mel' option is toggled on, 'MinRes' is set by default
Daniel@0 65 % to 66 Hz.
Daniel@0 66 % mirspectrum(...,'MinRes',mr,'OctaveRatio',tol): Indicates the
Daniel@0 67 % minimal accepted resolution in terms of number of divisions of
Daniel@0 68 % the octave. Low frequencies are ignored in order to reach the
Daniel@0 69 % desired resolution.
Daniel@0 70 % The corresponding required frequency resolution is equal to
Daniel@0 71 % the difference between the first frequency bins, multiplied
Daniel@0 72 % by the constraining multiplicative factor tol (set by
Daniel@0 73 % default to .75).
Daniel@0 74 % mirspectrum(...,'Res',r): Indicates the required precise frequency
Daniel@0 75 % resolution, in Hz. The audio signal is zero-padded in order to
Daniel@0 76 % reach the desired resolution.
Daniel@0 77 % mirspectrum(...,'Length',l): Specifies the length of the FFT,
Daniel@0 78 % overriding the FFT length initially planned.
Daniel@0 79 % mirspectrum(...,'ZeroPad',s): Zero-padding of s samples.
Daniel@0 80 % mirspectrum(...,'WarningRes',s): Indicates a required frequency
Daniel@0 81 % resolution, in Hz, for the input signal. If the resolution does
Daniel@0 82 % not reach that prerequisite, a warning is displayed.
Daniel@0 83 % mirspectrum(...,'ConstantQ',nb): Carries out a Constant Q Transform
Daniel@0 84 % instead of a FFT, with a number of bins per octave fixed to nb.
Daniel@0 85 % Default value for nb: 12 bins per octave.
Daniel@0 86 %
Daniel@0 87 % mirspectrum(...,'Smooth',o): smooths the envelope using a movering
Daniel@0 88 % average of order o.
Daniel@0 89 % Default value when the option is toggled on: o=10
Daniel@0 90 % mirspectrum(...,'Gauss',o): smooths the envelope using a gaussian
Daniel@0 91 % of standard deviation o samples.
Daniel@0 92 % Default value when the option is toggled on: o=10
Daniel@0 93 % mirspectrum(...,'Phase',0): do not compute the FFT phase.
Daniel@0 94
Daniel@0 95 win.key = 'Window';
Daniel@0 96 win.type = 'String';
Daniel@0 97 win.default = 'hamming';
Daniel@0 98 option.win = win;
Daniel@0 99
Daniel@0 100 min.key = 'Min';
Daniel@0 101 min.type = 'Integer';
Daniel@0 102 min.default = 0;
Daniel@0 103 option.min = min;
Daniel@0 104
Daniel@0 105 max.key = 'Max';
Daniel@0 106 max.type = 'Integer';
Daniel@0 107 max.default = Inf;
Daniel@0 108 option.max = max;
Daniel@0 109
Daniel@0 110 mr.key = 'MinRes';
Daniel@0 111 mr.type = 'Integer';
Daniel@0 112 mr.default = 0;
Daniel@0 113 option.mr = mr;
Daniel@0 114
Daniel@0 115 res.key = 'Res';
Daniel@0 116 res.type = 'Integer';
Daniel@0 117 res.default = NaN;
Daniel@0 118 option.res = res;
Daniel@0 119
Daniel@0 120 length.key = 'Length';
Daniel@0 121 length.type = 'Integer';
Daniel@0 122 length.default = NaN;
Daniel@0 123 option.length = length;
Daniel@0 124
Daniel@0 125 zp.key = 'ZeroPad';
Daniel@0 126 zp.type = 'Integer';
Daniel@0 127 zp.default = 0;
Daniel@0 128 zp.keydefault = Inf;
Daniel@0 129 option.zp = zp;
Daniel@0 130
Daniel@0 131 wr.key = 'WarningRes';
Daniel@0 132 wr.type = 'Integer';
Daniel@0 133 wr.default = 0;
Daniel@0 134 option.wr = wr;
Daniel@0 135
Daniel@0 136 octave.key = 'OctaveRatio';
Daniel@0 137 octave.type = 'Boolean';
Daniel@0 138 octave.default = 0;
Daniel@0 139 option.octave = octave;
Daniel@0 140
Daniel@0 141 constq.key = 'ConstantQ';
Daniel@0 142 constq.type = 'Integer';
Daniel@0 143 constq.default = 0;
Daniel@0 144 constq.keydefault = 12;
Daniel@0 145 option.constq = constq;
Daniel@0 146
Daniel@0 147 alongbands.key = 'AlongBands';
Daniel@0 148 alongbands.type = 'Boolean';
Daniel@0 149 alongbands.default = 0;
Daniel@0 150 option.alongbands = alongbands;
Daniel@0 151
Daniel@0 152 ni.key = 'NormalInput';
Daniel@0 153 ni.type = 'Boolean';
Daniel@0 154 ni.default = 0;
Daniel@0 155 option.ni = ni;
Daniel@0 156
Daniel@0 157 norm.key = 'Normal';
Daniel@0 158 norm.type = 'Integer';
Daniel@0 159 norm.default = 0;
Daniel@0 160 norm.keydefault = 1;
Daniel@0 161 norm.when = 'After';
Daniel@0 162 option.norm = norm;
Daniel@0 163
Daniel@0 164 band.type = 'String';
Daniel@0 165 band.choice = {'Freq','Mel','Bark','Cents'};
Daniel@0 166 band.default = 'Freq';
Daniel@0 167 band.when = 'Both';
Daniel@0 168 option.band = band;
Daniel@0 169
Daniel@0 170 nbbands.key = 'Bands';
Daniel@0 171 nbbands.type = 'Integer';
Daniel@0 172 nbbands.default = 0;
Daniel@0 173 nbbands.when = 'After';
Daniel@0 174 option.nbbands = nbbands;
Daniel@0 175
Daniel@0 176 mprod.key = 'Prod';
Daniel@0 177 mprod.type = 'Integers';
Daniel@0 178 mprod.default = [];
Daniel@0 179 mprod.keydefault = 2:6;
Daniel@0 180 mprod.when = 'After';
Daniel@0 181 option.mprod = mprod;
Daniel@0 182
Daniel@0 183 msum.key = 'Sum';
Daniel@0 184 msum.type = 'Integers';
Daniel@0 185 msum.default = [];
Daniel@0 186 msum.keydefault = 2:6;
Daniel@0 187 msum.when = 'After';
Daniel@0 188 option.msum = msum;
Daniel@0 189
Daniel@0 190 reso.key = 'Resonance';
Daniel@0 191 reso.type = 'String';
Daniel@0 192 reso.choice = {'ToiviainenSnyder','Fluctuation','Meter',0,'no','off'};
Daniel@0 193 reso.default = 0;
Daniel@0 194 reso.when = 'After';
Daniel@0 195 option.reso = reso;
Daniel@0 196
Daniel@0 197 log.key = 'log';
Daniel@0 198 log.type = 'Boolean';
Daniel@0 199 log.default = 0;
Daniel@0 200 log.when = 'After';
Daniel@0 201 option.log = log;
Daniel@0 202
Daniel@0 203 db.key = 'dB';
Daniel@0 204 db.type = 'Integer';
Daniel@0 205 db.default = 0;
Daniel@0 206 db.keydefault = Inf;
Daniel@0 207 db.when = 'After';
Daniel@0 208 option.db = db;
Daniel@0 209
Daniel@0 210 pow.key = 'Power';
Daniel@0 211 pow.type = 'Boolean';
Daniel@0 212 pow.default = 0;
Daniel@0 213 pow.when = 'After';
Daniel@0 214 option.pow = pow;
Daniel@0 215
Daniel@0 216 terhardt.key = 'Terhardt';
Daniel@0 217 terhardt.type = 'Boolean';
Daniel@0 218 terhardt.default = 0;
Daniel@0 219 terhardt.when = 'After';
Daniel@0 220 option.terhardt = terhardt;
Daniel@0 221
Daniel@0 222 mask.key = 'Mask';
Daniel@0 223 mask.type = 'Boolean';
Daniel@0 224 mask.default = 0;
Daniel@0 225 mask.when = 'After';
Daniel@0 226 option.mask = mask;
Daniel@0 227
Daniel@0 228 % e.key = 'Enhanced';
Daniel@0 229 % e.type = 'Integer';
Daniel@0 230 % e.default = [];
Daniel@0 231 % e.keydefault = 2:10;
Daniel@0 232 % e.when = 'After';
Daniel@0 233 %option.e = e;
Daniel@0 234
Daniel@0 235 collapsed.key = 'Collapsed';
Daniel@0 236 collapsed.type = 'Boolean';
Daniel@0 237 collapsed.default = 0;
Daniel@0 238 collapsed.when = 'Both';
Daniel@0 239 option.collapsed = collapsed;
Daniel@0 240
Daniel@0 241 aver.key = 'Smooth';
Daniel@0 242 aver.type = 'Integer';
Daniel@0 243 aver.default = 0;
Daniel@0 244 aver.keydefault = 10;
Daniel@0 245 aver.when = 'After';
Daniel@0 246 option.aver = aver;
Daniel@0 247
Daniel@0 248 gauss.key = 'Gauss';
Daniel@0 249 gauss.type = 'Integer';
Daniel@0 250 gauss.default = 0;
Daniel@0 251 gauss.keydefault = 10;
Daniel@0 252 gauss.when = 'After';
Daniel@0 253 option.gauss = gauss;
Daniel@0 254
Daniel@0 255 rapid.key = 'Rapid';
Daniel@0 256 rapid.type = 'Boolean';
Daniel@0 257 rapid.default = 0;
Daniel@0 258 option.rapid = rapid;
Daniel@0 259
Daniel@0 260 phase.key = 'Phase';
Daniel@0 261 phase.type = 'Boolean';
Daniel@0 262 phase.default = 1;
Daniel@0 263 option.phase = phase;
Daniel@0 264
Daniel@0 265 specif.option = option;
Daniel@0 266
Daniel@0 267 specif.defaultframelength = 0.05;
Daniel@0 268 specif.defaultframehop = 0.5;
Daniel@0 269
Daniel@0 270 specif.eachchunk = @eachchunk;
Daniel@0 271 specif.combinechunk = @combinechunk;
Daniel@0 272
Daniel@0 273 if isamir(orig,'mirscalar') || isamir(orig,'mirenvelope')
Daniel@0 274 specif.nochunk = 1;
Daniel@0 275 end
Daniel@0 276
Daniel@0 277 varargout = mirfunction(@mirspectrum,orig,varargin,nargout,specif,@init,@main);
Daniel@0 278
Daniel@0 279
Daniel@0 280 function [x type] = init(x,option)
Daniel@0 281 type = 'mirspectrum';
Daniel@0 282
Daniel@0 283
Daniel@0 284 function s = main(orig,option,postoption)
Daniel@0 285 if isstruct(option)
Daniel@0 286 if option.collapsed
Daniel@0 287 option.band = 'Cents';
Daniel@0 288 end
Daniel@0 289 if isnan(option.res) && strcmpi(option.band,'Cents') && option.min
Daniel@0 290 option.res = option.min *(2^(1/1200)-1)*.9;
Daniel@0 291 end
Daniel@0 292 end
Daniel@0 293 if not(isempty(postoption))
Daniel@0 294 if not(strcmpi(postoption.band,'Freq') && isempty(postoption.msum) ...
Daniel@0 295 || isempty(postoption.mprod)) || postoption.log || postoption.db ...
Daniel@0 296 || postoption.pow || postoption.mask || postoption.collapsed ...
Daniel@0 297 || postoption.aver || postoption.gauss
Daniel@0 298 option.phase = 0;
Daniel@0 299 end
Daniel@0 300 end
Daniel@0 301 if iscell(orig)
Daniel@0 302 orig = orig{1};
Daniel@0 303 end
Daniel@0 304 if isa(orig,'mirspectrum') && ...
Daniel@0 305 not(isfield(option,'alongbands') && option.alongbands)
Daniel@0 306 s = orig;
Daniel@0 307 if isfield(option,'min') && ...
Daniel@0 308 (option.min || iscell(option.max) || option.max < Inf)
Daniel@0 309 magn = get(s,'Magnitude');
Daniel@0 310 freq = get(s,'Frequency');
Daniel@0 311 for k = 1:length(magn)
Daniel@0 312 m = magn{k};
Daniel@0 313 f = freq{k};
Daniel@0 314 if iscell(option.max)
Daniel@0 315 mi = option.min{k};
Daniel@0 316 ma = option.max{k};
Daniel@0 317 else
Daniel@0 318 mi = option.min;
Daniel@0 319 ma = option.max;
Daniel@0 320 end
Daniel@0 321 if not(iscell(m))
Daniel@0 322 m = {m};
Daniel@0 323 f = {f};
Daniel@0 324 end
Daniel@0 325 for l = 1:length(m)
Daniel@0 326 range = find(and(f{l}(:,1) >= mi,f{l}(:,1) <= ma));
Daniel@0 327 m{l} = m{l}(range,:,:);
Daniel@0 328 f{l} = f{l}(range,:,:);
Daniel@0 329 end
Daniel@0 330 magn{k} = m;
Daniel@0 331 freq{k} = f;
Daniel@0 332 end
Daniel@0 333 s = set(s,'Magnitude',magn,'Frequency',freq);
Daniel@0 334 end
Daniel@0 335 if not(isempty(postoption)) && not(isequal(postoption,0))
Daniel@0 336 s = post(s,postoption);
Daniel@0 337 end
Daniel@0 338 elseif ischar(orig)
Daniel@0 339 s = mirspectrum(miraudio(orig),option,postoption);
Daniel@0 340 else
Daniel@0 341 if nargin == 0
Daniel@0 342 orig = [];
Daniel@0 343 end
Daniel@0 344 s.phase = [];
Daniel@0 345 s.log = 0;
Daniel@0 346 s.xscale = 'Freq';
Daniel@0 347 s.pow = 1;
Daniel@0 348 s = class(s,'mirspectrum',mirdata(orig));
Daniel@0 349 s = purgedata(s);
Daniel@0 350 s = set(s,'Title','Spectrum','Abs','frequency (Hz)','Ord','magnitude');
Daniel@0 351 %disp('Computing spectrum...')
Daniel@0 352 sig = get(orig,'Data');
Daniel@0 353 t = get(orig,'Pos');
Daniel@0 354 if isempty(t)
Daniel@0 355 t = get(orig,'FramePos');
Daniel@0 356 for k = 1:length(sig)
Daniel@0 357 for l = 1:length(sig{k})
Daniel@0 358 sig{k}{l} = sig{k}{l}';
Daniel@0 359 t{k}{l} = t{k}{l}(1,:,:)';
Daniel@0 360 end
Daniel@0 361 end
Daniel@0 362 end
Daniel@0 363 fs = get(orig,'Sampling');
Daniel@0 364 fp = get(orig,'FramePos');
Daniel@0 365 m = cell(1,length(sig));
Daniel@0 366 p = cell(1,length(sig));
Daniel@0 367 f = cell(1,length(sig));
Daniel@0 368 for i = 1:length(sig)
Daniel@0 369 d = sig{i};
Daniel@0 370 fpi = fp{i};
Daniel@0 371 if not(iscell(d))
Daniel@0 372 d = {d};
Daniel@0 373 end
Daniel@0 374 if option.alongbands
Daniel@0 375 fsi = 1 / (fpi{1}(1,2) - fpi{1}(1,1));
Daniel@0 376 else
Daniel@0 377 fsi = fs{i};
Daniel@0 378 end
Daniel@0 379 mi = cell(1,length(d));
Daniel@0 380 phi = cell(1,length(d));
Daniel@0 381 fi = cell(1,length(d));
Daniel@0 382 for J = 1:length(d)
Daniel@0 383 dj = d{J};
Daniel@0 384 if option.ni
Daniel@0 385 mxdj = repmat(max(dj),[size(dj,1),1,1]);
Daniel@0 386 mndj = repmat(min(dj),[size(dj,1),1,1]);
Daniel@0 387 dj = (dj-mndj)./(mxdj-mndj);
Daniel@0 388 end
Daniel@0 389 if option.alongbands
Daniel@0 390 if size(dj,1)>1
Daniel@0 391 error('ERROR IN MIRSPECTRUM: ''AlongBands'' is restricted to spectrum decomposed into bands, such as ''Mel'' and ''Bark''.')
Daniel@0 392 end
Daniel@0 393 dj = reshape(dj,[size(dj,2),1,size(dj,3)]);
Daniel@0 394 fp{i}{J} = fp{i}{J}([1;end]);
Daniel@0 395 end
Daniel@0 396
Daniel@0 397 if option.constq
Daniel@0 398 % Constant Q Transform
Daniel@0 399 r = 2^(1/option.constq);
Daniel@0 400 Q = 1 / (r - 1);
Daniel@0 401 f_max = min(fsi/2,option.max);
Daniel@0 402 f_min = option.min;
Daniel@0 403 if not(f_min)
Daniel@0 404 f_min = 16.3516;
Daniel@0 405 end
Daniel@0 406 B = floor(log(f_max/f_min) / log(r)); % number of bins
Daniel@0 407 N0 = round(Q*fsi/f_min); % maximum Nkcq
Daniel@0 408 j2piQn = -j*2*pi*Q*(0:N0-1)';
Daniel@0 409
Daniel@0 410 fj = f_min * r.^(0:B-1)';
Daniel@0 411 transf = NaN(B,size(dj,2),size(dj,3));
Daniel@0 412 for kcq = 1:B
Daniel@0 413 Nkcq = round(Q*fsi/fj(kcq));
Daniel@0 414 win = mirwindow(dj,option.win,Nkcq);
Daniel@0 415 exq = repmat(exp(j2piQn(1:Nkcq)/Nkcq),...
Daniel@0 416 [1,size(win,2),size(win,3)]);
Daniel@0 417 transf(kcq,:) = sum(win.* exq) / Nkcq;
Daniel@0 418 end
Daniel@0 419 else
Daniel@0 420 % FFT
Daniel@0 421 dj = mirwindow(dj,option.win);
Daniel@0 422 if option.zp
Daniel@0 423 if option.zp < Inf
Daniel@0 424 dj = [dj;zeros(option.zp,size(dj,2),size(dj,3))];
Daniel@0 425 else
Daniel@0 426 dj = [dj;zeros(size(dj))];
Daniel@0 427 end
Daniel@0 428 end
Daniel@0 429 if isstruct(postoption)
Daniel@0 430 if strcmpi(postoption.band,'Mel') && ...
Daniel@0 431 (not(option.mr) || option.mr > 66)
Daniel@0 432 option.mr = 66;
Daniel@0 433 end
Daniel@0 434 else
Daniel@0 435 %warning('WARNING in MIRSPECTRUM (for debugging purposes): By default, minimum resolution specified.')
Daniel@0 436 if not(option.mr)
Daniel@0 437 option.mr = 66;
Daniel@0 438 end
Daniel@0 439 end
Daniel@0 440 if option.octave
Daniel@0 441 N = size(dj,1);
Daniel@0 442 res = (2.^(1/option.mr)-1)*option.octave;
Daniel@0 443 % Minimal freq ratio between 2 first bins.
Daniel@0 444 % freq resolution should be > option.min * res
Daniel@0 445 Nrec = fsi/(option.min*res);
Daniel@0 446 % Recommended minimal sample length.
Daniel@0 447 if Nrec > N
Daniel@0 448 % If actual sample length is too small.
Daniel@0 449 option.min = fsi/N / res;
Daniel@0 450 warning('WARNING IN MIRSPECTRUM: The input signal is too short to obtain the desired octave resolution. Lowest frequencies will be ignored.');
Daniel@0 451 display(['(The recommended minimal input signal length would be ' num2str(Nrec/fsi) ' s.)']);
Daniel@0 452 display(['New low frequency range: ' num2str(option.min) ' Hz.']);
Daniel@0 453 end
Daniel@0 454 N = 2^nextpow2(N);
Daniel@0 455 elseif isnan(option.length)
Daniel@0 456 if isnan(option.res)
Daniel@0 457 N = size(dj,1);
Daniel@0 458 if option.mr && N < fsi/option.mr
Daniel@0 459 if option.wr && N < fsi/option.wr
Daniel@0 460 warning('WARNING IN MIRSPECTRUM: The input signal is too short to obtain the desired frequency resolution. Performed zero-padding will not guarantee the quality of the results.');
Daniel@0 461 end
Daniel@0 462 N = max(N,fsi/option.mr);
Daniel@0 463 end
Daniel@0 464 N = 2^nextpow2(N);
Daniel@0 465 else
Daniel@0 466 N = ceil(fsi/option.res);
Daniel@0 467 end
Daniel@0 468 else
Daniel@0 469 N = option.length;
Daniel@0 470 end
Daniel@0 471
Daniel@0 472 % Here is the spectrum computation itself
Daniel@0 473 transf = fft(dj,N);
Daniel@0 474
Daniel@0 475 len = ceil(size(transf,1)/2);
Daniel@0 476 fj = fsi/2 * linspace(0,1,len)';
Daniel@0 477 if option.max
Daniel@0 478 maxf = find(fj>=option.max,1);
Daniel@0 479 if isempty(maxf)
Daniel@0 480 maxf = len;
Daniel@0 481 end
Daniel@0 482 else
Daniel@0 483 maxf = len;
Daniel@0 484 end
Daniel@0 485 if option.min
Daniel@0 486 minf = find(fj>=option.min,1);
Daniel@0 487 if isempty(minf)
Daniel@0 488 maxf = len;
Daniel@0 489 end
Daniel@0 490 else
Daniel@0 491 minf = 1;
Daniel@0 492 end
Daniel@0 493
Daniel@0 494 transf = transf(minf:maxf,:,:);
Daniel@0 495 fj = fj(minf:maxf);
Daniel@0 496 end
Daniel@0 497
Daniel@0 498 mi{J} = abs(transf);
Daniel@0 499 if option.phase
Daniel@0 500 phi{J} = angle(transf);
Daniel@0 501 end
Daniel@0 502 fi{J} = repmat(fj,[1,size(transf,2),size(transf,3)]);
Daniel@0 503 end
Daniel@0 504 if iscell(sig{i})
Daniel@0 505 m{i} = mi;
Daniel@0 506 p{i} = phi;
Daniel@0 507 f{i} = fi;
Daniel@0 508 else
Daniel@0 509 m{i} = mi{1};
Daniel@0 510 p{i} = phi{1};
Daniel@0 511 f{i} = fi{1};
Daniel@0 512 end
Daniel@0 513 end
Daniel@0 514 s = set(s,'Frequency',f,'Magnitude',m,'Phase',p,'FramePos',fp);
Daniel@0 515 if not(isempty(postoption)) && isstruct(postoption)
Daniel@0 516 s = post(s,postoption);
Daniel@0 517 end
Daniel@0 518 end
Daniel@0 519
Daniel@0 520
Daniel@0 521 function s = post(s,option)
Daniel@0 522 if option.collapsed
Daniel@0 523 option.band = 'Cents';
Daniel@0 524 end
Daniel@0 525 m = get(s,'Magnitude');
Daniel@0 526 f = get(s,'Frequency');
Daniel@0 527 for k = 1:length(m)
Daniel@0 528 if not(iscell(m{k}))
Daniel@0 529 m{k} = {m{k}};
Daniel@0 530 f{k} = {f{k}};
Daniel@0 531 end
Daniel@0 532 end
Daniel@0 533 if get(s,'Power') == 1 && ...
Daniel@0 534 (option.pow || any(option.mprod) || any(option.msum))
Daniel@0 535 for h = 1:length(m)
Daniel@0 536 for l = 1:length(m{k})
Daniel@0 537 m{h}{l} = m{h}{l}.^2;
Daniel@0 538 end
Daniel@0 539 end
Daniel@0 540 s = set(s,'Power',2,'Title',['Power ',get(s,'Title')]);
Daniel@0 541 end
Daniel@0 542 if any(option.mprod)
Daniel@0 543 for h = 1:length(m)
Daniel@0 544 for l = 1:length(m{k})
Daniel@0 545 z0 = m{h}{l};
Daniel@0 546 z1 = z0;
Daniel@0 547 for k = 1:length(option.mprod)
Daniel@0 548 mpr = option.mprod(k);
Daniel@0 549 if mpr
Daniel@0 550 zi = ones(size(z0));
Daniel@0 551 zi(1:floor(end/mpr),:,:) = z0(mpr:mpr:end,:,:);
Daniel@0 552 z1 = z1.*zi;
Daniel@0 553 end
Daniel@0 554 end
Daniel@0 555 m{h}{l} = z1;
Daniel@0 556 end
Daniel@0 557 end
Daniel@0 558 s = set(s,'Title','Spectral product');
Daniel@0 559 end
Daniel@0 560 if any(option.msum)
Daniel@0 561 for h = 1:length(m)
Daniel@0 562 for l = 1:length(m{k})
Daniel@0 563 z0 = m{h}{l};
Daniel@0 564 z1 = z0;
Daniel@0 565 for k = 1:length(option.msum)
Daniel@0 566 mpr = option.msum(k);
Daniel@0 567 if mpr
Daniel@0 568 zi = ones(size(z0));
Daniel@0 569 zi(1:floor(end/mpr),:,:) = z0(mpr:mpr:end,:,:);
Daniel@0 570 z1 = z1+zi;
Daniel@0 571 end
Daniel@0 572 end
Daniel@0 573 m{h}{l} = z1;
Daniel@0 574 end
Daniel@0 575 end
Daniel@0 576 s = set(s,'Title','Spectral sum');
Daniel@0 577 end
Daniel@0 578 %for i = option.e % Enhancing procedure %%%% TO CHECK, t IS NOT DEFINED!
Daniel@0 579 % for h = 1:length(m)
Daniel@0 580 % for l = 1:length(m{k})
Daniel@0 581 % c = m{h}{l};
Daniel@0 582 % % option.e is the list of scaling factors
Daniel@0 583 % % i is the scaling factor
Daniel@0 584 % if i
Daniel@0 585 % ic = zeros(size(c));
Daniel@0 586 % for g = 1:size(c,2)
Daniel@0 587 % for h2 = 1:size(c,3)
Daniel@0 588 % beg = find(t(:,g,h2)/i >= t(1,g,h2))
Daniel@0 589 % if not(isempty(beg))
Daniel@0 590 % ic(:,g,h2) = interp1(t(:,g,h2),c(:,g,h2),t(:,g,h2)/i); %,'cubic');
Daniel@0 591 % The scaled autocorrelation
Daniel@0 592 % ic(1:beg(1)-1,g,h2) = 0;
Daniel@0 593 % end
Daniel@0 594 % end
Daniel@0 595 % end
Daniel@0 596 % ic(find(isnan(ic))) = Inf; % All the NaN values are changed into 0 in the resulting curve
Daniel@0 597 % ic = max(ic,0);
Daniel@0 598 % c = c - ic; % The scaled autocorrelation is substracted to the initial one
Daniel@0 599 % c = max(c,0); % Half-wave rectification
Daniel@0 600 %figure
Daniel@0 601 %plot(c)
Daniel@0 602 % end
Daniel@0 603 % end
Daniel@0 604 % end
Daniel@0 605 %end
Daniel@0 606 if option.norm
Daniel@0 607 for k = 1:length(m)
Daniel@0 608 for l = 1:length(m{k})
Daniel@0 609 mkl = m{k}{l};
Daniel@0 610 nkl = zeros(1,size(mkl,2),size(mkl,3));
Daniel@0 611 for kk = 1:size(mkl,2)
Daniel@0 612 for ll = 1:size(mkl,3)
Daniel@0 613 nkl(1,kk,l) = norm(mkl(:,kk,ll));
Daniel@0 614 end
Daniel@0 615 end
Daniel@0 616 m{k}{l} = mkl./repmat(nkl,[size(m{k}{k},1),1,1]);
Daniel@0 617 end
Daniel@0 618 end
Daniel@0 619 end
Daniel@0 620 if option.terhardt && not(isempty(find(f{1}{1}))) % This excludes the case where spectrum already along bands
Daniel@0 621 % Code taken from Pampalk's MA Toolbox
Daniel@0 622 for h = 1:length(m)
Daniel@0 623 for l = 1:length(m{k})
Daniel@0 624 W_Adb = zeros(size(f{k}{l}));
Daniel@0 625 W_Adb(2:size(f{k}{l},1),:,:) = ...
Daniel@0 626 + 10.^((-3.64*(f{k}{l}(2:end,:,:)/1000).^-0.8 ...
Daniel@0 627 + 6.5 * exp(-0.6 * (f{k}{l}(2:end,:,:)/1000 - 3.3).^2) ...
Daniel@0 628 - 0.001*(f{k}{l}(2:end,:,:)/1000).^4)/20);
Daniel@0 629 W_Adb = W_Adb.^2;
Daniel@0 630 m{h}{l} = m{h}{l}.*W_Adb;
Daniel@0 631 end
Daniel@0 632 end
Daniel@0 633 end
Daniel@0 634 if option.reso
Daniel@0 635 if not(ischar(option.reso))
Daniel@0 636 if strcmp(get(orig,'XScale'),'Mel')
Daniel@0 637 option.reso = 'Fluctuation';
Daniel@0 638 else
Daniel@0 639 option.reso = 'ToiviainenSnyder';
Daniel@0 640 end
Daniel@0 641 end
Daniel@0 642 %if strcmpi(option.reso,'ToiviainenSnyder') || ...
Daniel@0 643 % strcmpi(option.reso,'Meter') || ...
Daniel@0 644 % strcmpi(option.reso,'Fluctuation')
Daniel@0 645 for k = 1:length(m)
Daniel@0 646 for l = 1:length(m{k})
Daniel@0 647 if strcmpi(option.reso,'ToiviainenSnyder') || strcmpi(option.reso,'Meter')
Daniel@0 648 w = max(0,...
Daniel@0 649 1 - 0.25*(log2(max(1./max(f{k}{l},1e-12),1e-12)/0.5)).^2);
Daniel@0 650 elseif strcmpi(option.reso,'Fluctuation')
Daniel@0 651 w1 = f{k}{l} / 4; % ascending part of the fluctuation curve;
Daniel@0 652 w2 = 1 - 0.3 * (f{k}{l} - 4)/6; % descending part;
Daniel@0 653 w = min(w1,w2);
Daniel@0 654 end
Daniel@0 655 if max(w) == 0
Daniel@0 656 warning('The resonance curve, not defined for this range of delays, will not be applied.')
Daniel@0 657 else
Daniel@0 658 m{k}{l} = m{k}{l}.* w;
Daniel@0 659 end
Daniel@0 660 end
Daniel@0 661 end
Daniel@0 662 end
Daniel@0 663 if strcmp(s.xscale,'Freq')
Daniel@0 664 if strcmpi(option.band,'Mel')
Daniel@0 665 % The following is largely based on the source code from Auditory Toolbox
Daniel@0 666 % (A part that I could not call directly from MIRtoolbox)
Daniel@0 667
Daniel@0 668 % (Malcolm Slaney, August 1993, (c) 1998 Interval Research Corporation)
Daniel@0 669
Daniel@0 670 try
Daniel@0 671 MakeERBFilters(1,1,1); % Just to be sure that the Auditory Toolbox is installed
Daniel@0 672 catch
Daniel@0 673 error('ERROR IN MIRFILTERBANK: Auditory Toolbox needs to be installed.');
Daniel@0 674 end
Daniel@0 675
Daniel@0 676 %disp('Computing Mel-frequency spectral representation...')
Daniel@0 677 lowestFrequency = 133.3333;
Daniel@0 678 if not(option.nbbands)
Daniel@0 679 option.nbbands = 40;
Daniel@0 680 end
Daniel@0 681 linearFilters = min(13,option.nbbands);
Daniel@0 682 linearSpacing = 66.66666666;
Daniel@0 683 logFilters = option.nbbands - linearFilters;
Daniel@0 684 logSpacing = 1.0711703;
Daniel@0 685 totalFilters = option.nbbands;
Daniel@0 686
Daniel@0 687 % Figure the band edges. Interesting frequencies are spaced
Daniel@0 688 % by linearSpacing for a while, then go logarithmic. First figure
Daniel@0 689 % all the interesting frequencies. Lower, center, and upper band
Daniel@0 690 % edges are all consequtive interesting frequencies.
Daniel@0 691 freqs = lowestFrequency + (0:linearFilters-1)*linearSpacing;
Daniel@0 692 freqs(linearFilters+1:totalFilters+2) = ...
Daniel@0 693 freqs(linearFilters) * logSpacing.^(1:logFilters+2);
Daniel@0 694 lower = freqs(1:totalFilters);
Daniel@0 695 center = freqs(2:totalFilters+1);
Daniel@0 696 upper = freqs(3:totalFilters+2);
Daniel@0 697
Daniel@0 698 % Figure out the height of the triangle so that each filter has
Daniel@0 699 % unit weight, assuming a triangular weighting function.
Daniel@0 700 triangleHeight = 2./(upper-lower);
Daniel@0 701
Daniel@0 702 e = cell(1,length(m));
Daniel@0 703 nch = cell(1,length(m));
Daniel@0 704 for h = 1:length(m)
Daniel@0 705 e{h} = cell(1,length(m{h}));
Daniel@0 706 for i = 1:length(m{h})
Daniel@0 707 mi = m{h}{i};
Daniel@0 708 fi = f{h}{i}(:,1,1);
Daniel@0 709 fftSize = size(fi,1);
Daniel@0 710
Daniel@0 711 % We now want to combine FFT bins and figure out
Daniel@0 712 % each frequencies contribution
Daniel@0 713 mfccFilterWeights = zeros(totalFilters,fftSize);
Daniel@0 714 for chan=1:totalFilters
Daniel@0 715 mfccFilterWeights(chan,:) = triangleHeight(chan).*...
Daniel@0 716 ((fi > lower(chan) & fi <= center(chan)).* ...
Daniel@0 717 (fi-lower(chan))/(center(chan)-lower(chan)) + ...
Daniel@0 718 (fi > center(chan) & fi < upper(chan)).* ...
Daniel@0 719 (upper(chan)-fi)/(upper(chan)-center(chan)));
Daniel@0 720 end
Daniel@0 721 if find(diff(not(sum(mfccFilterWeights,2)))==-1)
Daniel@0 722 % If one channel has no weight whereas the higher one
Daniel@0 723 % has a positive weight.
Daniel@0 724 warning('WARNING in MIRSPECTRUM: The frequency resolution of the spectrum is too low for the Mel transformation. Some Mel components are undefined.')
Daniel@0 725 display('Recommended frequency resolution: at least 66 Hz.')
Daniel@0 726 end
Daniel@0 727 e{h}{i} = zeros(1,size(mi,2),totalFilters);
Daniel@0 728 for J = 1:size(mi,2)
Daniel@0 729 if max(mi(:,J)) > 0
Daniel@0 730 fftData = zeros(fftSize,1); % Zero-padding ?
Daniel@0 731 fftData(1:size(mi,1)) = mi(:,J);
Daniel@0 732 p = mfccFilterWeights * fftData + 1e-16;
Daniel@0 733 e{h}{i}(1,J,:) = reshape(p,[1,1,length(p)]);
Daniel@0 734 end
Daniel@0 735 end
Daniel@0 736 f{h}{i} = zeros(1,size(mi,2),totalFilters);
Daniel@0 737 end
Daniel@0 738 nch{h} = (1:totalFilters)';
Daniel@0 739 end
Daniel@0 740 m = e;
Daniel@0 741 s = set(s,'XScale','Mel','Title','Mel-Spectrum','Abs','Mel bands','Channels',nch);
Daniel@0 742 elseif strcmpi(option.band,'Bark')
Daniel@0 743 sr = get(s,'Sampling');
Daniel@0 744 % Code taken from Pampalk's MA Toolbox.
Daniel@0 745 %% zwicker & fastl: psychoacoustics 1999, page 159
Daniel@0 746 bark_upper = [10 20 30 40 51 63 77 92 108 127 148 172 200 232 270 315 370 440 530 640 770 950 1200 1550]*10; %% Hz
Daniel@0 747 e = cell(1,length(m));
Daniel@0 748 nch = cell(1,length(m));
Daniel@0 749 for h = 1:length(m)
Daniel@0 750 %% ignore critical bands outside of sampling rate range
Daniel@0 751 cb = min(min([find(bark_upper>sr{h}/2),length(bark_upper)]),length(bark_upper));
Daniel@0 752 e{h} = cell(1,length(m{h}));
Daniel@0 753 for i = 1:length(m{h})
Daniel@0 754 mi = sum(m{h}{i},3);
Daniel@0 755 e{h}{i} = zeros(1,size(mi,2),cb);
Daniel@0 756 k = 1;
Daniel@0 757 for J=1:cb, %% group into bark bands
Daniel@0 758 idx = find(f{h}{i}(k:end,1,1)<=bark_upper(J));
Daniel@0 759 idx = idx + k-1;
Daniel@0 760 e{h}{i}(1,:,J) = sum(mi(idx,:,:),1);
Daniel@0 761 k = max(idx)+1;
Daniel@0 762 end
Daniel@0 763 f{h}{i} = zeros(1,size(mi,2),cb);
Daniel@0 764 end
Daniel@0 765 nch{h} = (1:length(bark_upper))';
Daniel@0 766 end
Daniel@0 767 m = e;
Daniel@0 768 s = set(s,'XScale','Bark','Title','Bark-Spectrum','Abs','Bark bands','Channels',nch);
Daniel@0 769 elseif strcmpi(option.band,'Cents') || option.collapsed
Daniel@0 770 for h = 1:length(m)
Daniel@0 771 for i = 1:length(m{h})
Daniel@0 772 mi = m{h}{i};
Daniel@0 773 fi = f{h}{i};
Daniel@0 774 isgood = fi(:,1,1)*(2^(1/1200)-1) >= fi(2,1,1)-fi(1,1,1);
Daniel@0 775 good = find(isgood);
Daniel@0 776 if isempty(good)
Daniel@0 777 mirerror('mirspectrum',...
Daniel@0 778 'The frequency resolution of the spectrum is too low to be decomposed into cents.');
Daniel@0 779 display('Hint: if you specify a minimum value for the frequency range (''Min'' option)');
Daniel@0 780 display(' and if you do not specify any frequency resolution (''Res'' option), ');
Daniel@0 781 display(' the correct frequency resolution will be automatically chosen.');
Daniel@0 782 end
Daniel@0 783 if good>1
Daniel@0 784 warning(['MIRSPECTRUM: Frequency resolution in cent is achieved for frequencies over ',...
Daniel@0 785 num2str(floor(fi(good(1)))),' Hz. Lower frequencies are ignored.'])
Daniel@0 786 display('Hint: if you specify a minimum value for the frequency range (''Min'' option)');
Daniel@0 787 display(' and if you do not specify any frequency resolution (''Res'' option), ');
Daniel@0 788 display(' the correct frequency resolution will be automatically chosen.');
Daniel@0 789 end
Daniel@0 790 fi = fi(good,:,:);
Daniel@0 791 mi = mi(good,:,:);
Daniel@0 792 f2cents = 440*2.^(1/1200*(-1200*10:1200*10-1)');
Daniel@0 793 % The frequencies corresponding to the cent range
Daniel@0 794 cents = repmat((0:1199)',[20,size(fi,2),size(fi,3)]);
Daniel@0 795 % The cent range is for the moment centered to A440
Daniel@0 796 octaves = ones(1200,1)*(-10:10);
Daniel@0 797 octaves = repmat(octaves(:),[1,size(fi,2),size(fi,3)]);
Daniel@0 798 select = find(f2cents>fi(1) & f2cents<fi(end));
Daniel@0 799 % Cent range actually used in the current spectrum
Daniel@0 800 f2cents = repmat(f2cents(select),[1,size(fi,2),size(fi,3)]);
Daniel@0 801 cents = repmat(cents(select),[1,size(fi,2),size(fi,3)]);
Daniel@0 802 octaves = repmat(octaves(select),[1,size(fi,2),size(fi,3)]);
Daniel@0 803 m{h}{i} = interp1(fi(:,1,1),mi,f2cents(:,1,1));
Daniel@0 804 f{h}{i} = octaves*1200+cents + 6900;
Daniel@0 805 % Now the cent range is expressed in midicent
Daniel@0 806 end
Daniel@0 807 end
Daniel@0 808 s = set(s,'Abs','pitch (in midicents)','XScale','Cents');
Daniel@0 809 end
Daniel@0 810 end
Daniel@0 811 if option.mask
Daniel@0 812 if strcmp(s.xscale,'Freq')
Daniel@0 813 warning('WARNING IN MIRSPECTRUM: ''Mask'' option available only for Mel-spectrum and Bark-spectrum.');
Daniel@0 814 disp('''Mask'' option ignored');
Daniel@0 815 else
Daniel@0 816 nch = get(s,'Channels');
Daniel@0 817 for h = 1:length(m)
Daniel@0 818 % Code taken from Pampalk's MA Toolbox.
Daniel@0 819 %% spreading function: schroeder et al., 1979, JASA, optimizing
Daniel@0 820 %% digital speech coders by exploiting masking properties of the human ear
Daniel@0 821 cb = length(nch{h}); % Number of bands.
Daniel@0 822 for i = 1:cb,
Daniel@0 823 spread(i,:) = 10.^((15.81+7.5*((i-(1:cb))+0.474)-17.5*(1+((i-(1:cb))+0.474).^2).^0.5)/10);
Daniel@0 824 end
Daniel@0 825 for i = 1:length(m{h})
Daniel@0 826 for J = 1:size(m{h}{i},2)
Daniel@0 827 mj = m{h}{i}(1,J,:);
Daniel@0 828 mj = spread(1:length(mj),1:length(mj))*mj(:);
Daniel@0 829 m{h}{i}(1,J,:) = reshape(mj,1,1,length(mj));
Daniel@0 830 end
Daniel@0 831 end
Daniel@0 832 end
Daniel@0 833 end
Daniel@0 834 end
Daniel@0 835 if option.collapsed
Daniel@0 836 for h = 1:length(m)
Daniel@0 837 for i = 1:length(m{h})
Daniel@0 838 mi = m{h}{i};
Daniel@0 839 fi = f{h}{i};
Daniel@0 840 centclass = rem(fi(:,1,1),1200);
Daniel@0 841 %neg = find(centclass<0);
Daniel@0 842 %centclass(neg) = 1200 + centclass(neg);
Daniel@0 843 m{h}{i} = NaN(1200,size(mi,2),size(mi,3));
Daniel@0 844 for k = 0:1199
Daniel@0 845 m{h}{i}(k+1,:,:) = sum(mi(find(centclass==k),:,:),1);
Daniel@0 846 end
Daniel@0 847 f{h}{i} = repmat((0:1199)',[1,size(fi,2),size(fi,3)]);
Daniel@0 848 end
Daniel@0 849 end
Daniel@0 850 s = set(s,'Abs','Cents','XScale','Cents(Collapsed)');
Daniel@0 851 end
Daniel@0 852 if option.log || option.db
Daniel@0 853 if not(isa(s,'mirspectrum') && s.log)
Daniel@0 854 if option.db
Daniel@0 855 s = set(s,'log',10);
Daniel@0 856 else
Daniel@0 857 s = set(s,'log',1);
Daniel@0 858 end
Daniel@0 859 for k = 1:length(m)
Daniel@0 860 if not(iscell(m{k}))
Daniel@0 861 m{k} = {m{k}};
Daniel@0 862 f{k} = {f{k}};
Daniel@0 863 end
Daniel@0 864 for l = 1:length(m{k})
Daniel@0 865 m{k}{l} = log10(m{k}{l}+1e-16);
Daniel@0 866 if option.db
Daniel@0 867 m{k}{l} = 10*m{k}{l};
Daniel@0 868 end
Daniel@0 869 end
Daniel@0 870 end
Daniel@0 871 elseif isa(s,'mirspectrum') && s.log<10
Daniel@0 872 for k = 1:length(m)
Daniel@0 873 for l = 1:length(m{k})
Daniel@0 874 m{k}{l} = 10*m{k}{l};
Daniel@0 875 end
Daniel@0 876 end
Daniel@0 877 end
Daniel@0 878 if option.db>0 && option.db < Inf
Daniel@0 879 for k = 1:length(m)
Daniel@0 880 for l = 1:length(m{k})
Daniel@0 881 m{k}{l} = m{k}{l}-repmat(max(m{k}{l}),[size(m{k}{l},1) 1 1]);
Daniel@0 882 m{k}{l} = option.db + max(-option.db,m{k}{l});
Daniel@0 883 end
Daniel@0 884 end
Daniel@0 885 end
Daniel@0 886 end
Daniel@0 887 if option.aver
Daniel@0 888 for k = 1:length(m)
Daniel@0 889 for i = 1:length(m{k})
Daniel@0 890 m{k}{i} = filter(ones(1,option.aver),1,m{k}{i});
Daniel@0 891 end
Daniel@0 892 end
Daniel@0 893 end
Daniel@0 894 if option.gauss
Daniel@0 895 for k = 1:length(m)
Daniel@0 896 for i = 1:length(m{k})
Daniel@0 897 sigma = option.gauss;
Daniel@0 898 gauss = 1/sigma/2/pi...
Daniel@0 899 *exp(- (-4*sigma:4*sigma).^2 /2/sigma^2);
Daniel@0 900 y = filter(gauss,1,[m{k}{i};zeros(4*sigma,1)]);
Daniel@0 901 y = y(4*sigma:end,:,:);
Daniel@0 902 m{k}{i} = y(1:size(m{k}{i},1),:,:);
Daniel@0 903 end
Daniel@0 904 end
Daniel@0 905 end
Daniel@0 906 s = set(s,'Magnitude',m,'Frequency',f);
Daniel@0 907
Daniel@0 908
Daniel@0 909 function dj = mirwindow(dj,win,N)
Daniel@0 910 if nargin<3
Daniel@0 911 N = size(dj,1);
Daniel@0 912 elseif size(dj,1)<N
Daniel@0 913 dj(N,1,1) = 0;
Daniel@0 914 end
Daniel@0 915 if not(win == 0)
Daniel@0 916 winf = str2func(win);
Daniel@0 917 try
Daniel@0 918 w = window(winf,N);
Daniel@0 919 catch
Daniel@0 920 if strcmpi(win,'hamming')
Daniel@0 921 disp('Signal Processing Toolbox does not seem to be installed. Recompute the hamming window manually.');
Daniel@0 922 w = 0.54 - 0.46 * cos(2*pi*(0:N-1)'/(N-1));
Daniel@0 923 else
Daniel@0 924 error(['ERROR in MIRSPECTRUM: Unknown windowing function ',win,' (maybe Signal Processing Toolbox is not installed).']);
Daniel@0 925 end
Daniel@0 926 end
Daniel@0 927 kw = repmat(w,[1,size(dj,2),size(dj,3)]);
Daniel@0 928 dj = dj(1:N,:,:).* kw;
Daniel@0 929 end
Daniel@0 930
Daniel@0 931
Daniel@0 932 function [y orig] = eachchunk(orig,option,missing,postchunk)
Daniel@0 933 option.zp = option.zp+missing;
Daniel@0 934 y = mirspectrum(orig,option);
Daniel@0 935
Daniel@0 936
Daniel@0 937 function y = combinechunk(old,new)
Daniel@0 938 do = get(old,'Data');
Daniel@0 939 do = do{1}{1};
Daniel@0 940 dn = get(new,'Data');
Daniel@0 941 dn = dn{1}{1};
Daniel@0 942 y = set(old,'ChunkData',do+dn);