diff options
Diffstat (limited to 'lib/rbcodec/dsp/resample.c')
-rw-r--r-- | lib/rbcodec/dsp/resample.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/lib/rbcodec/dsp/resample.c b/lib/rbcodec/dsp/resample.c index 6e7e5b7b45..0a97bdf70c 100644 --- a/lib/rbcodec/dsp/resample.c +++ b/lib/rbcodec/dsp/resample.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "fracmul.h" | 25 | #include "fracmul.h" |
26 | #include "fixedpoint.h" | 26 | #include "fixedpoint.h" |
27 | #include "dsp_proc_entry.h" | 27 | #include "dsp_proc_entry.h" |
28 | #include "dsp_misc.h" | ||
28 | #include <string.h> | 29 | #include <string.h> |
29 | 30 | ||
30 | /** | 31 | /** |
@@ -50,9 +51,10 @@ static struct resample_data | |||
50 | int32_t history[2][3]; /* 08h: Last samples for interpolation (L+R) | 51 | int32_t history[2][3]; /* 08h: Last samples for interpolation (L+R) |
51 | 0 = oldest, 2 = newest */ | 52 | 0 = oldest, 2 = newest */ |
52 | /* 20h */ | 53 | /* 20h */ |
53 | int32_t frequency; /* Virtual samplerate */ | 54 | unsigned int frequency; /* Virtual input samplerate */ |
55 | unsigned int frequency_out; /* Resampler output samplerate */ | ||
54 | struct dsp_buffer resample_buf; /* Buffer descriptor for resampled data */ | 56 | struct dsp_buffer resample_buf; /* Buffer descriptor for resampled data */ |
55 | int32_t *resample_out_p[2]; /* Actual output buffer pointers */ | 57 | int32_t *resample_out_p[2]; /* Actual output buffer pointers */ |
56 | } resample_data[DSP_COUNT] IBSS_ATTR; | 58 | } resample_data[DSP_COUNT] IBSS_ATTR; |
57 | 59 | ||
58 | /* Actual worker function. Implemented here or in target assembly code. */ | 60 | /* Actual worker function. Implemented here or in target assembly code. */ |
@@ -73,14 +75,16 @@ static void resample_flush(struct dsp_proc_entry *this) | |||
73 | } | 75 | } |
74 | 76 | ||
75 | static bool resample_new_delta(struct resample_data *data, | 77 | static bool resample_new_delta(struct resample_data *data, |
76 | struct sample_format *format) | 78 | struct sample_format *format, |
79 | unsigned int fout) | ||
77 | { | 80 | { |
78 | int32_t frequency = format->frequency; /* virtual samplerate */ | 81 | unsigned int frequency = format->frequency; /* virtual samplerate */ |
79 | 82 | ||
80 | data->frequency = frequency; | 83 | data->frequency = frequency; |
81 | data->delta = fp_div(frequency, NATIVE_FREQUENCY, 16); | 84 | data->frequency_out = fout; |
85 | data->delta = fp_div(frequency, fout, 16); | ||
82 | 86 | ||
83 | if (frequency == NATIVE_FREQUENCY) | 87 | if (frequency == data->frequency_out) |
84 | { | 88 | { |
85 | /* NOTE: If fully glitch-free transistions from no resampling to | 89 | /* NOTE: If fully glitch-free transistions from no resampling to |
86 | resampling are desired, history should be maintained even when | 90 | resampling are desired, history should be maintained even when |
@@ -232,20 +236,23 @@ static intptr_t resample_new_format(struct dsp_proc_entry *this, | |||
232 | 236 | ||
233 | DSP_PRINT_FORMAT(DSP_PROC_RESAMPLE, *format); | 237 | DSP_PRINT_FORMAT(DSP_PROC_RESAMPLE, *format); |
234 | 238 | ||
235 | int32_t frequency = data->frequency; | 239 | unsigned int frequency = data->frequency; |
240 | unsigned int fout = dsp_get_output_frequency(dsp); | ||
236 | bool active = dsp_proc_active(dsp, DSP_PROC_RESAMPLE); | 241 | bool active = dsp_proc_active(dsp, DSP_PROC_RESAMPLE); |
237 | 242 | ||
238 | if (format->frequency != frequency) | 243 | if ((unsigned int)format->frequency != frequency || |
244 | data->frequency_out != fout) | ||
239 | { | 245 | { |
240 | DEBUGF(" DSP_PROC_RESAMPLE- new delta\n"); | 246 | DEBUGF(" DSP_PROC_RESAMPLE- new settings: %u %u\n", |
241 | active = resample_new_delta(data, format); | 247 | format->frequency, fout); |
248 | active = resample_new_delta(data, format, fout); | ||
242 | dsp_proc_activate(dsp, DSP_PROC_RESAMPLE, active); | 249 | dsp_proc_activate(dsp, DSP_PROC_RESAMPLE, active); |
243 | } | 250 | } |
244 | 251 | ||
245 | /* Everything after us is NATIVE_FREQUENCY */ | 252 | /* Everything after us is fout */ |
246 | dst->format = *format; | 253 | dst->format = *format; |
247 | dst->format.frequency = NATIVE_FREQUENCY; | 254 | dst->format.frequency = fout; |
248 | dst->format.codec_frequency = NATIVE_FREQUENCY; | 255 | dst->format.codec_frequency = fout; |
249 | 256 | ||
250 | if (active) | 257 | if (active) |
251 | return PROC_NEW_FORMAT_OK; | 258 | return PROC_NEW_FORMAT_OK; |
@@ -287,8 +294,10 @@ static void INIT_ATTR resample_dsp_init(struct dsp_config *dsp, | |||
287 | static void INIT_ATTR resample_proc_init(struct dsp_proc_entry *this, | 294 | static void INIT_ATTR resample_proc_init(struct dsp_proc_entry *this, |
288 | struct dsp_config *dsp) | 295 | struct dsp_config *dsp) |
289 | { | 296 | { |
297 | struct resample_data *data = &resample_data[dsp_get_id(dsp)]; | ||
298 | this->data = (intptr_t)data; | ||
290 | dsp_proc_set_in_place(dsp, DSP_PROC_RESAMPLE, false); | 299 | dsp_proc_set_in_place(dsp, DSP_PROC_RESAMPLE, false); |
291 | this->data = (intptr_t)&resample_data[dsp_get_id(dsp)]; | 300 | data->frequency_out = DSP_OUT_DEFAULT_HZ; |
292 | this->process = resample_process; | 301 | this->process = resample_process; |
293 | } | 302 | } |
294 | 303 | ||
@@ -322,6 +331,10 @@ static intptr_t resample_configure(struct dsp_proc_entry *this, | |||
322 | case DSP_PROC_NEW_FORMAT: | 331 | case DSP_PROC_NEW_FORMAT: |
323 | retval = resample_new_format(this, dsp, (struct sample_format *)value); | 332 | retval = resample_new_format(this, dsp, (struct sample_format *)value); |
324 | break; | 333 | break; |
334 | |||
335 | case DSP_SET_OUT_FREQUENCY: | ||
336 | dsp_proc_want_format_update(dsp, DSP_PROC_RESAMPLE); | ||
337 | break; | ||
325 | } | 338 | } |
326 | 339 | ||
327 | return retval; | 340 | return retval; |