Chris@8: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@8: Chris@8: /* Chris@8: Vamp feature extraction plugin for the BeatRoot beat tracker. Chris@8: Chris@8: Centre for Digital Music, Queen Mary, University of London. Chris@8: This file copyright 2011 Simon Dixon, Chris Cannam and QMUL. Chris@8: Chris@8: This program is free software; you can redistribute it and/or Chris@8: modify it under the terms of the GNU General Public License as Chris@8: published by the Free Software Foundation; either version 2 of the Chris@8: License, or (at your option) any later version. See the file Chris@8: COPYING included with this distribution for more information. Chris@8: */ Chris@8: Chris@8: #ifndef _AGENT_LIST_H_ Chris@8: #define _AGENT_LIST_H_ Chris@8: Chris@8: #include "Agent.h" Chris@8: #include "Event.h" Chris@8: Chris@13: #include Chris@8: #include Chris@8: Chris@12: #ifdef DEBUG_BEATROOT Chris@12: #include Chris@12: #endif Chris@12: Chris@8: /** Class for maintaining the set of all Agents involved in beat tracking a piece of music. Chris@8: */ Chris@8: class AgentList Chris@8: { Chris@8: public: Chris@16: typedef std::vector Container; Chris@8: typedef Container::iterator iterator; Chris@8: Chris@8: protected: Chris@8: Container list; Chris@8: Chris@20: static bool agentComparator(const Agent *a, const Agent *b) { Chris@20: if (a->beatInterval == b->beatInterval) { Chris@20: return a->idNumber < b->idNumber; // ensure stable ordering Chris@20: } else { Chris@20: return a->beatInterval < b->beatInterval; Chris@20: } Chris@20: } Chris@20: Chris@8: public: Chris@8: // expose some vector methods Chris@8: //!!! can we remove these again once the rest of AgentList is implemented? Chris@8: bool empty() const { return list.empty(); } Chris@8: Container::iterator begin() { return list.begin(); } Chris@8: Container::iterator end() { return list.end(); } Chris@12: size_t size() { return list.size(); } Chris@16: void push_back(Agent *a) { Chris@12: list.push_back(a); Chris@12: #ifdef DEBUG_BEATROOT Chris@16: std::cerr << " Added Ag#" << a->idNumber << ", have " << list.size() << " agent(s)" << std::endl; Chris@12: #endif Chris@12: } Chris@8: Chris@11: /** Flag for choice between sum and average beat salience values for Agent scores. Chris@11: * The use of summed saliences favours faster tempi or lower metrical levels. */ Chris@11: static bool useAverageSalience; Chris@8: Chris@11: /** For the purpose of removing duplicate agents, the default JND of IBI */ Chris@11: static const double DEFAULT_BI; Chris@8: Chris@11: /** For the purpose of removing duplicate agents, the default JND of phase */ Chris@11: static const double DEFAULT_BT; Chris@8: Chris@11: /** Inserts newAgent into the list in ascending order of beatInterval */ Chris@16: void add(Agent *a) { Chris@11: add(a, true); Chris@11: } // add()/1 Chris@8: Chris@11: /** Appends newAgent to list (sort==false), or inserts newAgent into the list Chris@11: * in ascending order of beatInterval Chris@11: * @param newAgent The agent to be added to the list Chris@11: * @param sort Flag indicating whether the list is sorted or not Chris@11: */ Chris@16: void add(Agent *newAgent, bool sort){ Chris@12: push_back(newAgent); Chris@11: if (sort) this->sort(); Chris@11: } // add()/2 Chris@8: Chris@11: /** Sorts the AgentList by increasing beatInterval. */ Chris@11: void sort() { Chris@20: #ifdef DEBUG_BEATROOT Chris@20: std::cerr << "sort: before: "; Chris@20: for (iterator i = list.begin(); i != list.end(); ++i) { Chris@20: std::cerr << (*i)->idNumber << " "; Chris@20: } Chris@20: std::cerr << std::endl; Chris@20: #endif Chris@20: std::sort(list.begin(), list.end(), agentComparator); Chris@20: #ifdef DEBUG_BEATROOT Chris@20: std::cerr << "sort: after: "; Chris@20: for (iterator i = list.begin(); i != list.end(); ++i) { Chris@20: std::cerr << (*i)->idNumber << " "; Chris@20: } Chris@20: std::cerr << std::endl; Chris@20: #endif Chris@11: } // sort() Chris@8: Chris@11: /** Removes the given item from the list. Chris@11: * @param ptr Points to the Agent which is removed from the list Chris@11: */ Chris@11: void remove(iterator itr) { Chris@11: list.erase(itr); Chris@11: } // remove() Chris@8: Chris@8: protected: Chris@11: /** Removes Agents from the list which are duplicates of other Agents. Chris@11: * A duplicate is defined by the tempo and phase thresholds Chris@11: * thresholdBI and thresholdBT respectively. Chris@11: */ Chris@15: void removeDuplicates(); Chris@8: Chris@8: public: Chris@11: /** Perform beat tracking on a list of events (onsets). Chris@11: * @param el The list of onsets (or events or peaks) to beat track Chris@11: */ Chris@23: void beatTrack(EventList el, AgentParameters params) { Chris@23: beatTrack(el, params, -1.0); Chris@11: } // beatTrack()/1 Chris@8: Chris@11: /** Perform beat tracking on a list of events (onsets). Chris@11: * @param el The list of onsets (or events or peaks) to beat track. Chris@11: * @param stop Do not find beats after stop seconds. Chris@11: */ Chris@23: void beatTrack(EventList el, AgentParameters params, double stop); Chris@8: Chris@11: /** Finds the Agent with the highest score in the list, or NULL if beat tracking has failed. Chris@11: * @return The Agent with the highest score Chris@11: */ Chris@15: Agent *bestAgent(); Chris@8: Chris@8: }; // class AgentList Chris@8: Chris@8: #endif Chris@8: