22 double *output,
unsigned max_output_len,
23 double in_rate,
double out_rate,
24 unsigned num_zero_crossings,
double kaiser_beta)
35 "max_output_len too small for expected output", 0);
38 unsigned taps_per_phase = 2 * num_zero_crossings;
39 unsigned table_size = (num_phases + 1) * taps_per_phase;
46 double *table = malloc(table_size *
sizeof(
double));
50 double ratio = out_rate / in_rate;
51 double cutoff_ratio = (ratio < 1.0) ? ratio : 1.0;
53 for (
unsigned p = 0; p <= num_phases; p++) {
54 double frac = (double)p / (
double)num_phases;
55 double *phase_row = table + p * taps_per_phase;
57 for (
unsigned t = 0; t < taps_per_phase; t++) {
58 int tap_offset = (int)t - (
int)num_zero_crossings;
59 double x = (double)tap_offset + frac;
62 double sinc_val =
MD_sinc(cutoff_ratio * x);
65 double half_width = (double)num_zero_crossings;
67 if (fabs(x) >= half_width) {
70 double r = x / half_width;
71 double arg = 1.0 - r * r;
72 if (arg < 0.0) arg = 0.0;
77 phase_row[t] = cutoff_ratio * sinc_val * w;
83 unsigned out_len = expected_len;
85 for (
unsigned n = 0; n < out_len; n++) {
86 double in_pos = (double)n / ratio;
87 int in_idx = (int)floor(in_pos);
88 double frac = in_pos - (double)in_idx;
91 double phase_exact = frac * (double)num_phases;
92 unsigned phase_lo = (unsigned)phase_exact;
93 double alpha = phase_exact - (double)phase_lo;
95 if (phase_lo >= num_phases) {
96 phase_lo = num_phases - 1;
100 const double *row_lo = table + phase_lo * taps_per_phase;
101 const double *row_hi = table + (phase_lo + 1) * taps_per_phase;
104 for (
unsigned t = 0; t < taps_per_phase; t++) {
105 int si = in_idx + (int)t - (
int)num_zero_crossings;
109 if (si < 0 || (
unsigned)si >= input_len) {
115 double coeff = row_lo[t] + alpha * (row_hi[t] - row_lo[t]);
116 acc += sample * coeff;
#define MD_CHECK(cond, code, msg, retval)
Check a precondition in a function that returns a value.
unsigned MD_resample(const double *input, unsigned input_len, double *output, unsigned max_output_len, double in_rate, double out_rate, unsigned num_zero_crossings, double kaiser_beta)
Resample a signal from one sample rate to another using polyphase sinc interpolation.