summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/crossfeed.c
diff options
context:
space:
mode:
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 */