changeset 11:7518c113bd03

Tidy the code up a bit
author Chris Cannam
date Fri, 14 Aug 2015 18:13:04 +0100
parents fa87ce20fe8c
children d9f993e094df
files Makefile.linux src/PitchFilterbank.cpp src/TipicVampPlugin.cpp
diffstat 3 files changed, 82 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.linux	Fri Aug 14 17:23:56 2015 +0100
+++ b/Makefile.linux	Fri Aug 14 18:13:04 2015 +0100
@@ -1,7 +1,7 @@
 
-#CFLAGS := -Wall -Werror -O3 -ffast-math -msse -msse2 -mfpmath=sse -ftree-vectorize -fPIC -I../vamp-plugin-sdk/ 
+CFLAGS := -Wall -Werror -O3 -ffast-math -msse -msse2 -mfpmath=sse -ftree-vectorize -fPIC -I../vamp-plugin-sdk/ 
 
-CFLAGS := -g -fPIC -I../vamp-plugin-sdk
+#CFLAGS := -g -fPIC -I../vamp-plugin-sdk
 
 CXXFLAGS := $(CFLAGS) -std=c++11
 
--- a/src/PitchFilterbank.cpp	Fri Aug 14 17:23:56 2015 +0100
+++ b/src/PitchFilterbank.cpp	Fri Aug 14 18:13:04 2015 +0100
@@ -8,7 +8,10 @@
 #include "filter-a.h"
 #include "filter-b.h"
 
+#include <deque>
+#include <map>
 #include <stdexcept>
+#include <iostream>
 
 using namespace std;
 
