Mercurial > hg > silvet
changeset 211:f742095301a6 noteagent
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 30 Jun 2014 11:38:33 +0100 |
parents | 5f4a38f8d9ff (diff) 2b3c6d53c1f1 (current diff) |
children | |
files | |
diffstat | 12 files changed, 1868 insertions(+), 199 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.inc Mon Jun 30 11:38:12 2014 +0100 +++ b/Makefile.inc Mon Jun 30 11:38:33 2014 +0100 @@ -19,11 +19,30 @@ PLUGIN := silvet$(PLUGIN_EXT) -PLUGIN_HEADERS := $(SRC_DIR)/Silvet.h $(SRC_DIR)/EM.h $(SRC_DIR)/Instruments.h -PLUGIN_SOURCES := $(SRC_DIR)/Silvet.cpp $(SRC_DIR)/EM.cpp $(SRC_DIR)/Instruments.cpp $(SRC_DIR)/libmain.cpp +PLUGIN_HEADERS := \ + $(SRC_DIR)/Silvet.h \ + $(SRC_DIR)/EM.h \ + $(SRC_DIR)/Instruments.h \ + $(SRC_DIR)/AgentFeeder.h \ + $(SRC_DIR)/AgentFeederMono.h \ + $(SRC_DIR)/AgentFeederPoly.h \ + $(SRC_DIR)/AgentHypothesis.h \ + $(SRC_DIR)/NoteHypothesis.h -BQVEC_HEADERS := $(BQVEC_DIR)/Allocators.h $(BQVEC_DIR)/Restrict.h $(BQVEC_DIR)/VectorOps.h -BQVEC_SOURCES := $(BQVEC_DIR)/Allocators.cpp +PLUGIN_SOURCES := \ + $(SRC_DIR)/Silvet.cpp \ + $(SRC_DIR)/EM.cpp \ + $(SRC_DIR)/Instruments.cpp \ + $(SRC_DIR)/NoteHypothesis.cpp \ + $(SRC_DIR)/libmain.cpp + +BQVEC_HEADERS := \ + $(BQVEC_DIR)/Allocators.h \ + $(BQVEC_DIR)/Restrict.h \ + $(BQVEC_DIR)/VectorOps.h + +BQVEC_SOURCES := \ + $(BQVEC_DIR)/Allocators.cpp HEADERS := $(PLUGIN_HEADERS) $(BQVEC_HEADERS) SOURCES := $(PLUGIN_SOURCES) $(BQVEC_SOURCES) @@ -48,7 +67,9 @@ # DO NOT DELETE -src/Silvet.o: src/Silvet.h src/MedianFilter.h src/Instruments.h src/EM.h +src/Silvet.o: src/Silvet.h src/MedianFilter.h src/Instruments.h +src/Silvet.o: src/NoteHypothesis.h src/AgentHypothesis.h src/EM.h +src/Silvet.o: src/AgentFeederPoly.h src/AgentFeeder.h src/Silvet.o: constant-q-cpp/src/dsp/Resampler.h src/EM.o: src/EM.h src/Instruments.h src/Instruments.o: src/Instruments.h data/include/templates.h @@ -58,9 +79,17 @@ src/Instruments.o: data/include/oboe.h data/include/tenorsax.h src/Instruments.o: data/include/violin.h data/include/piano1.h src/Instruments.o: data/include/piano2.h data/include/piano3.h +src/NoteHypothesis.o: src/NoteHypothesis.h src/AgentHypothesis.h +src/NoteHypothesis.o: src/AgentFeederPoly.h src/AgentFeeder.h src/libmain.o: src/Silvet.h src/MedianFilter.h src/Instruments.h +src/libmain.o: src/NoteHypothesis.h src/AgentHypothesis.h bqvec/src/Allocators.o: bqvec/src/Allocators.h bqvec/src/VectorOps.h bqvec/src/Allocators.o: bqvec/src/Restrict.h -src/Silvet.o: src/MedianFilter.h src/Instruments.h +src/Silvet.o: src/MedianFilter.h src/Instruments.h src/NoteHypothesis.h +src/Silvet.o: src/AgentHypothesis.h +src/AgentFeeder.o: src/AgentHypothesis.h +src/AgentFeederMono.o: src/AgentFeeder.h src/AgentHypothesis.h +src/AgentFeederPoly.o: src/AgentFeeder.h src/AgentHypothesis.h +src/NoteHypothesis.o: src/AgentHypothesis.h bqvec/src/Allocators.o: bqvec/src/VectorOps.h bqvec/src/Restrict.h bqvec/src/VectorOps.o: bqvec/src/Restrict.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/AgentFeeder.h Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,31 @@ +/* -*- 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 AGENT_FEEDER_H +#define AGENT_FEEDER_H + +#include "AgentHypothesis.h" + +class AgentFeeder +{ +public: + virtual void feed(AgentHypothesis::Observation) = 0; + virtual void finish() = 0; + + virtual ~AgentFeeder() { } +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/AgentFeederMono.h Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,180 @@ +/* -*- 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 AGENT_FEEDER_MONO_H +#define AGENT_FEEDER_MONO_H + +#include "AgentFeeder.h" + +//#define DEBUG_FEEDER 1 + +/** + * Take a series of observations or estimates (one at a time) and feed + * them to a set of agent hypotheses, creating a new candidate agent + * for each observation and also testing the observation against the + * existing set of hypotheses. + * + * One satisfied hypothesis is considered to be "accepted" at any + * moment (that is, the earliest contemporary hypothesis to have + * become satisfied). The series of accepted and completed hypotheses + * from construction to the present time can be queried through + * retrieveAcceptedHypotheses(), which detaches them from the current + * feeder (i.e. hypotheses returned from one call to this function + * will not be returned by any subsequent call). + * + * Call feed() to provide a new observation. Call finish() when all + * observations have been provided. The set of hypotheses returned by + * getAcceptedHypotheses() will not be complete unless finish() has + * been called. + */ +template <typename Hypothesis> +class AgentFeederMono : public AgentFeeder +{ +private: + typedef std::vector<Hypothesis> Hypotheses; + +public: + AgentFeederMono() : m_haveCurrent(false) { } + + virtual void feed(AgentHypothesis::Observation o) { + +#ifdef DEBUG_FEEDER + std::cerr << "feed: have observation [value = " << o.value << ", time = " << o.time << "]" << std::endl; +#endif + + if (m_haveCurrent) { + if (m_current.accept(o)) { + return; + } + if (m_current.getState() == Hypothesis::Expired) { + m_accepted.push_back(m_current); +#ifdef DEBUG_FEEDER + std::cerr << "current has expired, pushing to accepted" << std::endl; +#endif + m_haveCurrent = false; + } + } + + bool swallowed = false; + +#ifdef DEBUG_FEEDER + std::cerr << "not swallowed by current" << std::endl; +#endif + + Hypotheses newCandidates; + + for (typename Hypotheses::iterator i = m_candidates.begin(); + i != m_candidates.end(); ++i) { + + Hypothesis h = *i; + + if (swallowed) { + + // don't offer: each observation can only belong to one + // satisfied hypothesis + newCandidates.push_back(h); + + } else { + + if (h.accept(o)) { +#ifdef DEBUG_FEEDER + std::cerr << "accepted, state is " << h.getState() << std::endl; +#endif + if (h.getState() == Hypothesis::Satisfied) { + + swallowed = true; + + if (!m_haveCurrent || + m_current.getState() == Hypothesis::Expired || + m_current.getState() == Hypothesis::Rejected) { +#ifdef DEBUG_FEEDER + std::cerr << "current has ended, updating from candidate" << std::endl; +#endif + m_current = h; + m_haveCurrent = true; + } else { + newCandidates.push_back(h); + } + + } else { + newCandidates.push_back(h); + } + } + } + } + + if (!swallowed) { + Hypothesis h; + h.accept(o); // must succeed, as h is new + newCandidates.push_back(h); +#ifdef DEBUG_FEEDER + std::cerr << "not swallowed, creating new hypothesis" << std::endl; +#endif + } + + // reap rejected/expired hypotheses from candidates list, + // and assign back to m_candidates + + m_candidates.clear(); + + for (typename Hypotheses::const_iterator i = newCandidates.begin(); + i != newCandidates.end(); ++i) { + Hypothesis h = *i; + if (h.getState() != Hypothesis::Rejected && + h.getState() != Hypothesis::Expired) { + m_candidates.push_back(h); + } else { +#ifdef DEBUG_FEEDER + std::cerr << "reaping a candidate" << std::endl; +#endif + } + } +#ifdef DEBUG_FEEDER + std::cerr << "have " << m_candidates.size() << " candidates" << std::endl; +#endif + } + + virtual void finish() { + if (m_haveCurrent && + (m_current.getState() == Hypothesis::Satisfied)) { +#ifdef DEBUG_FEEDER + std::cerr << "finish: current is satisfied, pushing to accepted" << std::endl; +#endif + m_accepted.push_back(m_current); + } + } + + std::set<Hypothesis> retrieveAcceptedHypotheses() { + std::set<Hypothesis> hs; +#ifdef DEBUG_FEEDER + std::cerr << "retrieveAcceptedHypotheses: returning " << m_accepted.size() << " accepted" << std::endl; +#endif + for (typename Hypotheses::const_iterator i = m_accepted.begin(); + i != m_accepted.end(); ++i) { + hs.insert(*i); + } + m_accepted.clear(); + return hs; + } + +private: + Hypotheses m_candidates; + Hypothesis m_current; + bool m_haveCurrent; + Hypotheses m_accepted; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/AgentFeederPoly.h Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,295 @@ +/* -*- 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 AGENT_FEEDER_POLY_H +#define AGENT_FEEDER_POLY_H + +#include "AgentFeeder.h" + +#include <cassert> +#include <stdexcept> + +//#define DEBUG_FEEDER 1 + +/** + * Take a series of observations or estimates (one at a time) and feed + * them to a set of agent hypotheses, creating a new candidate agent + * for each observation and also testing the observation against the + * existing set of hypotheses. + * + *!!! -- todo: document poly-ness of it + * + * Call feed() to provide a new observation. Call finish() when all + * observations have been provided. The set of hypotheses returned by + * getAcceptedHypotheses() will not be complete unless finish() has + * been called. + */ +template <typename Hypothesis> +class AgentFeederPoly : public AgentFeeder +{ +private: + typedef std::vector<Hypothesis> Hypotheses; + + struct State { + Hypotheses provisional; + Hypotheses satisfied; + Hypotheses completed; + }; + State m_state; + +public: + AgentFeederPoly() { } + + virtual void feed(AgentHypothesis::Observation o) { +#ifdef DEBUG_FEEDER + std::cerr << "\nfeed: have observation [value = " << o.value << ", time = " << o.time << "]" << std::endl; +#endif + + m_state = update(m_state, o); + } + + virtual void finish() { +#ifdef DEBUG_FEEDER + std::cerr << "finish: satisfied count == " << m_state.satisfied.size() << std::endl; +#endif + for (typename Hypotheses::const_iterator i = m_state.satisfied.begin(); + i != m_state.satisfied.end(); ++i) { + m_state.completed.push_back(*i); + } + } + + std::set<Hypothesis> retrieveAcceptedHypotheses() { + std::set<Hypothesis> hs; + for (typename Hypotheses::const_iterator i = m_state.completed.begin(); + i != m_state.completed.end(); ++i) { + Hypothesis h(*i); +#ifdef DEBUG_FEEDER + std::cerr << "returning accepted hypothesis: strengths: "; + for (typename Hypothesis::Observations::const_iterator j = + h.getAcceptedObservations().begin(); + j != h.getAcceptedObservations().end(); ++j) { + std::cerr << j->confidence << " "; + } + std::cerr << std::endl; +#endif + hs.insert(h); + } + m_state.completed.clear(); + return hs; + } + +private: + State update(State s, AgentHypothesis::Observation o) { + + /* + An observation can "belong" to any number of provisional + hypotheses, but only to one satisfied hypothesis. + + A new observation is first offered to the hypotheses that + have already been satisfied. If one of these accepts it, it + gets to keep it and no other hypothesis can have it. + + Any observation not accepted by a hypothesis in satisfied + state is then offered to the provisional hypotheses; any + number of these may accept it. Also, every observation that + belongs to no satisfied hypothesis is used as the first + observation in its own new hypothesis (regardless of how + many other provisional hypotheses have accepted it). + + When a hypothesis subsequently becomes satisfied, all other + provisional hypotheses containing any of its observations + must be discarded. + */ + + State newState; + + // We only ever add to the completed hypotheses, never remove + // anything from them. But we may remove from provisional (if + // rejected or transferred to satisfied) and satisfied (when + // completed). + + newState.completed = s.completed; + + bool swallowed = false; + + for (typename Hypotheses::iterator i = s.satisfied.begin(); + i != s.satisfied.end(); ++i) { + + Hypothesis h = *i; + + assert(h.getState() == Hypothesis::Satisfied); + + if (swallowed) { + + // An observation that has already been accepted by a + // hypothesis cannot be offered to any other, because + // it can only belong to one satisfied hypothesis. Any + // subsequent satisfied hypotheses are retained + // unchanged in our updated state. We can't test them + // for expiry, because the state is only updated when + // accept() is called. + //!!! That looks like a limitation in the Hypothesis API + newState.satisfied.push_back(h); + + } else { // !swallowed + + if (h.accept(o)) { +#ifdef DEBUG_FEEDER + std::cerr << "accepted by satisfied hypothesis " << &(*i) << ", state is " << h.getState() << std::endl; +#endif + swallowed = true; + newState.satisfied.push_back(h); + } else if (h.getState() == Hypothesis::Expired) { + newState.completed.push_back(h); + } else { + newState.satisfied.push_back(h); + } + } + } + + if (swallowed) { + +#ifdef DEBUG_FEEDER + std::cerr << "was swallowed by satisfied hypothesis" << std::endl; +#endif + // no provisional hypotheses have become satisfied, no new + // ones have been introduced + newState.provisional = s.provisional; + + } else { + +#ifdef DEBUG_FEEDER + std::cerr << "remained unswallowed by " << newState.satisfied.size() << " satisfied hypotheses" << std::endl; +#endif + + // not swallowed by any satisfied hypothesis + + Hypothesis promoted; + + for (typename Hypotheses::iterator i = s.provisional.begin(); + i != s.provisional.end(); ++i) { + + Hypothesis h = *i; + + assert(h.getState() == Hypothesis::Provisional); + + // can only have one satisfied hypothesis for each + // observation, so try this only if promoted has not been + // set to something else yet + if (promoted == Hypothesis() && + h.accept(o) && + h.getState() == Hypothesis::Satisfied) { + newState.satisfied.push_back(h); +#ifdef DEBUG_FEEDER + std::cerr << "promoting a hypothesis to satisfied, have " << newState.satisfied.size() << " satisfied now" << std::endl; +#endif + promoted = h; + } else if (h.getState() != Hypothesis::Rejected) { + newState.provisional.push_back(h); + } + } + + if (promoted == Hypothesis()) { + + // No provisional hypothesis has become satisfied + + Hypothesis h; + h.accept(o); + + if (h.getState() == Hypothesis::Provisional) { + newState.provisional.push_back(h); + } else if (h.getState() == Hypothesis::Satisfied) { + newState.satisfied.push_back(h); + } + +#ifdef DEBUG_FEEDER + std::cerr << "update: new hypothesis of state " << h.getState() << ", provisional count -> " << newState.provisional.size() << std::endl; +#endif + } else { + +#ifdef DEBUG_FEEDER + std::cerr << "a hypothesis became satisfied, reaping its observations" << std::endl; +#endif + newState = reap(newState); + } + } + + return newState; + } + + State reap(State s) { + + // "When a hypothesis subsequently becomes satisfied, all + // other provisional hypotheses containing any of its + // observations must be discarded." + + if (s.provisional.empty()) return s; + + int reaped = 0; + + Hypotheses prior = s.provisional; + s.provisional = Hypotheses(); + + for (typename Hypotheses::const_iterator hi = prior.begin(); + hi != prior.end(); ++hi) { + + const AgentHypothesis::Observations obs = + hi->getAcceptedObservations(); + + bool keep = true; + + for (AgentHypothesis::Observations::const_iterator oi = obs.begin(); + oi != obs.end(); ++oi) { + + for (typename Hypotheses::const_iterator si = s.satisfied.end(); + si != s.satisfied.begin(); ) { + + --si; + + const AgentHypothesis::Observations sobs = + si->getAcceptedObservations(); + + if (sobs.find(*oi) != sobs.end()) { + keep = false; + break; + } + } + + if (!keep) { + break; + } + } + + if (keep) { + s.provisional.push_back(*hi); + } else { + ++reaped; + } + } + +#ifdef DEBUG_FEEDER + std::cerr << "reap: have " + << s.satisfied.size() << " satisfied, " + << s.provisional.size() << " provisional, " + << s.completed.size() << " completed, reaped " + << reaped << std::endl; +#endif + + return s; + } +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/AgentHypothesis.h Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,146 @@ +/* -*- 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 AGENT_HYPOTHESIS_H +#define AGENT_HYPOTHESIS_H + +#include "vamp-sdk/RealTime.h" + +#include <set> +#include <map> + +/** + * An agent used to test an incoming series of timed observations or + * estimates to see whether they fit a consistent single-object + * relationship. + * + * A freshly constructed hypothesis object should be in New state and + * should accept any observation. + */ + +class AgentHypothesis +{ +public: + virtual ~AgentHypothesis() { } + + enum State { + + /// Just constructed, will provisionally accept any observation + New, + + /// Accepted at least one observation, but not enough evidence to satisfy + Provisional, + + /// Could not find enough consistency in offered observations + Rejected, + + /// Have accepted enough consistent observations to satisfy hypothesis + Satisfied, + + /// Have been satisfied, but evidence has now changed: we're done + Expired + }; + + struct Observation { + + Observation() : value(0), time(), confidence(1) { } + + Observation(double _f, Vamp::RealTime _t, double _c) : + value(_f), time(_t), confidence(_c) { } + + bool operator==(const Observation &o) const { + return o.value == value && o.time == time && o.confidence == confidence; + } + bool operator<(const Observation &o) const { + return + (time < o.time || + (time == o.time && value < o.value) || + (time == o.time && value == o.value && confidence < o.confidence)); + } + + double value; + Vamp::RealTime time; + double confidence; + }; + typedef std::set<Observation> Observations; + + /** + * Test the given observation to see whether it is consistent with + * this hypothesis, and adjust the hypothesis' internal state + * accordingly. If the observation is not inconsistent with the + * hypothesis, return true. + *!!! should be called e.g. test? + */ + virtual bool accept(Observation) = 0; + + /** + * Return the current state of this hypothesis. + */ + virtual State getState() const = 0; + + /** + * If the hypothesis has been satisfied (i.e. is in Satisfied or + * Expired state), return the set of observations that it + * accepted. Otherwise return an empty set + */ + virtual Observations getAcceptedObservations() const = 0; + + /** + * Convert the given set of accepted hypotheses (of type + * subclassed from AgentHypothesis) into a flattened set of their + * accepted observations. + * + * That is, only one is included for at any given moment, so in + * the case of overlapping hypotheses, the observations for the + * earlier are taken until the next hypothesis begins and then the + * latter's observations begin instead. + * + * (If there are gaps between hypotheses, the gaps remain in the + * output.) + */ + template <typename HypothesisType> + static Observations flatten(const std::set<HypothesisType> &agents) { + + typedef typename std::set<HypothesisType>::const_iterator Itr; + Observations flattened; + + if (agents.empty()) return flattened; + Observations obs = agents.begin()->getAcceptedObservations(); + + for (Itr i = agents.begin(); i != agents.end(); ++i) { + + Itr j = i; + ++j; + + Observations nextObs; + if (j != agents.end()) nextObs = j->getAcceptedObservations(); + + for (Observations::const_iterator i = obs.begin(); + i != obs.end(); ++i) { + if (!nextObs.empty() && i->time >= nextObs.begin()->time) { + break; + } + flattened.insert(*i); + } + + obs = nextObs; + } + + return flattened; + } +}; + +#endif
--- a/src/Instruments.cpp Mon Jun 30 11:38:12 2014 +0100 +++ b/src/Instruments.cpp Mon Jun 30 11:38:33 2014 +0100 @@ -153,17 +153,15 @@ t.highestNote, simpleInstruments[i], tt); -// instr.pitchSparsity = 1.5; - instr.maxPolyphony = 5; - instr.levelThreshold = 6; + instr.pitchSparsity = 1.5; if (isString(i)) { -// instr.maxPolyphony = 2; -// instr.levelThreshold = 3; + instr.maxPolyphony = 1; + instr.levelThreshold = 3; stringTemplates.push_back(t); } if (isWind(i)) { -// instr.maxPolyphony = 1; -// instr.levelThreshold = 5; + instr.maxPolyphony = 1; + instr.levelThreshold = 3; windTemplates.push_back(t); } if (isOK(instr)) {
--- a/src/MedianFilter.h Mon Jun 30 11:38:12 2014 +0100 +++ b/src/MedianFilter.h Mon Jun 30 11:38:33 2014 +0100 @@ -1,16 +1,17 @@ /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* - QM DSP Library + Silvet - Centre for Digital Music, Queen Mary, University of London. - This file Copyright 2010 Chris Cannam. + A Vamp plugin for note transcription. + Centre for Digital Music, Queen Mary University of London. + This file Copyright 2010 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. + 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 MEDIAN_FILTER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NoteHypothesis.cpp Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,301 @@ +/* -*- 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. +*/ + +#include "NoteHypothesis.h" +#include "AgentFeederPoly.h" + +#include <cmath> +#include <cassert> + +#include <map> +#include <algorithm> + +using Vamp::RealTime; + +using std::cerr; +using std::endl; + +//#define DEBUG_NOTE_HYPOTHESIS 1 + +NoteHypothesis::NoteHypothesis() +{ + m_state = New; +} + +NoteHypothesis::~NoteHypothesis() +{ +} + +bool +NoteHypothesis::isWithinTolerance(Observation s) const +{ + if (m_pending.empty()) { + return true; + } + + // check we are within a relatively close tolerance of the last + // candidate + Observations::const_iterator i = m_pending.end(); + --i; + Observation last = *i; + double r = s.value / last.value; + int cents = lrint(1200.0 * (log(r) / log(2.0))); +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "isWithinTolerance: this " << s.value << " is " << cents + << " cents from prior " << last.value << endl; +#endif + if (cents < -60 || cents > 60) return false; + + // and within a slightly bigger tolerance of the current mean + double meanFreq = getMeanFrequency(); + r = s.value / meanFreq; + cents = lrint(1200.0 * (log(r) / log(2.0))); +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "isWithinTolerance: this " << s.value << " is " << cents + << " cents from mean " << meanFreq << endl; +#endif + if (cents < -80 || cents > 80) return false; + + return true; +} + +bool +NoteHypothesis::isOutOfDateFor(Observation s) const +{ + if (m_pending.empty()) return false; + + Observations::const_iterator i = m_pending.end(); + --i; + Observation last = *i; + +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "isOutOfDateFor: this " << s.time << " is " + << (s.time - last.time) << " from last " << last.time + << " (threshold " << RealTime::fromMilliseconds(40) << ")" + << endl; +#endif + + return ((s.time - last.time) > RealTime::fromMilliseconds(40)); +} + +bool +NoteHypothesis::isSatisfied() const +{ + if (m_pending.empty()) return false; + + double meanConfidence = 0.0; + for (Observations::const_iterator i = m_pending.begin(); + i != m_pending.end(); ++i) { + meanConfidence += i->confidence; + } + meanConfidence /= m_pending.size(); + + //!!! surely this depends on the hop size? + int lengthRequired = 100; + if (meanConfidence > 0.0) { + lengthRequired = int(2.0 / meanConfidence + 0.5); + } + //!!! + lengthRequired = lengthRequired / 2; + if (lengthRequired < 1) lengthRequired = 1; + +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "meanConfidence " << meanConfidence << ", lengthRequired " << lengthRequired << endl; +#endif + + return ((int)m_pending.size() > lengthRequired); +} + +#ifdef DEBUG_NOTE_HYPOTHESIS +static void printState(NoteHypothesis::State s) +{ + switch (s) { + case NoteHypothesis::New: cerr << "New"; break; + case NoteHypothesis::Provisional: cerr << "Provisional"; break; + case NoteHypothesis::Rejected: cerr << "Rejected"; break; + case NoteHypothesis::Satisfied: cerr << "Satisfied"; break; + case NoteHypothesis::Expired: cerr << "Expired"; break; + } +} +#endif + +bool +NoteHypothesis::accept(Observation s) +{ + bool accept = false; + +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "NoteHypothesis[" << this << "]::accept (value " << s.value << ", time " << s.time << ", confidence " << s.confidence << "): state "; + printState(m_state); + cerr << "..." << endl; +#endif + + static double negligibleConfidence = 0.0001; + + if (s.confidence < negligibleConfidence) { + // avoid piling up a lengthy sequence of estimates that are + // all acceptable but are in total not enough to cause us to + // be satisfied + if (m_state == New) { + m_state = Rejected; + } + return false; + } + + switch (m_state) { + + case New: + m_state = Provisional; + accept = true; + break; + + case Provisional: + if (isOutOfDateFor(s)) { + m_state = Rejected; + } else if (isWithinTolerance(s)) { + accept = true; + } + break; + + case Satisfied: + if (isOutOfDateFor(s)) { + m_state = Expired; + } else if (isWithinTolerance(s)) { + accept = true; + } + break; + + case Rejected: + break; + + case Expired: + break; + } + + if (accept) { +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "... accepting" << endl; +#endif + m_pending.insert(s); + if (m_state == Provisional && isSatisfied()) { + m_state = Satisfied; + } + } else { +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "... not accepting" << endl; +#endif + } + +#ifdef DEBUG_NOTE_HYPOTHESIS + cerr << "... -> "; + printState(m_state); + cerr << " (pending: " << m_pending.size() << ")" << endl; +#endif + + return accept; +} + +NoteHypothesis::State +NoteHypothesis::getState() const +{ + return m_state; +} + +NoteHypothesis::Observations +NoteHypothesis::getAcceptedObservations() const +{ + if (m_state == Satisfied || m_state == Expired) { + return m_pending; + } else { + return Observations(); + } +} + +double +NoteHypothesis::getMedianFrequency() const +{ + if (m_pending.empty()) return 0.0; + std::vector<double> freqs; + for (Observations::const_iterator i = m_pending.begin(); + i != m_pending.end(); ++i) { + freqs.push_back(i->value); + } + std::sort(freqs.begin(), freqs.end()); + return freqs[freqs.size()/2]; +} + +double +NoteHypothesis::getMeanFrequency() const +{ + double acc = 0.0; + if (m_pending.empty()) return acc; + for (Observations::const_iterator i = m_pending.begin(); + i != m_pending.end(); ++i) { + acc += i->value; + } + acc /= m_pending.size(); + return acc; +} + +double +NoteHypothesis::getMedianConfidence() const +{ + if (m_pending.empty()) return 0.0; + std::vector<double> confs; + for (Observations::const_iterator i = m_pending.begin(); + i != m_pending.end(); ++i) { + confs.push_back(i->confidence); + } + std::sort(confs.begin(), confs.end()); + return confs[confs.size()/2]; +} + +NoteHypothesis::Note +NoteHypothesis::getAveragedNote() const +{ + Note n; + + n.time = getStartTime(); + n.duration = getDuration(); + n.freq = getMedianFrequency(); + n.confidence = getMedianConfidence(); + + return n; +} + +RealTime +NoteHypothesis::getStartTime() const +{ + if (!(m_state == Satisfied || m_state == Expired)) { + return RealTime::zeroTime; + } else { + return m_pending.begin()->time; + } +} + +RealTime +NoteHypothesis::getDuration() const +{ +//!!! test this! it is wrong + if (!(m_state == Satisfied || m_state == Expired)) { + return RealTime::zeroTime; + } else { + RealTime start = m_pending.begin()->time; + Observations::const_iterator i = m_pending.end(); + --i; + return i->time - start; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NoteHypothesis.h Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,130 @@ +/* -*- 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(), confidence(1.0) { } + Note(double _f, Vamp::RealTime _t, Vamp::RealTime _d, double _i) : + freq(_f), time(_t), duration(_d), confidence(_i) { } + bool operator==(const Note &e) const { + return e.freq == freq && e.time == time && + e.duration == duration && e.confidence == confidence; + } + double freq; + Vamp::RealTime time; + Vamp::RealTime duration; + double confidence; + }; + + /** + * Return the mean frequency of the accepted observations + */ + double getMeanFrequency() const; + + /** + * Return the median frequency of the accepted observations + */ + double getMedianFrequency() const; + + /** + * Return the median confidence of the accepted observations + */ + double getMedianConfidence() 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; + + //!!! + bool operator==(const NoteHypothesis &other) const { + return m_state == other.m_state && m_pending == other.m_pending; + } + + bool operator<(const NoteHypothesis &other) const { + if (getStartTime() != other.getStartTime()) { + return getStartTime() < other.getStartTime(); + } else if (m_state != other.m_state) { + return m_state < other.m_state; + } else if (m_pending.size() != other.m_pending.size()) { + return m_pending.size() < other.m_pending.size(); + } else { + Observations::const_iterator i = m_pending.begin(); + Observations::const_iterator j = other.m_pending.begin(); + while (i != m_pending.end()) { + if (*i == *j) { + ++i; + ++j; + } else { + return *i < *j; + } + } + return false; + } + } + +private: + bool isWithinTolerance(Observation) const; + bool isOutOfDateFor(Observation) const; + bool isSatisfied() const; + + State m_state; + Observations m_pending; +}; + +#endif
--- a/src/Silvet.cpp Mon Jun 30 11:38:12 2014 +0100 +++ b/src/Silvet.cpp Mon Jun 30 11:38:33 2014 +0100 @@ -19,6 +19,10 @@ #include <cq/CQSpectrogram.h> #include "MedianFilter.h" +#include "AgentFeederPoly.h" +#include "AgentFeederMono.h" +#include "NoteHypothesis.h" + #include "constant-q-cpp/src/dsp/Resampler.h" #include <vector> @@ -42,7 +46,8 @@ m_hqMode(true), m_fineTuning(false), m_instrument(0), - m_colsPerSec(50) + m_colsPerSec(50), + m_agentFeeder(0) { } @@ -53,6 +58,7 @@ for (int i = 0; i < (int)m_postFilter.size(); ++i) { delete m_postFilter[i]; } + delete m_agentFeeder; } string @@ -323,6 +329,15 @@ return float(27.5 * pow(2.0, (note + pshift) / 12.0)); } +float +Silvet::roundToMidiFrequency(float freq) const +{ + // n is our note number, not actually MIDI note number as we have + // a different origin + float n = 12.0 * (log(freq / 27.5) / log(2.0)); + return 27.5 * pow(2.0, round(n) / 12.0); +} + bool Silvet::initialise(size_t channels, size_t stepSize, size_t blockSize) { @@ -347,6 +362,7 @@ { delete m_resampler; delete m_cq; + delete m_agentFeeder; if (m_inputSampleRate != processingSampleRate) { m_resampler = new Resampler(m_inputSampleRate, processingSampleRate); @@ -384,18 +400,26 @@ delete m_postFilter[i]; } m_postFilter.clear(); - for (int i = 0; i < m_instruments[0].templateNoteCount; ++i) { - m_postFilter.push_back(new MedianFilter<double>(3)); + for (int i = 0; i < m_instruments[m_instrument].templateNoteCount; ++i) { +//!!! m_postFilter.push_back(new MedianFilter<double>(3)); + m_postFilter.push_back(new MedianFilter<double>(1));//!!! } - m_pianoRoll.clear(); - m_columnCount = 0; + + m_columnCountIn = 0; + m_columnCountOut = 0; m_startTime = RealTime::zeroTime; + + if (m_instruments[m_instrument].maxPolyphony == 1) { + m_agentFeeder = new AgentFeederMono<NoteHypothesis>(); + } else { + m_agentFeeder = new AgentFeederPoly<NoteHypothesis>(); + } } Silvet::FeatureSet Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp) { - if (m_columnCount == 0) { + if (m_columnCountIn == 0) { m_startTime = timestamp; } @@ -417,7 +441,17 @@ Silvet::getRemainingFeatures() { Grid cqout = m_cq->getRemainingOutput(); + FeatureSet fs = transcribe(cqout); + + m_agentFeeder->finish(); + + FeatureList noteFeatures = obtainNotes(); + for (FeatureList::const_iterator fi = noteFeatures.begin(); + fi != noteFeatures.end(); ++fi) { + fs[m_notesOutputNo].push_back(*fi); + } + return fs; } @@ -447,7 +481,7 @@ //!!! pitches or notes? [terminology] Grid localPitches(width, vector<double>(pack.templateNoteCount, 0.0)); - bool wantShifts = m_hqMode && m_fineTuning; + bool wantShifts = m_hqMode; int shiftCount = 1; if (wantShifts) { shiftCount = pack.templateMaxShift * 2 + 1; @@ -509,21 +543,20 @@ for (int j = 0; j < pack.templateNoteCount; ++j) { m_postFilter[j]->push(0.0); } - m_pianoRoll.push_back(map<int, double>()); - if (wantShifts) { - m_pianoRollShifts.push_back(map<int, int>()); + } else { + + postProcess(localPitches[i], localBestShifts[i], + wantShifts, shiftCount); + + FeatureList noteFeatures = obtainNotes(); + + for (FeatureList::const_iterator fi = noteFeatures.begin(); + fi != noteFeatures.end(); ++fi) { + fs[m_notesOutputNo].push_back(*fi); } - continue; } - postProcess(localPitches[i], localBestShifts[i], wantShifts); - - FeatureList noteFeatures = noteTrack(shiftCount); - - for (FeatureList::const_iterator fi = noteFeatures.begin(); - fi != noteFeatures.end(); ++fi) { - fs[m_notesOutputNo].push_back(*fi); - } + ++m_columnCountOut; } return fs; @@ -552,13 +585,13 @@ for (int i = 0; i < width; ++i) { - if (m_columnCount < latentColumns) { - ++m_columnCount; + if (m_columnCountIn < latentColumns) { + ++m_columnCountIn; continue; } - int prevSampleNo = (m_columnCount - 1) * m_cq->getColumnHop(); - int sampleNo = m_columnCount * m_cq->getColumnHop(); + int prevSampleNo = (m_columnCountIn - 1) * m_cq->getColumnHop(); + int sampleNo = m_columnCountIn * m_cq->getColumnHop(); bool select = (sampleNo / spacing != prevSampleNo / spacing); @@ -607,7 +640,7 @@ out.push_back(outCol); } - ++m_columnCount; + ++m_columnCountIn; } return out; @@ -616,7 +649,8 @@ void Silvet::postProcess(const vector<double> &pitches, const vector<int> &bestShifts, - bool wantShifts) + bool wantShifts, + int shiftCount) { const InstrumentPack &pack = m_instruments[m_instrument]; @@ -627,172 +661,89 @@ filtered.push_back(m_postFilter[j]->get()); } - // Threshold for level and reduce number of candidate pitches + double threshold = 1; //!!! pack.levelThreshold - typedef std::multimap<double, int> ValueIndexMap; - - ValueIndexMap strengths; + double columnDuration = 1.0 / m_colsPerSec; + int postFilterLatency = int(m_postFilter[0]->getSize() / 2); + RealTime t = RealTime::fromSeconds + (columnDuration * (m_columnCountOut - postFilterLatency) + 0.02); for (int j = 0; j < pack.templateNoteCount; ++j) { + double strength = filtered[j]; - if (strength < pack.levelThreshold) continue; - strengths.insert(ValueIndexMap::value_type(strength, j)); - } + if (strength < threshold) { + continue; + } - ValueIndexMap::const_iterator si = strengths.end(); + double freq; + if (wantShifts) { + freq = noteFrequency(j, bestShifts[j], shiftCount); + } else { + freq = noteFrequency(j, 0, shiftCount); + } - map<int, double> active; - map<int, int> activeShifts; + double confidence = strength / 50.0; //!!!??? + if (confidence > 1.0) confidence = 1.0; - while (int(active.size()) < pack.maxPolyphony && si != strengths.begin()) { - - --si; - - double strength = si->first; - int j = si->second; - - active[j] = strength; - - if (wantShifts) { - activeShifts[j] = bestShifts[j]; - } - } - - m_pianoRoll.push_back(active); - - if (wantShifts) { - m_pianoRollShifts.push_back(activeShifts); + AgentHypothesis::Observation obs(freq, t, confidence); + m_agentFeeder->feed(obs); } } Vamp::Plugin::FeatureList -Silvet::noteTrack(int shiftCount) +Silvet::obtainNotes() { - // Minimum duration pruning, and conversion to notes. We can only - // report notes that have just ended (i.e. that are absent in the - // latest active set but present in the prior set in the piano - // roll) -- any notes that ended earlier will have been reported - // already, and if they haven't ended, we don't know their - // duration. - - int width = m_pianoRoll.size() - 1; - - const map<int, double> &active = m_pianoRoll[width]; - - double columnDuration = 1.0 / m_colsPerSec; - - // only keep notes >= 100ms or thereabouts - int durationThreshold = floor(0.1 / columnDuration); // columns - if (durationThreshold < 1) durationThreshold = 1; - FeatureList noteFeatures; - if (width < durationThreshold + 1) { + std::set<NoteHypothesis> hh; + + AgentFeederPoly<NoteHypothesis> *polyFeeder = + dynamic_cast<AgentFeederPoly<NoteHypothesis> *>(m_agentFeeder); + + AgentFeederMono<NoteHypothesis> *monoFeeder = + dynamic_cast<AgentFeederMono<NoteHypothesis> *>(m_agentFeeder); + + if (polyFeeder) { + + hh = polyFeeder->retrieveAcceptedHypotheses(); + + } else if (monoFeeder) { + + hh = monoFeeder->retrieveAcceptedHypotheses(); + + } else { + + cerr << "INTERNAL ERROR: Feeder is neither poly- nor " + << "mono-note-hypothesis-feeder!" << endl; return noteFeatures; } - - //!!! try: repeated note detection? (look for change in first derivative of the pitch matrix) - for (map<int, double>::const_iterator ni = m_pianoRoll[width-1].begin(); - ni != m_pianoRoll[width-1].end(); ++ni) { + for (std::set<NoteHypothesis>::const_iterator hi = hh.begin(); + hi != hh.end(); ++hi) { - int note = ni->first; - - if (active.find(note) != active.end()) { - // the note is still playing - continue; + NoteHypothesis h(*hi); + + NoteHypothesis::Note n = h.getAveragedNote(); + + int velocity = n.confidence * 127; + if (velocity > 127) velocity = 127; + + float freq = n.freq; + if (!m_fineTuning) { + freq = roundToMidiFrequency(freq); } - // the note was playing but just ended - int end = width; - int start = end-1; - - while (m_pianoRoll[start].find(note) != m_pianoRoll[start].end()) { - --start; - } - ++start; - - if ((end - start) < durationThreshold) { - continue; - } - - emitNote(start, end, note, shiftCount, noteFeatures); + Feature f; + f.hasTimestamp = true; + f.hasDuration = true; + f.timestamp = n.time; + f.duration = n.duration; + f.values.clear(); + f.values.push_back(freq); + f.values.push_back(velocity); +// f.label = noteName(note, partShift, shiftCount); + noteFeatures.push_back(f); } -// cerr << "returning " << noteFeatures.size() << " complete note(s) " << endl; - return noteFeatures; } - -void -Silvet::emitNote(int start, int end, int note, int shiftCount, - FeatureList ¬eFeatures) -{ - int partStart = start; - int partShift = 0; - int partVelocity = 0; - - Feature f; - f.hasTimestamp = true; - f.hasDuration = true; - - double columnDuration = 1.0 / m_colsPerSec; - int postFilterLatency = int(m_postFilter[0]->getSize() / 2); - int partThreshold = floor(0.05 / columnDuration); - - for (int i = start; i != end; ++i) { - - double strength = m_pianoRoll[i][note]; - - int shift = 0; - - if (shiftCount > 1) { - - shift = m_pianoRollShifts[i][note]; - - if (i == partStart) { - partShift = shift; - } - - if (i > partStart + partThreshold && shift != partShift) { - -// cerr << "i = " << i << ", partStart = " << partStart << ", shift = " << shift << ", partShift = " << partShift << endl; - - // pitch has changed, emit an intermediate note - f.timestamp = RealTime::fromSeconds - (columnDuration * (partStart - postFilterLatency) + 0.02); - f.duration = RealTime::fromSeconds - (columnDuration * (i - partStart)); - f.values.clear(); - f.values.push_back - (noteFrequency(note, partShift, shiftCount)); - f.values.push_back(partVelocity); - f.label = noteName(note, partShift, shiftCount); - noteFeatures.push_back(f); - partStart = i; - partShift = shift; - partVelocity = 0; - } - } - - int v = strength * 2; - if (v > 127) v = 127; - - if (v > partVelocity) { - partVelocity = v; - } - } - - if (end >= partStart + partThreshold) { - f.timestamp = RealTime::fromSeconds - (columnDuration * (partStart - postFilterLatency) + 0.02); - f.duration = RealTime::fromSeconds - (columnDuration * (end - partStart)); - f.values.clear(); - f.values.push_back - (noteFrequency(note, partShift, shiftCount)); - f.values.push_back(partVelocity); - f.label = noteName(note, partShift, shiftCount); - noteFeatures.push_back(f); - } -}
--- a/src/Silvet.h Mon Jun 30 11:38:12 2014 +0100 +++ b/src/Silvet.h Mon Jun 30 11:38:33 2014 +0100 @@ -24,6 +24,7 @@ #include "MedianFilter.h" #include "Instruments.h" +#include "NoteHypothesis.h" using std::string; using std::vector; @@ -32,6 +33,7 @@ class Resampler; class CQSpectrogram; +class AgentFeeder; class Silvet : public Vamp::Plugin { @@ -84,27 +86,27 @@ typedef vector<vector<double> > Grid; vector<MedianFilter<double> *> m_postFilter; - vector<map<int, double> > m_pianoRoll; - vector<map<int, int> > m_pianoRollShifts; + + AgentFeeder *m_agentFeeder; Grid preProcess(const Grid &); void postProcess(const vector<double> &pitches, const vector<int> &bestShifts, - bool wantShifts); // -> piano roll column + bool wantShifts, + int shiftCount); // -> feeder - FeatureList noteTrack(int shiftCount); - - void emitNote(int start, int end, int note, int shiftCount, - FeatureList ¬eFeatures); + FeatureList obtainNotes(); FeatureSet transcribe(const Grid &); string noteName(int n, int shift, int shiftCount) const; float noteFrequency(int n, int shift, int shiftCount) const; + float roundToMidiFrequency(float f) const; int m_blockSize; - int m_columnCount; + int m_columnCountIn; + int m_columnCountOut; Vamp::RealTime m_startTime; mutable int m_notesOutputNo;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testdata/evaluation/outputs/ce8118644f16-noteagent.txt Mon Jun 30 11:38:33 2014 +0100 @@ -0,0 +1,605 @@ +Yeti 0.9.9+ +1.0 +make -C constant-q-cpp -f Makefile.linux libcq.a +make[1]: Entering directory '/home/cannam/code/silvet/constant-q-cpp' +make[1]: 'libcq.a' is up to date. +make[1]: Leaving directory '/home/cannam/code/silvet/constant-q-cpp' +g++ -Wall -O3 -fopenmp -ffast-math -msse -msse2 -mfpmath=sse -ftree-vectorize -fPIC -I../vamp-plugin-sdk/ -DUSE_PTHREADS -I. -I../vamp-plugin-sdk -Iconstant-q-cpp -Ibqvec/src -Wall -O3 -fopenmp -ffast-math -msse -msse2 -mfpmath=sse -ftree-vectorize -fPIC -I../vamp-plugin-sdk/ -DUSE_PTHREADS -c -o src/Instruments.o src/Instruments.cpp +g++ -o silvet.so src/Silvet.o src/EM.o src/Instruments.o src/NoteHypothesis.o src/libmain.o bqvec/src/Allocators.o constant-q-cpp/libcq.a ../vamp-plugin-sdk/libvamp-sdk.a constant-q-cpp/libcq.a ../vamp-plugin-sdk/libvamp-sdk.a -lgomp -shared -Wl,-Bsymbolic -Wl,-z,defs -Wl,--version-script=vamp-plugin.map -lpthread + +Input files are: +/home/cannam/Music/TRIOS_dataset/mozart/piano.wav +/home/cannam/Music/TRIOS_dataset/mozart/viola.wav +/home/cannam/Music/TRIOS_dataset/mozart/mix.wav +/home/cannam/Music/TRIOS_dataset/mozart/clarinet.wav +/home/cannam/Music/TRIOS_dataset/lussier/piano.wav +/home/cannam/Music/TRIOS_dataset/lussier/mix.wav +/home/cannam/Music/TRIOS_dataset/lussier/bassoon.wav +/home/cannam/Music/TRIOS_dataset/lussier/trumpet.wav +/home/cannam/Music/TRIOS_dataset/take_five/piano.wav +/home/cannam/Music/TRIOS_dataset/take_five/mix.wav +/home/cannam/Music/TRIOS_dataset/take_five/saxophone.wav + +Evaluating for file /home/cannam/Music/TRIOS_dataset/mozart/piano.wav... + +For piece mozart, arrangement piano, using instrument 1... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="1"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 28.3, recall 33.5, accuracy 18.1, F 30.7 <-- main mozart/piano + +Validating against MIREX submission at 50 ms: +precision 15, recall 15.5, accuracy 8.2, F 15.2 + +Validating MIREX against ground truth at 50 ms: +precision 56.2, recall 64.3, accuracy 42.9, F 60 + +Validating against ground truth at 100 ms: +precision 45.6, recall 54.1, accuracy 32.9, F 49.5 + +Validating against MIREX submission at 100 ms: +precision 47.9, recall 49.7, accuracy 32.2, F 48.8 + +Validating MIREX against ground truth at 100 ms: +precision 69.4, recall 79.4, accuracy 58.8, F 74.1 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/mozart/viola.wav... + +For piece mozart, arrangement viola, using instrument 0... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="0"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 17, recall 53.1, accuracy 14.7, F 25.7 <-- main mozart/viola + +Validating against MIREX submission at 50 ms: +precision 17, recall 13.7, accuracy 8.2, F 15.1 + +Validating MIREX against ground truth at 50 ms: +precision 20.9, recall 81.2, accuracy 20, F 33.3 + +Validating against ground truth at 100 ms: +precision 26, recall 81.2, accuracy 24.5, F 39.3 + +Validating against MIREX submission at 100 ms: +precision 53, recall 42.7, accuracy 30.9, F 47.3 + +Validating MIREX against ground truth at 100 ms: +precision 22.5, recall 87.5, accuracy 21.8, F 35.8 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/mozart/mix.wav... + +For piece mozart, arrangement mix, using instrument 0... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="0"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 47.2, recall 38.8, accuracy 27.1, F 42.6 <-- main mozart/mix + +Validating against MIREX submission at 50 ms: +precision 17.2, recall 14, accuracy 8.3, F 15.4 + +Validating MIREX against ground truth at 50 ms: +precision 50.4, recall 51, accuracy 33.9, F 50.7 + +Validating against ground truth at 100 ms: +precision 62.5, recall 51.4, accuracy 39.3, F 56.4 + +Validating against MIREX submission at 100 ms: +precision 55.1, recall 44.8, accuracy 32.8, F 49.4 + +Validating MIREX against ground truth at 100 ms: +precision 67.2, recall 68, accuracy 51, F 67.6 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/mozart/clarinet.wav... + +For piece mozart, arrangement clarinet, using instrument 8... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="8"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 78.8, recall 59.4, accuracy 51.2, F 67.7 <-- main mozart/clarinet + +Validating against MIREX submission at 50 ms: +precision 59.6, recall 43, accuracy 33.3, F 50 + +Validating MIREX against ground truth at 50 ms: +precision 72.2, recall 75.3, accuracy 58.4, F 73.7 + +Validating against ground truth at 100 ms: +precision 100, recall 75.3, accuracy 75.3, F 85.9 + +Validating against MIREX submission at 100 ms: +precision 100, recall 72.2, accuracy 72.2, F 83.8 + +Validating MIREX against ground truth at 100 ms: +precision 75, recall 78.2, accuracy 62, F 76.5 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/lussier/piano.wav... + +For piece lussier, arrangement piano, using instrument 1... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="1"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 2% Extracting and writing features... 4% Extracting and writing features... 6% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 12% Extracting and writing features... 14% Extracting and writing features... 16% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 22% Extracting and writing features... 24% Extracting and writing features... 26% Extracting and writing features... 28% Extracting and writing features... 31% Extracting and writing features... 33% Extracting and writing features... 35% Extracting and writing features... 37% Extracting and writing features... 39% Extracting and writing features... 41% Extracting and writing features... 43% Extracting and writing features... 45% Extracting and writing features... 47% Extracting and writing features... 49% Extracting and writing features... 51% Extracting and writing features... 53% Extracting and writing features... 55% Extracting and writing features... 57% Extracting and writing features... 59% Extracting and writing features... 62% Extracting and writing features... 64% Extracting and writing features... 66% Extracting and writing features... 68% Extracting and writing features... 70% Extracting and writing features... 72% Extracting and writing features... 74% Extracting and writing features... 76% Extracting and writing features... 78% Extracting and writing features... 80% Extracting and writing features... 82% Extracting and writing features... 84% Extracting and writing features... 86% Extracting and writing features... 88% Extracting and writing features... 90% Extracting and writing features... 92% Extracting and writing features... 95% Extracting and writing features... 97% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 37.9, recall 39.4, accuracy 23.9, F 38.6 <-- main lussier/piano + +Validating against MIREX submission at 50 ms: +precision 18.5, recall 19.3, accuracy 10.4, F 18.9 + +Validating MIREX against ground truth at 50 ms: +precision 45.3, recall 45.3, accuracy 29.3, F 45.3 + +Validating against ground truth at 100 ms: +precision 50, recall 52.1, accuracy 34.2, F 51 + +Validating against MIREX submission at 100 ms: +precision 39.5, recall 41.1, accuracy 25.2, F 40.3 + +Validating MIREX against ground truth at 100 ms: +precision 62.1, recall 62.1, accuracy 45.1, F 62.1 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/lussier/mix.wav... + +For piece lussier, arrangement mix, using instrument 0... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="0"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 2% Extracting and writing features... 4% Extracting and writing features... 6% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 12% Extracting and writing features... 14% Extracting and writing features... 16% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 22% Extracting and writing features... 24% Extracting and writing features... 26% Extracting and writing features... 28% Extracting and writing features... 31% Extracting and writing features... 33% Extracting and writing features... 35% Extracting and writing features... 37% Extracting and writing features... 39% Extracting and writing features... 41% Extracting and writing features... 43% Extracting and writing features... 45% Extracting and writing features... 47% Extracting and writing features... 49% Extracting and writing features... 51% Extracting and writing features... 53% Extracting and writing features... 55% Extracting and writing features... 57% Extracting and writing features... 59% Extracting and writing features... 62% Extracting and writing features... 64% Extracting and writing features... 66% Extracting and writing features... 68% Extracting and writing features... 70% Extracting and writing features... 72% Extracting and writing features... 74% Extracting and writing features... 76% Extracting and writing features... 78% Extracting and writing features... 80% Extracting and writing features... 82% Extracting and writing features... 84% Extracting and writing features... 86% Extracting and writing features... 88% Extracting and writing features... 90% Extracting and writing features... 92% Extracting and writing features... 95% Extracting and writing features... 97% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 42.4, recall 35, accuracy 23.7, F 38.4 <-- main lussier/mix + +Validating against MIREX submission at 50 ms: +precision 15.6, recall 16.5, accuracy 8.7, F 16.1 + +Validating MIREX against ground truth at 50 ms: +precision 40.4, recall 31.7, accuracy 21.6, F 35.5 + +Validating against ground truth at 100 ms: +precision 51.7, recall 42.7, accuracy 30.5, F 46.8 + +Validating against MIREX submission at 100 ms: +precision 45.9, recall 48.4, accuracy 30.8, F 47.1 + +Validating MIREX against ground truth at 100 ms: +precision 57.6, recall 45.1, accuracy 33.9, F 50.6 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/lussier/bassoon.wav... + +For piece lussier, arrangement bassoon, using instrument 10... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="10"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 2% Extracting and writing features... 4% Extracting and writing features... 6% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 12% Extracting and writing features... 14% Extracting and writing features... 16% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 22% Extracting and writing features... 24% Extracting and writing features... 26% Extracting and writing features... 28% Extracting and writing features... 31% Extracting and writing features... 33% Extracting and writing features... 35% Extracting and writing features... 37% Extracting and writing features... 39% Extracting and writing features... 41% Extracting and writing features... 43% Extracting and writing features... 45% Extracting and writing features... 47% Extracting and writing features... 49% Extracting and writing features... 51% Extracting and writing features... 53% Extracting and writing features... 55% Extracting and writing features... 57% Extracting and writing features... 59% Extracting and writing features... 62% Extracting and writing features... 64% Extracting and writing features... 66% Extracting and writing features... 68% Extracting and writing features... 70% Extracting and writing features... 72% Extracting and writing features... 74% Extracting and writing features... 76% Extracting and writing features... 78% Extracting and writing features... 80% Extracting and writing features... 82% Extracting and writing features... 84% Extracting and writing features... 86% Extracting and writing features... 88% Extracting and writing features... 90% Extracting and writing features... 92% Extracting and writing features... 95% Extracting and writing features... 97% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 63, recall 44.6, accuracy 35.3, F 52.2 <-- main lussier/bassoon + +Validating against MIREX submission at 50 ms: +precision 43.4, recall 14.2, accuracy 12, F 21.5 + +Validating MIREX against ground truth at 50 ms: +precision 31.4, recall 67.6, accuracy 27.3, F 42.9 + +Validating against ground truth at 100 ms: +precision 84.7, recall 60, accuracy 54.1, F 70.2 + +Validating against MIREX submission at 100 ms: +precision 67.3, recall 22.1, accuracy 20, F 33.3 + +Validating MIREX against ground truth at 100 ms: +precision 37.1, recall 80, accuracy 33.9, F 50.7 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/lussier/trumpet.wav... + +For piece lussier, arrangement trumpet, using instrument 0... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="0"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 2% Extracting and writing features... 4% Extracting and writing features... 6% Extracting and writing features... 8% Extracting and writing features... 10% Extracting and writing features... 12% Extracting and writing features... 14% Extracting and writing features... 16% Extracting and writing features... 18% Extracting and writing features... 20% Extracting and writing features... 22% Extracting and writing features... 24% Extracting and writing features... 26% Extracting and writing features... 28% Extracting and writing features... 31% Extracting and writing features... 33% Extracting and writing features... 35% Extracting and writing features... 37% Extracting and writing features... 39% Extracting and writing features... 41% Extracting and writing features... 43% Extracting and writing features... 45% Extracting and writing features... 47% Extracting and writing features... 49% Extracting and writing features... 51% Extracting and writing features... 53% Extracting and writing features... 55% Extracting and writing features... 57% Extracting and writing features... 59% Extracting and writing features... 62% Extracting and writing features... 64% Extracting and writing features... 66% Extracting and writing features... 68% Extracting and writing features... 70% Extracting and writing features... 72% Extracting and writing features... 74% Extracting and writing features... 76% Extracting and writing features... 78% Extracting and writing features... 80% Extracting and writing features... 82% Extracting and writing features... 84% Extracting and writing features... 86% Extracting and writing features... 88% Extracting and writing features... 90% Extracting and writing features... 92% Extracting and writing features... 95% Extracting and writing features... 97% Extracting and writing features... 99% Extracting and writing features... Done + + +Validating against ground truth at 50 ms: +precision 32.3, recall 87.5, accuracy 30.8, F 47.1 <-- main lussier/trumpet + +Validating against MIREX submission at 50 ms: +precision 32.3, recall 30.4, accuracy 18.5, F 31.3 + +Validating MIREX against ground truth at 50 ms: +precision 28.9, recall 83.3, accuracy 27.3, F 43 + +Validating against ground truth at 100 ms: +precision 35.3, recall 95.8, accuracy 34.8, F 51.6 + +Validating against MIREX submission at 100 ms: +precision 67.6, recall 63.7, accuracy 48.8, F 65.6 + +Validating MIREX against ground truth at 100 ms: +precision 31.8, recall 91.6, accuracy 30.9, F 47.3 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/take_five/piano.wav... + +For piece take_five, arrangement piano, using instrument 1... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="1"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 9% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 19% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 29% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 39% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 49% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 60% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 70% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 80% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 90% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... 100% Extracting and writing features... Done + +Validating against ground truth at 50 ms: +precision 16.1, recall 21.6, accuracy 10.1, F 18.5 <-- main take_five/piano + +Validating against MIREX submission at 50 ms: +precision 18.5, recall 16.3, accuracy 9.5, F 17.3 + +Validating MIREX against ground truth at 50 ms: +precision 50.1, recall 76.4, accuracy 43.4, F 60.5 + +Validating against ground truth at 100 ms: +precision 32.9, recall 44.2, accuracy 23.3, F 37.7 + +Validating against MIREX submission at 100 ms: +precision 62.8, recall 55.2, accuracy 41.6, F 58.8 + +Validating MIREX against ground truth at 100 ms: +precision 51.9, recall 79.2, accuracy 45.7, F 62.7 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/take_five/mix.wav... + +For piece take_five, arrangement mix, using instrument 0... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="0"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 9% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 19% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 29% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 39% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 49% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 60% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 70% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 80% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 90% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... 100% Extracting and writing features... Done + +Validating against ground truth at 50 ms: +precision 33.4, recall 34.7, accuracy 20.5, F 34 <-- main take_five/mix + +Validating against MIREX submission at 50 ms: +precision 16.1, recall 13.8, accuracy 8, F 14.9 + +Validating MIREX against ground truth at 50 ms: +precision 56.5, recall 68.3, accuracy 44.8, F 61.8 + +Validating against ground truth at 100 ms: +precision 52.8, recall 54.9, accuracy 36.8, F 53.8 + +Validating against MIREX submission at 100 ms: +precision 56.4, recall 48.5, accuracy 35.3, F 52.2 + +Validating MIREX against ground truth at 100 ms: +precision 65.5, recall 79.1, accuracy 55.9, F 71.7 + + +Evaluating for file /home/cannam/Music/TRIOS_dataset/take_five/saxophone.wav... + +For piece take_five, arrangement saxophone, using instrument 0... +force -> +one-file -> /tmp/17183 +Have audio source: "/tmp/17183norm.wav" + Determining default rate and channel count from first input file... Done +File or URL "/tmp/17183norm.wav" opened successfully +Taking default channel count of 1 from file +Taking default sample rate of 44100Hz from file +(Note: Default may be overridden by transforms) +RDFTransformFactory: NOTE: Transform is: +<transform + id="vamp:silvet:silvet:" + pluginVersion="" + program="" + stepSize="1024" + blockSize="1024" + windowType="hanning" + startTime="0.000000000" + duration="0.000000000" + sampleRate="0"> + <parameter name="finetune" value="0"/> + <parameter name="instrument" value="0"/> + <parameter name="mode" value="1"/> +</transform> + +NOTE: Transform does not specify a sample rate, using default rate of 44100 +NOTE: Loaded and initialised plugin for transform "vamp:silvet:silvet:" with plugin step size 1024 and block size 1024 (adapter step and block size 16384) +Extracting features for: "/tmp/17183norm.wav" +Audio file "/tmp/17183norm.wav": 1ch at 44100Hz + Extracting and writing features... 1% Extracting and writing features... 2% Extracting and writing features... 3% Extracting and writing features... 4% Extracting and writing features... 5% Extracting and writing features... 6% Extracting and writing features... 7% Extracting and writing features... 8% Extracting and writing features... 9% Extracting and writing features... 10% Extracting and writing features... 11% Extracting and writing features... 12% Extracting and writing features... 13% Extracting and writing features... 14% Extracting and writing features... 15% Extracting and writing features... 16% Extracting and writing features... 17% Extracting and writing features... 18% Extracting and writing features... 19% Extracting and writing features... 20% Extracting and writing features... 21% Extracting and writing features... 22% Extracting and writing features... 23% Extracting and writing features... 24% Extracting and writing features... 25% Extracting and writing features... 26% Extracting and writing features... 27% Extracting and writing features... 28% Extracting and writing features... 29% Extracting and writing features... 30% Extracting and writing features... 31% Extracting and writing features... 32% Extracting and writing features... 33% Extracting and writing features... 34% Extracting and writing features... 35% Extracting and writing features... 36% Extracting and writing features... 37% Extracting and writing features... 38% Extracting and writing features... 39% Extracting and writing features... 40% Extracting and writing features... 41% Extracting and writing features... 42% Extracting and writing features... 43% Extracting and writing features... 44% Extracting and writing features... 45% Extracting and writing features... 46% Extracting and writing features... 47% Extracting and writing features... 48% Extracting and writing features... 49% Extracting and writing features... 50% Extracting and writing features... 51% Extracting and writing features... 52% Extracting and writing features... 53% Extracting and writing features... 54% Extracting and writing features... 55% Extracting and writing features... 56% Extracting and writing features... 57% Extracting and writing features... 58% Extracting and writing features... 59% Extracting and writing features... 60% Extracting and writing features... 61% Extracting and writing features... 62% Extracting and writing features... 63% Extracting and writing features... 64% Extracting and writing features... 65% Extracting and writing features... 66% Extracting and writing features... 67% Extracting and writing features... 68% Extracting and writing features... 69% Extracting and writing features... 70% Extracting and writing features... 71% Extracting and writing features... 72% Extracting and writing features... 73% Extracting and writing features... 74% Extracting and writing features... 75% Extracting and writing features... 76% Extracting and writing features... 77% Extracting and writing features... 78% Extracting and writing features... 79% Extracting and writing features... 80% Extracting and writing features... 81% Extracting and writing features... 82% Extracting and writing features... 83% Extracting and writing features... 84% Extracting and writing features... 85% Extracting and writing features... 86% Extracting and writing features... 87% Extracting and writing features... 88% Extracting and writing features... 89% Extracting and writing features... 90% Extracting and writing features... 91% Extracting and writing features... 92% Extracting and writing features... 93% Extracting and writing features... 94% Extracting and writing features... 95% Extracting and writing features... 96% Extracting and writing features... 97% Extracting and writing features... 98% Extracting and writing features... 99% Extracting and writing features... 100% Extracting and writing features... Done + +Validating against ground truth at 50 ms: +precision 50.3, recall 64.7, accuracy 39.5, F 56.6 <-- main take_five/saxophone + +Validating against MIREX submission at 50 ms: +precision 32.5, recall 31.4, accuracy 19, F 32 + +Validating MIREX against ground truth at 50 ms: +precision 67.8, recall 90.4, accuracy 63.3, F 77.5 + +Validating against ground truth at 100 ms: +precision 69.6, recall 89.5, accuracy 64.3, F 78.3 + +Validating against MIREX submission at 100 ms: +precision 82.9, recall 80, accuracy 68.7, F 81.4 + +Validating MIREX against ground truth at 100 ms: +precision 70, recall 93.3, accuracy 66.6, F 80 + + +real 3m23.608s +user 7m37.760s +sys 0m3.450s