Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirinharmonicity.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirinharmonicity.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,120 @@ +function varargout = mirinharmonicity(orig,varargin) +% ih = mirinharmonicity(x) estimates the inharmonicity of x, i.e., the +% amount of partials that are not multiples of the fundamental +% frequency. +% x can be either an audio file, a miraudio or a mirspectrum object. +% WARNING: This function presupposes that there is only one fundamental +% frequency. +% Optional argument: +% mirinharmonicity(...,'f0',f) bases the computation of the +% inharmonicity on the fundamental frequency indicated by f. +% Default value: f = mirpitch(...,'Mono') +% [ih,s] = mirinharmonicity(x) also displays the spectrum used for the +% computation of the inharmonicity. +% [ih,s,p] = mirinharmonicity(x) also displays the result of the +% estimation of the fundamental frequency. + + f0.key = 'f0'; + f0.default = []; + option.f0 = f0; + + frame.key = 'Frame'; + frame.type = 'Integer'; + frame.number = 2; + frame.default = [0 0]; + frame.keydefault = [.1 .125]; + option.frame = frame; + +specif.option = option; + +varargout = mirfunction(@mirinharmonicity,orig,varargin,nargout,specif,@init,@main); + + +function [i type] = init(x,option) +if isamir(x,'miraudio') + if option.frame.length.val + s = mirspectrum(x,'Frame',option.frame.length.val,... + option.frame.length.unit,... + option.frame.hop.val,... + option.frame.hop.unit); + else + s = mirspectrum(x); + end +else + s = x; +end +if isempty(option.f0) + if option.frame.length.val + p = mirpitch(x,'Mono','Frame',option.frame.length.val,... + option.frame.length.unit,... + option.frame.hop.val,... + option.frame.hop.unit); + else + p = mirpitch(x,'Mono'); + end +else + p = option.f0; +end +i = {s,p}; +type = {'mirscalar','mirspectrum','mirscalar'}; + + +function ih = main(x,option,postoption) +if isa(x{2},'mirdesign') + x = x{1}; +end +s = x{1}; +p = x{2}; +if iscell(p) + p = p{1}; +end +m = get(s,'Magnitude'); +f = get(s,'Frequency'); +fp1 = get(s,'FramePos'); +if isnumeric(p) + pf = {{{p}}}; +else + pf = get(p,'Data'); + fp2 = get(p,'FramePos'); +end +v = cell(1,length(m)); +for h = 1:length(m) + v{h} = cell(1,length(m{h})); + for i = 1:length(m{h}) + mi = m{h}{i}; + fi = f{h}{i}; + pfi = pf{h}{i}; + v{h}{i} = zeros(1,size(mi,2),size(mi,3)); + if not(size(mi,2) == size(pfi,2)) + beg = find(fp2{h}{i}(1,:) == fp1{h}{i}(1,1)); + if isempty(beg) || (beg + size(mi,2)-1 > size(pfi,2)) + error('ERROR IN MIRINHARMONICITY: The ''f0'' argument should have the same frame decomposition than the main input.'); + end + pfi = pfi(:,beg:beg+size(mi,2)-1); + end + for j = 1:size(mi,3) + for k = 1:size(mi,2) + mk = mi(:,k,j); + fk = fi(:,k,j); + pfk = pfi(:,k); + if isempty(pfk{1}) + v{h}{i}(1,k,j) = NaN; + else + r = fk/pfk{1}(1); + rr = 2*abs(r-round(r)); + if isempty(rr) + v{h}{i}(1,k,j) = NaN; + else + v{h}{i}(1,k,j) = sum(rr.*mk) / sum(mk); + end + end + end + end + end +end +ih = mirscalar(s,'Data',v,'Title','Inharmonicity'); +if isa(p,'mirdata') + ih = {ih s p}; +else + ih = {ih s}; +end \ No newline at end of file