comparison ConstrainedHarmonicPeak.cpp @ 6:e9b629578488

Default value fixes, docs etc
author Chris Cannam
date Mon, 10 Mar 2014 14:51:09 +0000
parents 3bf29717cc01
children f5b9bae2a8c3 5fb59edfab99
comparison
equal deleted inserted replaced
5:d2f7a8295671 6:e9b629578488
10 10
11 ConstrainedHarmonicPeak::ConstrainedHarmonicPeak(float inputSampleRate) : 11 ConstrainedHarmonicPeak::ConstrainedHarmonicPeak(float inputSampleRate) :
12 Plugin(inputSampleRate), 12 Plugin(inputSampleRate),
13 m_fftSize(0), 13 m_fftSize(0),
14 m_minFreq(0), 14 m_minFreq(0),
15 m_maxFreq(inputSampleRate/2), 15 m_maxFreq(22050),
16 m_harmonics(5) 16 m_harmonics(5)
17 { 17 {
18 } 18 }
19 19
20 ConstrainedHarmonicPeak::~ConstrainedHarmonicPeak() 20 ConstrainedHarmonicPeak::~ConstrainedHarmonicPeak()
34 } 34 }
35 35
36 string 36 string
37 ConstrainedHarmonicPeak::getDescription() const 37 ConstrainedHarmonicPeak::getDescription() const
38 { 38 {
39 //!!! Return something helpful here! 39 return "Return the interpolated peak frequency of a harmonic product spectrum within a given frequency range";
40 return "";
41 } 40 }
42 41
43 string 42 string
44 ConstrainedHarmonicPeak::getMaker() const 43 ConstrainedHarmonicPeak::getMaker() const
45 { 44 {
94 ParameterList list; 93 ParameterList list;
95 94
96 ParameterDescriptor d; 95 ParameterDescriptor d;
97 d.identifier = "minfreq"; 96 d.identifier = "minfreq";
98 d.name = "Minimum frequency"; 97 d.name = "Minimum frequency";
99 d.description = ""; 98 d.description = "Minimum frequency for peak finding. Will be rounded down to the nearest spectral bin.";
100 d.unit = "Hz"; 99 d.unit = "Hz";
101 d.minValue = 0; 100 d.minValue = 0;
102 d.maxValue = m_inputSampleRate/2; 101 d.maxValue = m_inputSampleRate/2;
103 d.defaultValue = 0; 102 d.defaultValue = 0;
104 d.isQuantized = false; 103 d.isQuantized = false;
105 list.push_back(d); 104 list.push_back(d);
106 105
107 d.identifier = "maxfreq"; 106 d.identifier = "maxfreq";
108 d.name = "Maximum frequency"; 107 d.name = "Maximum frequency";
109 d.description = ""; 108 d.description = "Maximum frequency for peak finding. Will be rounded up to the nearest spectral bin.";
110 d.unit = "Hz"; 109 d.unit = "Hz";
111 d.minValue = 0; 110 d.minValue = 0;
112 d.maxValue = m_inputSampleRate/2; 111 d.maxValue = m_inputSampleRate/2;
113 d.defaultValue = 0; 112 d.defaultValue = 22050;
114 d.isQuantized = false; 113 d.isQuantized = false;
115 list.push_back(d); 114 list.push_back(d);
116 115
117 d.identifier = "harmonics"; 116 d.identifier = "harmonics";
118 d.name = "Harmonics"; 117 d.name = "Harmonics";
177 OutputList list; 176 OutputList list;
178 177
179 OutputDescriptor d; 178 OutputDescriptor d;
180 d.identifier = "peak"; 179 d.identifier = "peak";
181 d.name = "Peak frequency"; 180 d.name = "Peak frequency";
182 d.description = ""; 181 d.description = "Interpolated frequency of the harmonic spectral peak within the given frequency range";
183 d.unit = "Hz"; 182 d.unit = "Hz";
184 d.sampleType = OutputDescriptor::OneSamplePerStep; 183 d.sampleType = OutputDescriptor::OneSamplePerStep;
185 d.hasDuration = false; 184 d.hasDuration = false;
186 list.push_back(d); 185 list.push_back(d);
187 186
240 239
241 ConstrainedHarmonicPeak::FeatureSet 240 ConstrainedHarmonicPeak::FeatureSet
242 ConstrainedHarmonicPeak::process(const float *const *inputBuffers, Vamp::RealTime timestamp) 241 ConstrainedHarmonicPeak::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
243 { 242 {
244 FeatureSet fs; 243 FeatureSet fs;
244
245 // This could be better. The procedure here is
246 //
247 // 1 Produce a harmonic product spectrum within a limited
248 // frequency range by effectively summing the dB values of the
249 // bins at each multiple of the bin numbers (up to a given
250 // number of harmonics) in the range under consideration
251 // 2 Find the peak bin
252 // 3 Calculate the peak location by quadratic interpolation
253 // from the peak bin and its two neighbouring bins
254 //
255 // Problems with this:
256 //
257 // 1 Harmonics might not be located at integer multiples of the
258 // original bin frequency
259 // 2 Quadratic interpolation works "correctly" for dB-valued
260 // magnitude spectra but might not produce the right results in
261 // the dB-summed hps, especially in light of the first problem
262 // 3 Interpolation might not make sense at all if there are
263 // multiple nearby frequencies interfering across the three
264 // bins used for interpolation (we may be unable to identify
265 // the right frequency at all, but it's possible interpolation
266 // will make our guess worse rather than better)
267 //
268 // Possible improvements:
269 //
270 // 1 Find the higher harmonics by looking for the peak bin within
271 // a range around the nominal peak location
272 // 2 Once a peak has been identified as the peak of the HPS, use
273 // the original spectrum (not the HPS) to obtain the values for
274 // interpolation? (would help with problem 2 but might make
275 // problem 3 worse)
245 276
246 int hs = m_fftSize/2; 277 int hs = m_fftSize/2;
247 278
248 double *mags = new double[hs+1]; 279 double *mags = new double[hs+1];
249 for (int i = 0; i <= hs; ++i) { 280 for (int i = 0; i <= hs; ++i) {