annotate toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirroughness.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 = mirroughness(x,varargin)
Daniel@0 2 % r = mirroughness(x) calculates the roughness, or sensory dissonance,
Daniel@0 3 % due to beating phenomenon between close frequency peaks.
Daniel@0 4 % The frequency components are supposed to remain sufficiently
Daniel@0 5 % constant throughout each frame of each audio file.
Daniel@0 6 % r = mirroughness(...,'Contrast',c) specifies the contrast parameter
Daniel@0 7 % used for peak picking (cf. mirpeaks).
Daniel@0 8 % Default value: c = .01
Daniel@0 9 % [r,s] = mirroughness(x) also displays the spectrum and its peaks, used
Daniel@0 10 % for the computation of roughness.
Daniel@0 11 % Optional arguments:
Daniel@0 12 % Method used:
Daniel@0 13 % mirroughness(...,'Sethares') (default): based on the summation
Daniel@0 14 % of roughness between all pairs of sines (obtained through
Daniel@0 15 % spectral peak-picking).
Daniel@0 16 % mirroughness(...,'Vassilakis'): variant of 'Sethares' model
Daniel@0 17 % with a more complex weighting (Vassilakis, 2001, Eq. 6.23).
Daniel@0 18
Daniel@0 19 meth.type = 'String';
Daniel@0 20 meth.choice = {'Sethares','Vassilakis'};
Daniel@0 21 meth.default = 'Sethares';
Daniel@0 22 option.meth = meth;
Daniel@0 23
Daniel@0 24 cthr.key = 'Contrast';
Daniel@0 25 cthr.type = 'Integer';
Daniel@0 26 cthr.default = .01;
Daniel@0 27 option.cthr = cthr;
Daniel@0 28
Daniel@0 29 frame.key = 'Frame';
Daniel@0 30 frame.type = 'Integer';
Daniel@0 31 frame.number = 2;
Daniel@0 32 frame.default = [.05 .5];
Daniel@0 33 option.frame = frame;
Daniel@0 34
Daniel@0 35 specif.option = option;
Daniel@0 36 specif.defaultframelength = .05;
Daniel@0 37 specif.defaultframehop = .5;
Daniel@0 38
Daniel@0 39
Daniel@0 40 varargout = mirfunction(@mirroughness,x,varargin,nargout,specif,@init,@main);
Daniel@0 41
Daniel@0 42
Daniel@0 43 function [x type] = init(x,option)
Daniel@0 44 if isamir(x,'miraudio') && not(isframed(x))
Daniel@0 45 x = mirframenow(x,option);
Daniel@0 46 end
Daniel@0 47 x = mirspectrum(x);
Daniel@0 48 if not(haspeaks(x))
Daniel@0 49 x = mirpeaks(x,'Contrast',option.cthr);
Daniel@0 50 end
Daniel@0 51 type = 'mirscalar';
Daniel@0 52
Daniel@0 53
Daniel@0 54 function r = main(p,option,postoption)
Daniel@0 55 if iscell(p)
Daniel@0 56 p = p{1};
Daniel@0 57 end
Daniel@0 58 if strcmpi(option.meth,'Sethares') || strcmpi(option.meth,'Vassilakis')
Daniel@0 59 pf = get(p,'PeakPosUnit');
Daniel@0 60 pv = get(p,'PeakVal');
Daniel@0 61 rg = cell(1,length(pf));
Daniel@0 62 for h = 1:length(pf)
Daniel@0 63 rg{h} = cell(1,length(pf{h}));
Daniel@0 64 for i = 1:length(pf{h})
Daniel@0 65 pfi = pf{h}{i};
Daniel@0 66 pvi = pv{h}{i};
Daniel@0 67 rg{h}{i} = zeros(1,length(pfi));
Daniel@0 68 for k = 1:size(pfi,3)
Daniel@0 69 for j = 1:size(pfi,2)
Daniel@0 70 pfj = pfi{1,j,k};
Daniel@0 71 pvj = pvi{1,j,k};
Daniel@0 72 f1 = repmat(pfj,[1 length(pfj)]);
Daniel@0 73 f2 = repmat(pfj',[length(pfj) 1]);
Daniel@0 74 v1 = repmat(pvj,[1 length(pvj)]);
Daniel@0 75 v2 = repmat(pvj',[length(pvj) 1]);
Daniel@0 76 rj = plomp(f1,f2);
Daniel@0 77 if strcmpi(option.meth,'Sethares')
Daniel@0 78 rj = v1.*v2.*rj;
Daniel@0 79 elseif strcmpi(option.meth,'Vassilakis')
Daniel@0 80 rj = (v1.*v2).^.1.*.5.*(2*v2./(v1+v2)).^3.11.*rj;
Daniel@0 81 end
Daniel@0 82 rg{h}{i}(1,j,k) = sum(sum(rj));
Daniel@0 83 end
Daniel@0 84 end
Daniel@0 85 end
Daniel@0 86 end
Daniel@0 87 else
Daniel@0 88 end
Daniel@0 89 r = mirscalar(p,'Data',rg,'Title','Roughness');
Daniel@0 90 r = {r,p};
Daniel@0 91
Daniel@0 92
Daniel@0 93 function pd = plomp(f1, f2)
Daniel@0 94 % returns the dissonance of two pure tones at frequencies f1 & f2 Hz
Daniel@0 95 % according to the Plomp-Levelt curve (see Sethares)
Daniel@0 96 b1 = 3.51;
Daniel@0 97 b2 = 5.75;
Daniel@0 98 xstar = .24;
Daniel@0 99 s1 = .0207;
Daniel@0 100 s2 = 18.96;
Daniel@0 101 s = tril(xstar ./ (s1 * min(f1,f2) + s2 ));
Daniel@0 102 pd = exp(-b1*s.*abs(f2-f1)) - exp(-b2*s.*abs(f2-f1));
Daniel@0 103 return