summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/resample.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/dsp/resample.c')
-rw-r--r--lib/rbcodec/dsp/resample.c41
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
75static bool resample_new_delta(struct resample_data *data, 77static 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,
287static void INIT_ATTR resample_proc_init(struct dsp_proc_entry *this, 294static 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;