Chris@2
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@2
|
2
|
Chris@2
|
3 /*
|
Chris@2
|
4 Vamp feature extraction plugin for the BeatRoot beat tracker.
|
Chris@2
|
5
|
Chris@2
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@2
|
7 This file copyright 2011 Simon Dixon, Chris Cannam and QMUL.
|
Chris@2
|
8
|
Chris@2
|
9 This program is free software; you can redistribute it and/or
|
Chris@2
|
10 modify it under the terms of the GNU General Public License as
|
Chris@2
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@2
|
12 License, or (at your option) any later version. See the file
|
Chris@2
|
13 COPYING included with this distribution for more information.
|
Chris@2
|
14 */
|
Chris@2
|
15
|
Chris@2
|
16 #include "BeatRootProcessor.h"
|
Chris@2
|
17
|
Chris@2
|
18 bool
|
Chris@2
|
19 BeatRootProcessor::silent = true;
|
Chris@2
|
20
|
Chris@15
|
21 void BeatRootProcessor::processFrame(const float *const *inputBuffers) {
|
Chris@15
|
22 double flux = 0;
|
Chris@15
|
23 for (int i = 0; i <= fftSize/2; i++) {
|
Chris@15
|
24 double mag = sqrt(inputBuffers[0][i*2] * inputBuffers[0][i*2] +
|
Chris@15
|
25 inputBuffers[0][i*2+1] * inputBuffers[0][i*2+1]);
|
Chris@15
|
26 if (mag > prevFrame[i]) flux += mag - prevFrame[i];
|
Chris@15
|
27 prevFrame[i] = mag;
|
Chris@15
|
28 }
|
Chris@15
|
29
|
Chris@15
|
30 spectralFlux.push_back(flux);
|
Chris@15
|
31
|
Chris@15
|
32 } // processFrame()
|
Chris@15
|
33
|
Chris@36
|
34 EventList BeatRootProcessor::beatTrack(EventList *unfilledReturn) {
|
Chris@15
|
35
|
Chris@15
|
36 #ifdef DEBUG_BEATROOT
|
Chris@15
|
37 std::cerr << "Spectral flux:" << std::endl;
|
Chris@15
|
38 for (int i = 0; i < spectralFlux.size(); ++i) {
|
Chris@15
|
39 if ((i % 8) == 0) std::cerr << "\n";
|
Chris@15
|
40 std::cerr << spectralFlux[i] << " ";
|
Chris@15
|
41 }
|
Chris@15
|
42 #endif
|
Chris@15
|
43
|
Chris@15
|
44 double hop = hopTime;
|
Chris@15
|
45 Peaks::normalise(spectralFlux);
|
Chris@15
|
46 vector<int> peaks = Peaks::findPeaks(spectralFlux, (int)lrint(0.06 / hop), 0.35, 0.84, true);
|
Chris@15
|
47 onsets.clear();
|
Chris@15
|
48 onsets.resize(peaks.size(), 0);
|
Chris@15
|
49 vector<int>::iterator it = peaks.begin();
|
Chris@15
|
50 onsetList.clear();
|
Chris@15
|
51 double minSalience = Peaks::min(spectralFlux);
|
Chris@22
|
52 for (int i = 0; i < (int)onsets.size(); i++) {
|
Chris@15
|
53 int index = *it;
|
Chris@15
|
54 ++it;
|
Chris@15
|
55 onsets[i] = index * hop;
|
Chris@15
|
56 Event e = BeatTracker::newBeat(onsets[i], 0);
|
Chris@15
|
57 // if (debug)
|
Chris@15
|
58 // System.err.printf("Onset: %8.3f %8.3f %8.3f\n",
|
Chris@15
|
59 // onsets[i], energy[index], slope[index]);
|
Chris@15
|
60 // e.salience = slope[index]; // or combination of energy + slope??
|
Chris@15
|
61 // Note that salience must be non-negative or the beat tracking system fails!
|
Chris@15
|
62 e.salience = spectralFlux[index] - minSalience;
|
Chris@15
|
63 onsetList.push_back(e);
|
Chris@15
|
64 }
|
Chris@15
|
65
|
Chris@15
|
66 #ifdef DEBUG_BEATROOT
|
Chris@15
|
67 std::cerr << "Onsets: " << onsetList.size() << std::endl;
|
Chris@15
|
68 #endif
|
Chris@15
|
69
|
Chris@36
|
70 return BeatTracker::beatTrack(agentParameters, onsetList, unfilledReturn);
|
Chris@15
|
71
|
Chris@15
|
72 } // processFile()
|
Chris@15
|
73
|