diff options
Diffstat (limited to 'apps/dsp.c')
-rw-r--r-- | apps/dsp.c | 388 |
1 files changed, 235 insertions, 153 deletions
diff --git a/apps/dsp.c b/apps/dsp.c index c7eed8bd76..c062f2c088 100644 --- a/apps/dsp.c +++ b/apps/dsp.c | |||
@@ -46,6 +46,18 @@ | |||
46 | #define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ | 46 | #define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ |
47 | #define DEFAULT_GAIN 0x01000000 | 47 | #define DEFAULT_GAIN 0x01000000 |
48 | 48 | ||
49 | |||
50 | enum | ||
51 | { | ||
52 | CONVERT_LE_NATIVE_I_STEREO = STEREO_INTERLEAVED, | ||
53 | CONVERT_LE_NATIVE_NI_STEREO = STEREO_NONINTERLEAVED, | ||
54 | CONVERT_LE_NATIVE_MONO = STEREO_MONO, | ||
55 | CONVERT_GT_NATIVE_I_STEREO = STEREO_INTERLEAVED + STEREO_NUM_MODES, | ||
56 | CONVERT_GT_NATIVE_NI_STEREO = STEREO_NONINTERLEAVED + STEREO_NUM_MODES, | ||
57 | CONVERT_GT_NATIVE_MONO = STEREO_MONO + STEREO_NUM_MODES, | ||
58 | CONVERT_GT_NATIVE_1ST_INDEX = STEREO_NUM_MODES | ||
59 | }; | ||
60 | |||
49 | struct dsp_config | 61 | struct dsp_config |
50 | { | 62 | { |
51 | long codec_frequency; /* Sample rate of data coming from the codec */ | 63 | long codec_frequency; /* Sample rate of data coming from the codec */ |
@@ -60,6 +72,7 @@ struct dsp_config | |||
60 | int sample_depth; | 72 | int sample_depth; |
61 | int sample_bytes; | 73 | int sample_bytes; |
62 | int stereo_mode; | 74 | int stereo_mode; |
75 | int num_channels; | ||
63 | int frac_bits; | 76 | int frac_bits; |
64 | bool dither_enabled; | 77 | bool dither_enabled; |
65 | long dither_bias; | 78 | long dither_bias; |
@@ -69,11 +82,13 @@ struct dsp_config | |||
69 | bool eq_enabled; | 82 | bool eq_enabled; |
70 | long eq_precut; | 83 | long eq_precut; |
71 | long gain; /* Note that this is in S8.23 format. */ | 84 | long gain; /* Note that this is in S8.23 format. */ |
85 | int (*convert_to_internal)(const char* src[], int32_t* dst[], int count); | ||
72 | }; | 86 | }; |
73 | 87 | ||
74 | struct resample_data | 88 | struct resample_data |
75 | { | 89 | { |
76 | long phase, delta; | 90 | long phase; |
91 | long delta; | ||
77 | int32_t last_sample[2]; | 92 | int32_t last_sample[2]; |
78 | }; | 93 | }; |
79 | 94 | ||
@@ -139,88 +154,157 @@ void sound_set_pitch(int permille) | |||
139 | * consume. Note that for mono, dst[0] equals dst[1], as there is no point | 154 | * consume. Note that for mono, dst[0] equals dst[1], as there is no point |
140 | * in processing the same data twice. | 155 | * in processing the same data twice. |
141 | */ | 156 | */ |
142 | static int convert_to_internal(const char* src[], int count, int32_t* dst[]) | 157 | |
158 | /* convert count 16-bit mono to 32-bit mono */ | ||
159 | static int convert_lte_native_mono( | ||
160 | const char *src[], int32_t *dst[], int count) | ||
143 | { | 161 | { |
144 | count = MIN(SAMPLE_BUF_COUNT / 2, count); | 162 | count = MIN(SAMPLE_BUF_COUNT/2, count); |
145 | 163 | ||
146 | if ((dsp->sample_depth <= NATIVE_DEPTH) | 164 | const short *s = (short*) src[0]; |
147 | || (dsp->stereo_mode == STEREO_INTERLEAVED)) | 165 | const short * const send = s + count; |
148 | { | 166 | int32_t *d = dst[0] = dst[1] = sample_buf; |
149 | dst[0] = &sample_buf[0]; | 167 | const int scale = WORD_SHIFT; |
150 | dst[1] = (dsp->stereo_mode == STEREO_MONO) | 168 | |
151 | ? dst[0] : &sample_buf[SAMPLE_BUF_COUNT / 2]; | 169 | do |
152 | } | ||
153 | else | ||
154 | { | 170 | { |
155 | dst[0] = (int32_t*) src[0]; | 171 | *d++ = *s++ << scale; |
156 | dst[1] = (int32_t*) ((dsp->stereo_mode == STEREO_MONO) ? src[0] : src[1]); | ||
157 | } | 172 | } |
173 | while (s < send); | ||
158 | 174 | ||
159 | if (dsp->sample_depth <= NATIVE_DEPTH) | 175 | src[0] = (char *)s; |
160 | { | ||
161 | short* s0 = (short*) src[0]; | ||
162 | int32_t* d0 = dst[0]; | ||
163 | int32_t* d1 = dst[1]; | ||
164 | int scale = WORD_SHIFT; | ||
165 | int i; | ||
166 | 176 | ||
167 | if (dsp->stereo_mode == STEREO_INTERLEAVED) | 177 | return count; |
168 | { | 178 | } |
169 | for (i = 0; i < count; i++) | ||
170 | { | ||
171 | *d0++ = *s0++ << scale; | ||
172 | *d1++ = *s0++ << scale; | ||
173 | } | ||
174 | } | ||
175 | else if (dsp->stereo_mode == STEREO_NONINTERLEAVED) | ||
176 | { | ||
177 | short* s1 = (short*) src[1]; | ||
178 | 179 | ||
179 | for (i = 0; i < count; i++) | 180 | /* convert count 16-bit interleaved stereo to 32-bit noninterleaved */ |
180 | { | 181 | static int convert_lte_native_interleaved_stereo( |
181 | *d0++ = *s0++ << scale; | 182 | const char *src[], int32_t *dst[], int count) |
182 | *d1++ = *s1++ << scale; | 183 | { |
183 | } | 184 | count = MIN(SAMPLE_BUF_COUNT/2, count); |
184 | } | ||
185 | else | ||
186 | { | ||
187 | for (i = 0; i < count; i++) | ||
188 | { | ||
189 | *d0++ = *s0++ << scale; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | else if (dsp->stereo_mode == STEREO_INTERLEAVED) | ||
194 | { | ||
195 | int32_t* s0 = (int32_t*) src[0]; | ||
196 | int32_t* d0 = dst[0]; | ||
197 | int32_t* d1 = dst[1]; | ||
198 | int i; | ||
199 | 185 | ||
200 | for (i = 0; i < count; i++) | 186 | const int32_t *s = (int32_t *) src[0]; |
201 | { | 187 | const int32_t * const send = s + count; |
202 | *d0++ = *s0++; | 188 | int32_t *dl = dst[0] = sample_buf; |
203 | *d1++ = *s0++; | 189 | int32_t *dr = dst[1] = sample_buf + SAMPLE_BUF_COUNT/2; |
204 | } | 190 | const int scale = WORD_SHIFT; |
205 | } | ||
206 | 191 | ||
207 | if (dsp->stereo_mode == STEREO_NONINTERLEAVED) | 192 | do |
208 | { | 193 | { |
209 | src[0] += count * dsp->sample_bytes; | 194 | short slr = *s++; |
210 | src[1] += count * dsp->sample_bytes; | 195 | #ifdef ROCKBOX_LITTLE_ENDIAN |
196 | *dl++ = (slr >> 16) << scale; | ||
197 | *dr++ = (int32_t)(short)slr << scale; | ||
198 | #else /* ROCKBOX_BIG_ENDIAN */ | ||
199 | *dl++ = (int32_t)(short)slr << scale; | ||
200 | *dr++ = (slr >> 16) << scale; | ||
201 | #endif | ||
211 | } | 202 | } |
212 | else if (dsp->stereo_mode == STEREO_INTERLEAVED) | 203 | while (s < send); |
204 | |||
205 | src[0] = (char *)s; | ||
206 | |||
207 | return count; | ||
208 | } | ||
209 | |||
210 | /* convert count 16-bit noninterleaved stereo to 32-bit noninterleaved */ | ||
211 | static int convert_lte_native_noninterleaved_stereo( | ||
212 | const char *src[], int32_t *dst[], int count) | ||
213 | { | ||
214 | const short *sl = (short *) src[0]; | ||
215 | const short *sr = (short *) src[1]; | ||
216 | const short * const slend = sl + count; | ||
217 | int32_t *dl = dst[0] = sample_buf; | ||
218 | int32_t *dr = dst[1] = sample_buf + SAMPLE_BUF_COUNT/2; | ||
219 | const int scale = WORD_SHIFT; | ||
220 | |||
221 | do | ||
213 | { | 222 | { |
214 | src[0] += count * dsp->sample_bytes * 2; | 223 | *dl++ = *sl++ << scale; |
224 | *dr++ = *sr++ << scale; | ||
215 | } | 225 | } |
216 | else | 226 | while (sl < slend); |
227 | |||
228 | src[0] = (char *)sl; | ||
229 | src[1] = (char *)sr; | ||
230 | |||
231 | return count; | ||
232 | } | ||
233 | |||
234 | /* convert count 32-bit mono to 32-bit mono */ | ||
235 | static int convert_gt_native_mono( | ||
236 | const char *src[], int32_t *dst[], int count) | ||
237 | { | ||
238 | count = MIN(SAMPLE_BUF_COUNT/2, count); | ||
239 | |||
240 | dst[0] = dst[1] = (int32_t *)src[0]; | ||
241 | src[0] = (char *)(dst[0] + count); | ||
242 | |||
243 | return count; | ||
244 | } | ||
245 | |||
246 | /* convert count 32-bit interleaved stereo to 32-bit noninterleaved stereo */ | ||
247 | static int convert_gt_native_interleaved_stereo( | ||
248 | const char *src[], int32_t *dst[], int count) | ||
249 | { | ||
250 | count = MIN(SAMPLE_BUF_COUNT/2, count); | ||
251 | |||
252 | const int32_t *s = (int32_t *)src[0]; | ||
253 | const int32_t * const send = s + 2*count; | ||
254 | int32_t *dl = sample_buf; | ||
255 | int32_t *dr = sample_buf + SAMPLE_BUF_COUNT/2; | ||
256 | |||
257 | dst[0] = dl; | ||
258 | dst[1] = dr; | ||
259 | |||
260 | do | ||
217 | { | 261 | { |
218 | src[0] += count * dsp->sample_bytes; | 262 | *dl++ = *s++; |
263 | *dr++ = *s++; | ||
219 | } | 264 | } |
265 | while (s < send); | ||
266 | |||
267 | src[0] = (char *)send; | ||
268 | |||
269 | return count; | ||
270 | } | ||
271 | |||
272 | /* convert 32 bit-noninterleaved stereo to 32-bit noninterleaved stereo */ | ||
273 | static int convert_gt_native_noninterleaved_stereo( | ||
274 | const char *src[], int32_t *dst[], int count) | ||
275 | { | ||
276 | count = MIN(SAMPLE_BUF_COUNT/2, count); | ||
277 | |||
278 | dst[0] = (int32_t *)src[0]; | ||
279 | dst[1] = (int32_t *)src[1]; | ||
280 | src[0] = (char *)(dst[0] + count); | ||
281 | src[1] = (char *)(dst[1] + count); | ||
220 | 282 | ||
221 | return count; | 283 | return count; |
222 | } | 284 | } |
223 | 285 | ||
286 | /* set the to-native sample conversion function based on dsp sample parameters */ | ||
287 | static void new_sample_conversion(void) | ||
288 | { | ||
289 | static int (*convert_to_internal_functions[])( | ||
290 | const char* src[], int32_t *dst[], int count) = | ||
291 | { | ||
292 | [CONVERT_LE_NATIVE_MONO] = convert_lte_native_mono, | ||
293 | [CONVERT_LE_NATIVE_I_STEREO] = convert_lte_native_interleaved_stereo, | ||
294 | [CONVERT_LE_NATIVE_NI_STEREO] = convert_lte_native_noninterleaved_stereo, | ||
295 | [CONVERT_GT_NATIVE_MONO] = convert_gt_native_mono, | ||
296 | [CONVERT_GT_NATIVE_I_STEREO] = convert_gt_native_interleaved_stereo, | ||
297 | [CONVERT_GT_NATIVE_NI_STEREO] = convert_gt_native_noninterleaved_stereo, | ||
298 | }; | ||
299 | |||
300 | int convert = dsp->stereo_mode; | ||
301 | |||
302 | if (dsp->sample_depth > NATIVE_DEPTH) | ||
303 | convert += CONVERT_GT_NATIVE_1ST_INDEX; | ||
304 | |||
305 | dsp->convert_to_internal = convert_to_internal_functions[convert]; | ||
306 | } | ||
307 | |||
224 | static void resampler_set_delta(int frequency) | 308 | static void resampler_set_delta(int frequency) |
225 | { | 309 | { |
226 | resample_data[current_codec].delta = (unsigned long) | 310 | resample_data[current_codec].delta = (unsigned long) |
@@ -230,124 +314,118 @@ static void resampler_set_delta(int frequency) | |||
230 | /* Linear interpolation resampling that introduces a one sample delay because | 314 | /* Linear interpolation resampling that introduces a one sample delay because |
231 | * of our inability to look into the future at the end of a frame. | 315 | * of our inability to look into the future at the end of a frame. |
232 | */ | 316 | */ |
233 | 317 | #ifndef DSP_HAVE_ASM_RESAMPLING | |
234 | /* TODO: we really should have a separate set of resample functions for both | 318 | static int dsp_downsample(int channels, int count, struct resample_data *r, |
235 | mono and stereo to avoid all this internal branching and looping. */ | 319 | int32_t **src, int32_t **dst) |
236 | static int downsample(int32_t **dst, int32_t **src, int count, | ||
237 | struct resample_data *r) | ||
238 | { | 320 | { |
239 | long phase = r->phase; | ||
240 | long delta = r->delta; | 321 | long delta = r->delta; |
241 | int32_t last_sample; | 322 | long phase, pos; |
242 | int32_t *d[2] = { dst[0], dst[1] }; | 323 | int32_t *d; |
243 | int pos = phase >> 16; | 324 | |
244 | int i = 1, j; | 325 | /* Rolled channel loop actually showed slightly faster. */ |
245 | int num_channels = dsp->stereo_mode == STEREO_MONO ? 1 : 2; | 326 | do |
246 | 327 | { | |
247 | for (j = 0; j < num_channels; j++) { | 328 | /* Just initialize things and not worry too much about the relatively |
248 | last_sample = r->last_sample[j]; | 329 | * uncommon case of not being able to spit out a sample for the frame. |
330 | */ | ||
331 | int32_t *s = src[--channels]; | ||
332 | int32_t last = r->last_sample[channels]; | ||
333 | |||
334 | r->last_sample[channels] = s[count - 1]; | ||
335 | d = dst[channels]; | ||
336 | phase = r->phase; | ||
337 | pos = phase >> 16; | ||
338 | |||
249 | /* Do we need last sample of previous frame for interpolation? */ | 339 | /* Do we need last sample of previous frame for interpolation? */ |
250 | if (pos > 0) | 340 | if (pos > 0) |
251 | last_sample = src[j][pos - 1]; | 341 | last = s[pos - 1]; |
252 | 342 | ||
253 | /* Be sure starting position isn't passed the available data */ | 343 | while (pos < count) |
254 | if (pos < count) | ||
255 | *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15, | ||
256 | src[j][pos] - last_sample); | ||
257 | else | ||
258 | { | 344 | { |
259 | /* No samples can be output here since were already passed the | 345 | *d++ = last + FRACMUL((phase & 0xffff) << 15, s[pos] - last); |
260 | end. Keep phase, save the last sample and return nothing. */ | 346 | phase += delta; |
261 | i = 0; | 347 | pos = phase >> 16; |
262 | goto done; | 348 | last = s[pos - 1]; |
263 | } | 349 | } |
264 | } | 350 | } |
265 | 351 | while (channels > 0); | |
266 | phase += delta; | ||
267 | |||
268 | while ((pos = phase >> 16) < count) | ||
269 | { | ||
270 | for (j = 0; j < num_channels; j++) | ||
271 | *d[j]++ = src[j][pos - 1] + FRACMUL((phase & 0xffff) << 15, | ||
272 | src[j][pos] - src[j][pos - 1]); | ||
273 | phase += delta; | ||
274 | i++; | ||
275 | } | ||
276 | 352 | ||
277 | /* Wrap phase accumulator back to start of next frame. */ | 353 | /* Wrap phase accumulator back to start of next frame. */ |
278 | done: | ||
279 | r->phase = phase - (count << 16); | 354 | r->phase = phase - (count << 16); |
280 | r->last_sample[0] = src[0][count - 1]; | 355 | return d - dst[0]; |
281 | r->last_sample[1] = src[1][count - 1]; | ||
282 | return i; | ||
283 | } | 356 | } |
284 | 357 | ||
285 | static long upsample(int32_t **dst, int32_t **src, int count, struct resample_data *r) | 358 | static int dsp_upsample(int channels, int count, struct resample_data *r, |
359 | int32_t **src, int32_t **dst) | ||
286 | { | 360 | { |
287 | long phase = r->phase; | ||
288 | long delta = r->delta; | 361 | long delta = r->delta; |
289 | int32_t *d[2] = { dst[0], dst[1] }; | 362 | long phase, pos; |
290 | int i = 0, j; | 363 | int32_t *d; |
291 | int pos; | ||
292 | int num_channels = dsp->stereo_mode == STEREO_MONO ? 1 : 2; | ||
293 | |||
294 | while ((phase >> 16) == 0) | ||
295 | { | ||
296 | for (j = 0; j < num_channels; j++) | ||
297 | *d[j]++ = r->last_sample[j] + FRACMUL((phase & 0xffff) << 15, | ||
298 | src[j][0] - r->last_sample[j]); | ||
299 | phase += delta; | ||
300 | i++; | ||
301 | } | ||
302 | 364 | ||
303 | while ((pos = phase >> 16) < count) | 365 | /* Rolled channel loop actually showed slightly faster. */ |
366 | do | ||
304 | { | 367 | { |
305 | for (j = 0; j < num_channels; j++) | 368 | /* Should always be able to output a sample for a ratio up to |
306 | *d[j]++ = src[j][pos - 1] + FRACMUL((phase & 0xffff) << 15, | 369 | RESAMPLE_BUF_COUNT / SAMPLE_BUF_COUNT. */ |
307 | src[j][pos] - src[j][pos - 1]); | 370 | int32_t *s = src[--channels]; |
308 | phase += delta; | 371 | int32_t last = r->last_sample[channels]; |
309 | i++; | 372 | |
373 | r->last_sample[channels] = s[count - 1]; | ||
374 | d = dst[channels]; | ||
375 | phase = r->phase; | ||
376 | pos = phase >> 16; | ||
377 | |||
378 | while (pos == 0) | ||
379 | { | ||
380 | *d++ = last + FRACMUL((phase & 0xffff) << 15, s[0] - last); | ||
381 | phase += delta; | ||
382 | pos = phase >> 16; | ||
383 | } | ||
384 | |||
385 | while (pos < count) | ||
386 | { | ||
387 | last = s[pos - 1]; | ||
388 | *d++ = last + FRACMUL((phase & 0xffff) << 15, s[pos] - last); | ||
389 | phase += delta; | ||
390 | pos = phase >> 16; | ||
391 | } | ||
310 | } | 392 | } |
393 | while (channels > 0); | ||
311 | 394 | ||
312 | /* Wrap phase accumulator back to start of next frame. */ | 395 | /* Wrap phase accumulator back to start of next frame. */ |
313 | r->phase = phase - (count << 16); | 396 | r->phase = phase & 0xffff; |
314 | r->last_sample[0] = src[0][count - 1]; | 397 | return d - dst[0]; |
315 | r->last_sample[1] = src[1][count - 1]; | ||
316 | return i; | ||
317 | } | 398 | } |
399 | #endif /* DSP_HAVE_ASM_RESAMPLING */ | ||
318 | 400 | ||
319 | /* Resample count stereo samples. Updates the src array, if resampling is | 401 | /* Resample count stereo samples. Updates the src array, if resampling is |
320 | * done, to refer to the resampled data. Returns number of stereo samples | 402 | * done, to refer to the resampled data. Returns number of stereo samples |
321 | * for further processing. | 403 | * for further processing. |
322 | */ | 404 | */ |
323 | static inline int resample(int32_t* src[], int count) | 405 | static inline int resample(int32_t *src[], int count) |
324 | { | 406 | { |
325 | long new_count; | 407 | long new_count = count; |
326 | 408 | ||
327 | if (dsp->frequency != NATIVE_FREQUENCY) | 409 | if (dsp->frequency != NATIVE_FREQUENCY) |
328 | { | 410 | { |
329 | int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_COUNT / 2]}; | 411 | int32_t *dst[2] = |
412 | { | ||
413 | resample_buf, | ||
414 | resample_buf + RESAMPLE_BUF_COUNT/2, | ||
415 | }; | ||
416 | int channels = dsp->num_channels; | ||
330 | 417 | ||
331 | if (dsp->frequency < NATIVE_FREQUENCY) | 418 | if (dsp->frequency < NATIVE_FREQUENCY) |
332 | { | 419 | new_count = dsp_upsample(channels, count, |
333 | new_count = upsample(dst, src, count, | 420 | &resample_data[current_codec], |
334 | &resample_data[current_codec]); | 421 | src, dst); |
335 | } | ||
336 | else | 422 | else |
337 | { | 423 | new_count = dsp_downsample(channels, count, |
338 | new_count = downsample(dst, src, count, | 424 | &resample_data[current_codec], |
339 | &resample_data[current_codec]); | 425 | src, dst); |
340 | } | ||
341 | 426 | ||
342 | src[0] = dst[0]; | 427 | src[0] = dst[0]; |
343 | if (dsp->stereo_mode != STEREO_MONO) | 428 | src[1] = dst[channels - 1]; |
344 | src[1] = dst[1]; | ||
345 | else | ||
346 | src[1] = dst[0]; | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | new_count = count; | ||
351 | } | 429 | } |
352 | 430 | ||
353 | return new_count; | 431 | return new_count; |
@@ -378,8 +456,7 @@ void dsp_dither_enable(bool enable) | |||
378 | 456 | ||
379 | static void dither_init(void) | 457 | static void dither_init(void) |
380 | { | 458 | { |
381 | memset(&dither_data[0], 0, sizeof(struct dither_data)); | 459 | memset(dither_data, 0, sizeof(dither_data)); |
382 | memset(&dither_data[1], 0, sizeof(struct dither_data)); | ||
383 | dsp->dither_bias = (1L << (dsp->frac_bits - NATIVE_DEPTH)); | 460 | dsp->dither_bias = (1L << (dsp->frac_bits - NATIVE_DEPTH)); |
384 | dsp->dither_mask = (1L << (dsp->frac_bits + 1 - NATIVE_DEPTH)) - 1; | 461 | dsp->dither_mask = (1L << (dsp->frac_bits + 1 - NATIVE_DEPTH)) - 1; |
385 | } | 462 | } |
@@ -592,7 +669,7 @@ void dsp_set_eq_coefs(int band) | |||
592 | static void eq_process(int32_t **x, unsigned num) | 669 | static void eq_process(int32_t **x, unsigned num) |
593 | { | 670 | { |
594 | int i; | 671 | int i; |
595 | unsigned int channels = dsp->stereo_mode != STEREO_MONO ? 2 : 1; | 672 | unsigned int channels = dsp->num_channels; |
596 | unsigned shift; | 673 | unsigned shift; |
597 | 674 | ||
598 | /* filter configuration currently is 1 low shelf filter, 3 band peaking | 675 | /* filter configuration currently is 1 low shelf filter, 3 band peaking |
@@ -772,7 +849,7 @@ int dsp_process(char *dst, const char *src[], int count) | |||
772 | 849 | ||
773 | while (count > 0) | 850 | while (count > 0) |
774 | { | 851 | { |
775 | samples = convert_to_internal(src, count, tmp); | 852 | samples = dsp->convert_to_internal(src, tmp, count); |
776 | count -= samples; | 853 | count -= samples; |
777 | apply_gain(tmp, samples); | 854 | apply_gain(tmp, samples); |
778 | samples = resample(tmp, samples); | 855 | samples = resample(tmp, samples); |
@@ -886,7 +963,7 @@ bool dsp_configure(int setting, intptr_t value) | |||
886 | 963 | ||
887 | case DSP_SET_SAMPLE_DEPTH: | 964 | case DSP_SET_SAMPLE_DEPTH: |
888 | dsp->sample_depth = value; | 965 | dsp->sample_depth = value; |
889 | 966 | ||
890 | if (dsp->sample_depth <= NATIVE_DEPTH) | 967 | if (dsp->sample_depth <= NATIVE_DEPTH) |
891 | { | 968 | { |
892 | dsp->frac_bits = WORD_FRACBITS; | 969 | dsp->frac_bits = WORD_FRACBITS; |
@@ -902,15 +979,19 @@ bool dsp_configure(int setting, intptr_t value) | |||
902 | dsp->clip_min = -(1 << value); | 979 | dsp->clip_min = -(1 << value); |
903 | } | 980 | } |
904 | 981 | ||
982 | new_sample_conversion(); | ||
905 | dither_init(); | 983 | dither_init(); |
906 | break; | 984 | break; |
907 | 985 | ||
908 | case DSP_SET_STEREO_MODE: | 986 | case DSP_SET_STEREO_MODE: |
909 | dsp->stereo_mode = (long) value; | 987 | dsp->stereo_mode = value; |
988 | dsp->num_channels = value == STEREO_MONO ? 1 : 2; | ||
989 | new_sample_conversion(); | ||
910 | break; | 990 | break; |
911 | 991 | ||
912 | case DSP_RESET: | 992 | case DSP_RESET: |
913 | dsp->stereo_mode = STEREO_NONINTERLEAVED; | 993 | dsp->stereo_mode = STEREO_NONINTERLEAVED; |
994 | dsp->num_channels = 2; | ||
914 | dsp->clip_max = ((1 << WORD_FRACBITS) - 1); | 995 | dsp->clip_max = ((1 << WORD_FRACBITS) - 1); |
915 | dsp->clip_min = -((1 << WORD_FRACBITS)); | 996 | dsp->clip_min = -((1 << WORD_FRACBITS)); |
916 | dsp->track_gain = 0; | 997 | dsp->track_gain = 0; |
@@ -921,6 +1002,7 @@ bool dsp_configure(int setting, intptr_t value) | |||
921 | dsp->sample_depth = NATIVE_DEPTH; | 1002 | dsp->sample_depth = NATIVE_DEPTH; |
922 | dsp->frac_bits = WORD_FRACBITS; | 1003 | dsp->frac_bits = WORD_FRACBITS; |
923 | dsp->new_gain = true; | 1004 | dsp->new_gain = true; |
1005 | new_sample_conversion(); | ||
924 | break; | 1006 | break; |
925 | 1007 | ||
926 | case DSP_FLUSH: | 1008 | case DSP_FLUSH: |