annotate Agent.h @ 37:1f175ae200a6 tip

Update RDF
author Chris Cannam
date Wed, 25 Jun 2014 13:48:49 +0100
parents 633ec097fa56
children
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 #ifndef _AGENT_H_
Chris@6 17 #define _AGENT_H_
Chris@6 18
Chris@6 19 #include "Event.h"
Chris@6 20
Chris@9 21 #include <cmath>
Chris@9 22
Chris@12 23 #ifdef DEBUG_BEATROOT
Chris@12 24 #include <iostream>
Chris@12 25 #endif
Chris@12 26
Chris@8 27 class AgentList;
Chris@8 28
Chris@23 29 class AgentParameters
Chris@23 30 {
Chris@23 31 public:
Chris@23 32 static const double DEFAULT_POST_MARGIN_FACTOR;
Chris@23 33 static const double DEFAULT_PRE_MARGIN_FACTOR;
Chris@23 34 static const double DEFAULT_MAX_CHANGE;
Chris@23 35 static const double DEFAULT_EXPIRY_TIME;
Chris@23 36
Chris@23 37 AgentParameters() :
Chris@23 38 postMarginFactor(DEFAULT_POST_MARGIN_FACTOR),
Chris@23 39 preMarginFactor(DEFAULT_PRE_MARGIN_FACTOR),
Chris@23 40 maxChange(DEFAULT_MAX_CHANGE),
Chris@23 41 expiryTime(DEFAULT_EXPIRY_TIME) { }
Chris@23 42
Chris@23 43 /** The maximum amount by which a beat can be later than the
Chris@23 44 * predicted beat time, expressed as a fraction of the beat
Chris@23 45 * period. */
Chris@23 46 double postMarginFactor;
Chris@23 47
Chris@23 48 /** The maximum amount by which a beat can be earlier than the
Chris@23 49 * predicted beat time, expressed as a fraction of the beat
Chris@23 50 * period. */
Chris@23 51 double preMarginFactor;
Chris@23 52
Chris@23 53 /** The maximum allowed deviation from the initial tempo,
Chris@23 54 * expressed as a fraction of the initial beat period. */
Chris@23 55 double maxChange;
Chris@23 56
Chris@23 57 /** The default value of expiryTime, which is the time (in
Chris@23 58 * seconds) after which an Agent that has no Event matching its
Chris@23 59 * beat predictions will be destroyed. */
Chris@23 60 double expiryTime;
Chris@23 61 };
Chris@23 62
Chris@6 63 /** Agent is the central class for beat tracking.
Chris@6 64 * Each Agent object has a tempo hypothesis, a history of tracked beats, and
Chris@6 65 * a score evaluating the continuity, regularity and salience of its beat track.
Chris@6 66 */
Chris@6 67 class Agent
Chris@6 68 {
Chris@6 69 public:
Chris@23 70 /** The default value of innerMargin, which is the maximum time
Chris@23 71 * (in seconds) that a beat can deviate from the predicted beat
Chris@23 72 * time without a fork occurring. */
Chris@6 73 static const double INNER_MARGIN;
Chris@6 74
Chris@23 75 /** The slope of the penalty function for onsets which do not
Chris@23 76 * coincide precisely with predicted beat times. */
Chris@23 77 static const double CONF_FACTOR;
Chris@6 78
Chris@23 79 /** The reactiveness/inertia balance, i.e. degree of change in the
Chris@23 80 * tempo, is controlled by the correctionFactor variable. This
Chris@23 81 * constant defines its default value, which currently is not
Chris@23 82 * subsequently changed. The beat period is updated by the
Chris@23 83 * reciprocal of the correctionFactor multiplied by the
Chris@23 84 * difference between the predicted beat time and matching
Chris@23 85 * onset. */
Chris@6 86 static const double DEFAULT_CORRECTION_FACTOR;
Chris@6 87
Chris@6 88 protected:
Chris@6 89 /** The identity number of the next created Agent */
Chris@6 90 static int idCounter;
Chris@6 91
Chris@23 92 /** The maximum time (in seconds) that a beat can deviate from the
Chris@23 93 * predicted beat time without a fork occurring (i.e. a 2nd Agent
Chris@23 94 * being created). */
Chris@23 95 double innerMargin;
Chris@6 96
Chris@23 97 /** Controls the reactiveness/inertia balance, i.e. degree of
Chris@23 98 * change in the tempo. The beat period is updated by the
Chris@23 99 * reciprocal of the correctionFactor multiplied by the
Chris@23 100 * difference between the predicted beat time and matching
Chris@23 101 * onset. */
Chris@23 102 double correctionFactor;
Chris@6 103
Chris@23 104 /** The time (in seconds) after which an Agent that has no Event
Chris@23 105 * matching its beat predictions will be destroyed. */
Chris@23 106 double expiryTime;
Chris@6 107
Chris@23 108 /** For scoring Agents in a (non-existent) real-time version
Chris@23 109 * (otherwise not used). */
Chris@23 110 double decayFactor;
Chris@6 111
Chris@6 112 public:
Chris@6 113 /** The size of the outer half-window before the predicted beat time. */
Chris@6 114 double preMargin;
Chris@6 115
Chris@6 116 /** The size of the outer half-window after the predicted beat time. */
Chris@6 117 double postMargin;
Chris@6 118
Chris@6 119 /** The Agent's unique identity number. */
Chris@6 120 int idNumber;
Chris@6 121
Chris@6 122 /** To be used in real-time version?? */
Chris@6 123 double tempoScore;
Chris@6 124
Chris@23 125 /** Sum of salience values of the Events which have been
Chris@23 126 * interpreted as beats by this Agent, weighted by their nearness
Chris@23 127 * to the predicted beat times. */
Chris@6 128 double phaseScore;
Chris@6 129
Chris@23 130 /** How long has this agent been the best? For real-time version;
Chris@23 131 * otherwise not used. */
Chris@6 132 double topScoreTime;
Chris@6 133
Chris@23 134 /** The number of beats found by this Agent, including
Chris@23 135 * interpolated beats. */
Chris@6 136 int beatCount;
Chris@6 137
Chris@23 138 /** The current tempo hypothesis of the Agent, expressed as the
Chris@23 139 * beat period in seconds. */
Chris@6 140 double beatInterval;
Chris@6 141
Chris@23 142 /** The initial tempo hypothesis of the Agent, expressed as the
Chris@23 143 * beat period in seconds. */
Chris@6 144 double initialBeatInterval;
Chris@6 145
Chris@6 146 /** The time of the most recent beat accepted by this Agent. */
Chris@6 147 double beatTime;
Chris@23 148
Chris@23 149 /** The maximum allowed deviation from the initial tempo,
Chris@23 150 * expressed as a fraction of the initial beat period. */
Chris@23 151 double maxChange;
Chris@6 152
Chris@23 153 /** The list of Events (onsets) accepted by this Agent as beats,
Chris@23 154 * plus interpolated beats. */
Chris@6 155 EventList events;
Chris@6 156
Chris@6 157 /** Constructor: the work is performed by init()
Chris@6 158 * @param ibi The beat period (inter-beat interval) of the Agent's tempo hypothesis.
Chris@6 159 */
Chris@23 160 Agent(AgentParameters params, double ibi) :
Chris@23 161 innerMargin(INNER_MARGIN),
Chris@23 162 correctionFactor(DEFAULT_CORRECTION_FACTOR),
Chris@23 163 expiryTime(params.expiryTime),
Chris@23 164 decayFactor(0),
Chris@23 165 preMargin(ibi * params.preMarginFactor),
Chris@23 166 postMargin(ibi * params.postMarginFactor),
Chris@23 167 idNumber(idCounter++),
Chris@23 168 tempoScore(0.0),
Chris@23 169 phaseScore(0.0),
Chris@23 170 topScoreTime(0.0),
Chris@23 171 beatCount(0),
Chris@23 172 beatInterval(ibi),
Chris@23 173 initialBeatInterval(ibi),
Chris@23 174 beatTime(-1.0),
Chris@23 175 maxChange(params.maxChange) {
Chris@12 176 } // constructor
Chris@6 177
Chris@16 178 Agent *clone() const {
Chris@16 179 Agent *a = new Agent(*this);
Chris@16 180 a->idNumber = idCounter++;
Chris@12 181 return a;
Chris@12 182 }
Chris@6 183
Chris@12 184 protected:
Chris@6 185 double threshold(double value, double min, double max) {
Chris@6 186 if (value < min)
Chris@6 187 return min;
Chris@6 188 if (value > max)
Chris@6 189 return max;
Chris@6 190 return value;
Chris@6 191 }
Chris@6 192
Chris@8 193 public:
Chris@6 194 /** Accept a new Event as a beat time, and update the state of the Agent accordingly.
Chris@6 195 * @param e The Event which is accepted as being on the beat.
Chris@6 196 * @param err The difference between the predicted and actual beat times.
Chris@6 197 * @param beats The number of beats since the last beat that matched an Event.
Chris@6 198 */
Chris@15 199 void accept(Event e, double err, int beats);
Chris@6 200
Chris@6 201 /** The given Event is tested for a possible beat time. The following situations can occur:
Chris@6 202 * 1) The Agent has no beats yet; the Event is accepted as the first beat.
Chris@6 203 * 2) The Event is beyond expiryTime seconds after the Agent's last 'confirming' beat; the Agent is terminated.
Chris@6 204 * 3) The Event is within the innerMargin of the beat prediction; it is accepted as a beat.
Chris@9 205 * 4) The Event is within the postMargin's of the beat prediction; it is accepted as a beat by this Agent,
Chris@6 206 * and a new Agent is created which doesn't accept it as a beat.
Chris@6 207 * 5) The Event is ignored because it is outside the windows around the Agent's predicted beat time.
Chris@6 208 * @param e The Event to be tested
Chris@6 209 * @param a The list of all agents, which is updated if a new agent is created.
Chris@6 210 * @return Indicate whether the given Event was accepted as a beat by this Agent.
Chris@6 211 */
Chris@8 212 bool considerAsBeat(Event e, AgentList &a);
Chris@6 213
Chris@6 214 /** Interpolates missing beats in the Agent's beat track, starting from the beginning of the piece. */
Chris@6 215 void fillBeats() {
Chris@6 216 fillBeats(-1.0);
Chris@6 217 } // fillBeats()/0
Chris@6 218
Chris@6 219 /** Interpolates missing beats in the Agent's beat track.
Chris@6 220 * @param start Ignore beats earlier than this start time
Chris@6 221 */
Chris@6 222 void fillBeats(double start);
Chris@6 223
Chris@6 224 }; // class Agent
Chris@6 225
Chris@6 226 #endif