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