Skip to content

Commit 2758cb7

Browse files
committed
resample.c: A bit of cleanup.
1 parent c22a83b commit 2758cb7

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

resample.c

+26-22
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ struct resample_state {
3434
struct {
3535
int n, d;
3636
} ratio;
37-
ssize_t m, sinc_len, sinc_fr_len, tmp_fr_len, in_len, out_len;
38-
ssize_t in_buf_pos, out_buf_pos, drain_pos, drain_frames, out_delay;
37+
int sinc_fr_len, tmp_fr_len, in_len, out_len;
38+
int in_buf_pos, out_buf_pos, drain_pos, drain_frames, out_delay;
3939
fftw_complex *sinc_fr;
4040
fftw_complex *tmp_fr, *tmp_fr_2;
4141
sample_t **input, **output, **overlap;
@@ -48,10 +48,12 @@ static double window(const double x)
4848
#if WINDOW_SHAPE == 1
4949
/* Blackman (~75dB stopband attenuation) */
5050
#define M_FACT 6
51+
if (x >= 1.0 || x <= 0.0) return 0.0;
5152
return 0.42 - 0.5*cos(2*M_PI*x) + 0.08*cos(4*M_PI*x);
5253
#elif WINDOW_SHAPE == 2
5354
/* Nuttall window (continuous first derivative) (~112dB stopband attenuation) */
5455
#define M_FACT 8
56+
if (x >= 1.0 || x <= 0.0) return 0.0;
5557
return 0.355768 - 0.487396*cos(2*M_PI*x) + 0.144232*cos(4*M_PI*x) - 0.012604*cos(6*M_PI*x);
5658
#else
5759
#error "error: illegal WINDOW_SHAPE"
@@ -68,32 +70,32 @@ static double norm_sinc(const double x, const double fc)
6870
sample_t * resample_effect_run(struct effect *e, ssize_t *frames, sample_t *ibuf, sample_t *obuf)
6971
{
7072
struct resample_state *state = (struct resample_state *) e->data;
71-
ssize_t i, k, j, l, d1, d2, iframes = 0, oframes = 0;
73+
ssize_t iframes = 0, oframes = 0;
7274
const ssize_t max_oframes = ratio_mult_ceil(*frames, state->ratio.n, state->ratio.d);
7375

7476
while (iframes < *frames) {
7577
while (state->in_buf_pos < state->in_len && iframes < *frames) {
76-
for (i = 0; i < e->ostream.channels; ++i)
78+
for (int i = 0; i < e->ostream.channels; ++i)
7779
state->input[i][state->in_buf_pos] = ibuf[iframes * e->ostream.channels + i];
7880
++iframes;
7981
++state->in_buf_pos;
8082
}
8183

8284
while (state->out_buf_pos < state->out_len && oframes < max_oframes && state->has_output) {
83-
for (i = 0; i < e->ostream.channels; ++i)
85+
for (int i = 0; i < e->ostream.channels; ++i)
8486
obuf[oframes * e->ostream.channels + i] = state->output[i][state->out_buf_pos];
8587
++oframes;
8688
++state->out_buf_pos;
8789
}
8890

8991
if (state->in_buf_pos == state->in_len && (!state->has_output || state->out_buf_pos == state->out_len)) {
90-
for (i = 0; i < e->ostream.channels; ++i) {
92+
for (int i = 0; i < e->ostream.channels; ++i) {
9193
/* FFT(state->input[i]) -> state->tmp_fr */
9294
fftw_execute(state->r2c_plan[i]);
9395
memset(state->tmp_fr_2, 0, state->tmp_fr_len * sizeof(fftw_complex));
9496
/* convolve input with sinc filter */
9597
state->tmp_fr_2[0] = state->tmp_fr[0] * state->sinc_fr[0];
96-
for (k = 1, j = 1, l = 1, d1 = 1, d2 = 1;; ++k) {
98+
for (int k = 1, j = 1, l = 1, d1 = 1, d2 = 1;; ++k) {
9799
fftw_complex s = (d1 == 1) ? state->tmp_fr[j] : conj(state->tmp_fr[j]);
98100
state->tmp_fr_2[l] += (d2 == 1) ? s * state->sinc_fr[k] : conj(s * state->sinc_fr[k]);
99101
if (k + 1 == state->sinc_fr_len) break;
@@ -111,10 +113,10 @@ sample_t * resample_effect_run(struct effect *e, ssize_t *frames, sample_t *ibuf
111113
/* IFFT(state->tmp_fr_2) -> state->output[i] */
112114
fftw_execute(state->c2r_plan[i]);
113115
/* normalize */
114-
for (k = 0; k < state->out_len * 2; ++k)
116+
for (int k = 0; k < state->out_len * 2; ++k)
115117
state->output[i][k] /= state->in_len * 2;
116118
/* handle overlap */
117-
for (k = 0; k < state->out_len; ++k) {
119+
for (int k = 0; k < state->out_len; ++k) {
118120
state->output[i][k] += state->overlap[i][k];
119121
state->overlap[i][k] = state->output[i][k + state->out_len];
120122
}
@@ -260,11 +262,12 @@ struct effect * resample_effect_init(const struct effect_info *ei, const struct
260262
const int m = lround(M_FACT / (width / max_rate));
261263
const int sinc_os = MINIMUM(min_factor, SINC_MAX_OVERSAMPLE);
262264
const double fc_os = fc / sinc_os;
263-
const int m_os = m * sinc_os;
265+
const int m_os = (m + 1) * sinc_os - 1;
264266

265267
/* determine array lengths */
266-
state->m = (m + 1) * 2 - 1; /* final impulse length after convolving sinc function with itself */
267-
int len_mult = (state->m % max_factor != 0) ? state->m / max_factor + 1 : state->m / max_factor;
268+
const int m_conv = (m + 1) * 2 - 1; /* after convolving sinc function with itself */
269+
int len_mult = (m_conv + 1) / max_factor;
270+
if ((m_conv + 1) % max_factor != 0) len_mult += 1;
268271
if (len_mult > 16) { /* 17 is the first slow size */
269272
const int fast_len_mult = next_fast_fftw_len(len_mult);
270273
if (fast_len_mult != len_mult
@@ -273,17 +276,17 @@ struct effect * resample_effect_init(const struct effect_info *ei, const struct
273276
|| next_fast_fftw_len(state->ratio.d) == state->ratio.d))
274277
len_mult = fast_len_mult;
275278
}
276-
state->sinc_len = max_factor * len_mult * sinc_os;
279+
const int sinc_len = max_factor * len_mult * sinc_os;
277280
state->in_len = state->ratio.d * len_mult;
278281
state->out_len = state->ratio.n * len_mult;
279282
state->tmp_fr_len = max_factor * len_mult + 1;
280-
state->sinc_fr_len = state->sinc_len + 1;
283+
state->sinc_fr_len = sinc_len + 1;
281284

282285
/* calculate output delay */
283286
if (rate == max_rate)
284-
state->out_delay = state->m / 2;
287+
state->out_delay = m_conv / 2;
285288
else
286-
state->out_delay = lround(state->m / 2 * ((double) state->ratio.n / state->ratio.d));
289+
state->out_delay = lround(m_conv / 2 * ((double) state->ratio.n / state->ratio.d));
287290

288291
/* allocate arrays, construct fftw plans */
289292
state->input = calloc(e->ostream.channels, sizeof(sample_t *));
@@ -293,12 +296,12 @@ struct effect * resample_effect_init(const struct effect_info *ei, const struct
293296
state->c2r_plan = calloc(e->ostream.channels, sizeof(fftw_plan));
294297
state->tmp_fr = fftw_malloc(state->tmp_fr_len * sizeof(fftw_complex));
295298
state->tmp_fr_2 = fftw_malloc(state->tmp_fr_len * sizeof(fftw_complex));
296-
sinc = fftw_malloc(state->sinc_len * 2 * sizeof(sample_t));
299+
sinc = fftw_malloc(sinc_len * 2 * sizeof(sample_t));
297300
state->sinc_fr = fftw_malloc(state->sinc_fr_len * sizeof(fftw_complex));
298301

299302
dsp_fftw_acquire();
300303
const int planner_flags = (dsp_fftw_load_wisdom()) ? FFTW_MEASURE : FFTW_ESTIMATE;
301-
sinc_plan = fftw_plan_dft_r2c_1d(state->sinc_len * 2, sinc, state->sinc_fr, FFTW_ESTIMATE);
304+
sinc_plan = fftw_plan_dft_r2c_1d(sinc_len * 2, sinc, state->sinc_fr, FFTW_ESTIMATE);
302305
for (int i = 0; i < e->ostream.channels; ++i) {
303306
state->input[i] = fftw_malloc(state->in_len * 2 * sizeof(sample_t));
304307
state->output[i] = fftw_malloc(state->out_len * 2 * sizeof(sample_t));
@@ -310,13 +313,14 @@ struct effect * resample_effect_init(const struct effect_info *ei, const struct
310313
memset(state->overlap[i], 0, state->out_len * sizeof(sample_t));
311314
}
312315
dsp_fftw_release();
313-
memset(sinc, 0, state->sinc_len * 2 * sizeof(sample_t));
316+
memset(sinc, 0, sinc_len * 2 * sizeof(sample_t));
314317
memset(state->sinc_fr, 0, state->sinc_fr_len * sizeof(fftw_complex));
315318
memset(state->tmp_fr, 0, state->tmp_fr_len * sizeof(fftw_complex));
316319
memset(state->tmp_fr_2, 0, state->tmp_fr_len * sizeof(fftw_complex));
317320

318321
/* generate windowed sinc function */
319-
for (int i = 0; i < m_os + 1; ++i)
322+
/* note: all supported windows are zero at endpoints, so skip the first and last indicies */
323+
for (int i = 1; i < m_os; ++i)
320324
sinc[i] = norm_sinc((i*2 - m_os)/2.0, fc_os) * window((double) i / m_os);
321325

322326
fftw_execute(sinc_plan);
@@ -327,8 +331,8 @@ struct effect * resample_effect_init(const struct effect_info *ei, const struct
327331
for (int i = 0; i < state->sinc_fr_len; ++i)
328332
state->sinc_fr[i] *= state->sinc_fr[i];
329333

330-
LOG_FMT(LL_VERBOSE, "%s: info: gcd=%d ratio=%d/%d width=%fHz fc=%f filter_len=%zd in_len=%zd out_len=%zd sinc_oversample=%d",
331-
argv[0], gcd, state->ratio.n, state->ratio.d, width, fc, state->m, state->in_len, state->out_len, sinc_os);
334+
LOG_FMT(LL_VERBOSE, "%s: info: gcd=%d ratio=%d/%d width=%fHz fc=%f filter_len=%d in_len=%d out_len=%d sinc_oversample=%d",
335+
argv[0], gcd, state->ratio.n, state->ratio.d, width, fc, m_conv+1, state->in_len, state->out_len, sinc_os);
332336

333337
return e;
334338
}

0 commit comments

Comments
 (0)