summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/crossfeed.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/crossfeed.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/crossfeed.c')
-rw-r--r--lib/rbcodec/dsp/crossfeed.c122
1 files changed, 62 insertions, 60 deletions
diff --git a/lib/rbcodec/dsp/crossfeed.c b/lib/rbcodec/dsp/crossfeed.c
index 3fb51a7594..bd8ee95042 100644
--- a/lib/rbcodec/dsp/crossfeed.c
+++ b/lib/rbcodec/dsp/crossfeed.c
@@ -68,8 +68,7 @@ static struct crossfeed_state
68 }; 68 };
69 }; 69 };
70 int32_t *index; /* 88h: Current pointer into the delay line */ 70 int32_t *index; /* 88h: Current pointer into the delay line */
71 struct dsp_config *dsp; /* 8ch: Current DSP */ 71 /* 8ch */
72 /* 90h */
73} crossfeed_state IBSS_ATTR; 72} crossfeed_state IBSS_ATTR;
74 73
75static int crossfeed_type = CROSSFEED_TYPE_NONE; 74static int crossfeed_type = CROSSFEED_TYPE_NONE;
@@ -79,62 +78,21 @@ static void crossfeed_flush(struct dsp_proc_entry *this)
79{ 78{
80 struct crossfeed_state *state = (void *)this->data; 79 struct crossfeed_state *state = (void *)this->data;
81 80
82 if (crossfeed_type == CROSSFEED_TYPE_CUSTOM) 81 if (crossfeed_type != CROSSFEED_TYPE_CUSTOM)
83 { 82 {
84 memset(state->history, 0, 83 state->vcl = state->vcr = state->vdiff = 0;
85 sizeof (state->history) + sizeof (state->delay));
86 state->index = state->delay;
87 } 84 }
88 else 85 else
89 { 86 {
90 state->vcl = state->vcr = state->vdiff = 0; 87 memset(state->history, 0,
88 sizeof (state->history) + sizeof (state->delay));
89 state->index = state->delay;
91 } 90 }
92} 91}
93 92
94 93
95/** DSP interface **/ 94/** DSP interface **/
96 95
97/* Crossfeed boot/format change function */
98static void crossfeed_process_new_format(struct dsp_proc_entry *this,
99 struct dsp_buffer **buf_p)
100{
101 struct crossfeed_state *state = (void *)this->data;
102 struct dsp_buffer *buf = *buf_p;
103
104 DSP_PRINT_FORMAT(DSP_PROC_CROSSFEED, DSP_PROC_CROSSFEED, buf->format);
105
106 bool was_active = dsp_proc_active(state->dsp, DSP_PROC_CROSSFEED);
107 bool active = buf->format.num_channels >= 2;
108 dsp_proc_activate(state->dsp, DSP_PROC_CROSSFEED, active);
109
110 if (!active)
111 {
112 /* Can't do this. Sleep until next change */
113 DEBUGF(" DSP_PROC_CROSSFEED- deactivated\n");
114 return;
115 }
116
117 dsp_proc_fn_type fn = crossfeed_process;
118
119 if (crossfeed_type != CROSSFEED_TYPE_CUSTOM)
120 {
121 /* 1 / (F.Rforward.C) */
122 state->coef1 = (0x7fffffff / NATIVE_FREQUENCY) * 2128;
123 /* 1 / (F.Rcross.C) */
124 state->coef2 = (0x7fffffff / NATIVE_FREQUENCY) * 1000;
125 fn = crossfeed_meier_process;
126 }
127
128 if (!was_active || this->process[0] != fn)
129 {
130 crossfeed_flush(this); /* Going online or actual type change */
131 this->process[0] = fn; /* Set real function */
132 }
133
134 /* Call it once */
135 dsp_proc_call(this, buf_p, (unsigned)buf->format.changed - 1);
136}
137
138/* Set the type of crossfeed to use */ 96/* Set the type of crossfeed to use */
139void dsp_set_crossfeed_type(int type) 97void dsp_set_crossfeed_type(int type)
140{ 98{
@@ -273,39 +231,83 @@ void crossfeed_meier_process(struct dsp_proc_entry *this,
273} 231}
274#endif /* CPU */ 232#endif /* CPU */
275 233
234/* Update the processing function according to crossfeed type */
235static void update_process_fn(struct dsp_proc_entry *this,
236 struct dsp_config *dsp)
237{
238 struct crossfeed_state *state = (struct crossfeed_state *)this->data;
239 dsp_proc_fn_type fn = crossfeed_process;
240
241 if (crossfeed_type != CROSSFEED_TYPE_CUSTOM)
242 {
243 /* Set up for Meier */
244 /* 1 / (F.Rforward.C) */
245 state->coef1 = (0x7fffffff / NATIVE_FREQUENCY) * 2128;
246 /* 1 / (F.Rcross.C) */
247 state->coef2 = (0x7fffffff / NATIVE_FREQUENCY) * 1000;
248 fn = crossfeed_meier_process;
249 }
250
251 if (this->process != fn)
252 {
253 this->process = fn; /* Set proper function */
254 if (dsp_proc_active(dsp, DSP_PROC_CROSSFEED))
255 crossfeed_flush(this);
256 }
257}
258
259/* Crossfeed boot/format change function */
260static intptr_t crossfeed_new_format(struct dsp_proc_entry *this,
261 struct dsp_config *dsp,
262 struct sample_format *format)
263{
264 DSP_PRINT_FORMAT(DSP_PROC_CROSSFEED, format);
265
266 bool was_active = dsp_proc_active(dsp, DSP_PROC_CROSSFEED);
267 bool active = format->num_channels >= 2;
268 dsp_proc_activate(dsp, DSP_PROC_CROSSFEED, active);
269
270 if (active)
271 {
272 if (!was_active)
273 crossfeed_flush(this); /* Going online */
274
275 return PROC_NEW_FORMAT_OK;
276 }
277
278 /* Can't do this. Sleep until next change */
279 DEBUGF(" DSP_PROC_CROSSFEED- deactivated\n");
280 return PROC_NEW_FORMAT_DEACTIVATED;
281}
282
276/* DSP message hook */ 283/* DSP message hook */
277static intptr_t crossfeed_configure(struct dsp_proc_entry *this, 284static intptr_t crossfeed_configure(struct dsp_proc_entry *this,
278 struct dsp_config *dsp, 285 struct dsp_config *dsp,
279 unsigned int setting, 286 unsigned int setting,
280 intptr_t value) 287 intptr_t value)
281{ 288{
289 intptr_t retval = 0;
290
282 switch (setting) 291 switch (setting)
283 { 292 {
284 case DSP_PROC_INIT: 293 case DSP_PROC_INIT:
285 if (value == 0) 294 if (value == 0)
286 {
287 /* New object */
288 this->data = (intptr_t)&crossfeed_state; 295 this->data = (intptr_t)&crossfeed_state;
289 this->process[1] = crossfeed_process_new_format;
290 ((struct crossfeed_state *)this->data)->dsp = dsp;
291 }
292 296
293 /* Force format change call each time */ 297 update_process_fn(this, dsp);
294 this->process[0] = crossfeed_process_new_format;
295 dsp_proc_activate(dsp, DSP_PROC_CROSSFEED, true);
296 break; 298 break;
297 299
298 case DSP_FLUSH: 300 case DSP_FLUSH:
299 crossfeed_flush(this); 301 crossfeed_flush(this);
300 break; 302 break;
301 303
302 case DSP_PROC_CLOSE: 304 case DSP_PROC_NEW_FORMAT:
303 ((struct crossfeed_state *)this->data)->dsp = NULL; 305 retval = crossfeed_new_format(this, dsp,
306 (struct sample_format *)value);
304 break; 307 break;
305 } 308 }
306 309
307 return 1; 310 return retval;
308 (void)value;
309} 311}
310 312
311/* Database entry */ 313/* Database entry */