openal-soft/common/polyphase_resampler.h
Chris Robinson f2858ac865 Resample before frequency analysis
We want to resample before minimum phase reconstruction since that changes the
phase relationship of the sampled signal, introducing a slight bit of noise
from truncated sampling. It's not clear that the frequency domain resampling
method is accurate, so resampling prior to frequency analysis is an alternative
to ensure the resulting frequencies are given the proper phase for sampling.

This also cleans up some micro allocations in loops.
2022-05-13 15:40:15 -07:00

46 lines
1.5 KiB
C++

#ifndef POLYPHASE_RESAMPLER_H
#define POLYPHASE_RESAMPLER_H
#include <vector>
using uint = unsigned int;
/* 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 {
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 */