sound, prepare FM filtering

This commit is contained in:
kub 2022-03-31 17:27:49 +00:00
parent 882f697ad4
commit e2e2b6ad1b
8 changed files with 1180 additions and 3 deletions

44
pico/sound/resampler.h Normal file
View file

@ -0,0 +1,44 @@
/* 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));