diff options
Diffstat (limited to 'lib/rbcodec/dsp/crossfeed.c')
-rw-r--r-- | lib/rbcodec/dsp/crossfeed.c | 122 |
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 | ||
75 | static int crossfeed_type = CROSSFEED_TYPE_NONE; | 74 | static 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 */ | ||
98 | static 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 */ |
139 | void dsp_set_crossfeed_type(int type) | 97 | void 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 */ | ||
235 | static 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 */ | ||
260 | static 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 */ |
277 | static intptr_t crossfeed_configure(struct dsp_proc_entry *this, | 284 | static 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 */ |