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;