wolffd@0
|
1 function varargout = mirinharmonicity(orig,varargin)
|
wolffd@0
|
2 % ih = mirinharmonicity(x) estimates the inharmonicity of x, i.e., the
|
wolffd@0
|
3 % amount of partials that are not multiples of the fundamental
|
wolffd@0
|
4 % frequency.
|
wolffd@0
|
5 % x can be either an audio file, a miraudio or a mirspectrum object.
|
wolffd@0
|
6 % WARNING: This function presupposes that there is only one fundamental
|
wolffd@0
|
7 % frequency.
|
wolffd@0
|
8 % Optional argument:
|
wolffd@0
|
9 % mirinharmonicity(...,'f0',f) bases the computation of the
|
wolffd@0
|
10 % inharmonicity on the fundamental frequency indicated by f.
|
wolffd@0
|
11 % Default value: f = mirpitch(...,'Mono')
|
wolffd@0
|
12 % [ih,s] = mirinharmonicity(x) also displays the spectrum used for the
|
wolffd@0
|
13 % computation of the inharmonicity.
|
wolffd@0
|
14 % [ih,s,p] = mirinharmonicity(x) also displays the result of the
|
wolffd@0
|
15 % estimation of the fundamental frequency.
|
wolffd@0
|
16
|
wolffd@0
|
17 f0.key = 'f0';
|
wolffd@0
|
18 f0.default = [];
|
wolffd@0
|
19 option.f0 = f0;
|
wolffd@0
|
20
|
wolffd@0
|
21 frame.key = 'Frame';
|
wolffd@0
|
22 frame.type = 'Integer';
|
wolffd@0
|
23 frame.number = 2;
|
wolffd@0
|
24 frame.default = [0 0];
|
wolffd@0
|
25 frame.keydefault = [.1 .125];
|
wolffd@0
|
26 option.frame = frame;
|
wolffd@0
|
27
|
wolffd@0
|
28 specif.option = option;
|
wolffd@0
|
29
|
wolffd@0
|
30 varargout = mirfunction(@mirinharmonicity,orig,varargin,nargout,specif,@init,@main);
|
wolffd@0
|
31
|
wolffd@0
|
32
|
wolffd@0
|
33 function [i type] = init(x,option)
|
wolffd@0
|
34 if isamir(x,'miraudio')
|
wolffd@0
|
35 if option.frame.length.val
|
wolffd@0
|
36 s = mirspectrum(x,'Frame',option.frame.length.val,...
|
wolffd@0
|
37 option.frame.length.unit,...
|
wolffd@0
|
38 option.frame.hop.val,...
|
wolffd@0
|
39 option.frame.hop.unit);
|
wolffd@0
|
40 else
|
wolffd@0
|
41 s = mirspectrum(x);
|
wolffd@0
|
42 end
|
wolffd@0
|
43 else
|
wolffd@0
|
44 s = x;
|
wolffd@0
|
45 end
|
wolffd@0
|
46 if isempty(option.f0)
|
wolffd@0
|
47 if option.frame.length.val
|
wolffd@0
|
48 p = mirpitch(x,'Mono','Frame',option.frame.length.val,...
|
wolffd@0
|
49 option.frame.length.unit,...
|
wolffd@0
|
50 option.frame.hop.val,...
|
wolffd@0
|
51 option.frame.hop.unit);
|
wolffd@0
|
52 else
|
wolffd@0
|
53 p = mirpitch(x,'Mono');
|
wolffd@0
|
54 end
|
wolffd@0
|
55 else
|
wolffd@0
|
56 p = option.f0;
|
wolffd@0
|
57 end
|
wolffd@0
|
58 i = {s,p};
|
wolffd@0
|
59 type = {'mirscalar','mirspectrum','mirscalar'};
|
wolffd@0
|
60
|
wolffd@0
|
61
|
wolffd@0
|
62 function ih = main(x,option,postoption)
|
wolffd@0
|
63 if isa(x{2},'mirdesign')
|
wolffd@0
|
64 x = x{1};
|
wolffd@0
|
65 end
|
wolffd@0
|
66 s = x{1};
|
wolffd@0
|
67 p = x{2};
|
wolffd@0
|
68 if iscell(p)
|
wolffd@0
|
69 p = p{1};
|
wolffd@0
|
70 end
|
wolffd@0
|
71 m = get(s,'Magnitude');
|
wolffd@0
|
72 f = get(s,'Frequency');
|
wolffd@0
|
73 fp1 = get(s,'FramePos');
|
wolffd@0
|
74 if isnumeric(p)
|
wolffd@0
|
75 pf = {{{p}}};
|
wolffd@0
|
76 else
|
wolffd@0
|
77 pf = get(p,'Data');
|
wolffd@0
|
78 fp2 = get(p,'FramePos');
|
wolffd@0
|
79 end
|
wolffd@0
|
80 v = cell(1,length(m));
|
wolffd@0
|
81 for h = 1:length(m)
|
wolffd@0
|
82 v{h} = cell(1,length(m{h}));
|
wolffd@0
|
83 for i = 1:length(m{h})
|
wolffd@0
|
84 mi = m{h}{i};
|
wolffd@0
|
85 fi = f{h}{i};
|
wolffd@0
|
86 pfi = pf{h}{i};
|
wolffd@0
|
87 v{h}{i} = zeros(1,size(mi,2),size(mi,3));
|
wolffd@0
|
88 if not(size(mi,2) == size(pfi,2))
|
wolffd@0
|
89 beg = find(fp2{h}{i}(1,:) == fp1{h}{i}(1,1));
|
wolffd@0
|
90 if isempty(beg) || (beg + size(mi,2)-1 > size(pfi,2))
|
wolffd@0
|
91 error('ERROR IN MIRINHARMONICITY: The ''f0'' argument should have the same frame decomposition than the main input.');
|
wolffd@0
|
92 end
|
wolffd@0
|
93 pfi = pfi(:,beg:beg+size(mi,2)-1);
|
wolffd@0
|
94 end
|
wolffd@0
|
95 for j = 1:size(mi,3)
|
wolffd@0
|
96 for k = 1:size(mi,2)
|
wolffd@0
|
97 mk = mi(:,k,j);
|
wolffd@0
|
98 fk = fi(:,k,j);
|
wolffd@0
|
99 pfk = pfi(:,k);
|
wolffd@0
|
100 if isempty(pfk{1})
|
wolffd@0
|
101 v{h}{i}(1,k,j) = NaN;
|
wolffd@0
|
102 else
|
wolffd@0
|
103 r = fk/pfk{1}(1);
|
wolffd@0
|
104 rr = 2*abs(r-round(r));
|
wolffd@0
|
105 if isempty(rr)
|
wolffd@0
|
106 v{h}{i}(1,k,j) = NaN;
|
wolffd@0
|
107 else
|
wolffd@0
|
108 v{h}{i}(1,k,j) = sum(rr.*mk) / sum(mk);
|
wolffd@0
|
109 end
|
wolffd@0
|
110 end
|
wolffd@0
|
111 end
|
wolffd@0
|
112 end
|
wolffd@0
|
113 end
|
wolffd@0
|
114 end
|
wolffd@0
|
115 ih = mirscalar(s,'Data',v,'Title','Inharmonicity');
|
wolffd@0
|
116 if isa(p,'mirdata')
|
wolffd@0
|
117 ih = {ih s p};
|
wolffd@0
|
118 else
|
wolffd@0
|
119 ih = {ih s};
|
wolffd@0
|
120 end |