annotate AgentList.cpp @ 37:1f175ae200a6 tip

Update RDF
author Chris Cannam
date Wed, 25 Jun 2014 13:48:49 +0100
parents 633ec097fa56
children
rev   line source
Chris@8 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@8 2
Chris@8 3 /*
Chris@8 4 Vamp feature extraction plugin for the BeatRoot beat tracker.
Chris@8 5
Chris@8 6 Centre for Digital Music, Queen Mary, University of London.
Chris@8 7 This file copyright 2011 Simon Dixon, Chris Cannam and QMUL.
Chris@8 8
Chris@8 9 This program is free software; you can redistribute it and/or
Chris@8 10 modify it under the terms of the GNU General Public License as
Chris@8 11 published by the Free Software Foundation; either version 2 of the
Chris@8 12 License, or (at your option) any later version. See the file
Chris@8 13 COPYING included with this distribution for more information.
Chris@8 14 */
Chris@8 15
Chris@8 16 #include "AgentList.h"
Chris@8 17
Chris@8 18 bool AgentList::useAverageSalience = false;
Chris@8 19 const double AgentList::DEFAULT_BI = 0.02;
Chris@8 20 const double AgentList::DEFAULT_BT = 0.04;
Chris@8 21
Chris@15 22 void AgentList::removeDuplicates()
Chris@15 23 {
Chris@15 24 sort();
Chris@15 25 for (iterator itr = begin(); itr != end(); ++itr) {
Chris@22 26 #ifdef DEBUG_BEATROOT
Chris@22 27 std::cerr << "removeDuplicates: considering agent " << (*itr)->idNumber << std::endl;
Chris@22 28 #endif
Chris@16 29 if ((*itr)->phaseScore < 0.0) // already flagged for deletion
Chris@15 30 continue;
Chris@15 31 iterator itr2 = itr;
Chris@15 32 for (++itr2; itr2 != end(); ++itr2) {
Chris@16 33 if ((*itr2)->beatInterval - (*itr)->beatInterval > DEFAULT_BI)
Chris@15 34 break;
Chris@16 35 if (fabs((*itr)->beatTime - (*itr2)->beatTime) > DEFAULT_BT)
Chris@15 36 continue;
Chris@16 37 if ((*itr)->phaseScore < (*itr2)->phaseScore) {
Chris@22 38 #ifdef DEBUG_BEATROOT
Chris@22 39 std::cerr << "agent " << (*itr)->idNumber << " is similar to but lower-scoring than agent " << (*itr2)->idNumber << ", marking for deletion" << std::endl;
Chris@22 40 #endif
Chris@16 41 (*itr)->phaseScore = -1.0; // flag for deletion
Chris@16 42 if ((*itr2)->topScoreTime < (*itr)->topScoreTime)
Chris@16 43 (*itr2)->topScoreTime = (*itr)->topScoreTime;
Chris@15 44 break;
Chris@15 45 } else {
Chris@22 46 #ifdef DEBUG_BEATROOT
Chris@22 47 std::cerr << "agent " << (*itr2)->idNumber << " is similar to but lower-scoring than agent " << (*itr)->idNumber << ", marking for deletion" << std::endl;
Chris@22 48 #endif
Chris@16 49 (*itr2)->phaseScore = -1.0; // flag for deletion
Chris@16 50 if ((*itr)->topScoreTime < (*itr2)->topScoreTime)
Chris@16 51 (*itr)->topScoreTime = (*itr2)->topScoreTime;
Chris@15 52 }
Chris@15 53 }
Chris@15 54 }
Chris@15 55 int removed = 0;
Chris@15 56 for (iterator itr = begin(); itr != end(); ) {
Chris@16 57 if ((*itr)->phaseScore < 0.0) {
Chris@15 58 ++removed;
Chris@16 59 delete *itr;
Chris@15 60 list.erase(itr);
Chris@15 61 } else {
Chris@15 62 ++itr;
Chris@15 63 }
Chris@15 64 }
Chris@15 65 #ifdef DEBUG_BEATROOT
Chris@15 66 if (removed > 0) {
Chris@15 67 std::cerr << "removeDuplicates: removed " << removed << ", have "
Chris@15 68 << list.size() << " agent(s) remaining" << std::endl;
Chris@15 69 }
Chris@15 70 int n = 0;
Chris@15 71 for (Container::iterator i = list.begin(); i != list.end(); ++i) {
Chris@16 72 std::cerr << "agent " << n++ << ": time " << (*i)->beatTime << std::endl;
Chris@15 73 }
Chris@15 74 #endif
Chris@15 75 } // removeDuplicates()
Chris@15 76
Chris@15 77
Chris@23 78 void AgentList::beatTrack(EventList el, AgentParameters params, double stop)
Chris@15 79 {
Chris@15 80 EventList::iterator ei = el.begin();
Chris@16 81 bool phaseGiven = !empty() && ((*begin())->beatTime >= 0); // if given for one, assume given for others
Chris@15 82 while (ei != el.end()) {
Chris@15 83 Event ev = *ei;
Chris@15 84 ++ei;
Chris@15 85 if ((stop > 0) && (ev.time > stop))
Chris@15 86 break;
Chris@15 87 bool created = phaseGiven;
Chris@15 88 double prevBeatInterval = -1.0;
Chris@15 89 // cc: Duplicate our list of agents, and scan through the
Chris@15 90 // copy. This means we can safely add agents to our own
Chris@15 91 // list while scanning without disrupting our scan. Each
Chris@15 92 // agent needs to be re-added to our own list explicitly
Chris@15 93 // (since it is modified by e.g. considerAsBeat)
Chris@15 94 Container currentAgents = list;
Chris@15 95 list.clear();
Chris@15 96 for (Container::iterator ai = currentAgents.begin();
Chris@15 97 ai != currentAgents.end(); ++ai) {
Chris@16 98 Agent *currentAgent = *ai;
Chris@16 99 if (currentAgent->beatInterval != prevBeatInterval) {
Chris@15 100 if ((prevBeatInterval>=0) && !created && (ev.time<5.0)) {
Chris@15 101 #ifdef DEBUG_BEATROOT
Chris@15 102 std::cerr << "Creating a new agent" << std::endl;
Chris@15 103 #endif
Chris@15 104 // Create new agent with different phase
Chris@23 105 Agent *newAgent = new Agent(params, prevBeatInterval);
Chris@15 106 // This may add another agent to our list as well
Chris@16 107 newAgent->considerAsBeat(ev, *this);
Chris@15 108 add(newAgent);
Chris@15 109 }
Chris@16 110 prevBeatInterval = currentAgent->beatInterval;
Chris@15 111 created = phaseGiven;
Chris@15 112 }
Chris@16 113 if (currentAgent->considerAsBeat(ev, *this))
Chris@15 114 created = true;
Chris@15 115 add(currentAgent);
Chris@15 116 } // loop for each agent
Chris@15 117 removeDuplicates();
Chris@15 118 } // loop for each event
Chris@15 119 } // beatTrack()
Chris@15 120
Chris@15 121 Agent *AgentList::bestAgent()
Chris@15 122 {
Chris@15 123 double best = -1.0;
Chris@15 124 Agent *bestAg = 0;
Chris@15 125 for (iterator itr = begin(); itr != end(); ++itr) {
Chris@16 126 if ((*itr)->events.empty()) continue;
Chris@16 127 double conf = ((*itr)->phaseScore + (*itr)->tempoScore) /
Chris@16 128 (useAverageSalience? (double)(*itr)->beatCount: 1.0);
Chris@15 129 if (conf > best) {
Chris@16 130 bestAg = *itr;
Chris@15 131 best = conf;
Chris@15 132 }
Chris@15 133 }
Chris@15 134 #ifdef DEBUG_BEATROOT
Chris@15 135 if (bestAg) {
Chris@15 136 std::cerr << "Best agent: Ag#" << bestAg->idNumber << std::endl;
Chris@15 137 std::cerr << " Av-salience = " << best << std::endl;
Chris@15 138 } else {
Chris@15 139 std::cerr << "No surviving agent - beat tracking failed" << std::endl;
Chris@15 140 }
Chris@15 141 #endif
Chris@15 142 return bestAg;
Chris@15 143 } // bestAgent()
Chris@15 144