1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2 /*
3     QM DSP Library
4 
5     Centre for Digital Music, Queen Mary, University of London.
6     This file by Chris Cannam.
7 
8     This program is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License as
10     published by the Free Software Foundation; either version 2 of the
11     License, or (at your option) any later version.  See the file
12     COPYING included with this distribution for more information.
13 */
14 
15 #ifndef QM_DSP_RESAMPLER_H
16 #define QM_DSP_RESAMPLER_H
17 
18 #include <vector>
19 
20 /**
21  * Resampler resamples a stream from one integer sample rate to
22  * another (arbitrary) rate, using a kaiser-windowed sinc filter.  The
23  * results and performance are pretty similar to libraries such as
24  * libsamplerate, though this implementation does not support
25  * time-varying ratios (the ratio is fixed on construction).
26  *
27  * See also Decimator, which is faster and rougher but supports only
28  * power-of-two downsampling factors.
29  */
30 class Resampler
31 {
32 public:
33     /**
34      * Construct a Resampler to resample from sourceRate to
35      * targetRate.
36      */
37     Resampler(int sourceRate, int targetRate);
38 
39     /**
40      * Construct a Resampler to resample from sourceRate to
41      * targetRate, using the given filter parameters.
42      */
43     Resampler(int sourceRate, int targetRate,
44               double snr, double bandwidth);
45 
46     virtual ~Resampler();
47 
48     /**
49      * Read n input samples from src and write resampled data to
50      * dst. The return value is the number of samples written, which
51      * will be no more than ceil((n * targetRate) / sourceRate). The
52      * caller must ensure the dst buffer has enough space for the
53      * samples returned.
54      */
55     int process(const double *src, double *dst, int n);
56 
57     /**
58      * Read n input samples from src and return resampled data by
59      * value.
60      */
61     std::vector<double> process(const double *src, int n);
62 
63     /**
64      * Return the number of samples of latency at the output due by
65      * the filter. (That is, the output will be delayed by this number
66      * of samples relative to the input.)
67      */
getLatency()68     int getLatency() const { return m_latency; }
69 
70     /**
71      * Carry out a one-off resample of a single block of n
72      * samples. The output is latency-compensated.
73      */
74     static std::vector<double> resample
75     (int sourceRate, int targetRate, const double *data, int n);
76 
77 private:
78     int m_sourceRate;
79     int m_targetRate;
80     int m_gcd;
81     int m_filterLength;
82     int m_latency;
83     double m_peakToPole;
84 
85     struct Phase {
86         int nextPhase;
87         std::vector<double> filter;
88         int drop;
89     };
90 
91     Phase *m_phaseData;
92     int m_phase;
93     std::vector<double> m_buffer;
94     int m_bufferOrigin;
95 
96     void initialise(double, double);
97     double reconstructOne();
98 };
99 
100 #endif
101 
102