Mercurial > hg > qm-vamp-plugins
comparison plugins/KeyDetect.cpp @ 242:3e882621e2dd
Add "rapid" option (frame overlap factor)
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Thu, 06 Jun 2019 14:21:39 +0100 |
parents | c9c562f37dd7 |
children | ed249a345715 |
comparison
equal
deleted
inserted
replaced
241:d4ba927300f5 | 242:3e882621e2dd |
---|---|
14 | 14 |
15 #include "KeyDetect.h" | 15 #include "KeyDetect.h" |
16 | 16 |
17 using std::string; | 17 using std::string; |
18 using std::vector; | 18 using std::vector; |
19 //using std::cerr; | |
20 using std::endl; | |
21 | 19 |
22 #include <cmath> | 20 #include <cmath> |
23 | 21 |
24 | 22 |
25 // Order for circle-of-5ths plotting | 23 // Order for circle-of-5ths plotting |
32 Plugin(inputSampleRate), | 30 Plugin(inputSampleRate), |
33 m_stepSize(0), | 31 m_stepSize(0), |
34 m_blockSize(0), | 32 m_blockSize(0), |
35 m_tuningFrequency(440), | 33 m_tuningFrequency(440), |
36 m_length(10), | 34 m_length(10), |
35 m_rapid(true), | |
37 m_getKeyMode(0), | 36 m_getKeyMode(0), |
38 m_inputFrame(0), | 37 m_inputFrame(0), |
39 m_prevKey(-1) | 38 m_prevKey(-1) |
40 { | 39 { |
41 } | 40 } |
79 } | 78 } |
80 | 79 |
81 string | 80 string |
82 KeyDetector::getCopyright() const | 81 KeyDetector::getCopyright() const |
83 { | 82 { |
84 return "Plugin by Katy Noland and Christian Landone. Copyright (c) 2006-2009 QMUL - All Rights Reserved"; | 83 return "Plugin by Katy Noland and Christian Landone. Copyright (c) 2006-2019 QMUL - All Rights Reserved"; |
85 } | 84 } |
86 | 85 |
87 KeyDetector::ParameterList | 86 KeyDetector::ParameterList |
88 KeyDetector::getParameterDescriptors() const | 87 KeyDetector::getParameterDescriptors() const |
89 { | 88 { |
109 desc.defaultValue = 10; | 108 desc.defaultValue = 10; |
110 desc.isQuantized = true; | 109 desc.isQuantized = true; |
111 desc.quantizeStep = 1; | 110 desc.quantizeStep = 1; |
112 list.push_back(desc); | 111 list.push_back(desc); |
113 | 112 |
113 desc.identifier = "rapid"; | |
114 desc.name = "Rapid"; | |
115 desc.unit = ""; | |
116 desc.description = "Sample intervals without overlap, for speed"; | |
117 desc.minValue = 0; | |
118 desc.maxValue = 1; | |
119 desc.defaultValue = 1; | |
120 desc.isQuantized = true; | |
121 desc.quantizeStep = 1; | |
122 list.push_back(desc); | |
123 | |
114 return list; | 124 return list; |
115 } | 125 } |
116 | 126 |
117 float | 127 float |
118 KeyDetector::getParameter(std::string param) const | 128 KeyDetector::getParameter(std::string param) const |
120 if (param == "tuning") { | 130 if (param == "tuning") { |
121 return m_tuningFrequency; | 131 return m_tuningFrequency; |
122 } | 132 } |
123 if (param == "length") { | 133 if (param == "length") { |
124 return m_length; | 134 return m_length; |
135 } | |
136 if (param == "rapid") { | |
137 return m_rapid ? 1.f : 0.f; | |
125 } | 138 } |
126 std::cerr << "WARNING: KeyDetector::getParameter: unknown parameter \"" | 139 std::cerr << "WARNING: KeyDetector::getParameter: unknown parameter \"" |
127 << param << "\"" << std::endl; | 140 << param << "\"" << std::endl; |
128 return 0.0; | 141 return 0.0; |
129 } | 142 } |
133 { | 146 { |
134 if (param == "tuning") { | 147 if (param == "tuning") { |
135 m_tuningFrequency = value; | 148 m_tuningFrequency = value; |
136 } else if (param == "length") { | 149 } else if (param == "length") { |
137 m_length = int(value + 0.1); | 150 m_length = int(value + 0.1); |
151 } else if (param == "rapid") { | |
152 m_rapid = (value > 0.5); | |
138 } else { | 153 } else { |
139 std::cerr << "WARNING: KeyDetector::setParameter: unknown parameter \"" | 154 std::cerr << "WARNING: KeyDetector::setParameter: unknown parameter \"" |
140 << param << "\"" << std::endl; | 155 << param << "\"" << std::endl; |
141 } | 156 } |
157 | |
158 // force recalculate: | |
159 m_stepSize = 0; | |
160 m_blockSize = 0; | |
161 } | |
162 | |
163 GetKeyMode::Config | |
164 KeyDetector::getConfig() const | |
165 { | |
166 GetKeyMode::Config config(m_inputSampleRate, m_tuningFrequency); | |
167 config.hpcpAverage = m_length; | |
168 config.medianAverage = m_length; | |
169 config.frameOverlapFactor = (m_rapid ? 1 : 8); | |
170 config.decimationFactor = 8; | |
171 return config; | |
142 } | 172 } |
143 | 173 |
144 bool | 174 bool |
145 KeyDetector::initialise(size_t channels, size_t stepSize, size_t blockSize) | 175 KeyDetector::initialise(size_t channels, size_t stepSize, size_t blockSize) |
146 { | 176 { |
150 } | 180 } |
151 | 181 |
152 if (channels < getMinChannelCount() || | 182 if (channels < getMinChannelCount() || |
153 channels > getMaxChannelCount()) return false; | 183 channels > getMaxChannelCount()) return false; |
154 | 184 |
155 m_getKeyMode = new GetKeyMode(int(m_inputSampleRate + 0.1), | 185 m_getKeyMode = new GetKeyMode(getConfig()); |
156 m_tuningFrequency, | |
157 m_length, m_length); | |
158 | 186 |
159 m_stepSize = m_getKeyMode->getHopSize(); | 187 m_stepSize = m_getKeyMode->getHopSize(); |
160 m_blockSize = m_getKeyMode->getBlockSize(); | 188 m_blockSize = m_getKeyMode->getBlockSize(); |
161 | 189 |
162 if (stepSize != m_stepSize || blockSize != m_blockSize) { | 190 if (stepSize != m_stepSize || blockSize != m_blockSize) { |
179 void | 207 void |
180 KeyDetector::reset() | 208 KeyDetector::reset() |
181 { | 209 { |
182 if (m_getKeyMode) { | 210 if (m_getKeyMode) { |
183 delete m_getKeyMode; | 211 delete m_getKeyMode; |
184 m_getKeyMode = new GetKeyMode(int(m_inputSampleRate + 0.1), | 212 m_getKeyMode = new GetKeyMode(getConfig()); |
185 m_tuningFrequency, | |
186 m_length, m_length); | |
187 } | 213 } |
188 | 214 |
189 if (m_inputFrame) { | 215 if (m_inputFrame) { |
190 for( unsigned int i = 0; i < m_blockSize; i++ ) { | 216 for( unsigned int i = 0; i < m_blockSize; i++ ) { |
191 m_inputFrame[ i ] = 0.0; | 217 m_inputFrame[ i ] = 0.0; |
287 for ( unsigned int i = 0 ; i < m_blockSize; i++ ) { | 313 for ( unsigned int i = 0 ; i < m_blockSize; i++ ) { |
288 m_inputFrame[i] = (double)inputBuffers[0][i]; | 314 m_inputFrame[i] = (double)inputBuffers[0][i]; |
289 } | 315 } |
290 | 316 |
291 int key = m_getKeyMode->process(m_inputFrame); | 317 int key = m_getKeyMode->process(m_inputFrame); |
292 bool minor = m_getKeyMode->isModeMinor(key); | 318 |
293 int tonic = key; | 319 int tonic = key; |
294 if (tonic > 12) tonic -= 12; | 320 if (tonic > 12) tonic -= 12; |
295 | 321 |
296 int prevTonic = m_prevKey; | 322 int prevTonic = m_prevKey; |
297 if (prevTonic > 12) prevTonic -= 12; | 323 if (prevTonic > 12) prevTonic -= 12; |
324 | |
325 bool minor = (key > 12); | |
326 bool prevMinor = (m_prevKey > 12); | |
298 | 327 |
299 if (m_first || (tonic != prevTonic)) { | 328 if (m_first || (tonic != prevTonic)) { |
300 Feature feature; | 329 Feature feature; |
301 feature.hasTimestamp = true; | 330 feature.hasTimestamp = true; |
302 feature.timestamp = now; | 331 feature.timestamp = now; |
303 feature.values.push_back((float)tonic); | 332 feature.values.push_back((float)tonic); |
304 feature.label = getKeyName(tonic, minor, false); | 333 feature.label = getKeyName(tonic, minor, false); |
305 returnFeatures[0].push_back(feature); // tonic | 334 returnFeatures[0].push_back(feature); // tonic |
306 } | 335 } |
307 | 336 |
308 if (m_first || (minor != (m_getKeyMode->isModeMinor(m_prevKey)))) { | 337 if (m_first || (minor != prevMinor)) { |
309 Feature feature; | 338 Feature feature; |
310 feature.hasTimestamp = true; | 339 feature.hasTimestamp = true; |
311 feature.timestamp = now; | 340 feature.timestamp = now; |
312 feature.values.push_back(minor ? 1.f : 0.f); | 341 feature.values.push_back(minor ? 1.f : 0.f); |
313 feature.label = (minor ? "Minor" : "Major"); | 342 feature.label = (minor ? "Minor" : "Major"); |
343 KeyDetector::getRemainingFeatures() | 372 KeyDetector::getRemainingFeatures() |
344 { | 373 { |
345 return FeatureSet(); | 374 return FeatureSet(); |
346 } | 375 } |
347 | 376 |
348 | |
349 size_t | 377 size_t |
350 KeyDetector::getPreferredStepSize() const | 378 KeyDetector::getPreferredStepSize() const |
351 { | 379 { |
352 if (!m_stepSize) { | 380 if (!m_stepSize) { |
353 GetKeyMode gkm(int(m_inputSampleRate + 0.1), | 381 GetKeyMode gkm(getConfig()); |
354 m_tuningFrequency, m_length, m_length); | |
355 m_stepSize = gkm.getHopSize(); | 382 m_stepSize = gkm.getHopSize(); |
356 m_blockSize = gkm.getBlockSize(); | 383 m_blockSize = gkm.getBlockSize(); |
357 } | 384 } |
358 return m_stepSize; | 385 return m_stepSize; |
359 } | 386 } |
360 | 387 |
361 size_t | 388 size_t |
362 KeyDetector::getPreferredBlockSize() const | 389 KeyDetector::getPreferredBlockSize() const |
363 { | 390 { |
364 if (!m_blockSize) { | 391 if (!m_blockSize) { |
365 GetKeyMode gkm(int(m_inputSampleRate + 0.1), | 392 GetKeyMode gkm(getConfig()); |
366 m_tuningFrequency, m_length, m_length); | |
367 m_stepSize = gkm.getHopSize(); | 393 m_stepSize = gkm.getHopSize(); |
368 m_blockSize = gkm.getBlockSize(); | 394 m_blockSize = gkm.getBlockSize(); |
369 } | 395 } |
370 return m_blockSize; | 396 return m_blockSize; |
371 } | 397 } |