diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2012-12-19 17:34:57 -0500 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2013-05-04 13:43:33 -0400 |
commit | 78a45b47dede5ddf35dfc53e965b486a79177b18 (patch) | |
tree | edb3ad7c101e600a7cc3be4b40380430cbeb3e55 /lib/rbcodec/dsp/channel_mode.c | |
parent | cdb71c707bb434f44368b72f2db3becc37b7a46c (diff) | |
download | rockbox-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/channel_mode.c')
-rw-r--r-- | lib/rbcodec/dsp/channel_mode.c | 98 |
1 files changed, 43 insertions, 55 deletions
diff --git a/lib/rbcodec/dsp/channel_mode.c b/lib/rbcodec/dsp/channel_mode.c index 78e7b8f10c..2ae2d45fd3 100644 --- a/lib/rbcodec/dsp/channel_mode.c +++ b/lib/rbcodec/dsp/channel_mode.c | |||
@@ -49,30 +49,14 @@ static struct channel_mode_data | |||
49 | { | 49 | { |
50 | long sw_gain; /* 00h: for mode: custom */ | 50 | long sw_gain; /* 00h: for mode: custom */ |
51 | long sw_cross; /* 04h: for mode: custom */ | 51 | long sw_cross; /* 04h: for mode: custom */ |
52 | struct dsp_config *dsp; | ||
53 | int mode; | 52 | int mode; |
54 | const dsp_proc_fn_type fns[SOUND_CHAN_NUM_MODES]; | ||
55 | } channel_mode_data = | 53 | } channel_mode_data = |
56 | { | 54 | { |
57 | .sw_gain = 0, | 55 | .sw_gain = 0, |
58 | .sw_cross = 0, | 56 | .sw_cross = 0, |
59 | .mode = SOUND_CHAN_STEREO, | 57 | .mode = SOUND_CHAN_STEREO |
60 | .fns = | ||
61 | { | ||
62 | [SOUND_CHAN_STEREO] = NULL, | ||
63 | [SOUND_CHAN_MONO] = channel_mode_proc_mono, | ||
64 | [SOUND_CHAN_CUSTOM] = channel_mode_proc_custom, | ||
65 | [SOUND_CHAN_MONO_LEFT] = channel_mode_proc_mono_left, | ||
66 | [SOUND_CHAN_MONO_RIGHT] = channel_mode_proc_mono_right, | ||
67 | [SOUND_CHAN_KARAOKE] = channel_mode_proc_karaoke, | ||
68 | }, | ||
69 | }; | 58 | }; |
70 | 59 | ||
71 | static dsp_proc_fn_type get_process_fn(void) | ||
72 | { | ||
73 | return channel_mode_data.fns[channel_mode_data.mode]; | ||
74 | } | ||
75 | |||
76 | #if 0 | 60 | #if 0 |
77 | /* SOUND_CHAN_STEREO mode is a noop so has no function - just outline one for | 61 | /* SOUND_CHAN_STEREO mode is a noop so has no function - just outline one for |
78 | * completeness. */ | 62 | * completeness. */ |
@@ -166,33 +150,6 @@ void channel_mode_proc_mono_right(struct dsp_proc_entry *this, | |||
166 | (void)this; | 150 | (void)this; |
167 | } | 151 | } |
168 | 152 | ||
169 | /* This is the initial function pointer when first enabled/changed in order | ||
170 | * to facilitate verification of the format compatibility at the proper time | ||
171 | * This gets called for changes even if stage is inactive. */ | ||
172 | static void channel_mode_process_new_format(struct dsp_proc_entry *this, | ||
173 | struct dsp_buffer **buf_p) | ||
174 | { | ||
175 | struct channel_mode_data *data = (void *)this->data; | ||
176 | struct dsp_buffer *buf = *buf_p; | ||
177 | |||
178 | DSP_PRINT_FORMAT(DSP_PROC_CHANNEL_MODE, DSP_PROC_CHANNEL_MODE, | ||
179 | buf->format); | ||
180 | |||
181 | bool active = buf->format.num_channels >= 2; | ||
182 | dsp_proc_activate(data->dsp, DSP_PROC_CHANNEL_MODE, active); | ||
183 | |||
184 | if (!active) | ||
185 | { | ||
186 | /* Can't do this. Sleep until next change. */ | ||
187 | DEBUGF(" DSP_PROC_CHANNEL_MODE- deactivated\n"); | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | /* Switch to the real function and call it once */ | ||
192 | this->process[0] = get_process_fn(); | ||
193 | dsp_proc_call(this, buf_p, (unsigned)buf->format.changed - 1); | ||
194 | } | ||
195 | |||
196 | void channel_mode_set_config(int value) | 153 | void channel_mode_set_config(int value) |
197 | { | 154 | { |
198 | if (value < 0 || value >= SOUND_CHAN_NUM_MODES) | 155 | if (value < 0 || value >= SOUND_CHAN_NUM_MODES) |
@@ -228,34 +185,65 @@ void channel_mode_custom_set_width(int value) | |||
228 | channel_mode_data.sw_cross = cross << 8; | 185 | channel_mode_data.sw_cross = cross << 8; |
229 | } | 186 | } |
230 | 187 | ||
188 | static void update_process_fn(struct dsp_proc_entry *this) | ||
189 | { | ||
190 | static const dsp_proc_fn_type fns[SOUND_CHAN_NUM_MODES] = | ||
191 | { | ||
192 | [SOUND_CHAN_STEREO] = NULL, | ||
193 | [SOUND_CHAN_MONO] = channel_mode_proc_mono, | ||
194 | [SOUND_CHAN_CUSTOM] = channel_mode_proc_custom, | ||
195 | [SOUND_CHAN_MONO_LEFT] = channel_mode_proc_mono_left, | ||
196 | [SOUND_CHAN_MONO_RIGHT] = channel_mode_proc_mono_right, | ||
197 | [SOUND_CHAN_KARAOKE] = channel_mode_proc_karaoke, | ||
198 | }; | ||
199 | |||
200 | this->process = fns[((struct channel_mode_data *)this->data)->mode]; | ||
201 | } | ||
202 | |||
203 | /* Handle format changes and verify the format compatibility */ | ||
204 | static intptr_t channel_mode_new_format(struct dsp_proc_entry *this, | ||
205 | struct dsp_config *dsp, | ||
206 | struct sample_format *format) | ||
207 | { | ||
208 | DSP_PRINT_FORMAT(DSP_PROC_CHANNEL_MODE, format); | ||
209 | |||
210 | bool active = format->num_channels >= 2; | ||
211 | dsp_proc_activate(dsp, DSP_PROC_CHANNEL_MODE, active); | ||
212 | |||
213 | if (active) | ||
214 | return PROC_NEW_FORMAT_OK; | ||
215 | |||
216 | /* Can't do this. Sleep until next change. */ | ||
217 | DEBUGF(" DSP_PROC_CHANNEL_MODE- deactivated\n"); | ||
218 | return PROC_NEW_FORMAT_DEACTIVATED; | ||
219 | |||
220 | (void)this; | ||
221 | } | ||
222 | |||
231 | /* DSP message hook */ | 223 | /* DSP message hook */ |
232 | static intptr_t channel_mode_configure(struct dsp_proc_entry *this, | 224 | static intptr_t channel_mode_configure(struct dsp_proc_entry *this, |
233 | struct dsp_config *dsp, | 225 | struct dsp_config *dsp, |
234 | unsigned int setting, | 226 | unsigned int setting, |
235 | intptr_t value) | 227 | intptr_t value) |
236 | { | 228 | { |
229 | intptr_t retval = 0; | ||
230 | |||
237 | switch (setting) | 231 | switch (setting) |
238 | { | 232 | { |
239 | case DSP_PROC_INIT: | 233 | case DSP_PROC_INIT: |
240 | if (value == 0) | 234 | if (value == 0) |
241 | { | ||
242 | /* New object */ | ||
243 | this->data = (intptr_t)&channel_mode_data; | 235 | this->data = (intptr_t)&channel_mode_data; |
244 | this->process[1] = channel_mode_process_new_format; | ||
245 | ((struct channel_mode_data *)this->data)->dsp = dsp; | ||
246 | } | ||
247 | 236 | ||
248 | /* Force format change call each time */ | 237 | update_process_fn(this); |
249 | this->process[0] = channel_mode_process_new_format; | ||
250 | dsp_proc_activate(dsp, DSP_PROC_CHANNEL_MODE, true); | ||
251 | break; | 238 | break; |
252 | 239 | ||
253 | case DSP_PROC_CLOSE: | 240 | case DSP_PROC_NEW_FORMAT: |
254 | ((struct channel_mode_data *)this->data)->dsp = NULL; | 241 | retval = channel_mode_new_format(this, dsp, |
242 | (struct sample_format *)value); | ||
255 | break; | 243 | break; |
256 | } | 244 | } |
257 | 245 | ||
258 | return 1; | 246 | return retval; |
259 | } | 247 | } |
260 | 248 | ||
261 | /* Database entry */ | 249 | /* Database entry */ |