Mercurial > hg > qm-vamp-plugins
comparison plugins/OnsetDetect.cpp @ 30:ff5a09e45209
* add support for adaptive whitening
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Thu, 09 Aug 2007 16:35:37 +0000 |
parents | 56fe3bd9de6e |
children | 5cd7e3069553 |
comparison
equal
deleted
inserted
replaced
29:56fe3bd9de6e | 30:ff5a09e45209 |
---|---|
43 | 43 |
44 OnsetDetector::OnsetDetector(float inputSampleRate) : | 44 OnsetDetector::OnsetDetector(float inputSampleRate) : |
45 Vamp::Plugin(inputSampleRate), | 45 Vamp::Plugin(inputSampleRate), |
46 m_d(0), | 46 m_d(0), |
47 m_dfType(DF_COMPLEXSD), | 47 m_dfType(DF_COMPLEXSD), |
48 m_sensitivity(50) | 48 m_sensitivity(50), |
49 m_whiten(false) | |
49 { | 50 { |
50 } | 51 } |
51 | 52 |
52 OnsetDetector::~OnsetDetector() | 53 OnsetDetector::~OnsetDetector() |
53 { | 54 { |
107 desc.valueNames.push_back("High-Frequency Content"); | 108 desc.valueNames.push_back("High-Frequency Content"); |
108 desc.valueNames.push_back("Spectral Difference"); | 109 desc.valueNames.push_back("Spectral Difference"); |
109 desc.valueNames.push_back("Phase Deviation"); | 110 desc.valueNames.push_back("Phase Deviation"); |
110 desc.valueNames.push_back("Complex Domain"); | 111 desc.valueNames.push_back("Complex Domain"); |
111 desc.valueNames.push_back("Broadband Energy Rise"); | 112 desc.valueNames.push_back("Broadband Energy Rise"); |
113 desc.valueNames.push_back("Spectral Magnitude"); | |
112 list.push_back(desc); | 114 list.push_back(desc); |
113 | 115 |
114 desc.identifier = "sensitivity"; | 116 desc.identifier = "sensitivity"; |
115 desc.name = "Onset Detector Sensitivity"; | 117 desc.name = "Onset Detector Sensitivity"; |
116 desc.description = "Sensitivity of peak-picker for onset detection"; | 118 desc.description = "Sensitivity of peak-picker for onset detection"; |
121 desc.quantizeStep = 1; | 123 desc.quantizeStep = 1; |
122 desc.unit = "%"; | 124 desc.unit = "%"; |
123 desc.valueNames.clear(); | 125 desc.valueNames.clear(); |
124 list.push_back(desc); | 126 list.push_back(desc); |
125 | 127 |
128 desc.identifier = "whiten"; | |
129 desc.name = "Adaptive Whitening"; | |
130 desc.description = "Normalize frequency bin magnitudes relative to recent peak levels"; | |
131 desc.minValue = 0; | |
132 desc.maxValue = 1; | |
133 desc.defaultValue = 0; | |
134 desc.isQuantized = true; | |
135 desc.quantizeStep = 1; | |
136 desc.unit = ""; | |
137 list.push_back(desc); | |
138 | |
126 return list; | 139 return list; |
127 } | 140 } |
128 | 141 |
129 float | 142 float |
130 OnsetDetector::getParameter(std::string name) const | 143 OnsetDetector::getParameter(std::string name) const |
134 case DF_HFC: return 0; | 147 case DF_HFC: return 0; |
135 case DF_SPECDIFF: return 1; | 148 case DF_SPECDIFF: return 1; |
136 case DF_PHASEDEV: return 2; | 149 case DF_PHASEDEV: return 2; |
137 default: case DF_COMPLEXSD: return 3; | 150 default: case DF_COMPLEXSD: return 3; |
138 case DF_BROADBAND: return 4; | 151 case DF_BROADBAND: return 4; |
152 case DF_POWER: return 5; | |
139 } | 153 } |
140 } else if (name == "sensitivity") { | 154 } else if (name == "sensitivity") { |
141 return m_sensitivity; | 155 return m_sensitivity; |
156 } else if (name == "whiten") { | |
157 return m_whiten ? 1.0 : 0.0; | |
142 } | 158 } |
143 return 0.0; | 159 return 0.0; |
144 } | 160 } |
145 | 161 |
146 void | 162 void |
147 OnsetDetector::setParameter(std::string name, float value) | 163 OnsetDetector::setParameter(std::string name, float value) |
148 { | 164 { |
149 if (name == "dftype") { | 165 if (name == "dftype") { |
166 int dfType = m_dfType; | |
150 switch (lrintf(value)) { | 167 switch (lrintf(value)) { |
151 case 0: m_dfType = DF_HFC; break; | 168 case 0: dfType = DF_HFC; break; |
152 case 1: m_dfType = DF_SPECDIFF; break; | 169 case 1: dfType = DF_SPECDIFF; break; |
153 case 2: m_dfType = DF_PHASEDEV; break; | 170 case 2: dfType = DF_PHASEDEV; break; |
154 default: case 3: m_dfType = DF_COMPLEXSD; break; | 171 default: case 3: dfType = DF_COMPLEXSD; break; |
155 case 4: m_dfType = DF_BROADBAND; break; | 172 case 4: dfType = DF_BROADBAND; break; |
173 case 5: dfType = DF_POWER; break; | |
156 } | 174 } |
175 if (dfType == m_dfType) return; | |
176 m_dfType = dfType; | |
177 m_program = ""; | |
157 } else if (name == "sensitivity") { | 178 } else if (name == "sensitivity") { |
179 if (m_sensitivity == value) return; | |
158 m_sensitivity = value; | 180 m_sensitivity = value; |
181 m_program = ""; | |
182 } else if (name == "whiten") { | |
183 if (m_whiten == (value > 0.5)) return; | |
184 m_whiten = (value > 0.5); | |
185 m_program = ""; | |
159 } | 186 } |
160 } | 187 } |
161 | 188 |
162 OnsetDetector::ProgramList | 189 OnsetDetector::ProgramList |
163 OnsetDetector::getPrograms() const | 190 OnsetDetector::getPrograms() const |
164 { | 191 { |
165 ProgramList programs; | 192 ProgramList programs; |
193 programs.push_back(""); | |
166 programs.push_back("General purpose"); | 194 programs.push_back("General purpose"); |
167 programs.push_back("Soft onsets"); | 195 programs.push_back("Soft onsets"); |
168 programs.push_back("Percussive onsets"); | 196 programs.push_back("Percussive onsets"); |
169 return programs; | 197 return programs; |
170 } | 198 } |
171 | 199 |
172 std::string | 200 std::string |
173 OnsetDetector::getCurrentProgram() const | 201 OnsetDetector::getCurrentProgram() const |
174 { | 202 { |
175 if (m_program == "") return "General purpose"; | 203 if (m_program == "") return ""; |
176 else return m_program; | 204 else return m_program; |
177 } | 205 } |
178 | 206 |
179 void | 207 void |
180 OnsetDetector::selectProgram(std::string program) | 208 OnsetDetector::selectProgram(std::string program) |
181 { | 209 { |
182 if (program == "General purpose") { | 210 if (program == "General purpose") { |
183 setParameter("dftype", 3); // complex | 211 setParameter("dftype", 3); // complex |
184 setParameter("sensitivity", 50); | 212 setParameter("sensitivity", 50); |
213 setParameter("whiten", 0); | |
185 } else if (program == "Soft onsets") { | 214 } else if (program == "Soft onsets") { |
186 setParameter("dftype", 2); // phase deviation | 215 setParameter("dftype", 2); // phase deviation |
187 setParameter("sensitivity", 70); | 216 setParameter("sensitivity", 70); |
217 setParameter("whiten", 0); | |
188 } else if (program == "Percussive onsets") { | 218 } else if (program == "Percussive onsets") { |
189 setParameter("dftype", 4); // broadband energy rise | 219 setParameter("dftype", 4); // broadband energy rise |
190 setParameter("sensitivity", 40); | 220 setParameter("sensitivity", 40); |
221 setParameter("whiten", 0); | |
191 } else { | 222 } else { |
192 return; | 223 return; |
193 } | 224 } |
194 m_program = program; | 225 m_program = program; |
195 } | 226 } |
225 dfConfig.DFType = m_dfType; | 256 dfConfig.DFType = m_dfType; |
226 dfConfig.stepSecs = float(stepSize) / m_inputSampleRate; | 257 dfConfig.stepSecs = float(stepSize) / m_inputSampleRate; |
227 dfConfig.stepSize = stepSize; | 258 dfConfig.stepSize = stepSize; |
228 dfConfig.frameLength = blockSize; | 259 dfConfig.frameLength = blockSize; |
229 dfConfig.dbRise = 6.0 - m_sensitivity / 16.6667; | 260 dfConfig.dbRise = 6.0 - m_sensitivity / 16.6667; |
261 dfConfig.adaptiveWhitening = m_whiten; | |
262 dfConfig.whiteningRelaxCoeff = -1; | |
263 dfConfig.whiteningFloor = -1; | |
230 | 264 |
231 m_d = new OnsetDetectorData(dfConfig); | 265 m_d = new OnsetDetectorData(dfConfig); |
232 return true; | 266 return true; |
233 } | 267 } |
234 | 268 |
433 (frame, lrintf(m_inputSampleRate)); | 467 (frame, lrintf(m_inputSampleRate)); |
434 | 468 |
435 returnFeatures[0].push_back(feature); // onsets are output 0 | 469 returnFeatures[0].push_back(feature); // onsets are output 0 |
436 } | 470 } |
437 | 471 |
438 for (int i = 0; i < ppParams.length; ++i) { | 472 for (unsigned int i = 0; i < ppParams.length; ++i) { |
439 | 473 |
440 Feature feature; | 474 Feature feature; |
441 // feature.hasTimestamp = false; | 475 // feature.hasTimestamp = false; |
442 feature.hasTimestamp = true; | 476 feature.hasTimestamp = true; |
443 size_t frame = i * m_d->dfConfig.stepSize; | 477 size_t frame = i * m_d->dfConfig.stepSize; |