annotate src/NoteHypothesis.h @ 184:9b9cdfccbd14 noteagent

Wire up note agent code -- results are not very good, so far
author Chris Cannam
date Wed, 28 May 2014 14:54:01 +0100
parents e1718e64a921
children
rev   line source
Chris@181 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@181 2
Chris@181 3 /*
Chris@181 4 Silvet
Chris@181 5
Chris@181 6 A Vamp plugin for note transcription.
Chris@181 7 Centre for Digital Music, Queen Mary University of London.
Chris@181 8 This file Copyright 2012 Chris Cannam.
Chris@181 9
Chris@181 10 This program is free software; you can redistribute it and/or
Chris@181 11 modify it under the terms of the GNU General Public License as
Chris@181 12 published by the Free Software Foundation; either version 2 of the
Chris@181 13 License, or (at your option) any later version. See the file
Chris@181 14 COPYING included with this distribution for more information.
Chris@181 15 */
Chris@181 16
Chris@181 17 #ifndef NOTE_HYPOTHESIS_H
Chris@181 18 #define NOTE_HYPOTHESIS_H
Chris@181 19
Chris@181 20 #include "AgentHypothesis.h"
Chris@181 21
Chris@181 22 #include <set>
Chris@181 23 #include <vector>
Chris@181 24
Chris@181 25 /**
Chris@181 26 * An AgentHypothesis which tests a series of instantaneous pitch
Chris@181 27 * estimates to see whether they fit a single-note relationship.
Chris@181 28 * Contains rules specific to testing note pitch and timing.
Chris@181 29 */
Chris@181 30
Chris@181 31 class NoteHypothesis : public AgentHypothesis
Chris@181 32 {
Chris@181 33 public:
Chris@181 34 /**
Chris@181 35 * Construct an empty hypothesis. This will be in New state and
Chris@181 36 * will provisionally accept any estimate.
Chris@181 37 */
Chris@181 38 NoteHypothesis();
Chris@181 39
Chris@181 40 /**
Chris@181 41 * Destroy the hypothesis
Chris@181 42 */
Chris@181 43 ~NoteHypothesis();
Chris@181 44
Chris@181 45 virtual bool accept(Observation);
Chris@181 46 virtual State getState() const;
Chris@181 47 virtual Observations getAcceptedObservations() const;
Chris@181 48
Chris@181 49 struct Note {
Chris@184 50 Note() : freq(0), time(), duration(), confidence(1.0) { }
Chris@184 51 Note(double _f, Vamp::RealTime _t, Vamp::RealTime _d, double _i) :
Chris@184 52 freq(_f), time(_t), duration(_d), confidence(_i) { }
Chris@181 53 bool operator==(const Note &e) const {
Chris@184 54 return e.freq == freq && e.time == time &&
Chris@184 55 e.duration == duration && e.confidence == confidence;
Chris@181 56 }
Chris@181 57 double freq;
Chris@181 58 Vamp::RealTime time;
Chris@181 59 Vamp::RealTime duration;
Chris@184 60 double confidence;
Chris@181 61 };
Chris@181 62
Chris@181 63 /**
Chris@181 64 * Return the mean frequency of the accepted observations
Chris@181 65 */
Chris@181 66 double getMeanFrequency() const;
Chris@184 67
Chris@184 68 /**
Chris@184 69 * Return the median frequency of the accepted observations
Chris@184 70 */
Chris@184 71 double getMedianFrequency() const;
Chris@184 72
Chris@184 73 /**
Chris@184 74 * Return the median confidence of the accepted observations
Chris@184 75 */
Chris@184 76 double getMedianConfidence() const;
Chris@181 77
Chris@181 78 /**
Chris@181 79 * Return a single note roughly matching this hypothesis
Chris@181 80 */
Chris@181 81 Note getAveragedNote() const;
Chris@181 82
Chris@181 83 /**
Chris@181 84 * Return the time of the first accepted observation
Chris@181 85 */
Chris@181 86 Vamp::RealTime getStartTime() const;
Chris@181 87
Chris@181 88 /**
Chris@181 89 * Return the difference between the start time and the end of the
Chris@181 90 * final accepted observation
Chris@181 91 */
Chris@181 92 Vamp::RealTime getDuration() const;
Chris@181 93
Chris@181 94 //!!!
Chris@181 95 bool operator==(const NoteHypothesis &other) const {
Chris@181 96 return m_state == other.m_state && m_pending == other.m_pending;
Chris@181 97 }
Chris@181 98
Chris@181 99 bool operator<(const NoteHypothesis &other) const {
Chris@184 100 if (getStartTime() != other.getStartTime()) {
Chris@184 101 return getStartTime() < other.getStartTime();
Chris@184 102 } else if (m_state != other.m_state) {
Chris@184 103 return m_state < other.m_state;
Chris@184 104 } else if (m_pending.size() != other.m_pending.size()) {
Chris@184 105 return m_pending.size() < other.m_pending.size();
Chris@184 106 } else {
Chris@184 107 Observations::const_iterator i = m_pending.begin();
Chris@184 108 Observations::const_iterator j = other.m_pending.begin();
Chris@184 109 while (i != m_pending.end()) {
Chris@184 110 if (*i == *j) {
Chris@184 111 ++i;
Chris@184 112 ++j;
Chris@184 113 } else {
Chris@184 114 return *i < *j;
Chris@184 115 }
Chris@184 116 }
Chris@184 117 return false;
Chris@184 118 }
Chris@181 119 }
Chris@181 120
Chris@181 121 private:
Chris@181 122 bool isWithinTolerance(Observation) const;
Chris@181 123 bool isOutOfDateFor(Observation) const;
Chris@181 124 bool isSatisfied() const;
Chris@181 125
Chris@181 126 State m_state;
Chris@181 127 Observations m_pending;
Chris@181 128 };
Chris@181 129
Chris@181 130 #endif