annotate Agent.cpp @ 8:f04f87b5e643

Add agent list class, and continue plodding through
author Chris Cannam
date Fri, 30 Sep 2011 11:37:25 +0100
parents 02d388f98c23
children 4f6626f9ffac
rev   line source
Chris@6 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@6 2
Chris@6 3 /*
Chris@6 4 Vamp feature extraction plugin for the BeatRoot beat tracker.
Chris@6 5
Chris@6 6 Centre for Digital Music, Queen Mary, University of London.
Chris@6 7 This file copyright 2011 Simon Dixon, Chris Cannam and QMUL.
Chris@6 8
Chris@6 9 This program is free software; you can redistribute it and/or
Chris@6 10 modify it under the terms of the GNU General Public License as
Chris@6 11 published by the Free Software Foundation; either version 2 of the
Chris@6 12 License, or (at your option) any later version. See the file
Chris@6 13 COPYING included with this distribution for more information.
Chris@6 14 */
Chris@6 15
Chris@6 16 #include "Agent.h"
Chris@6 17 #include "BeatTracker.h"
Chris@6 18
Chris@6 19 double Agent::POST_MARGIN_FACTOR = 0.3;
Chris@6 20 double Agent::PRE_MARGIN_FACTOR = 0.15;
Chris@6 21 const double Agent::INNER_MARGIN = 0.040;
Chris@6 22 double Agent::MAX_CHANGE = 0.2;
Chris@6 23 double Agent::CONF_FACTOR = 0.5;
Chris@6 24 const double Agent::DEFAULT_CORRECTION_FACTOR = 50.0;
Chris@6 25 const double Agent::DEFAULT_EXPIRY_TIME = 10.0;
Chris@6 26
Chris@6 27 int Agent::idCounter = 0;
Chris@6 28
Chris@6 29 double Agent::innerMargin = 0.0;
Chris@6 30 double Agent::outerMargin = 0.0;
Chris@6 31 double Agent::correctionFactor = 0.0;
Chris@6 32 double Agent::expiryTime = 0.0;
Chris@6 33 double Agent::decayFactor = 0.0;
Chris@6 34
Chris@8 35 bool Agent::considerAsBeat(Event e, AgentList &a) {
Chris@6 36 double err;
Chris@6 37 if (beatTime < 0) { // first event
Chris@6 38 accept(e, 0, 1);
Chris@6 39 return true;
Chris@6 40 } else { // subsequent events
Chris@8 41 if (e.time - events.l.getLast().keyDown > expiryTime) {
Chris@6 42 phaseScore = -1.0; // flag agent to be deleted
Chris@6 43 return false;
Chris@6 44 }
Chris@8 45 double beats = nearbyint((e.time - beatTime) / beatInterval);
Chris@8 46 err = e.time - beatTime - beats * beatInterval;
Chris@6 47 if ((beats > 0) && (-preMargin <= err) && (err <= postMargin)) {
Chris@8 48 if (fabs(err) > innerMargin) // Create new agent that skips this
Chris@8 49 a.push_back(Agent(*this)); // event (avoids large phase jump)
Chris@6 50 accept(e, err, (int)beats);
Chris@6 51 return true;
Chris@6 52 }
Chris@6 53 }
Chris@6 54 return false;
Chris@6 55 } // considerAsBeat()
Chris@6 56
Chris@6 57
Chris@6 58 void fillBeats(double start) {
Chris@6 59 double prevBeat = 0, nextBeat, currentInterval, beats;
Chris@6 60 EventList::iterator list = events.begin();
Chris@6 61 if (list != events.end()) {
Chris@6 62 ++list;
Chris@6 63 prevBeat = list->time;
Chris@6 64 --list;
Chris@6 65 }
Chris@6 66 for ( ; list != events.end(); ++list) {
Chris@6 67 ++list;
Chris@6 68 nextBeat = list->time;
Chris@6 69 --list;
Chris@6 70 beats = nearbyint((nextBeat - prevBeat) / beatInterval - 0.01); //prefer slow
Chris@6 71 currentInterval = (nextBeat - prevBeat) / beats;
Chris@6 72 for ( ; (nextBeat > start) && (beats > 1.5); beats--) {
Chris@6 73 prevBeat += currentInterval;
Chris@6 74 //!!! need to insert this event after current itr
Chris@6 75 list.add(BeatTracker::newBeat(prevBeat, 0)); // more than once OK??
Chris@6 76 }
Chris@6 77 prevBeat = nextBeat;
Chris@6 78 }
Chris@6 79 } // fillBeats()