Chris@0
|
1 function [f_CENS,sideinfo] = pitch_to_CENS(f_pitch,parameter,sideinfo)
|
Chris@0
|
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
3 % Name: pitch_to_CENS
|
Chris@0
|
4 % Date of Revision: 2011-03
|
Chris@0
|
5 % Programmer: Meinard Mueller, Sebastian Ewert
|
Chris@0
|
6 %
|
Chris@0
|
7 % Description:
|
Chris@0
|
8 % Normalized statistical chroma-based energy distribution feature (CENS).
|
Chris@0
|
9 % The following is computed:
|
Chris@0
|
10 % * energy for each chroma band
|
Chris@0
|
11 % * normalisation of the chroma vectors
|
Chris@0
|
12 % * local statistics:
|
Chris@0
|
13 % - component-wise quantisation of the normalized chroma vectors
|
Chris@0
|
14 % - upfirdn filters and downsamples each column of f_stat_help
|
Chris@0
|
15 % - normalize each vector with its l^2 norm
|
Chris@0
|
16 %
|
Chris@0
|
17 % Remark:
|
Chris@0
|
18 % * parameter.inputFeatureRate specifies the feature rate of f_pitch. The value
|
Chris@0
|
19 % is used to derive the output feature rate given via sideinfo.
|
Chris@0
|
20 %
|
Chris@0
|
21 % Input:
|
Chris@0
|
22 % f_pitch
|
Chris@0
|
23 % parameter.quantSteps = [40 20 10 5] / 100;
|
Chris@0
|
24 % parameter.quantWeights = [ 1 1 1 1]/4;
|
Chris@0
|
25 % parameter.normThresh = 0.001;
|
Chris@0
|
26 % parameter.winLenSmooth = 41;
|
Chris@0
|
27 % parameter.downsampSmooth = 10;
|
Chris@0
|
28 % parameter.midiMin = 21;
|
Chris@0
|
29 % parameter.midiMax = 108;
|
Chris@0
|
30 % parameter.inputFeatureRate = 0;
|
Chris@0
|
31 % parameter.save = 0;
|
Chris@0
|
32 % parameter.saveDir = '';
|
Chris@0
|
33 % parameter.saveFilename = '';
|
Chris@0
|
34 % parameter.visualize = 0;
|
Chris@0
|
35 % sideinfo
|
Chris@0
|
36 %
|
Chris@0
|
37 % Output:
|
Chris@0
|
38 % f_CENS
|
Chris@0
|
39 % sideinfo
|
Chris@0
|
40 %
|
Chris@0
|
41 % License:
|
Chris@0
|
42 % This file is part of 'Chroma Toolbox'.
|
Chris@0
|
43 %
|
Chris@0
|
44 % 'Chroma Toolbox' is free software: you can redistribute it and/or modify
|
Chris@0
|
45 % it under the terms of the GNU General Public License as published by
|
Chris@0
|
46 % the Free Software Foundation, either version 2 of the License, or
|
Chris@0
|
47 % (at your option) any later version.
|
Chris@0
|
48 %
|
Chris@0
|
49 % 'Chroma Toolbox' is distributed in the hope that it will be useful,
|
Chris@0
|
50 % but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Chris@0
|
51 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@0
|
52 % GNU General Public License for more details.
|
Chris@0
|
53 %
|
Chris@0
|
54 % You should have received a copy of the GNU General Public License
|
Chris@0
|
55 % along with 'Chroma Toolbox'. If not, see <http://www.gnu.org/licenses/>.
|
Chris@0
|
56 %
|
Chris@0
|
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
58
|
Chris@0
|
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
60 % Check parameters
|
Chris@0
|
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
62
|
Chris@0
|
63 if nargin<3
|
Chris@0
|
64 sideinfo=[];
|
Chris@0
|
65 end
|
Chris@0
|
66 if nargin<2
|
Chris@0
|
67 parameter=[];
|
Chris@0
|
68 end
|
Chris@0
|
69 if nargin<1
|
Chris@0
|
70 error('Please specify input data f_pitch');
|
Chris@0
|
71 end
|
Chris@0
|
72
|
Chris@0
|
73 if isfield(parameter,'quantSteps')==0
|
Chris@0
|
74 parameter.quantSteps = [40 20 10 5] / 100;
|
Chris@0
|
75 end
|
Chris@0
|
76 if isfield(parameter,'quantWeights')==0
|
Chris@0
|
77 parameter.quantWeights = [ 1 1 1 1]/4;
|
Chris@0
|
78 end
|
Chris@0
|
79 if isfield(parameter,'normThresh')==0
|
Chris@0
|
80 parameter.normThresh = 0.001;
|
Chris@0
|
81 end
|
Chris@0
|
82 if isfield(parameter,'winLenSmooth')==0
|
Chris@0
|
83 parameter.winLenSmooth = 41;
|
Chris@0
|
84 end
|
Chris@0
|
85 if isfield(parameter,'downsampSmooth')==0
|
Chris@0
|
86 parameter.downsampSmooth = 10;
|
Chris@0
|
87 end
|
Chris@0
|
88 if isfield(parameter,'midiMin')==0
|
Chris@0
|
89 parameter.midiMin = 21;
|
Chris@0
|
90 end
|
Chris@0
|
91 if isfield(parameter,'midiMax')==0
|
Chris@0
|
92 parameter.midiMax = 108;
|
Chris@0
|
93 end
|
Chris@0
|
94 if isfield(parameter,'inputFeatureRate')==0
|
Chris@0
|
95 parameter.inputFeatureRate = 0;
|
Chris@0
|
96 end
|
Chris@0
|
97 if isfield(parameter,'save')==0
|
Chris@0
|
98 parameter.save = 0;
|
Chris@0
|
99 end
|
Chris@0
|
100 if isfield(parameter,'saveDir')==0
|
Chris@0
|
101 parameter.saveDir = '';
|
Chris@0
|
102 end
|
Chris@0
|
103 if isfield(parameter,'saveFilename')==0
|
Chris@0
|
104 parameter.saveFilename = '';
|
Chris@0
|
105 end
|
Chris@0
|
106 if isfield(parameter,'visualize')==0
|
Chris@0
|
107 parameter.visualize = 0;
|
Chris@0
|
108 end
|
Chris@0
|
109
|
Chris@0
|
110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
111 % Main program
|
Chris@0
|
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
113
|
Chris@0
|
114 seg_num = size(f_pitch,2);
|
Chris@0
|
115
|
Chris@0
|
116 % calculate energy for each chroma band
|
Chris@0
|
117 f_chroma_energy = zeros(12,seg_num);
|
Chris@0
|
118 for p=parameter.midiMin:parameter.midiMax
|
Chris@0
|
119 chroma = mod(p,12)+1;
|
Chris@0
|
120 f_chroma_energy(chroma,:) = f_chroma_energy(chroma,:)+f_pitch(p,:);
|
Chris@0
|
121 end
|
Chris@0
|
122
|
Chris@0
|
123 % normalize the chroma vectors
|
Chris@0
|
124 f_chroma_energy_distr = zeros(12,seg_num);
|
Chris@0
|
125 for k=1:seg_num
|
Chris@0
|
126 if sum(f_chroma_energy(:,k)>parameter.normThresh)>0
|
Chris@0
|
127 seg_energy_square = sum(f_chroma_energy(:,k));
|
Chris@0
|
128 f_chroma_energy_distr(:,k) = ((f_chroma_energy(:,k))/seg_energy_square);
|
Chris@0
|
129 end
|
Chris@0
|
130 end
|
Chris@0
|
131
|
Chris@0
|
132 % calculate a CENS feature
|
Chris@0
|
133
|
Chris@0
|
134 % component-wise quantisation of the normalized chroma vectors
|
Chris@0
|
135 f_stat_help = zeros(12,seg_num);
|
Chris@0
|
136 for n=1:length(parameter.quantSteps)
|
Chris@0
|
137 f_stat_help = f_stat_help + (f_chroma_energy_distr>parameter.quantSteps(n))*parameter.quantWeights(n);
|
Chris@0
|
138 end
|
Chris@0
|
139
|
Chris@0
|
140 % Temporal smoothing and downsampling
|
Chris@0
|
141 [f_chroma_energy_stat,CENSfeatureRate] = smoothDownsampleFeature(f_stat_help,parameter);
|
Chris@0
|
142
|
Chris@0
|
143 % last step: normalize each vector with its l^2 norm
|
Chris@0
|
144 f_CENS = normalizeFeature(f_chroma_energy_stat,2, parameter.normThresh);
|
Chris@0
|
145
|
Chris@0
|
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
147 % Update sideinfo
|
Chris@0
|
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
149 sideinfo.CENS.version = 1;
|
Chris@0
|
150 sideinfo.CENS.midiMin = parameter.midiMin;
|
Chris@0
|
151 sideinfo.CENS.midiMax = parameter.midiMax;
|
Chris@0
|
152 sideinfo.CENS.featureRate = CENSfeatureRate;
|
Chris@0
|
153 sideinfo.CENS.quantSteps = parameter.quantSteps;
|
Chris@0
|
154 sideinfo.CENS.quantWeights = parameter.quantWeights;
|
Chris@0
|
155 sideinfo.CENS.normThresh = parameter.normThresh;
|
Chris@0
|
156 sideinfo.CENS.winLenSmooth = parameter.winLenSmooth;
|
Chris@0
|
157 sideinfo.CENS.downsampSmooth = parameter.downsampSmooth;
|
Chris@0
|
158
|
Chris@0
|
159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
160 % Saving to file
|
Chris@0
|
161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
162 if parameter.save
|
Chris@0
|
163 filename = strcat(parameter.saveFilename,'_CENS_',num2str(parameter.winLenSmooth),'_',num2str(parameter.downsampSmooth));
|
Chris@0
|
164 save(strcat(parameter.saveDir,filename),'f_CENS','sideinfo');
|
Chris@0
|
165 end
|
Chris@0
|
166
|
Chris@0
|
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
168 % Visualization
|
Chris@0
|
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Chris@0
|
170 if parameter.visualize
|
Chris@0
|
171 parameterVis.featureRate = CENSfeatureRate;
|
Chris@0
|
172 parameterVis.title = 'CENS chromagram';
|
Chris@0
|
173 visualizeChroma(f_CENS,parameterVis)
|
Chris@0
|
174 end
|
Chris@0
|
175
|
Chris@0
|
176 end
|