comparison plugins/BarBeatTrack.cpp @ 146:c4837ed2eeb1

Merge mepd_new_params branch
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 02 Sep 2013 09:29:34 +0100
parents edad8a88a074
children 88c05c0ac438
comparison
equal deleted inserted replaced
143:592ac92002a8 146:c4837ed2eeb1
33 33
34 class BarBeatTrackerData 34 class BarBeatTrackerData
35 { 35 {
36 public: 36 public:
37 BarBeatTrackerData(float rate, const DFConfig &config) : dfConfig(config) { 37 BarBeatTrackerData(float rate, const DFConfig &config) : dfConfig(config) {
38 df = new DetectionFunction(config); 38 df = new DetectionFunction(config);
39 // decimation factor aims at resampling to c. 3KHz; must be power of 2 39 // decimation factor aims at resampling to c. 3KHz; must be power of 2
40 int factor = MathUtilities::nextPowerOfTwo(rate / 3000); 40 int factor = MathUtilities::nextPowerOfTwo(rate / 3000);
41 // std::cerr << "BarBeatTrackerData: factor = " << factor << std::endl; 41 // std::cerr << "BarBeatTrackerData: factor = " << factor << std::endl;
42 downBeat = new DownBeat(rate, factor, config.stepSize); 42 downBeat = new DownBeat(rate, factor, config.stepSize);
43 } 43 }
44 ~BarBeatTrackerData() { 44 ~BarBeatTrackerData() {
45 delete df; 45 delete df;
46 delete downBeat; 46 delete downBeat;
47 } 47 }
48 void reset() { 48 void reset() {
49 delete df; 49 delete df;
50 df = new DetectionFunction(dfConfig); 50 df = new DetectionFunction(dfConfig);
51 dfOutput.clear(); 51 dfOutput.clear();
52 downBeat->resetAudioBuffer(); 52 downBeat->resetAudioBuffer();
53 origin = Vamp::RealTime::zeroTime; 53 origin = Vamp::RealTime::zeroTime;
54 } 54 }
55 55
56 DFConfig dfConfig; 56 DFConfig dfConfig;
57 DetectionFunction *df; 57 DetectionFunction *df;
58 DownBeat *downBeat; 58 DownBeat *downBeat;
59 vector<double> dfOutput; 59 vector<double> dfOutput;
60 Vamp::RealTime origin; 60 Vamp::RealTime origin;
61 }; 61 };
62 62
63 63
64 BarBeatTracker::BarBeatTracker(float inputSampleRate) : 64 BarBeatTracker::BarBeatTracker(float inputSampleRate) :
65 Vamp::Plugin(inputSampleRate), 65 Vamp::Plugin(inputSampleRate),
66 m_d(0), 66 m_d(0),
67 m_bpb(4) 67 m_bpb(4),
68 m_alpha(0.9), // changes are as per the BeatTrack.cpp
69 m_tightness(4.), // changes are as per the BeatTrack.cpp
70 m_inputtempo(120.), // changes are as per the BeatTrack.cpp
71 m_constraintempo(false) // changes are as per the BeatTrack.cpp
68 { 72 {
69 } 73 }
70 74
71 BarBeatTracker::~BarBeatTracker() 75 BarBeatTracker::~BarBeatTracker()
72 { 76 {
98 } 102 }
99 103
100 int 104 int
101 BarBeatTracker::getPluginVersion() const 105 BarBeatTracker::getPluginVersion() const
102 { 106 {
103 return 2; 107 return 3;
104 } 108 }
105 109
106 string 110 string
107 BarBeatTracker::getCopyright() const 111 BarBeatTracker::getCopyright() const
108 { 112 {
124 desc.defaultValue = 4; 128 desc.defaultValue = 4;
125 desc.isQuantized = true; 129 desc.isQuantized = true;
126 desc.quantizeStep = 1; 130 desc.quantizeStep = 1;
127 list.push_back(desc); 131 list.push_back(desc);
128 132
133 // changes are as per the BeatTrack.cpp
134 //Alpha Parameter of Beat Tracker
135 desc.identifier = "alpha";
136 desc.name = "Alpha";
137 desc.description = "Inertia - Flexibility Trade Off";
138 desc.minValue = 0.1;
139 desc.maxValue = 0.99;
140 desc.defaultValue = 0.90;
141 desc.unit = "";
142 desc.isQuantized = false;
143 list.push_back(desc);
144
145
146 // changes are as per the BeatTrack.cpp
147 //Tightness Parameter of Beat Tracker
148 desc.identifier = "tightness";
149 desc.name = "Tightness";
150 desc.description = "Inertia - Flexibility Trade Off 2";
151 desc.minValue = 3;
152 desc.maxValue = 7;
153 desc.defaultValue = 4;
154 desc.unit = "";
155 desc.isQuantized = true;
156 list.push_back(desc);
157
158 // changes are as per the BeatTrack.cpp
159 //User input tempo
160 desc.identifier = "inputtempo";
161 desc.name = "InputTempo";
162 desc.description = "User defined Tempo";
163 desc.minValue = 50;
164 desc.maxValue = 250;
165 desc.defaultValue = 120;
166 desc.unit = "BPM";
167 desc.isQuantized = true;
168 list.push_back(desc);
169
170 // changes are as per the BeatTrack.cpp
171 desc.identifier = "constraintempo";
172 desc.name = "Constrain Tempo";
173 desc.description = "Constrain tempo to use Gaussian weighting";
174 desc.minValue = 0;
175 desc.maxValue = 1;
176 desc.defaultValue = 0;
177 desc.isQuantized = true;
178 desc.quantizeStep = 1;
179 desc.unit = "";
180 desc.valueNames.clear();
181 list.push_back(desc);
182
183
129 return list; 184 return list;
130 } 185 }
131 186
132 float 187 float
133 BarBeatTracker::getParameter(std::string name) const 188 BarBeatTracker::getParameter(std::string name) const
134 { 189 {
135 if (name == "bpb") return m_bpb; 190 if (name == "bpb") {
191 return m_bpb;
192 } else if (name == "alpha") {
193 return m_alpha;
194 } else if (name == "tightness") {
195 return m_tightness;
196 } else if (name == "inputtempo") {
197 return m_inputtempo;
198 } else if (name == "constraintempo") {
199 return m_constraintempo ? 1.0 : 0.0;
200 }
136 return 0.0; 201 return 0.0;
137 } 202 }
138 203
139 void 204 void
140 BarBeatTracker::setParameter(std::string name, float value) 205 BarBeatTracker::setParameter(std::string name, float value)
141 { 206 {
142 if (name == "bpb") m_bpb = lrintf(value); 207 if (name == "bpb") {
208 m_bpb = lrintf(value);
209 } else if (name == "alpha") {
210 m_alpha = value;
211 } else if (name == "tightness") {
212 m_tightness = value;
213 } else if (name == "inputtempo") {
214 m_inputtempo = value;
215 } else if (name == "constraintempo") {
216 m_constraintempo = (value > 0.5);
217 }
143 } 218 }
144 219
145 bool 220 bool
146 BarBeatTracker::initialise(size_t channels, size_t stepSize, size_t blockSize) 221 BarBeatTracker::initialise(size_t channels, size_t stepSize, size_t blockSize)
147 { 222 {
148 if (m_d) { 223 if (m_d) {
149 delete m_d; 224 delete m_d;
150 m_d = 0; 225 m_d = 0;
151 } 226 }
152 227
153 if (channels < getMinChannelCount() || 228 if (channels < getMinChannelCount() ||
154 channels > getMaxChannelCount()) { 229 channels > getMaxChannelCount()) {
155 std::cerr << "BarBeatTracker::initialise: Unsupported channel count: " 230 std::cerr << "BarBeatTracker::initialise: Unsupported channel count: "
156 << channels << std::endl; 231 << channels << std::endl;
157 return false; 232 return false;
158 } 233 }
159 234
175 dfConfig.frameLength = blockSize; 250 dfConfig.frameLength = blockSize;
176 dfConfig.dbRise = 3; 251 dfConfig.dbRise = 3;
177 dfConfig.adaptiveWhitening = false; 252 dfConfig.adaptiveWhitening = false;
178 dfConfig.whiteningRelaxCoeff = -1; 253 dfConfig.whiteningRelaxCoeff = -1;
179 dfConfig.whiteningFloor = -1; 254 dfConfig.whiteningFloor = -1;
180 255
181 m_d = new BarBeatTrackerData(m_inputSampleRate, dfConfig); 256 m_d = new BarBeatTrackerData(m_inputSampleRate, dfConfig);
182 m_d->downBeat->setBeatsPerBar(m_bpb); 257 m_d->downBeat->setBeatsPerBar(m_bpb);
183 return true; 258 return true;
184 } 259 }
185 260
265 BarBeatTracker::FeatureSet 340 BarBeatTracker::FeatureSet
266 BarBeatTracker::process(const float *const *inputBuffers, 341 BarBeatTracker::process(const float *const *inputBuffers,
267 Vamp::RealTime timestamp) 342 Vamp::RealTime timestamp)
268 { 343 {
269 if (!m_d) { 344 if (!m_d) {
270 cerr << "ERROR: BarBeatTracker::process: " 345 cerr << "ERROR: BarBeatTracker::process: "
271 << "BarBeatTracker has not been initialised" 346 << "BarBeatTracker has not been initialised"
272 << endl; 347 << endl;
273 return FeatureSet(); 348 return FeatureSet();
274 } 349 }
275 350
276 // We use time domain input, because DownBeat requires it -- so we 351 // We use time domain input, because DownBeat requires it -- so we
277 // use the time-domain version of DetectionFunction::process which 352 // use the time-domain version of DetectionFunction::process which
278 // does its own FFT. It requires doubles as input, so we need to 353 // does its own FFT. It requires doubles as input, so we need to
309 384
310 BarBeatTracker::FeatureSet 385 BarBeatTracker::FeatureSet
311 BarBeatTracker::getRemainingFeatures() 386 BarBeatTracker::getRemainingFeatures()
312 { 387 {
313 if (!m_d) { 388 if (!m_d) {
314 cerr << "ERROR: BarBeatTracker::getRemainingFeatures: " 389 cerr << "ERROR: BarBeatTracker::getRemainingFeatures: "
315 << "BarBeatTracker has not been initialised" 390 << "BarBeatTracker has not been initialised"
316 << endl; 391 << endl;
317 return FeatureSet(); 392 return FeatureSet();
318 } 393 }
319 394
320 return barBeatTrack(); 395 return barBeatTrack();
321 } 396 }
322 397
332 beatPeriod.push_back(0.0); 407 beatPeriod.push_back(0.0);
333 } 408 }
334 if (df.empty()) return FeatureSet(); 409 if (df.empty()) return FeatureSet();
335 410
336 TempoTrackV2 tt(m_inputSampleRate, m_d->dfConfig.stepSize); 411 TempoTrackV2 tt(m_inputSampleRate, m_d->dfConfig.stepSize);
337 tt.calculateBeatPeriod(df, beatPeriod, tempi); 412
413 // changes are as per the BeatTrack.cpp - allow m_inputtempo and m_constraintempo to be set be the user
414 tt.calculateBeatPeriod(df, beatPeriod, tempi, m_inputtempo, m_constraintempo);
338 415
339 vector<double> beats; 416 vector<double> beats;
340 tt.calculateBeats(df, beatPeriod, beats); 417 // changes are as per the BeatTrack.cpp - allow m_alpha and m_tightness to be set be the user
418 tt.calculateBeats(df, beatPeriod, beats, m_alpha, m_tightness);
419
420 // tt.calculateBeatPeriod(df, beatPeriod, tempi, 0., 0); // use default parameters
421
422 // vector<double> beats;
423 // tt.calculateBeats(df, beatPeriod, beats, 0.9, 4.); // use default parameters until i fix this plugin too
341 424
342 vector<int> downbeats; 425 vector<int> downbeats;
343 size_t downLength = 0; 426 size_t downLength = 0;
344 const float *downsampled = m_d->downBeat->getBufferedAudio(downLength); 427 const float *downsampled = m_d->downBeat->getBufferedAudio(downLength);
345 m_d->downBeat->findDownBeats(downsampled, downLength, beats, downbeats); 428 m_d->downBeat->findDownBeats(downsampled, downLength, beats, downbeats);
347 vector<double> beatsd; 430 vector<double> beatsd;
348 m_d->downBeat->getBeatSD(beatsd); 431 m_d->downBeat->getBeatSD(beatsd);
349 432
350 // std::cerr << "BarBeatTracker: found downbeats at: "; 433 // std::cerr << "BarBeatTracker: found downbeats at: ";
351 // for (int i = 0; i < downbeats.size(); ++i) std::cerr << downbeats[i] << " " << std::endl; 434 // for (int i = 0; i < downbeats.size(); ++i) std::cerr << downbeats[i] << " " << std::endl;
352 435
353 FeatureSet returnFeatures; 436 FeatureSet returnFeatures;
354 437
355 char label[20]; 438 char label[20];
356 439
357 int dbi = 0; 440 int dbi = 0;
366 if (beat == m_bpb) beat = 0; 449 if (beat == m_bpb) beat = 0;
367 } 450 }
368 451
369 for (size_t i = 0; i < beats.size(); ++i) { 452 for (size_t i = 0; i < beats.size(); ++i) {
370 453
371 size_t frame = beats[i] * m_d->dfConfig.stepSize; 454 size_t frame = beats[i] * m_d->dfConfig.stepSize;
372 455
373 if (dbi < downbeats.size() && i == downbeats[dbi]) { 456 if (dbi < downbeats.size() && i == downbeats[dbi]) {
374 beat = 0; 457 beat = 0;
375 ++bar; 458 ++bar;
376 ++dbi; 459 ++dbi;
381 // outputs are: 464 // outputs are:
382 // 465 //
383 // 0 -> beats 466 // 0 -> beats
384 // 1 -> bars 467 // 1 -> bars
385 // 2 -> beat counter function 468 // 2 -> beat counter function
386 469
387 Feature feature; 470 Feature feature;
388 feature.hasTimestamp = true; 471 feature.hasTimestamp = true;
389 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime 472 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime
390 (frame, lrintf(m_inputSampleRate)); 473 (frame, lrintf(m_inputSampleRate));
391 474
392 sprintf(label, "%d", beat + 1); 475 sprintf(label, "%d", beat + 1);
393 feature.label = label; 476 feature.label = label;
394 returnFeatures[0].push_back(feature); // labelled beats 477 returnFeatures[0].push_back(feature); // labelled beats
395 478
396 feature.values.push_back(beat + 1); 479 feature.values.push_back(beat + 1);
397 returnFeatures[2].push_back(feature); // beat function 480 returnFeatures[2].push_back(feature); // beat function
398 481
399 if (i > 0 && i <= beatsd.size()) { 482 if (i > 0 && i <= beatsd.size()) {