Mercurial > hg > tipic
view src/PitchFilterbank.cpp @ 9:f440b0e2192b
Call the (not yet existing) implementation functions
author | Chris Cannam |
---|---|
date | Fri, 14 Aug 2015 14:40:48 +0100 |
parents | e62530cdc1c3 |
children | fa87ce20fe8c |
line wrap: on
line source
#include "PitchFilterbank.h" #include "Resampler.h" #include "Filter.h" #include "delays.h" #include "filter-a.h" #include "filter-b.h" #include <stdexcept> using namespace std; static const int HIGHEST_FILTER_INDEX_AT_882 = 38; // MIDI pitch 59 static const int HIGHEST_FILTER_INDEX_AT_4410 = 74; // MIDI pitch 95 static const int HIGHEST_FILTER_INDEX_AT_22050 = 87; // MIDI pitch 108 static const int HIGHEST_FILTER_INDEX = HIGHEST_FILTER_INDEX_AT_22050; class PitchFilterbank::D { public: D(int sampleRate) : m_sampleRate(sampleRate), m_to22050(sampleRate, 22050), m_to4410(sampleRate, 4410), m_to882(sampleRate, 882) { for (int i = 0; i < HIGHEST_FILTER_INDEX; ++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(Filter({ a, b })); } } ~D() { } int getSampleRate() const { return m_sampleRate; } /// 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 &); RealBlock getRemainingOutput(); private: int m_sampleRate; Resampler m_to22050; Resampler m_to4410; Resampler m_to882; 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 // span the MIDI range from pitch 21 to 108. Then m_filters[n] has // coefficients drawn from filter_a[20+n] and filter_b[20+n], and // has effective delay filter_delay[20+n]. vector<Filter> m_filters; int filterIndexForMidiPitch(int pitch) const { return pitch - 21; } 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(); } }; PitchFilterbank::PitchFilterbank(int sampleRate) : m_d(new D(sampleRate)) { } PitchFilterbank::~PitchFilterbank() { delete m_d; } void PitchFilterbank::reset() { int rate = m_d->getSampleRate(); delete m_d; m_d = new D(rate); } PitchFilterbank::RealBlock PitchFilterbank::process(const RealSequence &in) { return m_d->process(in); } PitchFilterbank::RealBlock PitchFilterbank::getRemainingOutput() { return m_d->getRemainingOutput(); }