Chris@366: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@366: /* Chris@366: Constant-Q library Chris@366: Copyright (c) 2013-2014 Queen Mary, University of London Chris@366: Chris@366: Permission is hereby granted, free of charge, to any person Chris@366: obtaining a copy of this software and associated documentation Chris@366: files (the "Software"), to deal in the Software without Chris@366: restriction, including without limitation the rights to use, copy, Chris@366: modify, merge, publish, distribute, sublicense, and/or sell copies Chris@366: of the Software, and to permit persons to whom the Software is Chris@366: furnished to do so, subject to the following conditions: Chris@366: Chris@366: The above copyright notice and this permission notice shall be Chris@366: included in all copies or substantial portions of the Software. Chris@366: Chris@366: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Chris@366: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF Chris@366: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND Chris@366: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY Chris@366: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Chris@366: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION Chris@366: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Chris@366: Chris@366: Except as contained in this notice, the names of the Centre for Chris@366: Digital Music; Queen Mary, University of London; and Chris Cannam Chris@366: shall not be used in advertising or otherwise to promote the sale, Chris@366: use or other dealings in this Software without prior written Chris@366: authorization. Chris@366: */ Chris@366: Chris@366: #ifndef RESAMPLER_H Chris@366: #define RESAMPLER_H Chris@366: Chris@366: #include Chris@366: Chris@366: /** Chris@366: * Resampler resamples a stream from one integer sample rate to Chris@366: * another (arbitrary) rate, using a kaiser-windowed sinc filter. The Chris@366: * results and performance are pretty similar to libraries such as Chris@366: * libsamplerate, though this implementation does not support Chris@366: * time-varying ratios (the ratio is fixed on construction). Chris@366: * Chris@366: * See also Decimator, which is faster and rougher but supports only Chris@366: * power-of-two downsampling factors. Chris@366: */ Chris@366: class Resampler Chris@366: { Chris@366: public: Chris@366: /** Chris@366: * Construct a Resampler to resample from sourceRate to Chris@366: * targetRate. Chris@366: */ Chris@366: Resampler(int sourceRate, int targetRate); Chris@366: Chris@366: /** Chris@366: * Construct a Resampler to resample from sourceRate to Chris@366: * targetRate, using the given filter parameters. Chris@366: */ Chris@366: Resampler(int sourceRate, int targetRate, Chris@366: double snr, double bandwidth); Chris@366: Chris@366: virtual ~Resampler(); Chris@366: Chris@366: /** Chris@366: * Read n input samples from src and write resampled data to Chris@366: * dst. The return value is the number of samples written, which Chris@366: * will be no more than ceil((n * targetRate) / sourceRate). The Chris@366: * caller must ensure the dst buffer has enough space for the Chris@366: * samples returned. Chris@366: */ Chris@366: int process(const double *src, double *dst, int n); Chris@366: Chris@366: /** Chris@366: * Read n input samples from src and return resampled data by Chris@366: * value. Chris@366: */ Chris@366: std::vector process(const double *src, int n); Chris@366: Chris@366: /** Chris@366: * Return the number of samples of latency at the output due by Chris@366: * the filter. (That is, the output will be delayed by this number Chris@366: * of samples relative to the input.) Chris@366: */ Chris@366: int getLatency() const { return m_latency; } Chris@366: Chris@366: /** Chris@366: * Carry out a one-off resample of a single block of n Chris@366: * samples. The output is latency-compensated. Chris@366: */ Chris@366: static std::vector resample Chris@366: (int sourceRate, int targetRate, const double *data, int n); Chris@366: Chris@366: private: Chris@366: int m_sourceRate; Chris@366: int m_targetRate; Chris@366: int m_gcd; Chris@366: int m_filterLength; Chris@366: int m_latency; Chris@366: double m_peakToPole; Chris@366: Chris@366: struct Phase { Chris@366: int nextPhase; Chris@366: std::vector filter; Chris@366: int drop; Chris@366: }; Chris@366: Chris@366: Phase *m_phaseData; Chris@366: int m_phase; Chris@366: std::vector m_buffer; Chris@366: int m_bufferOrigin; Chris@366: Chris@366: void initialise(double, double); Chris@366: double reconstructOne(); Chris@366: }; Chris@366: Chris@366: #endif Chris@366: