Mercurial > hg > tipic
changeset 39:bfd9acbcfd7c
Add CENS features
author | Chris Cannam |
---|---|
date | Thu, 01 Oct 2015 11:51:54 +0100 |
parents | ec93dacba3bd |
children | 14e0bbb06a9a |
files | Makefile.inc src/CENS.cpp src/CENS.h src/Quantize.h src/TipicVampPlugin.cpp src/TipicVampPlugin.h |
diffstat | 6 files changed, 214 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.inc Thu Oct 01 11:21:45 2015 +0100 +++ b/Makefile.inc Thu Oct 01 11:51:54 2015 +0100 @@ -24,8 +24,34 @@ 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 $(SRC_DIR)/Types.h $(SRC_DIR)/CRP.h $(SRC_DIR)/Normalise.h $(SRC_DIR)/LogCompress.h $(SRC_DIR)/OctaveFold.h $(SRC_DIR)/Resize.h $(SRC_DIR)/Chroma.h $(SRC_DIR)/FeatureDownsample.h -LIB_SOURCES := $(SRC_DIR)/Filter.cpp $(SRC_DIR)/PitchFilterbank.cpp $(SRC_DIR)/DCT.cpp $(SRC_DIR)/CRP.cpp $(SRC_DIR)/Normalise.cpp $(SRC_DIR)/Chroma.cpp $(SRC_DIR)/FeatureDownsample.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 \ + $(SRC_DIR)/Normalise.h \ + $(SRC_DIR)/LogCompress.h \ + $(SRC_DIR)/OctaveFold.h \ + $(SRC_DIR)/Resize.h \ + $(SRC_DIR)/Chroma.h \ + $(SRC_DIR)/FeatureDownsample.h \ + $(SRC_DIR)/Quantize.h \ + $(SRC_DIR)/CENS.h + +LIB_SOURCES := \ + $(SRC_DIR)/Filter.cpp \ + $(SRC_DIR)/PitchFilterbank.cpp \ + $(SRC_DIR)/DCT.cpp \ + $(SRC_DIR)/CRP.cpp \ + $(SRC_DIR)/Normalise.cpp \ + $(SRC_DIR)/Chroma.cpp \ + $(SRC_DIR)/FeatureDownsample.cpp \ + $(SRC_DIR)/CENS.cpp + LIB_OBJECTS := $(LIB_SOURCES:.cpp=.o) LIB_OBJECTS := $(LIB_OBJECTS:.c=.o) @@ -102,15 +128,17 @@ src/CRP.o: src/CRP.h src/Types.h src/DCTReduce.h src/DCT.h src/Normalise.h src/CRP.o: src/LogCompress.h src/OctaveFold.h src/Resize.h src/Normalise.o: src/Normalise.h -src/Chroma.o: src/Chroma.h src/Types.h src/FeatureDownsample.h -src/Chroma.o: src/Normalise.h src/LogCompress.h src/OctaveFold.h src/Resize.h +src/Chroma.o: src/Chroma.h src/Types.h src/Normalise.h src/LogCompress.h +src/Chroma.o: src/OctaveFold.h src/Resize.h src/FeatureDownsample.o: src/FeatureDownsample.h src/Types.h src/Filter.h -src/FeatureDownsample.o: bqvec/bqvec/Restrict.h +src/FeatureDownsample.o: bqvec/bqvec/Restrict.h src/Normalise.h +src/CENS.o: src/CENS.h src/Types.h src/Quantize.h src/Normalise.h +src/CENS.o: src/OctaveFold.h src/Resize.h src/TipicVampPlugin.o: src/TipicVampPlugin.h src/Types.h src/TipicVampPlugin.o: src/PitchFilterbank.h src/CRP.h src/DCTReduce.h -src/TipicVampPlugin.o: src/DCT.h src/Chroma.h src/FeatureDownsample.h -src/TipicVampPlugin.o: bqvec/bqvec/Range.h bqvec/bqvec/VectorOps.h -src/TipicVampPlugin.o: bqvec/bqvec/Restrict.h +src/TipicVampPlugin.o: src/DCT.h src/Chroma.h src/CENS.h src/Quantize.h +src/TipicVampPlugin.o: src/FeatureDownsample.h bqvec/bqvec/Range.h +src/TipicVampPlugin.o: bqvec/bqvec/VectorOps.h bqvec/bqvec/Restrict.h src/libmain.o: src/TipicVampPlugin.h src/Types.h src/test-filter.o: src/Filter.h bqvec/bqvec/Restrict.h src/test-dct.o: src/DCT.h @@ -118,6 +146,7 @@ src/Filter.o: bqvec/bqvec/Restrict.h src/PitchFilterbank.o: src/Types.h src/CRP.o: src/Types.h src/DCTReduce.h src/DCT.h -src/Chroma.o: src/Types.h src/FeatureDownsample.h +src/Chroma.o: src/Types.h src/FeatureDownsample.o: src/Types.h +src/CENS.o: src/Types.h src/Quantize.h src/TipicVampPlugin.o: src/Types.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/CENS.cpp Thu Oct 01 11:51:54 2015 +0100 @@ -0,0 +1,53 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "CENS.h" + +#include "Normalise.h" +#include "OctaveFold.h" +#include "Resize.h" + +#include <cmath> +#include <iostream> + +using namespace std; + +static Quantize::Parameters +qparams(CENS::Parameters params) +{ + Quantize::Parameters qp; + qp.steps = params.quantSteps; + qp.weights = params.quantWeights; + return qp; +} + +CENS::CENS(Parameters params) : + m_params(params), + m_quantize(qparams(params)) +{ +} + +CENS::~CENS() +{ +} + +RealBlock +CENS::process(const RealBlock &in) +{ + if (in.empty()) { + return in; + } + + RealBlock out; + + for (RealColumn col: in) { + + out.push_back(m_quantize.process + (Normalise::normalise + (OctaveFold::process + (Resize::process(col)), + m_params.normP, m_params.normThresh))); + } + + return out; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/CENS.h Thu Oct 01 11:51:54 2015 +0100 @@ -0,0 +1,37 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#ifndef CENS_H +#define CENS_H + +#include "Types.h" +#include "Quantize.h" + +class CENS +{ +public: + struct Parameters { + public: + std::vector<double> quantSteps; + std::vector<double> quantWeights; + int normP; // 0 = no normalisation, 1 = L^1, 2 = L^2 + double normThresh; + Parameters() : + quantSteps({ 0.4, 0.2, 0.1, 0.05 }), + quantWeights({ 0.25, 0.25, 0.25, 0.25 }), + normP(1), + normThresh(1e-3) + { } + }; + + CENS(Parameters params); + ~CENS(); + + RealBlock process(const RealBlock &in); + +private: + Parameters m_params; + Quantize m_quantize; +}; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Quantize.h Thu Oct 01 11:51:54 2015 +0100 @@ -0,0 +1,49 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#ifndef QUANTIZE_H +#define QUANTIZE_H + +#include <vector> +#include <stdexcept> + +class Quantize +{ +public: + class Parameters { + public: + std::vector<double> steps; + std::vector<double> weights; + Parameters() : + steps({ 0.4, 0.2, 0.1, 0.05 }), + weights({ 0.25, 0.25, 0.25, 0.25 }) { } + }; + + Quantize(Parameters params) : m_params(params) { + if (params.steps.empty()) { + throw std::invalid_argument("Quantize steps must not be empty"); + } + if (params.steps.size() != params.weights.size()) { + throw std::invalid_argument("Must have same number of quantize steps and weights"); + } + } + ~Quantize() { } + + std::vector<double> process(const std::vector<double> &in) { + int n = in.size(); + int m = m_params.steps.size(); + std::vector<double> out(n, 0.0); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + if (in[i] > m_params.steps[j]) { + out[i] += m_params.weights[j]; + } + } + } + return out; + } + +private: + Parameters m_params; +}; + +#endif
--- a/src/TipicVampPlugin.cpp Thu Oct 01 11:21:45 2015 +0100 +++ b/src/TipicVampPlugin.cpp Thu Oct 01 11:51:54 2015 +0100 @@ -4,6 +4,7 @@ #include "PitchFilterbank.h" #include "CRP.h" #include "Chroma.h" +#include "CENS.h" #include "FeatureDownsample.h" #include <bqvec/Range.h> @@ -27,9 +28,11 @@ m_crp(0), m_chroma(0), m_logChroma(0), + m_cens(0), m_pitchOutputNo(-1), m_cpOutputNo(-1), m_clpOutputNo(-1), + m_censOutputNo(-1), m_crpOutputNo(-1) { } @@ -40,6 +43,7 @@ delete m_crp; delete m_chroma; delete m_logChroma; + delete m_cens; for (auto &d: m_downsamplers) delete d.second; } @@ -249,6 +253,13 @@ d.sampleRate /= 10.0; list.push_back(d); + d.identifier = "cens"; + d.name = "Chroma Energy Normalised Statistics Features"; + d.description = ""; + d.sampleRate = PitchFilterbank::getOutputSampleRate() / 10.0; + m_censOutputNo = list.size(); + list.push_back(d); + d.identifier = "crp"; d.name = "Chroma DCT-Reduced Log Pitch Features"; d.description = ""; @@ -281,6 +292,7 @@ if (m_pitchOutputNo < 0 || m_cpOutputNo < 0 || m_clpOutputNo < 0 || + m_censOutputNo < 0 || m_crpOutputNo < 0) { throw std::logic_error("setup went wrong"); } @@ -318,6 +330,8 @@ Chroma::Parameters params; params.applyLogCompression = true; m_logChroma = new Chroma(params); + + m_cens = new CENS({}); } m_filterbank->reset(); @@ -336,12 +350,14 @@ RealBlock cp = m_chroma->process(pitchFiltered); RealBlock clp = m_logChroma->process(pitchFiltered); + RealBlock cens = m_cens->process(pitchFiltered); RealBlock crp = m_crp->process(pitchFiltered); FeatureSet fs; addFeatures(fs, m_pitchOutputNo, pitchFiltered, false); addFeatures(fs, m_cpOutputNo, cp, false); addFeatures(fs, m_clpOutputNo, clp, false); + addFeatures(fs, m_censOutputNo, cens, false); addFeatures(fs, m_crpOutputNo, crp, false); return fs; } @@ -353,12 +369,14 @@ RealBlock cp = m_chroma->process(pitchFiltered); RealBlock clp = m_logChroma->process(pitchFiltered); + RealBlock cens = m_cens->process(pitchFiltered); RealBlock crp = m_crp->process(pitchFiltered); FeatureSet fs; addFeatures(fs, m_pitchOutputNo, pitchFiltered, true); addFeatures(fs, m_cpOutputNo, cp, true); addFeatures(fs, m_clpOutputNo, clp, true); + addFeatures(fs, m_censOutputNo, cens, true); addFeatures(fs, m_crpOutputNo, crp, true); return fs; } @@ -367,13 +385,21 @@ Tipic::addFeatures(FeatureSet &fs, int outputNo, const RealBlock &block, bool final) { if (block.empty()) return; - - 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[outputNo].push_back(f); + + int downsampledOutputNo = outputNo + 1; + if (outputNo == m_censOutputNo) { + // CENS exists only in downsampled form + downsampledOutputNo = outputNo; + } + + if (outputNo != downsampledOutputNo) { + 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[outputNo].push_back(f); + } } if (m_downsamplers.find(outputNo) == m_downsamplers.end()) { @@ -394,6 +420,6 @@ int h = downsampled[i].size(); f.values.resize(h); v_convert(f.values.data(), downsampled[i].data(), h); - fs[outputNo + 1].push_back(f); + fs[downsampledOutputNo].push_back(f); } }
--- a/src/TipicVampPlugin.h Thu Oct 01 11:21:45 2015 +0100 +++ b/src/TipicVampPlugin.h Thu Oct 01 11:51:54 2015 +0100 @@ -8,6 +8,7 @@ class PitchFilterbank; class CRP; class Chroma; +class CENS; class FeatureDownsample; using std::string; @@ -57,9 +58,11 @@ CRP *m_crp; Chroma *m_chroma; Chroma *m_logChroma; + CENS *m_cens; mutable int m_pitchOutputNo; mutable int m_cpOutputNo; mutable int m_clpOutputNo; + mutable int m_censOutputNo; mutable int m_crpOutputNo; std::map<int, FeatureDownsample *> m_downsamplers;