176 lines
5.2 KiB
C
176 lines
5.2 KiB
C
/* SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
|
|
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
|
|
|
#if !defined soxr_rate1_included
|
|
#define soxr_rate1_included
|
|
|
|
#define FIFO_SIZE_T int
|
|
#include "fifo.h"
|
|
|
|
typedef void real; /* float or double */
|
|
struct stage;
|
|
typedef void (* stage_fn_t)(struct stage * input, fifo_t * output);
|
|
typedef struct half_fir_info {int num_coefs; real const * coefs; stage_fn_t fn, dfn; float att;} half_fir_info_t;
|
|
typedef struct {float scalar; stage_fn_t fn;} poly_fir1_t;
|
|
typedef struct {float beta; poly_fir1_t interp[3];} poly_fir_t;
|
|
|
|
#define U100_l 42
|
|
#define MULT32 (65536. * 65536.)
|
|
|
|
/* Conceptually: coef_p is &coefs[num_phases][fir_len][interp_order+1]: */
|
|
#define coef(coef_p, interp_order, fir_len, phase_num, coef_interp_num, fir_coef_num) (coef_p)[\
|
|
(fir_len) * ((interp_order) + 1) * (phase_num) + \
|
|
((interp_order) + 1) * (fir_coef_num) + \
|
|
((interp_order) - (coef_interp_num))]
|
|
|
|
/* Conceptually: coef_p is &coefs[num_phases][fir_len/4][interp_order+1][4]: */
|
|
#define coef4(coef_p, interp_order, fir_len, phase_num, coef_interp_num, fir_coef_num) (coef_p)[\
|
|
(fir_len) * ((interp_order) + 1) * (phase_num) + \
|
|
((interp_order) + 1) * ((fir_coef_num) & ~3) + \
|
|
4 * ((interp_order) - (coef_interp_num)) + \
|
|
((fir_coef_num) & 3)]
|
|
|
|
typedef union { /* Int64 in parts */
|
|
#if HAVE_BIGENDIAN
|
|
struct {int32_t ms; uint32_t ls;} parts;
|
|
#else
|
|
struct {uint32_t ls; int32_t ms;} parts;
|
|
#endif
|
|
int64_t all;
|
|
} int64p_t;
|
|
|
|
typedef union { /* Uint64 in parts */
|
|
#if HAVE_BIGENDIAN
|
|
struct {uint32_t ms, ls;} parts;
|
|
#else
|
|
struct {uint32_t ls, ms;} parts;
|
|
#endif
|
|
uint64_t all;
|
|
} uint64p_t;
|
|
|
|
#define FLOAT_HI_PREC_CLOCK 0 /* Non-float hi-prec has ~96 bits. */
|
|
#define float_step_t long double /* __float128 is also a (slow) option */
|
|
|
|
typedef struct {
|
|
int dft_length, num_taps, post_peak;
|
|
void * dft_forward_setup, * dft_backward_setup;
|
|
real * coefs;
|
|
} dft_filter_t;
|
|
|
|
typedef struct { /* So generated filter coefs may be shared between channels */
|
|
real * poly_fir_coefs;
|
|
dft_filter_t dft_filter[2];
|
|
} rate_shared_t;
|
|
|
|
typedef union { /* Fixed point arithmetic */
|
|
struct {uint64p_t ls; int64p_t ms;} fix;
|
|
float_step_t flt;
|
|
} step_t;
|
|
|
|
#define CORE_DBL 1
|
|
#define CORE_SIMD_POLY 2
|
|
#define CORE_SIMD_HALF 4
|
|
#define CORE_SIMD_DFT 8
|
|
#define LOG2_SIZEOF_REAL(core_flags) (2 + ((core_flags) & 1))
|
|
|
|
typedef int core_flags_t;
|
|
|
|
#if defined SOXR_LIB
|
|
#include "rdft_t.h"
|
|
#else
|
|
typedef void fn_t;
|
|
#endif
|
|
|
|
typedef struct stage {
|
|
int num;
|
|
|
|
/* Common to all stage types: */
|
|
core_flags_t core_flags;
|
|
stage_fn_t fn;
|
|
fifo_t fifo;
|
|
int pre; /* Number of past samples to store */
|
|
int pre_post; /* pre + number of future samples to store */
|
|
int preload; /* Number of zero samples to pre-load the fifo */
|
|
double out_in_ratio; /* For buffer management. */
|
|
int input_size;
|
|
bool is_input;
|
|
|
|
/* For a stage with variable (run-time generated) filter coefs: */
|
|
fn_t const * rdft_cb;
|
|
rate_shared_t * shared;
|
|
unsigned dft_filter_num; /* Which, if any, of the 2 DFT filters to use */
|
|
real * dft_scratch;
|
|
float * dft_out;
|
|
real const * coefs;
|
|
|
|
/* For a stage with variable L/M: */
|
|
step_t at, step;
|
|
bool use_hi_prec_clock;
|
|
int L, remM;
|
|
int n, phase_bits, block_len;
|
|
double mult, phase0;
|
|
} stage_t;
|
|
|
|
#define stage_occupancy(s) max(0, fifo_occupancy(&(s)->fifo) - (s)->pre_post)
|
|
#define stage_read_p(s) ((sample_t *)fifo_read_ptr(&(s)->fifo) + (s)->pre)
|
|
#define integer fix.ms.parts.ms
|
|
#define fraction fix.ms.parts.ls
|
|
#define whole fix.ms.all
|
|
|
|
|
|
#define lq_bw0 (1385/2048.) /* ~.67625, FP exact. */
|
|
|
|
typedef enum {rolloff_small, rolloff_medium, rolloff_none} rolloff_t;
|
|
|
|
|
|
typedef struct {
|
|
void * (* alloc)(size_t);
|
|
void * (* calloc)(size_t, size_t);
|
|
void (* free)(void *);
|
|
} alloc_t;
|
|
|
|
typedef struct {
|
|
alloc_t mem;
|
|
half_fir_info_t const * half_firs;
|
|
size_t half_firs_len;
|
|
half_fir_info_t const * doub_firs;
|
|
size_t doub_firs_len;
|
|
stage_fn_t cubic_stage_fn;
|
|
poly_fir_t const * poly_firs;
|
|
fn_t * rdft_cb;
|
|
} cr_core_t;
|
|
|
|
typedef struct rate rate_t;
|
|
struct rate {
|
|
cr_core_t const * core;
|
|
double io_ratio;
|
|
int64_t samples_in, samples_out;
|
|
int num_stages, flushing;
|
|
stage_t * stages;
|
|
};
|
|
|
|
#if defined SOXR_LIB
|
|
|
|
#include "soxr.h"
|
|
|
|
char const * _soxr_init(
|
|
rate_t * const p, /* Per audio channel. */
|
|
rate_shared_t * const shared, /* Between channels (undergoing same rate change)*/
|
|
double const io_ratio, /* Input rate divided by output rate. */
|
|
soxr_quality_spec_t const * const q_spec,
|
|
soxr_runtime_spec_t const * const r_spec,
|
|
double multiplier, /* Linear gain to apply during conversion. 1 */
|
|
cr_core_t const * const core,
|
|
core_flags_t const);
|
|
|
|
void _soxr_process(struct rate * p, size_t olen);
|
|
real * _soxr_input(struct rate * p, real const * samples, size_t n);
|
|
real const * _soxr_output(struct rate * p, real * samples, size_t * n0);
|
|
void _soxr_flush(struct rate * p);
|
|
void _soxr_close(struct rate * p);
|
|
double _soxr_delay(struct rate * p);
|
|
void _soxr_sizes(size_t * shared, size_t * channel);
|
|
#endif
|
|
|
|
#endif
|