diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/NoteHypothesis.h	Fri May 23 12:40:18 2014 +0100
@@ -0,0 +1,137 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+  Silvet
+
+  A Vamp plugin for note transcription.
+  Centre for Digital Music, Queen Mary University of London.
+  This file Copyright 2012 Chris Cannam.
+    
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.  See the file
+  COPYING included with this distribution for more information.
+*/
+
+#ifndef NOTE_HYPOTHESIS_H
+#define NOTE_HYPOTHESIS_H
+
+#include "AgentHypothesis.h"
+
+#include <set>
+#include <vector>
+
+/**
+ * An AgentHypothesis which tests a series of instantaneous pitch
+ * estimates to see whether they fit a single-note relationship.
+ * Contains rules specific to testing note pitch and timing.
+ */
+
+class NoteHypothesis : public AgentHypothesis
+{
+public:
+    /**
+     * Construct an empty hypothesis. This will be in New state and
+     * will provisionally accept any estimate.
+     */
+    NoteHypothesis();
+
+    /**
+     * Destroy the hypothesis
+     */
+    ~NoteHypothesis();
+
+    virtual bool accept(Observation);
+    virtual State getState() const;
+    virtual Observations getAcceptedObservations() const;
+
+    struct Note {
+        Note() : freq(0), time(), duration() { }
+        Note(double _f, Vamp::RealTime _t, Vamp::RealTime _d) :
+            freq(_f), time(_t), duration(_d) { }
+        bool operator==(const Note &e) const {
+            return e.freq == freq && e.time == time && e.duration == duration;
+        }
+	double freq;
+	Vamp::RealTime time;
+	Vamp::RealTime duration;
+    };
+    
+    /**
+     * Return the mean frequency of the accepted observations
+     */
+    double getMeanFrequency() const;
+
+    /**
+     * Return a single note roughly matching this hypothesis
+     */
+    Note getAveragedNote() const;
+    
+    /**
+     * Return the time of the first accepted observation
+     */
+    Vamp::RealTime getStartTime() const;
+
+    /**
+     * Return the difference between the start time and the end of the
+     * final accepted observation
+     */
+    Vamp::RealTime getDuration() const;
+
+    /**
+     * Convert the given sequence of accepted hypotheses into a
+     * sampled series of pitches (in Hz), returned at regular
+     * intervals determined by the given start time, end time, and
+     * interval. The range is [start,end], i.e. the end time is
+     * included. The interval must be greater than zero.
+     *
+     * Unvoiced samples are returned as 0Hz.
+     */
+    static std::vector<double> sample(const std::set<NoteHypothesis> &,
+                                      Vamp::RealTime startTime,
+                                      Vamp::RealTime endTime,
+                                      Vamp::RealTime interval);
+
+    /**
+     *!!! No! Not equally spaced, should be able to be anything [ordered]
+     
+     * Given a series of equally spaced observations, return a series
+     * of the same number of pitches (in Hz) calculated by running an
+     * AgentFeeder<NoteHypothesis> on the observations and flattening
+     * and sampling the resulting accepted hypotheses.
+     *
+     * The result should contain only pitches that contributed to
+     * recognised notes in the input observations, with the remaining
+     * (unvoiced) samples returned as 0Hz.
+     *
+     * If the input observations are not equally spaced, the result is
+     * undefined.
+     *!!! (what about rounding errors from RealTime to frame and vice versa?)
+     *!!! (should provide a Timebase?)
+     *!!! update docs for updated api
+     */
+    static std::vector<double> winnow(const Observations &,
+                                      Vamp::RealTime startTime,
+                                      Vamp::RealTime endTime,
+                                      Vamp::RealTime interval);
+
+    //!!!
+    bool operator==(const NoteHypothesis &other) const {
+        return m_state == other.m_state && m_pending == other.m_pending;
+    }
+
+    bool operator<(const NoteHypothesis &other) const {
+        return getStartTime() < other.getStartTime();
+    }
+
+private:
+    bool isWithinTolerance(Observation) const;
+    bool isOutOfDateFor(Observation) const;
+    bool isSatisfied() const;
+    
+    State m_state;
+    Observations m_pending;
+};
+
+#endif