Mercurial > hg > chp
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) { |
