changeset 9:4f6626f9ffac

Many fixes. This now compiles and passes the plugin tester, but I don't expect it produces any results yet.
author Chris Cannam
date Fri, 30 Sep 2011 15:39:17 +0100
parents f04f87b5e643
children 1c1e98cd1b2e
files Agent.cpp Agent.h BeatRootProcessor.cpp BeatRootProcessor.h BeatRootVampPlugin.cpp Induction.cpp Induction.h Makefile Peaks.cpp
diffstat 9 files changed, 59 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/Agent.cpp	Fri Sep 30 11:37:25 2011 +0100
+++ b/Agent.cpp	Fri Sep 30 15:39:17 2011 +0100
@@ -27,7 +27,6 @@
 int Agent::idCounter = 0;
 
 double Agent::innerMargin = 0.0;
-double Agent::outerMargin = 0.0;
 double Agent::correctionFactor = 0.0;
 double Agent::expiryTime = 0.0;
 double Agent::decayFactor = 0.0;
@@ -38,7 +37,9 @@
 	accept(e, 0, 1);
 	return true;
     } else {			// subsequent events
-	if (e.time - events.l.getLast().keyDown > expiryTime) {
+        EventList::iterator last = events.end();
+        --last;
+	if (e.time - last->time > expiryTime) {
 	    phaseScore = -1.0;	// flag agent to be deleted
 	    return false;
 	}
@@ -46,7 +47,7 @@
 	err = e.time - beatTime - beats * beatInterval;
 	if ((beats > 0) && (-preMargin <= err) && (err <= postMargin)) {
 	    if (fabs(err) > innerMargin)	// Create new agent that skips this
-		a.push_back(Agent(*this));	//  event (avoids large phase jump)
+		a.add(Agent(*this));	//  event (avoids large phase jump)
 	    accept(e, err, (int)beats);
 	    return true;
 	}
@@ -55,24 +56,24 @@
 } // considerAsBeat()
 
 
-void fillBeats(double start) {
+void Agent::fillBeats(double start) {
     double prevBeat = 0, nextBeat, currentInterval, beats;
-    EventList::iterator list = events.begin();
-    if (list != events.end()) {
-	++list;
-	prevBeat = list->time;
-	--list;
+    EventList::iterator ei = events.begin();
+    if (ei != events.end()) {
+	++ei;
+	prevBeat = ei->time;
+	--ei;
     }
-    for ( ; list != events.end(); ++list) {
-	++list;
-	nextBeat = list->time;
-	--list;
+    for ( ; ei != events.end(); ++ei) {
+	++ei;
+	nextBeat = ei->time;
+	--ei; // so as to insert before nextBeat
 	beats = nearbyint((nextBeat - prevBeat) / beatInterval - 0.01); //prefer slow
 	currentInterval = (nextBeat - prevBeat) / beats;
 	for ( ; (nextBeat > start) && (beats > 1.5); beats--) {
 	    prevBeat += currentInterval;
-	    //!!! need to insert this event after current itr
-	    list.add(BeatTracker::newBeat(prevBeat, 0));	// more than once OK??
+            events.insert(ei, BeatTracker::newBeat(prevBeat, 0));
+            ++ei;
 	}
 	prevBeat = nextBeat;
     }
--- a/Agent.h	Fri Sep 30 11:37:25 2011 +0100
+++ b/Agent.h	Fri Sep 30 15:39:17 2011 +0100
@@ -18,6 +18,8 @@
 
 #include "Event.h"
 
+#include <cmath>
+
 class AgentList;
 
 /** Agent is the central class for beat tracking.
@@ -191,7 +193,7 @@
      *  1) The Agent has no beats yet; the Event is accepted as the first beat.
      *  2) The Event is beyond expiryTime seconds after the Agent's last 'confirming' beat; the Agent is terminated.
      *  3) The Event is within the innerMargin of the beat prediction; it is accepted as a beat.
-     *  4) The Event is within the outerMargin's of the beat prediction; it is accepted as a beat by this Agent,
+     *  4) The Event is within the postMargin's of the beat prediction; it is accepted as a beat by this Agent,
      *     and a new Agent is created which doesn't accept it as a beat.
      *  5) The Event is ignored because it is outside the windows around the Agent's predicted beat time.
      * @param e The Event to be tested
--- a/BeatRootProcessor.cpp	Fri Sep 30 11:37:25 2011 +0100
+++ b/BeatRootProcessor.cpp	Fri Sep 30 15:39:17 2011 +0100
@@ -16,9 +16,6 @@
 #include "BeatRootProcessor.h"
 
 bool
-BeatRootProcessor::debug = false;
-
-bool
 BeatRootProcessor::silent = true;
 
 double
--- a/BeatRootProcessor.h	Fri Sep 30 11:37:25 2011 +0100
+++ b/BeatRootProcessor.h	Fri Sep 30 15:39:17 2011 +0100
@@ -27,6 +27,10 @@
 
 class BeatRootProcessor
 {
+public:
+    int getFFTSize() const { return fftSize; }
+    int getHopSize() const { return hopSize; }
+
 protected:
     /** Sample rate of audio */
     float sampleRate;
@@ -91,12 +95,6 @@
 	
     /** The estimated onset times and their saliences. */	
     EventList onsetList;
-
-    /** Total number of audio frames if known, or -1 for live or compressed input. */
-    int totalFrames;
-	
-    /** Flag for enabling or disabling debugging output */
-    static bool debug;
 	
     /** Flag for suppressing all standard output messages except results. */
     static bool silent;
@@ -135,16 +133,19 @@
         frameCount = 0;
         hopSize = 0;
         fftSize = 0;
-        hopTime = 0.010;	// DEFAULT, overridden with -h
-        fftTime = 0.04644;	// DEFAULT, overridden with -f
-        totalFrames = -1; //!!! not needed?
+        hopTime = 0.010;
+        fftTime = 0.04644;
+        hopSize = lrint(sampleRate * hopTime);
+        fftSize = lrint(pow(2, lrint( log(fftTime * sampleRate) / log(2))));
     } // constructor
 
+    void reset() {
+        init();
+    }
+
 protected:
     /** Allocates memory for arrays, based on parameter settings */
     void init() {
-        hopSize = lrint(sampleRate * hopTime);
-        fftSize = lrint(pow(2, lrint( log(fftTime * sampleRate) / log(2))));
         makeFreqMap(fftSize, sampleRate);
         prevFrame.clear();
         for (int i = 0; i < freqMapSize; i++) prevFrame.push_back(0);
@@ -168,7 +169,7 @@
         int crossoverMidi = (int)lrint(log(crossoverBin*binWidth/440)/
                                        log(2) * 12 + 69);
         int i = 0;
-        while (i <= crossoverBin)
+        while (i <= crossoverBin && i <= fftSize/2)
             freqMap[i++] = i;
         while (i <= fftSize/2) {
             double midi = log(i*binWidth/440) / log(2) * 12 + 69;
@@ -179,10 +180,10 @@
         freqMapSize = freqMap[i-1] + 1;
     } // makeFreqMap()
 
-    /** Processes a frame of audio data by first computing the STFT with a
-     *  Hamming window, then mapping the frequency bins into a part-linear
-     *  part-logarithmic array, then computing the spectral flux 
-     *  then (optionally) normalising and calculating onsets.
+    /** Processes a frame of frequency-domain audio data by mapping
+     *  the frequency bins into a part-linear part-logarithmic array,
+     *  then computing the spectral flux then (optionally) normalising
+     *  and calculating onsets.
      */
     void processFrame(const float *const *inputBuffers) {
         newFrame.clear();
--- a/BeatRootVampPlugin.cpp	Fri Sep 30 11:37:25 2011 +0100
+++ b/BeatRootVampPlugin.cpp	Fri Sep 30 15:39:17 2011 +0100
@@ -16,6 +16,7 @@
 #include "BeatRootVampPlugin.h"
 #include "BeatRootProcessor.h"
 
+#include <vamp-sdk/PluginAdapter.h>
 
 BeatRootVampPlugin::BeatRootVampPlugin(float inputSampleRate) :
     Plugin(inputSampleRate)
@@ -182,7 +183,7 @@
 	return false;
     }
 
-    m_processor->initialise();
+    m_processor->reset();
 
     return true;
 }
--- a/Induction.cpp	Fri Sep 30 11:37:25 2011 +0100
+++ b/Induction.cpp	Fri Sep 30 15:39:17 2011 +0100
@@ -13,6 +13,8 @@
   COPYING included with this distribution for more information.
 */
 
+#include "Induction.h"
+
 double Induction::clusterWidth = 0.025;
 double Induction::minIOI = 0.070;
 double Induction::maxIOI = 2.500;
--- a/Induction.h	Fri Sep 30 11:37:25 2011 +0100
+++ b/Induction.h	Fri Sep 30 15:39:17 2011 +0100
@@ -17,6 +17,7 @@
 #define _INDUCTION_H_
 
 #include "Agent.h"
+#include "AgentList.h"
 #include "Event.h"
 
 #include <vector>
--- a/Makefile	Fri Sep 30 11:37:25 2011 +0100
+++ b/Makefile	Fri Sep 30 15:39:17 2011 +0100
@@ -1,9 +1,23 @@
 
 CXXFLAGS	:= -g
 
-beatroot-vamp.so:	BeatRootProcessor.o BeatRootVampPlugin.o BeatTracker.o Peaks.o Agent.o AgentList.o Induction.o
-	g++ -shared $^ -o $@ -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic -lpthread -Wl,--version-script=vamp-plugin.map
+OBJECTS	:= BeatRootProcessor.o BeatRootVampPlugin.o Peaks.o Agent.o AgentList.o Induction.o
+
+HEADERS := Agent.h AgentList.h BeatRootProcessor.h BeatRootVampPlugin.h BeatTracker.h Event.h Induction.h Peaks.h
+
+beatroot-vamp.so:	$(OBJECTS) $(HEADERS)
+	g++ -g -shared $(OBJECTS) -o $@ -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic -lpthread -Wl,--version-script=vamp-plugin.map
 
 clean:	
 	rm *.o
 
+# DO NOT DELETE
+
+Agent.o: Agent.h Event.h BeatTracker.h AgentList.h Induction.h
+AgentList.o: AgentList.h Agent.h Event.h
+BeatRootProcessor.o: BeatRootProcessor.h Peaks.h Event.h BeatTracker.h
+BeatRootProcessor.o: Agent.h AgentList.h Induction.h
+BeatRootVampPlugin.o: BeatRootVampPlugin.h BeatRootProcessor.h Peaks.h
+BeatRootVampPlugin.o: Event.h BeatTracker.h Agent.h AgentList.h Induction.h
+Induction.o: Induction.h Agent.h Event.h AgentList.h
+Peaks.o: Peaks.h
--- a/Peaks.cpp	Fri Sep 30 11:37:25 2011 +0100
+++ b/Peaks.cpp	Fri Sep 30 15:39:17 2011 +0100
@@ -15,6 +15,6 @@
 
 #include "Peaks.h"
 
-static int Peaks::pre = 3;
-static int Peaks::post = 1;
+int Peaks::pre = 3;
+int Peaks::post = 1;