mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
44 lines
2 KiB
C
44 lines
2 KiB
C
/* Configurable fixed point resampling SINC filter for mono and stereo audio.
|
|
*
|
|
* (C) 2022 kub
|
|
*
|
|
* This work is licensed under the terms of any of these licenses
|
|
* (at your option):
|
|
* - GNU GPL, version 2 or later.
|
|
* - MAME license.
|
|
* See COPYING file in the top-level directory.
|
|
*/
|
|
|
|
struct resampler {
|
|
int stereo; // mono or stereo?
|
|
int taps; // taps to compute per output sample
|
|
int interpolation; // upsampling factor (numerator)
|
|
int decimation; // downsampling factor (denominator)
|
|
int ratio_int; // floor(decimation/interpolation)
|
|
u32 interp_inv; // Q16, 1.0/interpolation
|
|
s16 *filter; // filter taps
|
|
s32 *buffer; // filter history and input buffer (w/o zero stuffing)
|
|
int buffer_sz; // buffer size in frames
|
|
int buffer_idx; // buffer offset
|
|
int phase; // filter phase for last output sample
|
|
};
|
|
typedef struct resampler resampler_t;
|
|
|
|
|
|
/* Release a resampler */
|
|
void resampler_free(resampler_t *r);
|
|
/* Create a resampler with upsampling factor :interpolation and downsampling
|
|
* factor :decimation, Kaiser windowed SINC polyphase FIR with bank size :taps.
|
|
* The created filter has a size of :taps*:interpolation for upsampling and
|
|
* :taps*:decimation for downsampling. :taps is limiting the cost per sample and
|
|
* should be big enough to avoid inaccuracy (>= 8, higher is more accurate).
|
|
* :cutoff is in [0..1] with 1 representing the Nyquist rate after decimation.
|
|
* :beta is the Kaiser window beta.
|
|
* :max_input is the maximum length in a resampler_update call */
|
|
resampler_t *resampler_new(unsigned taps, unsigned interpolation, unsigned decimation,
|
|
double cutoff, double beta, unsigned max_input, int stereo);
|
|
/* Obtain :length resampled audio frames in :buffer. Use :get_samples to obtain
|
|
* the needed amount of input samples */
|
|
void resampler_update(resampler_t *r, s32 *buffer, int length,
|
|
void (*generate_samples)(s32 *buffer, int length, int stereo));
|
|
|