aboutsummaryrefslogtreecommitdiffstats
path: root/common/polyphase_resampler.h
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-11-28 10:54:47 -0800
committerChris Robinson <[email protected]>2019-11-28 10:54:47 -0800
commitc093728ced2da0eb5fb01235c62460262b704790 (patch)
tree8ff77170d197628875f5af3fda7c855fa2d244bf /common/polyphase_resampler.h
parent576adf06b16f6b1c88991970dce06fcabbb04f28 (diff)
Move the polyphase resampler to the common lib
Diffstat (limited to 'common/polyphase_resampler.h')
-rw-r--r--common/polyphase_resampler.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/common/polyphase_resampler.h b/common/polyphase_resampler.h
new file mode 100644
index 00000000..e9833d12
--- /dev/null
+++ b/common/polyphase_resampler.h
@@ -0,0 +1,45 @@
+#ifndef POLYPHASE_RESAMPLER_H
+#define POLYPHASE_RESAMPLER_H
+
+#include <vector>
+
+
+/* This is a polyphase sinc-filtered resampler. It is built for very high
+ * quality results, rather than real-time performance.
+ *
+ * Upsample Downsample
+ *
+ * p/q = 3/2 p/q = 3/5
+ *
+ * M-+-+-+-> M-+-+-+->
+ * -------------------+ ---------------------+
+ * p s * f f f f|f| | p s * f f f f f |
+ * | 0 * 0 0 0|0|0 | | 0 * 0 0 0 0|0| |
+ * v 0 * 0 0|0|0 0 | v 0 * 0 0 0|0|0 |
+ * s * f|f|f f f | s * f f|f|f f |
+ * 0 * |0|0 0 0 0 | 0 * 0|0|0 0 0 |
+ * --------+=+--------+ 0 * |0|0 0 0 0 |
+ * d . d .|d|. d . d ----------+=+--------+
+ * d . . . .|d|. . . .
+ * q->
+ * q-+-+-+->
+ *
+ * P_f(i,j) = q i mod p + pj
+ * P_s(i,j) = floor(q i / p) - j
+ * d[i=0..N-1] = sum_{j=0}^{floor((M - 1) / p)} {
+ * { f[P_f(i,j)] s[P_s(i,j)], P_f(i,j) < M
+ * { 0, P_f(i,j) >= M. }
+ */
+
+struct PPhaseResampler {
+ using uint = unsigned int;
+
+ void init(const uint srcRate, const uint dstRate);
+ void process(const uint inN, const double *in, const uint outN, double *out);
+
+private:
+ uint mP, mQ, mM, mL;
+ std::vector<double> mF;
+};
+
+#endif /* POLYPHASE_RESAMPLER_H */