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