# HG changeset patch # User Chris Cannam # Date 1317910863 -3600 # Node ID 59520cd6abacebe83054e4a5cafadc0c8f6656e3 # Parent 7169eb47b1bcabe083ef99084213d22ac35f7156 Debug output, and some actual debugging... getting there. diff -r 7169eb47b1bc -r 59520cd6abac Agent.cpp --- a/Agent.cpp Fri Sep 30 23:11:14 2011 +0100 +++ b/Agent.cpp Thu Oct 06 15:21:03 2011 +0100 @@ -34,20 +34,35 @@ bool Agent::considerAsBeat(Event e, AgentList &a) { double err; if (beatTime < 0) { // first event +#ifdef DEBUG_BEATROOT + std::cerr << "Ag#" << idNumber << ": accepting first event trivially at " << e.time << std::endl; +#endif accept(e, 0, 1); return true; } else { // subsequent events EventList::iterator last = events.end(); --last; if (e.time - last->time > expiryTime) { +#ifdef DEBUG_BEATROOT + std::cerr << "Ag#" << idNumber << ": time " << e.time + << " too late relative to " << last->time << " (expiry " + << expiryTime << "), giving up" << std::endl; +#endif phaseScore = -1.0; // flag agent to be deleted return false; } double beats = nearbyint((e.time - beatTime) / beatInterval); err = e.time - beatTime - beats * beatInterval; +#ifdef DEBUG_BEATROOT + std::cerr << "Ag#" << idNumber << ": time " << e.time << ", err " << err << " for beats " << beats << std::endl; +#endif if ((beats > 0) && (-preMargin <= err) && (err <= postMargin)) { - if (fabs(err) > innerMargin) // Create new agent that skips this - a.add(Agent(*this)); // event (avoids large phase jump) + if (fabs(err) > innerMargin) { // Create new agent that skips this +#ifdef DEBUG_BEATROOT + std::cerr << "Ag#" << idNumber << ": creating another new agent" << std::endl; +#endif + a.add(clone()); // event (avoids large phase jump) + } accept(e, err, (int)beats); return true; } diff -r 7169eb47b1bc -r 59520cd6abac Agent.h --- a/Agent.h Fri Sep 30 23:11:14 2011 +0100 +++ b/Agent.h Thu Oct 06 15:21:03 2011 +0100 @@ -20,6 +20,10 @@ #include +#ifdef DEBUG_BEATROOT +#include +#endif + class AgentList; /** Agent is the central class for beat tracking. @@ -116,30 +120,6 @@ * @param ibi The beat period (inter-beat interval) of the Agent's tempo hypothesis. */ Agent(double ibi) { - init(ibi); - } // constructor - - /** Copy constructor. - * @param clone The Agent to duplicate. */ - Agent(const Agent &clone) { - idNumber = idCounter++; - phaseScore = clone.phaseScore; - tempoScore = clone.tempoScore; - topScoreTime = clone.topScoreTime; - beatCount = clone.beatCount; - beatInterval = clone.beatInterval; - initialBeatInterval = clone.initialBeatInterval; - beatTime = clone.beatTime; - events = EventList(clone.events); - postMargin = clone.postMargin; - preMargin = clone.preMargin; - } // copy constructor - -protected: - /** Initialise all the fields of this Agent. - * @param ibi The initial tempo hypothesis of the Agent. - */ - void init(double ibi) { innerMargin = INNER_MARGIN; correctionFactor = DEFAULT_CORRECTION_FACTOR; expiryTime = DEFAULT_EXPIRY_TIME; @@ -154,10 +134,15 @@ topScoreTime = 0.0; beatCount = 0; beatTime = -1.0; - events.clear(); - } // init() + } // constructor + Agent clone() const { + Agent a(*this); + a.idCounter++; + return a; + } +protected: double threshold(double value, double min, double max) { if (value < min) return min; @@ -187,6 +172,12 @@ (1.0 - memFactor) * conFactor * e.salience; } else phaseScore += conFactor * e.salience; +#ifdef DEBUG_BEATROOT + std::cerr << "Ag#" << idNumber << ": " << beatInterval << std::endl; + std::cerr << " Beat" << beatCount << " Time=" << beatTime + << " Score=" << tempoScore << ":P" << phaseScore << ":" + << topScoreTime << std::endl; +#endif } // accept() /** The given Event is tested for a possible beat time. The following situations can occur: diff -r 7169eb47b1bc -r 59520cd6abac AgentList.h --- a/AgentList.h Fri Sep 30 23:11:14 2011 +0100 +++ b/AgentList.h Thu Oct 06 15:21:03 2011 +0100 @@ -21,6 +21,10 @@ #include +#ifdef DEBUG_BEATROOT +#include +#endif + /** Class for maintaining the set of all Agents involved in beat tracking a piece of music. */ class AgentList @@ -38,7 +42,13 @@ bool empty() const { return list.empty(); } Container::iterator begin() { return list.begin(); } Container::iterator end() { return list.end(); } - void push_back(const Agent &a) { list.push_back(a); } + size_t size() { return list.size(); } + void push_back(const Agent &a) { + list.push_back(a); +#ifdef DEBUG_BEATROOT + std::cerr << " Added Ag#" << a.idNumber << ", have " << list.size() << " agent(s)" << std::endl; +#endif + } /** Flag for choice between sum and average beat salience values for Agent scores. * The use of summed saliences favours faster tempi or lower metrical levels. */ @@ -61,7 +71,7 @@ * @param sort Flag indicating whether the list is sorted or not */ void add(Agent newAgent, bool sort){ - list.push_back(newAgent); + push_back(newAgent); if (sort) this->sort(); } // add()/2 @@ -105,13 +115,24 @@ } } } + int removed = 0; for (iterator itr = begin(); itr != end(); ) { if (itr->phaseScore < 0.0) { + ++removed; list.erase(itr); } else { ++itr; } } +#ifdef DEBUG_BEATROOT + if (removed > 0) { + std::cerr << "removeDuplicates: removed " << removed << ", have " + << list.size() << " agent(s) remaining" << std::endl; + } + for (int i = 0; i =0) && !created && (ev.time<5.0)) { +#ifdef DEBUG_BEATROOT + std::cerr << "Creating a new agent" << std::endl; +#endif // Create new agent with different phase Agent newAgent(prevBeatInterval); - // This may add an agent to our list + // This may add another agent to our list as well newAgent.considerAsBeat(ev, *this); + add(newAgent); } prevBeatInterval = currentAgent.beatInterval; created = phaseGiven; } if (currentAgent.considerAsBeat(ev, *this)) created = true; + add(currentAgent); } // loop for each agent removeDuplicates(); } // loop for each event @@ -177,6 +205,14 @@ best = conf; } } +#ifdef DEBUG_BEATROOT + if (bestAg) { + std::cerr << "Best agent: Ag#" << bestAg->idNumber << std::endl; + std::cerr << " Av-salience = " << best << std::endl; + } else { + std::cerr << "No surviving agent - beat tracking failed" << std::endl; + } +#endif return bestAg; } // bestAgent() diff -r 7169eb47b1bc -r 59520cd6abac BeatRootProcessor.h --- a/BeatRootProcessor.h Fri Sep 30 23:11:14 2011 +0100 +++ b/BeatRootProcessor.h Thu Oct 06 15:21:03 2011 +0100 @@ -23,6 +23,10 @@ #include #include +#ifdef DEBUG_BEATROOT +#include +#endif + using std::vector; class BeatRootProcessor @@ -143,6 +147,10 @@ onsetList.push_back(e); } +#ifdef DEBUG_BEATROOT + std::cerr << "Onsets: " << onsetList.size() << std::endl; +#endif + return BeatTracker::beatTrack(onsetList); } // processFile() diff -r 7169eb47b1bc -r 59520cd6abac Induction.h --- a/Induction.h Fri Sep 30 23:11:14 2011 +0100 +++ b/Induction.h Thu Oct 06 15:21:03 2011 +0100 @@ -22,6 +22,10 @@ #include +#ifdef DEBUG_BEATROOT +#include +#endif + using std::vector; /** Performs tempo induction by finding clusters of similar @@ -227,6 +231,9 @@ a.push_back(Agent(beat)); } } +#ifdef DEBUG_BEATROOT + std::cerr << "Induction complete, returning " << a.size() << " agent(s)" << std::endl; +#endif return a; } // beatInduction() diff -r 7169eb47b1bc -r 59520cd6abac Makefile --- a/Makefile Fri Sep 30 23:11:14 2011 +0100 +++ b/Makefile Thu Oct 06 15:21:03 2011 +0100 @@ -1,5 +1,5 @@ -CXXFLAGS := -g +CXXFLAGS := -g -DDEBUG_BEATROOT OBJECTS := BeatRootProcessor.o BeatRootVampPlugin.o Peaks.o Agent.o AgentList.o Induction.o