diff options
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 */ |