Mercurial > hg > tipic
changeset 19:51eb8b1a1910
Add CRP (lacking some features)
author | Chris Cannam |
---|---|
date | Thu, 24 Sep 2015 16:35:48 +0100 |
parents | c785eaaeac40 |
children | 3bbdd3dada9f |
files | .hgsubstate Makefile.inc src/CRP.cpp src/CRP.h src/PitchFilterbank.cpp src/PitchFilterbank.h src/TipicVampPlugin.cpp src/TipicVampPlugin.h src/Types.h |
diffstat | 9 files changed, 175 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgsubstate Thu Sep 24 12:45:43 2015 +0100 +++ b/.hgsubstate Thu Sep 24 16:35:48 2015 +0100 @@ -1,2 +1,2 @@ 5c47cf61c391c403a5d57ac0f7d8101ce129018b bqvec -500416b7a651efa2a334ef0ee75fffde0d1f755d constant-q-cpp +bc8033ed4c291e96202b32db94c9665724b2cb23 constant-q-cpp
--- a/Makefile.inc Thu Sep 24 12:45:43 2015 +0100 +++ b/Makefile.inc Thu Sep 24 16:35:48 2015 +0100 @@ -24,8 +24,8 @@ PUBLIC_HEADERS := -LIB_HEADERS := $(SRC_DIR)/delays.h $(SRC_DIR)/filter-a.h $(SRC_DIR)/filter-b.h $(SRC_DIR)/Filter.h $(SRC_DIR)/PitchFilterbank.h $(SRC_DIR)/DCT.h -LIB_SOURCES := $(SRC_DIR)/Filter.cpp $(SRC_DIR)/PitchFilterbank.cpp $(SRC_DIR)/DCT.cpp +LIB_HEADERS := $(SRC_DIR)/delays.h $(SRC_DIR)/filter-a.h $(SRC_DIR)/filter-b.h $(SRC_DIR)/Filter.h $(SRC_DIR)/PitchFilterbank.h $(SRC_DIR)/DCT.h $(SRC_DIR)/Types.h $(SRC_DIR)/CRP.h +LIB_SOURCES := $(SRC_DIR)/Filter.cpp $(SRC_DIR)/PitchFilterbank.cpp $(SRC_DIR)/DCT.cpp $(SRC_DIR)/CRP.cpp LIB_OBJECTS := $(LIB_SOURCES:.cpp=.o) LIB_OBJECTS := $(LIB_OBJECTS:.c=.o)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/CRP.cpp Thu Sep 24 16:35:48 2015 +0100 @@ -0,0 +1,69 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "CRP.h" + +#include "DCT.h" + +#include <cmath> +#include <iostream> + +using namespace std; + +CRP::~CRP() +{ + delete m_dct; +} + +RealBlock +CRP::process(const RealBlock &in) +{ + if (in.empty()) { + return in; + } + if (!m_dct) { + m_size = in[0].size(); + m_dct = new DCT(m_size); + } + + int bins = 12; + RealBlock out; + RealColumn dctOut(m_size); + + for (RealColumn col: in) { + + RealColumn crp(bins); + + if (int(col.size()) != m_size) { + cerr << "ERROR: Inconsistent value count in pitch column: found " + << col.size() << " where previous column(s) have had " << m_size + << endl; + throw std::logic_error("Inconsistent value count in pitch column"); + } + + if (m_params.applyLogCompression) { + for (auto &v: col) { + //!!! These numbers are parameters in the MATLAB + v = log10(1.0 + 1000.0 * v); + } + } + + m_dct->forward(col.data(), dctOut.data()); + + for (int i = 0; i < m_params.coefficientsToDrop; ++i) { + dctOut[i] = 0.0; + } + + m_dct->inverse(dctOut.data(), col.data()); + + for (int i = 0; i < m_size; ++i) { + crp[i % bins] += col[i]; + } + + //!!! normalise as in normalizeFeature.m + + out.push_back(crp); + } + + return out; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/CRP.h Thu Sep 24 16:35:48 2015 +0100 @@ -0,0 +1,33 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#ifndef CRP_H +#define CRP_H + +#include "Types.h" + +class DCT; + +//!!! Downsampling/temporal smoothing not yet implemented + +class CRP +{ +public: + struct Parameters { + int coefficientsToDrop; + bool applyLogCompression; + Parameters() : coefficientsToDrop(54), applyLogCompression(true) { } + }; + + CRP(Parameters params) : m_params(params), m_size(0), m_dct(0) { } + ~CRP(); + + RealBlock process(const RealBlock &in); + +private: + Parameters m_params; + int m_size; + DCT *m_dct; +}; + +#endif +
--- a/src/PitchFilterbank.cpp Thu Sep 24 12:45:43 2015 +0100 +++ b/src/PitchFilterbank.cpp Thu Sep 24 16:35:48 2015 +0100 @@ -63,15 +63,6 @@ int getSampleRate() const { return m_sampleRate; } float getTuningFrequency() const { return m_tuningFrequency; } - - /// A series of real-valued samples ordered in time. - typedef vector<double> RealSequence; - - /// A series of real-valued samples ordered by bin (frequency or similar). - typedef vector<double> RealColumn; - - /// A matrix of real-valued samples, indexed by time then bin number. - typedef vector<RealColumn> RealBlock; RealBlock process(const RealSequence &in) { @@ -277,13 +268,13 @@ m_d = new D(rate, freq); } -PitchFilterbank::RealBlock +RealBlock PitchFilterbank::process(const RealSequence &in) { return m_d->process(in); } -PitchFilterbank::RealBlock +RealBlock PitchFilterbank::getRemainingOutput() { return m_d->getRemainingOutput();
--- a/src/PitchFilterbank.h Thu Sep 24 12:45:43 2015 +0100 +++ b/src/PitchFilterbank.h Thu Sep 24 16:35:48 2015 +0100 @@ -3,7 +3,7 @@ #ifndef PITCH_FILTERBANK_H #define PITCH_FILTERBANK_H -#include <vector> +#include "Types.h" class PitchFilterbank { @@ -11,15 +11,6 @@ PitchFilterbank(int sampleRate, float tuningFrequency); ~PitchFilterbank(); - /// A series of real-valued samples ordered in time. - typedef std::vector<double> RealSequence; - - /// A series of real-valued samples ordered by bin (frequency or similar). - typedef std::vector<double> RealColumn; - - /// A matrix of real-valued samples, indexed by time then bin number. - typedef std::vector<RealColumn> RealBlock; - void reset(); RealBlock process(const RealSequence &);
--- a/src/TipicVampPlugin.cpp Thu Sep 24 12:45:43 2015 +0100 +++ b/src/TipicVampPlugin.cpp Thu Sep 24 16:35:48 2015 +0100 @@ -1,6 +1,9 @@ #include "TipicVampPlugin.h" +#include "PitchFilterbank.h" +#include "CRP.h" + #include <bqvec/Range.h> #include <bqvec/VectorOps.h> @@ -18,7 +21,9 @@ m_blockSize(0), m_tuningFrequency(defaultTuningFrequency), m_filterbank(0), - m_pitchOutputNo(-1) + m_crp(0), + m_pitchOutputNo(-1), + m_crpOutputNo(-1) { } @@ -177,21 +182,44 @@ m_pitchOutputNo = list.size(); list.push_back(d); + d.identifier = "crp"; + d.name = "Chroma DCT-Reduced Log Pitch Features"; + d.description = ""; + d.unit = ""; + d.hasFixedBinCount = true; + d.binCount = 12; //!!! make parameter in CRP + d.hasKnownExtents = false; + d.isQuantized = false; + d.sampleType = OutputDescriptor::FixedSampleRate; + d.sampleRate = 22050 / 2205; //!!! get block size & hop from filterbank + d.hasDuration = false; + m_crpOutputNo = list.size(); + list.push_back(d); + return list; } bool Tipic::initialise(size_t channels, size_t stepSize, size_t blockSize) { + if (m_inputSampleRate > 192000) { + cerr << "ERROR: Tipic::initialise: Max sample rate 192000 exceeded " + << "(requested rate = " << m_inputSampleRate << ")" << endl; + return false; + } + if (m_pitchOutputNo < 0) { // getOutputDescriptors has never been called, it sets up the // outputNo members (void)getOutputDescriptors(); } + if (m_pitchOutputNo < 0 || m_crpOutputNo < 0) { + throw std::logic_error("setup went wrong"); + } if (channels < getMinChannelCount() || channels > getMaxChannelCount()) { - cerr << "ERROR: initialise: wrong number of channels supplied (only 1 supported)" << endl; + cerr << "ERROR: Tipic::initialise: wrong number of channels supplied (only 1 supported)" << endl; return false; } @@ -213,6 +241,7 @@ { if (!m_filterbank) { m_filterbank = new PitchFilterbank(m_inputSampleRate, m_tuningFrequency); + m_crp = new CRP({}); } m_filterbank->reset(); } @@ -220,36 +249,39 @@ Tipic::FeatureSet Tipic::process(const float *const *inputBuffers, Vamp::RealTime timestamp) { - PitchFilterbank::RealSequence in; + RealSequence in; in.resize(m_blockSize); v_convert(in.data(), inputBuffers[0], m_blockSize); - PitchFilterbank::RealBlock pitchFiltered = m_filterbank->process(in); + RealBlock pitchFiltered = m_filterbank->process(in); + RealBlock crpReduced = m_crp->process(pitchFiltered); FeatureSet fs; - addPitchFeatures(fs, pitchFiltered); + addFeatures(fs, m_pitchOutputNo, pitchFiltered); + addFeatures(fs, m_crpOutputNo, crpReduced); return fs; } Tipic::FeatureSet Tipic::getRemainingFeatures() { - PitchFilterbank::RealBlock pitchFiltered = m_filterbank->getRemainingOutput(); + RealBlock pitchFiltered = m_filterbank->getRemainingOutput(); + RealBlock crpReduced = m_crp->process(pitchFiltered); FeatureSet fs; - addPitchFeatures(fs, pitchFiltered); + addFeatures(fs, m_pitchOutputNo, pitchFiltered); + addFeatures(fs, m_crpOutputNo, crpReduced); return fs; } void -Tipic::addPitchFeatures(FeatureSet &fs, const PitchFilterbank::RealBlock &block) +Tipic::addFeatures(FeatureSet &fs, int outputNo, const RealBlock &block) { for (int i = 0; in_range_for(block, i); ++i) { Feature f; int h = block[i].size(); f.values.resize(h); v_convert(f.values.data(), block[i].data(), h); - fs[m_pitchOutputNo].push_back(f); + fs[outputNo].push_back(f); } } -
--- a/src/TipicVampPlugin.h Thu Sep 24 12:45:43 2015 +0100 +++ b/src/TipicVampPlugin.h Thu Sep 24 16:35:48 2015 +0100 @@ -3,7 +3,10 @@ #include <vamp-sdk/Plugin.h> -#include "PitchFilterbank.h" +#include "Types.h" + +class PitchFilterbank; +class CRP; using std::string; @@ -49,9 +52,11 @@ int m_blockSize; float m_tuningFrequency; PitchFilterbank *m_filterbank; + CRP *m_crp; mutable int m_pitchOutputNo; + mutable int m_crpOutputNo; - void addPitchFeatures(FeatureSet &, const PitchFilterbank::RealBlock &); + void addFeatures(FeatureSet &, int outputNo, const RealBlock &); };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Types.h Thu Sep 24 16:35:48 2015 +0100 @@ -0,0 +1,18 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#ifndef TIPIC_TYPES_H +#define TIPIC_TYPES_H + +#include <vector> + +/// A series of real-valued samples ordered in time. +typedef std::vector<double> RealSequence; + +/// A series of real-valued samples ordered by bin (frequency or similar). +typedef std::vector<double> RealColumn; + +/// A matrix of real-valued samples, indexed by time then bin number. +typedef std::vector<RealColumn> RealBlock; + +#endif +