summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/channel_mode.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/channel_mode.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/channel_mode.c')
-rw-r--r--lib/rbcodec/dsp/channel_mode.c98
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
71static 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. */
172static 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
196void channel_mode_set_config(int value) 153void 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
188static 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 */
204static 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 */
232static intptr_t channel_mode_configure(struct dsp_proc_entry *this, 224static 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 */