/* 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));