@@ -21,24 +24,28 @@
 {
 public:
     D(int sampleRate) :
-	m_sampleRate(sampleRate),
-	m_to22050(sampleRate, 22050),
-	m_to4410(sampleRate, 4410),
-	m_to882(sampleRate, 882)
+	m_nfilters(HIGHEST_FILTER_INDEX + 1),
+	m_sampleRate(sampleRate)
     {
-	for (int i = 0; i <= HIGHEST_FILTER_INDEX; ++i) {
+	m_resamplers[882] = new Resampler(sampleRate, 882);
+	m_resamplers[4410] = new Resampler(sampleRate, 4410);
+	m_resamplers[22050] = new Resampler(sampleRate, 22050);
+	
+	for (int i = 0; i < m_nfilters; ++i) {
 	    int ix = i + 20;
 	    int coeffs = sizeof(filter_a[0]) / sizeof(filter_a[0][0]);
 	    vector<double> a(filter_a[ix], filter_a[ix] + coeffs);
 	    vector<double> b(filter_b[ix], filter_b[ix] + coeffs);
 	    m_filters.push_back(new Filter({ a, b }));
 	}
+
+	m_filtered.resize(m_nfilters);
+	m_energies.resize(m_nfilters);
     }
 	
     ~D() {
-	for (int i = 0; i <= HIGHEST_FILTER_INDEX; ++i) {
-	    delete m_filters[i];
-	}
+	for (auto f: m_filters) delete f;
+	for (auto r: m_resamplers) delete r.second;
     }
 
     int getSampleRate() const { return m_sampleRate; }
@@ -54,54 +61,57 @@
 
     RealBlock process(const RealSequence &in) {
 
-	m_at22050 = m_to22050.process(in.data(), in.size());
-	m_at4410  =  m_to4410.process(in.data(), in.size());
-	m_at882   =   m_to882.process(in.data(), in.size());
+	cerr << "process" << endl;
+	
+	for (auto r: m_resamplers) {
+	    m_resampled[r.first] = r.second->process(in.data(), in.size());
+	}
 
-	for (int i = 0; i <= HIGHEST_FILTER_INDEX; ++i) {
-
-	    if (i <= HIGHEST_FILTER_INDEX_AT_882) {
-		pushFiltered(i, m_at882);
-	    } else if (i <= HIGHEST_FILTER_INDEX_AT_4410) {
-		pushFiltered(i, m_at4410);
-	    } else {
-		pushFiltered(i, m_at22050);
+	for (int i = 0; i < m_nfilters; ++i) {
+	    int rate = filterRate(i);
+	    if (m_resampled.find(rate) == m_resampled.end()) {
+		throw logic_error("No resampled output for rate of filter");
 	    }
+	    pushFiltered(i, m_resampled[rate]);
 	}
 
 	//!!! todo make this known through api. these values are at 22050Hz
 	int windowSize = 4410;
 
-	RealBlock energies(HIGHEST_FILTER_INDEX + 1);
-	int cols = 0;
-	
-	while (m_filtered[HIGHEST_FILTER_INDEX].size() >= unsigned(windowSize)) {
-	    //!!! Quite inefficient -- we're counting everything
-	    //!!! twice. Since there is no actual window shape, isn't
-	    //!!! the overlap just averaging?
-	    for (int i = 0; i <= HIGHEST_FILTER_INDEX; ++i) {
-		int n = windowSize;
-		double factor = 1.0;
-		if (i <= HIGHEST_FILTER_INDEX_AT_882) {
-		    factor = 22050.0 / 882.0;
-		} else if (i <= HIGHEST_FILTER_INDEX_AT_4410) {
-		    factor = 22050.0 / 4410.0;
-		}
-		//!!! Problem -- this is not an integer, for
-		//!!! fs=882 (it's 176.4)
-		n = n / factor;
+	//!!! This is all quite inefficient -- we're counting
+	//!!! everything twice. Since there is no actual window shape,
+	//!!! isn't the overlap just averaging?
+
+	for (int i = 0; i < m_nfilters; ++i) {
+
+	    double factor = 22050.0 / filterRate(i);
+	    //!!! Problem -- this is not an integer, for
+	    //!!! fs=882 (it's 176.4)
+	    int n = windowSize / factor;
+	    int hop = n / 2;
+	    
+	    while (m_filtered[i].size() >= unsigned(n)) {
 		double energy = calculateEnergy(m_filtered[i], n, factor);
-		energies[i].push_back(energy);
-		m_filtered[i] =
-		    RealSequence(m_filtered[i].begin() + n/2, m_filtered[i].end());
+		m_energies[i].push_back(energy);
+		m_filtered[i] = RealSequence(m_filtered[i].begin() + hop,
+					     m_filtered[i].end());
 	    }
-	    ++cols;
 	}
 
-	RealBlock out(cols);
-	for (int j = 0; j < cols; ++j) {
-	    for (int i = 0; i <= HIGHEST_FILTER_INDEX; ++i) {
-		out[j].push_back(energies[i][j]);
+	int minCols = 0;
+	for (int i = 0; i < m_nfilters; ++i) {
+	    int n = m_energies[i].size();
+	    if (i == 0 || n < minCols) {
+		minCols = n;
+	    }
+	}
+	
+	RealBlock out(minCols);
+	cerr << "process: minCols = " << minCols << endl;
+	for (int j = 0; j < minCols; ++j) {
+	    for (int i = 0; i < m_nfilters; ++i) {
+		out[j].push_back(m_energies[i][0]);
+		m_energies[i].pop_front();
 	    }
 	}
 
@@ -123,37 +133,14 @@
     double calculateEnergy(const RealSequence &seq, int n, double factor) {
 	double energy = 0.0;
 	for (int i = 0; i < n; ++i) {
-	    energy += seq[i] * seq[i] * factor;
+	    energy += seq[i] * seq[i];
 	}
-	return energy;
+	return energy * factor;
     }
     
 private:
+    int m_nfilters;
     int m_sampleRate;
-    
-    Resampler m_to22050;
-    Resampler m_to4410;
-    Resampler m_to882;
-
-    RealSequence m_at22050;
-    RealSequence m_at4410;
-    RealSequence m_at882;
-
-    RealSequence m_filtered[HIGHEST_FILTER_INDEX + 1];
-    
-    Resampler &resamplerFor(int filterIndex) {
-	if (filterIndex < 0) {
-	    throw std::logic_error("Filter index is negative");
-	} else if (filterIndex <= HIGHEST_FILTER_INDEX_AT_882) {
-	    return m_to882;
-	} else if (filterIndex <= HIGHEST_FILTER_INDEX_AT_4410) {
-	    return m_to4410;
-	} else if (filterIndex <= HIGHEST_FILTER_INDEX_AT_22050) {
-	    return m_to22050;
-	} else {
-	    throw std::logic_error("Filter index out of expected range");
-	}
-    }
 
     // This vector is initialised with 88 filter instances.
     // m_filters[n] (for n from 0 to 87) is for MIDI pitch 21+n, so we
@@ -162,15 +149,34 @@
     // has effective delay filter_delay[20+n].
     vector<Filter *> m_filters;
 
-    int filterIndexForMidiPitch(int pitch) const {
-	return pitch - 21;
+    map<int, Resampler *> m_resamplers; // rate -> resampler
+    map<int, RealSequence> m_resampled;
+    vector<RealSequence> m_filtered;
+    vector<deque<double>> m_energies;
+    
+    Resampler *resamplerFor(int filterIndex) {
+	int rate = filterRate(filterIndex);
+	if (m_resamplers.find(rate) == m_resamplers.end()) {
+	    throw std::logic_error("Filter index has unknown or unexpected rate");
+	}
+	return m_resamplers[rate];
+    }
+
+    int filterRate(int filterIndex) const {
+	if (filterIndex <= HIGHEST_FILTER_INDEX_AT_882) {
+	    return 882;
+	} else if (filterIndex <= HIGHEST_FILTER_INDEX_AT_4410) {
+	    return 4410;
+	} else {
+	    return 22050;
+	}
     }
     int filterDelay(int filterIndex) const {
 	return filter_delay[20 + filterIndex];
     }
     int totalDelay(int filterIndex) const {
 	return filterDelay(filterIndex) +
-	    const_cast<D *>(this)->resamplerFor(filterIndex).getLatency();
+	    const_cast<D *>(this)->resamplerFor(filterIndex)->getLatency();
     }
 };
 
--- a/src/TipicVampPlugin.cpp	Fri Aug 14 17:23:56 2015 +0100
+++ b/src/TipicVampPlugin.cpp	Fri Aug 14 18:13:04 2015 +0100
@@ -151,7 +151,6 @@
     d.isQuantized = false;
     d.sampleType = OutputDescriptor::FixedSampleRate;
     d.sampleRate = 22050 / 2205; //!!! get block size & hop from filterbank
-    cerr << "output sampleRate = " << d.sampleRate << endl;
     d.hasDuration = false;
     m_pitchOutputNo = list.size();
     list.push_back(d);