summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/lin_resample.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-12-19 17:34:57 -0500
committerMichael Sevakis <jethead71@rockbox.org>2013-05-04 13:43:33 -0400
commit78a45b47dede5ddf35dfc53e965b486a79177b18 (patch)
treeedb3ad7c101e600a7cc3be4b40380430cbeb3e55 /lib/rbcodec/dsp/lin_resample.c
parentcdb71c707bb434f44368b72f2db3becc37b7a46c (diff)
downloadrockbox-78a45b47dede5ddf35dfc53e965b486a79177b18.tar.gz
rockbox-78a45b47dede5ddf35dfc53e965b486a79177b18.zip
Cleanup and simplify latest DSP code incarnation.
Some things can just be a bit simpler in handling the list of stages and some things, especially format change handling, can be simplified for each stage implementation. Format changes are sent through the configure() callback. Hide some internal details and variables from processing stages and let the core deal with it. Do some miscellaneous cleanup and keep things a bit better factored. Change-Id: I19dd8ce1d0b792ba914d426013088a49a52ecb7e
Diffstat (limited to 'lib/rbcodec/dsp/lin_resample.c')
-rw-r--r--lib/rbcodec/dsp/lin_resample.c97
1 files changed, 45 insertions, 52 deletions
diff --git a/lib/rbcodec/dsp/lin_resample.c b/lib/rbcodec/dsp/lin_resample.c
index 34dc35b2dd..20bb78e68d 100644
--- a/lib/rbcodec/dsp/lin_resample.c
+++ b/lib/rbcodec/dsp/lin_resample.c
@@ -51,9 +51,8 @@ static struct resample_data
51 int32_t last_sample[2]; /* 08h: Last samples for interpolation (L+R) */ 51 int32_t last_sample[2]; /* 08h: Last samples for interpolation (L+R) */
52 /* 10h */ 52 /* 10h */
53 int32_t frequency; /* Virtual samplerate */ 53 int32_t frequency; /* Virtual samplerate */
54 struct dsp_config *dsp; /* The DSP for this resampler */
55 struct dsp_buffer resample_buf; /* Buffer descriptor for resampled data */ 54 struct dsp_buffer resample_buf; /* Buffer descriptor for resampled data */
56 int32_t *resample_buf_arr[2]; /* Actual output data pointers */ 55 int32_t *resample_out_p[2]; /* Actual output buffer pointers */
57} resample_data[DSP_COUNT] IBSS_ATTR; 56} resample_data[DSP_COUNT] IBSS_ATTR;
58 57
59/* Actual worker function. Implemented here or in target assembly code. */ 58/* Actual worker function. Implemented here or in target assembly code. */
@@ -75,9 +74,9 @@ static void lin_resample_flush(struct dsp_proc_entry *this)
75} 74}
76 75
77static bool lin_resample_new_delta(struct resample_data *data, 76static bool lin_resample_new_delta(struct resample_data *data,
78 struct dsp_buffer *buf) 77 struct sample_format *format)
79{ 78{
80 int32_t frequency = buf->format.frequency; /* virtual samplerate */ 79 int32_t frequency = format->frequency; /* virtual samplerate */
81 80
82 data->frequency = frequency; 81 data->frequency = frequency;
83 data->delta = fp_div(frequency, NATIVE_FREQUENCY, 16); 82 data->delta = fp_div(frequency, NATIVE_FREQUENCY, 16);
@@ -169,8 +168,8 @@ static void lin_resample_process(struct dsp_proc_entry *this,
169 return; /* data still remains */ 168 return; /* data still remains */
170 169
171 dst->remcount = 0; 170 dst->remcount = 0;
172 dst->p32[0] = data->resample_buf_arr[0]; 171 dst->p32[0] = data->resample_out_p[0];
173 dst->p32[1] = data->resample_buf_arr[1]; 172 dst->p32[1] = data->resample_out_p[1];
174 173
175 if (src->remcount > 0) 174 if (src->remcount > 0)
176 { 175 {
@@ -189,63 +188,44 @@ static void lin_resample_process(struct dsp_proc_entry *this,
189} 188}
190 189
191/* Finish draining old samples then switch format or shut off */ 190/* Finish draining old samples then switch format or shut off */
192static void lin_resample_new_format(struct dsp_proc_entry *this, 191static intptr_t lin_resample_new_format(struct dsp_proc_entry *this,
193 struct dsp_buffer **buf_p) 192 struct dsp_config *dsp,
193 struct sample_format *format)
194{ 194{
195 struct resample_data *data = (void *)this->data; 195 struct resample_data *data = (void *)this->data;
196 struct dsp_buffer *src = *buf_p;
197 struct dsp_buffer *dst = &data->resample_buf; 196 struct dsp_buffer *dst = &data->resample_buf;
198 197
199 if (dst->remcount > 0) 198 if (dst->remcount > 0)
200 { 199 return PROC_NEW_FORMAT_TRANSITION;
201 *buf_p = dst;
202 return; /* data still remains */
203 }
204 200
205 DSP_PRINT_FORMAT(DSP_PROC_RESAMPLE, DSP_PROC_RESAMPLE, src->format); 201 DSP_PRINT_FORMAT(DSP_PROC_RESAMPLE, *format);
206 202
207 struct dsp_config *dsp = data->dsp;
208 int32_t frequency = data->frequency; 203 int32_t frequency = data->frequency;
209 bool active = dsp_proc_active(dsp, DSP_PROC_RESAMPLE); 204 bool active = dsp_proc_active(dsp, DSP_PROC_RESAMPLE);
210 205
211 if (src->format.frequency != frequency) 206 if (format->frequency != frequency)
212 { 207 {
213 DEBUGF(" DSP_PROC_RESAMPLE- new delta\n"); 208 DEBUGF(" DSP_PROC_RESAMPLE- new delta\n");
214 active = lin_resample_new_delta(data, src); 209 active = lin_resample_new_delta(data, format);
215 dsp_proc_activate(dsp, DSP_PROC_RESAMPLE, active); 210 dsp_proc_activate(dsp, DSP_PROC_RESAMPLE, active);
216 } 211 }
217 212
218 /* Everything after us is NATIVE_FREQUENCY */ 213 /* Everything after us is NATIVE_FREQUENCY */
219 struct sample_format f = src->format; 214 dst->format = *format;
220 f.frequency = NATIVE_FREQUENCY; 215 dst->format.frequency = NATIVE_FREQUENCY;
221 f.codec_frequency = NATIVE_FREQUENCY; 216 dst->format.codec_frequency = NATIVE_FREQUENCY;
222
223 if (!active)
224 {
225 DEBUGF(" DSP_PROC_RESAMPLE- not active\n");
226 dst->format = f; /* Keep track */
227 return; /* No resampling required */
228 }
229
230 format_change_ack(&src->format);
231 217
232 if (EQU_SAMPLE_FORMAT(f, dst->format)) 218 if (active)
233 { 219 return PROC_NEW_FORMAT_OK;
234 DEBUGF(" DSP_PROC_RESAMPLE- same dst format\n");
235 format_change_ack(&f); /* Nothing changed that matters downstream */
236 }
237 220
238 dst->format = f; 221 /* No longer needed */
239 dsp_proc_call(this, buf_p, 0); 222 DEBUGF(" DSP_PROC_RESAMPLE- deactivated\n");
223 return PROC_NEW_FORMAT_DEACTIVATED;
240} 224}
241 225
242static void lin_resample_init(struct dsp_config *dsp, 226static void INIT_ATTR lin_resample_dsp_init(struct dsp_config *dsp,
243 enum dsp_ids dsp_id) 227 enum dsp_ids dsp_id)
244{ 228{
245 /* Always enable resampler so that format changes may be monitored and
246 * it self-activated when required */
247 dsp_proc_enable(dsp, DSP_PROC_RESAMPLE, true);
248
249 int32_t *lbuf, *rbuf; 229 int32_t *lbuf, *rbuf;
250 230
251 switch (dsp_id) 231 switch (dsp_id)
@@ -265,8 +245,19 @@ static void lin_resample_init(struct dsp_config *dsp,
265 return; 245 return;
266 } 246 }
267 247
268 resample_data[dsp_id].resample_buf_arr[0] = lbuf; 248 /* Always enable resampler so that format changes may be monitored and
269 resample_data[dsp_id].resample_buf_arr[1] = rbuf; 249 * it self-activated when required */
250 dsp_proc_enable(dsp, DSP_PROC_RESAMPLE, true);
251 resample_data[dsp_id].resample_out_p[0] = lbuf;
252 resample_data[dsp_id].resample_out_p[1] = rbuf;
253}
254
255static void INIT_ATTR lin_resample_proc_init(struct dsp_proc_entry *this,
256 struct dsp_config *dsp)
257{
258 dsp_proc_set_in_place(dsp, DSP_PROC_RESAMPLE, false);
259 this->data = (intptr_t)&resample_data[dsp_get_id(dsp)];
260 this->process = lin_resample_process;
270} 261}
271 262
272/* DSP message hook */ 263/* DSP message hook */
@@ -275,10 +266,12 @@ static intptr_t lin_resample_configure(struct dsp_proc_entry *this,
275 unsigned int setting, 266 unsigned int setting,
276 intptr_t value) 267 intptr_t value)
277{ 268{
269 intptr_t retval = 0;
270
278 switch (setting) 271 switch (setting)
279 { 272 {
280 case DSP_INIT: 273 case DSP_INIT:
281 lin_resample_init(dsp, (enum dsp_ids)value); 274 lin_resample_dsp_init(dsp, (enum dsp_ids)value);
282 break; 275 break;
283 276
284 case DSP_FLUSH: 277 case DSP_FLUSH:
@@ -286,21 +279,21 @@ static intptr_t lin_resample_configure(struct dsp_proc_entry *this,
286 break; 279 break;
287 280
288 case DSP_PROC_INIT: 281 case DSP_PROC_INIT:
289 this->data = (intptr_t)&resample_data[dsp_get_id(dsp)]; 282 lin_resample_proc_init(this, dsp);
290 this->ip_mask = 0; /* Not in-place */
291 this->process[0] = lin_resample_process;
292 this->process[1] = lin_resample_new_format;
293 ((struct resample_data *)this->data)->dsp = dsp;
294 break; 283 break;
295 284
296 case DSP_PROC_CLOSE: 285 case DSP_PROC_CLOSE:
297 /* This stage should be enabled at all times */ 286 /* This stage should be enabled at all times */
298 DEBUGF("DSP_PROC_RESAMPLE- Error: Closing!\n"); 287 DEBUGF("DSP_PROC_RESAMPLE- Error: Closing!\n");
299 break; 288 break;
289
290 case DSP_PROC_NEW_FORMAT:
291 retval = lin_resample_new_format(this, dsp,
292 (struct sample_format *)value);
293 break;
300 } 294 }
301 295
302 return 1; 296 return retval;
303 (void)value;
304} 297}
305 298
306/* Database entry */ 299/* Database entry */