annotate src/NoteHypothesis.h @ 181:10e7c3ff575e noteagent

Experimental branch toward note-agent stuff (not actually plumbed in yet)
author Chris Cannam
date Fri, 23 May 2014 12:40:18 +0100
parents
children e1718e64a921
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@181 50 Note() : freq(0), time(), duration() { }
Chris@181 51 Note(double _f, Vamp::RealTime _t, Vamp::RealTime _d) :
Chris@181 52 freq(_f), time(_t), duration(_d) { }
Chris@181 53 bool operator==(const Note &e) const {
Chris@181 54 return e.freq == freq && e.time == time && e.duration == duration;
Chris@181 55 }
Chris@181 56 double freq;
Chris@181 57 Vamp::RealTime time;
Chris@181 58 Vamp::RealTime duration;
Chris@181 59 };
Chris@181 60
Chris@181 61 /**
Chris@181 62 * Return the mean frequency of the accepted observations
Chris@181 63 */
Chris@181 64 double getMeanFrequency() const;
Chris@181 65
Chris@181 66 /**
Chris@181 67 * Return a single note roughly matching this hypothesis
Chris@181 68 */
Chris@181 69 Note getAveragedNote() const;
Chris@181 70
Chris@181 71 /**
Chris@181 72 * Return the time of the first accepted observation
Chris@181 73 */
Chris@181 74 Vamp::RealTime getStartTime() const;
Chris@181 75
Chris@181 76 /**
Chris@181 77 * Return the difference between the start time and the end of the
Chris@181 78 * final accepted observation
Chris@181 79 */
Chris@181 80 Vamp::RealTime getDuration() const;
Chris@181 81
Chris@181 82 /**
Chris@181 83 * Convert the given sequence of accepted hypotheses into a
Chris@181 84 * sampled series of pitches (in Hz), returned at regular
Chris@181 85 * intervals determined by the given start time, end time, and
Chris@181 86 * interval. The range is [start,end], i.e. the end time is
Chris@181 87 * included. The interval must be greater than zero.
Chris@181 88 *
Chris@181 89 * Unvoiced samples are returned as 0Hz.
Chris@181 90 */
Chris@181 91 static std::vector<double> sample(const std::set<NoteHypothesis> &,
Chris@181 92 Vamp::RealTime startTime,
Chris@181 93 Vamp::RealTime endTime,
Chris@181 94 Vamp::RealTime interval);
Chris@181 95
Chris@181 96 /**
Chris@181 97 *!!! No! Not equally spaced, should be able to be anything [ordered]
Chris@181 98
Chris@181 99 * Given a series of equally spaced observations, return a series
Chris@181 100 * of the same number of pitches (in Hz) calculated by running an
Chris@181 101 * AgentFeeder<NoteHypothesis> on the observations and flattening
Chris@181 102 * and sampling the resulting accepted hypotheses.
Chris@181 103 *
Chris@181 104 * The result should contain only pitches that contributed to
Chris@181 105 * recognised notes in the input observations, with the remaining
Chris@181 106 * (unvoiced) samples returned as 0Hz.
Chris@181 107 *
Chris@181 108 * If the input observations are not equally spaced, the result is
Chris@181 109 * undefined.
Chris@181 110 *!!! (what about rounding errors from RealTime to frame and vice versa?)
Chris@181 111 *!!! (should provide a Timebase?)
Chris@181 112 *!!! update docs for updated api
Chris@181 113 */
Chris@181 114 static std::vector<double> winnow(const Observations &,
Chris@181 115 Vamp::RealTime startTime,
Chris@181 116 Vamp::RealTime endTime,
Chris@181 117 Vamp::RealTime interval);
Chris@181 118
Chris@181 119 //!!!
Chris@181 120 bool operator==(const NoteHypothesis &other) const {
Chris@181 121 return m_state == other.m_state && m_pending == other.m_pending;
Chris@181 122 }
Chris@181 123
Chris@181 124 bool operator<(const NoteHypothesis &other) const {
Chris@181 125 return getStartTime() < other.getStartTime();
Chris@181 126 }
Chris@181 127
Chris@181 128 private:
Chris@181 129 bool isWithinTolerance(Observation) const;
Chris@181 130 bool isOutOfDateFor(Observation) const;
Chris@181 131 bool isSatisfied() const;
Chris@181 132
Chris@181 133 State m_state;
Chris@181 134 Observations m_pending;
Chris@181 135 };
Chris@181 136
Chris@181 137 #endif