summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dsp.c')
-rw-r--r--apps/dsp.c195
1 files changed, 109 insertions, 86 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index 2ba7fb99f6..8064a881a3 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -132,9 +132,12 @@ struct dither_data
132 long random; 132 long random;
133}; 133};
134 134
135static struct dsp_config dsp IDATA_ATTR; 135static struct dsp_config dsp_conf[2] IDATA_ATTR;
136static struct dither_data dither_data[2] IDATA_ATTR; 136static struct dither_data dither_data[2] IDATA_ATTR;
137static struct resample_data resample_data[2] IDATA_ATTR; 137static struct resample_data resample_data[2][2] IDATA_ATTR;
138
139extern int current_codec;
140struct dsp_config *dsp;
138 141
139/* The internal format is 32-bit samples, non-interleaved, stereo. This 142/* The internal format is 32-bit samples, non-interleaved, stereo. This
140 * format is similar to the raw output from several codecs, so the amount 143 * format is similar to the raw output from several codecs, so the amount
@@ -155,20 +158,20 @@ static int convert_to_internal(char* src[], int count, long* dst[])
155{ 158{
156 count = MIN(SAMPLE_BUF_SIZE / 2, count); 159 count = MIN(SAMPLE_BUF_SIZE / 2, count);
157 160
158 if ((dsp.sample_depth <= NATIVE_DEPTH) 161 if ((dsp->sample_depth <= NATIVE_DEPTH)
159 || (dsp.stereo_mode == STEREO_INTERLEAVED)) 162 || (dsp->stereo_mode == STEREO_INTERLEAVED))
160 { 163 {
161 dst[0] = &sample_buf[0]; 164 dst[0] = &sample_buf[0];
162 dst[1] = (dsp.stereo_mode == STEREO_MONO) 165 dst[1] = (dsp->stereo_mode == STEREO_MONO)
163 ? dst[0] : &sample_buf[SAMPLE_BUF_SIZE / 2]; 166 ? dst[0] : &sample_buf[SAMPLE_BUF_SIZE / 2];
164 } 167 }
165 else 168 else
166 { 169 {
167 dst[0] = (long*) src[0]; 170 dst[0] = (long*) src[0];
168 dst[1] = (long*) ((dsp.stereo_mode == STEREO_MONO) ? src[0] : src[1]); 171 dst[1] = (long*) ((dsp->stereo_mode == STEREO_MONO) ? src[0] : src[1]);
169 } 172 }
170 173
171 if (dsp.sample_depth <= NATIVE_DEPTH) 174 if (dsp->sample_depth <= NATIVE_DEPTH)
172 { 175 {
173 short* s0 = (short*) src[0]; 176 short* s0 = (short*) src[0];
174 long* d0 = dst[0]; 177 long* d0 = dst[0];
@@ -176,7 +179,7 @@ static int convert_to_internal(char* src[], int count, long* dst[])
176 int scale = WORD_SHIFT; 179 int scale = WORD_SHIFT;
177 int i; 180 int i;
178 181
179 if (dsp.stereo_mode == STEREO_INTERLEAVED) 182 if (dsp->stereo_mode == STEREO_INTERLEAVED)
180 { 183 {
181 for (i = 0; i < count; i++) 184 for (i = 0; i < count; i++)
182 { 185 {
@@ -184,7 +187,7 @@ static int convert_to_internal(char* src[], int count, long* dst[])
184 *d1++ = *s0++ << scale; 187 *d1++ = *s0++ << scale;
185 } 188 }
186 } 189 }
187 else if (dsp.stereo_mode == STEREO_NONINTERLEAVED) 190 else if (dsp->stereo_mode == STEREO_NONINTERLEAVED)
188 { 191 {
189 short* s1 = (short*) src[1]; 192 short* s1 = (short*) src[1];
190 193
@@ -202,7 +205,7 @@ static int convert_to_internal(char* src[], int count, long* dst[])
202 } 205 }
203 } 206 }
204 } 207 }
205 else if (dsp.stereo_mode == STEREO_INTERLEAVED) 208 else if (dsp->stereo_mode == STEREO_INTERLEAVED)
206 { 209 {
207 long* s0 = (long*) src[0]; 210 long* s0 = (long*) src[0];
208 long* d0 = dst[0]; 211 long* d0 = dst[0];
@@ -216,18 +219,18 @@ static int convert_to_internal(char* src[], int count, long* dst[])
216 } 219 }
217 } 220 }
218 221
219 if (dsp.stereo_mode == STEREO_NONINTERLEAVED) 222 if (dsp->stereo_mode == STEREO_NONINTERLEAVED)
220 { 223 {
221 src[0] += count * dsp.sample_bytes; 224 src[0] += count * dsp->sample_bytes;
222 src[1] += count * dsp.sample_bytes; 225 src[1] += count * dsp->sample_bytes;
223 } 226 }
224 else if (dsp.stereo_mode == STEREO_INTERLEAVED) 227 else if (dsp->stereo_mode == STEREO_INTERLEAVED)
225 { 228 {
226 src[0] += count * dsp.sample_bytes * 2; 229 src[0] += count * dsp->sample_bytes * 2;
227 } 230 }
228 else 231 else
229 { 232 {
230 src[0] += count * dsp.sample_bytes; 233 src[0] += count * dsp->sample_bytes;
231 } 234 }
232 235
233 return count; 236 return count;
@@ -310,29 +313,33 @@ static inline int resample(long* src[], int count)
310{ 313{
311 long new_count; 314 long new_count;
312 315
313 if (dsp.frequency != NATIVE_FREQUENCY) 316 if (dsp->frequency != NATIVE_FREQUENCY)
314 { 317 {
315 long* d0 = &resample_buf[0]; 318 long* d0 = &resample_buf[0];
316 /* Only process the second channel if needed. */ 319 /* Only process the second channel if needed. */
317 long* d1 = (src[0] == src[1]) ? d0 320 long* d1 = (src[0] == src[1]) ? d0
318 : &resample_buf[RESAMPLE_BUF_SIZE / 2]; 321 : &resample_buf[RESAMPLE_BUF_SIZE / 2];
319 322
320 if (dsp.frequency < NATIVE_FREQUENCY) 323 if (dsp->frequency < NATIVE_FREQUENCY)
321 { 324 {
322 new_count = upsample(d0, src[0], count, &resample_data[0]); 325 new_count = upsample(d0, src[0], count,
326 &resample_data[current_codec][0]);
323 327
324 if (d0 != d1) 328 if (d0 != d1)
325 { 329 {
326 upsample(d1, src[1], count, &resample_data[1]); 330 upsample(d1, src[1], count,
331 &resample_data[current_codec][1]);
327 } 332 }
328 } 333 }
329 else 334 else
330 { 335 {
331 new_count = downsample(d0, src[0], count, &resample_data[0]); 336 new_count = downsample(d0, src[0], count,
337 &resample_data[current_codec][0]);
332 338
333 if (d0 != d1) 339 if (d0 != d1)
334 { 340 {
335 downsample(d1, src[1], count, &resample_data[1]); 341 downsample(d1, src[1], count,
342 &resample_data[current_codec][1]);
336 } 343 }
337 } 344 }
338 345
@@ -389,8 +396,8 @@ static long dither_sample(long sample, long bias, long mask,
389 396
390 /* Clip and quantize */ 397 /* Clip and quantize */
391 398
392 min = dsp.clip_min; 399 min = dsp->clip_min;
393 max = dsp.clip_max; 400 max = dsp->clip_max;
394 sample = clip_sample(sample, min, max); 401 sample = clip_sample(sample, min, max);
395 output = clip_sample(output, min, max) & ~mask; 402 output = clip_sample(output, min, max) & ~mask;
396 403
@@ -407,13 +414,13 @@ static long dither_sample(long sample, long bias, long mask,
407 */ 414 */
408static void apply_gain(long* src[], int count) 415static void apply_gain(long* src[], int count)
409{ 416{
410 if (dsp.replaygain) 417 if (dsp->replaygain)
411 { 418 {
412 long* s0 = src[0]; 419 long* s0 = src[0];
413 long* s1 = src[1]; 420 long* s1 = src[1];
414 long* d0 = &sample_buf[0]; 421 long* d0 = &sample_buf[0];
415 long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2]; 422 long* d1 = (s0 == s1) ? d0 : &sample_buf[SAMPLE_BUF_SIZE / 2];
416 long gain = dsp.replaygain; 423 long gain = dsp->replaygain;
417 long s; 424 long s;
418 long i; 425 long i;
419 426
@@ -442,11 +449,11 @@ static void write_samples(short* dst, long* src[], int count)
442{ 449{
443 long* s0 = src[0]; 450 long* s0 = src[0];
444 long* s1 = src[1]; 451 long* s1 = src[1];
445 int scale = dsp.frac_bits + 1 - NATIVE_DEPTH; 452 int scale = dsp->frac_bits + 1 - NATIVE_DEPTH;
446 453
447 if (dsp.dither_enabled) 454 if (dsp->dither_enabled)
448 { 455 {
449 long bias = (1L << (dsp.frac_bits - NATIVE_DEPTH)); 456 long bias = (1L << (dsp->frac_bits - NATIVE_DEPTH));
450 long mask = (1L << scale) - 1; 457 long mask = (1L << scale) - 1;
451 458
452 while (count-- > 0) 459 while (count-- > 0)
@@ -459,8 +466,8 @@ static void write_samples(short* dst, long* src[], int count)
459 } 466 }
460 else 467 else
461 { 468 {
462 long min = dsp.clip_min; 469 long min = dsp->clip_min;
463 long max = dsp.clip_max; 470 long max = dsp->clip_max;
464 471
465 while (count-- > 0) 472 while (count-- > 0)
466 { 473 {
@@ -482,10 +489,13 @@ long dsp_process(char* dst, char* src[], long size)
482{ 489{
483 long* tmp[2]; 490 long* tmp[2];
484 long written = 0; 491 long written = 0;
485 long factor = (dsp.stereo_mode != STEREO_MONO) ? 2 : 1; 492 long factor;
486 int samples; 493 int samples;
487 494
488 size /= dsp.sample_bytes * factor; 495 dsp = &dsp_conf[current_codec];
496
497 factor = (dsp->stereo_mode != STEREO_MONO) ? 2 : 1;
498 size /= dsp->sample_bytes * factor;
489 INIT(); 499 INIT();
490 dsp_set_replaygain(false); 500 dsp_set_replaygain(false);
491 501
@@ -513,21 +523,23 @@ long dsp_process(char* dst, char* src[], long size)
513/* dsp_input_size MUST be called afterwards */ 523/* dsp_input_size MUST be called afterwards */
514long dsp_output_size(long size) 524long dsp_output_size(long size)
515{ 525{
516 if (dsp.sample_depth > NATIVE_DEPTH) 526 dsp = &dsp_conf[current_codec];
527
528 if (dsp->sample_depth > NATIVE_DEPTH)
517 { 529 {
518 size /= 2; 530 size /= 2;
519 } 531 }
520 532
521 if (dsp.frequency != NATIVE_FREQUENCY) 533 if (dsp->frequency != NATIVE_FREQUENCY)
522 { 534 {
523 size = (long) ((((unsigned long) size * NATIVE_FREQUENCY) 535 size = (long) ((((unsigned long) size * NATIVE_FREQUENCY)
524 + (dsp.frequency - 1)) / dsp.frequency); 536 + (dsp->frequency - 1)) / dsp->frequency);
525 } 537 }
526 538
527 /* round to the next multiple of 2 (these are shorts) */ 539 /* round to the next multiple of 2 (these are shorts) */
528 size = (size + 1) & ~1; 540 size = (size + 1) & ~1;
529 541
530 if (dsp.stereo_mode == STEREO_MONO) 542 if (dsp->stereo_mode == STEREO_MONO)
531 { 543 {
532 size *= 2; 544 size *= 2;
533 } 545 }
@@ -547,25 +559,28 @@ long dsp_output_size(long size)
547 */ 559 */
548long dsp_input_size(long size) 560long dsp_input_size(long size)
549{ 561{
562 dsp = &dsp_conf[current_codec];
563
550 /* convert to number of output stereo samples. */ 564 /* convert to number of output stereo samples. */
551 size /= 2; 565 size /= 2;
552 566
553 /* Mono means we need half input samples to fill the output buffer */ 567 /* Mono means we need half input samples to fill the output buffer */
554 if (dsp.stereo_mode == STEREO_MONO) 568 if (dsp->stereo_mode == STEREO_MONO)
555 size /= 2; 569 size /= 2;
556 570
557 /* size is now the number of resampled input samples. Convert to 571 /* size is now the number of resampled input samples. Convert to
558 original input samples. */ 572 original input samples. */
559 if (dsp.frequency != NATIVE_FREQUENCY) 573 if (dsp->frequency != NATIVE_FREQUENCY)
560 { 574 {
561 /* Use the real resampling delta = 575 /* Use the real resampling delta =
562 * (unsigned long) dsp.frequency * 65536 / NATIVE_FREQUENCY, and 576 * (unsigned long) dsp->frequency * 65536 / NATIVE_FREQUENCY, and
563 * round towards zero to avoid buffer overflows. */ 577 * round towards zero to avoid buffer overflows. */
564 size = ((unsigned long)size * resample_data[0].delta) >> 16; 578 size = ((unsigned long)size *
579 resample_data[current_codec][0].delta) >> 16;
565 } 580 }
566 581
567 /* Convert back to bytes. */ 582 /* Convert back to bytes. */
568 if (dsp.sample_depth > NATIVE_DEPTH) 583 if (dsp->sample_depth > NATIVE_DEPTH)
569 size *= 4; 584 size *= 4;
570 else 585 else
571 size *= 2; 586 size *= 2;
@@ -575,90 +590,96 @@ long dsp_input_size(long size)
575 590
576int dsp_stereo_mode(void) 591int dsp_stereo_mode(void)
577{ 592{
578 return dsp.stereo_mode; 593 dsp = &dsp_conf[current_codec];
594
595 return dsp->stereo_mode;
579} 596}
580 597
581bool dsp_configure(int setting, void *value) 598bool dsp_configure(int setting, void *value)
582{ 599{
600 dsp = &dsp_conf[current_codec];
601
583 switch (setting) 602 switch (setting)
584 { 603 {
585 case DSP_SET_FREQUENCY: 604 case DSP_SET_FREQUENCY:
586 memset(resample_data, 0, sizeof(resample_data)); 605 memset(&resample_data[current_codec][0], 0,
606 sizeof(struct resample_data) * 2);
587 /* Fall through!!! */ 607 /* Fall through!!! */
588 case DSP_SWITCH_FREQUENCY: 608 case DSP_SWITCH_FREQUENCY:
589 dsp.frequency = ((int) value == 0) ? NATIVE_FREQUENCY : (int) value; 609 dsp->frequency = ((int) value == 0) ? NATIVE_FREQUENCY : (int) value;
590 resample_data[0].delta = resample_data[1].delta = 610 resample_data[current_codec][0].delta =
591 (unsigned long) dsp.frequency * 65536 / NATIVE_FREQUENCY; 611 resample_data[current_codec][1].delta =
612 (unsigned long) dsp->frequency * 65536 / NATIVE_FREQUENCY;
592 break; 613 break;
593 614
594 case DSP_SET_CLIP_MIN: 615 case DSP_SET_CLIP_MIN:
595 dsp.clip_min = (long) value; 616 dsp->clip_min = (long) value;
596 break; 617 break;
597 618
598 case DSP_SET_CLIP_MAX: 619 case DSP_SET_CLIP_MAX:
599 dsp.clip_max = (long) value; 620 dsp->clip_max = (long) value;
600 break; 621 break;
601 622
602 case DSP_SET_SAMPLE_DEPTH: 623 case DSP_SET_SAMPLE_DEPTH:
603 dsp.sample_depth = (long) value; 624 dsp->sample_depth = (long) value;
604 625
605 if (dsp.sample_depth <= NATIVE_DEPTH) 626 if (dsp->sample_depth <= NATIVE_DEPTH)
606 { 627 {
607 dsp.frac_bits = WORD_FRACBITS; 628 dsp->frac_bits = WORD_FRACBITS;
608 dsp.sample_bytes = sizeof(short); 629 dsp->sample_bytes = sizeof(short);
609 dsp.clip_max = ((1 << WORD_FRACBITS) - 1); 630 dsp->clip_max = ((1 << WORD_FRACBITS) - 1);
610 dsp.clip_min = -((1 << WORD_FRACBITS)); 631 dsp->clip_min = -((1 << WORD_FRACBITS));
611 } 632 }
612 else 633 else
613 { 634 {
614 dsp.frac_bits = (long) value; 635 dsp->frac_bits = (long) value;
615 dsp.sample_bytes = sizeof(long); 636 dsp->sample_bytes = sizeof(long);
616 } 637 }
617 638
618 break; 639 break;
619 640
620 case DSP_SET_STEREO_MODE: 641 case DSP_SET_STEREO_MODE:
621 dsp.stereo_mode = (long) value; 642 dsp->stereo_mode = (long) value;
622 break; 643 break;
623 644
624 case DSP_RESET: 645 case DSP_RESET:
625 dsp.dither_enabled = false; 646 dsp->dither_enabled = false;
626 dsp.stereo_mode = STEREO_NONINTERLEAVED; 647 dsp->stereo_mode = STEREO_NONINTERLEAVED;
627 dsp.clip_max = ((1 << WORD_FRACBITS) - 1); 648 dsp->clip_max = ((1 << WORD_FRACBITS) - 1);
628 dsp.clip_min = -((1 << WORD_FRACBITS)); 649 dsp->clip_min = -((1 << WORD_FRACBITS));
629 dsp.track_gain = 0; 650 dsp->track_gain = 0;
630 dsp.album_gain = 0; 651 dsp->album_gain = 0;
631 dsp.track_peak = 0; 652 dsp->track_peak = 0;
632 dsp.album_peak = 0; 653 dsp->album_peak = 0;
633 dsp.frequency = NATIVE_FREQUENCY; 654 dsp->frequency = NATIVE_FREQUENCY;
634 dsp.sample_depth = NATIVE_DEPTH; 655 dsp->sample_depth = NATIVE_DEPTH;
635 dsp.frac_bits = WORD_FRACBITS; 656 dsp->frac_bits = WORD_FRACBITS;
636 dsp.new_gain = true; 657 dsp->new_gain = true;
637 break; 658 break;
638 659
639 case DSP_DITHER: 660 case DSP_DITHER:
640 memset(dither_data, 0, sizeof(dither_data)); 661 memset(dither_data, 0, sizeof(dither_data));
641 dsp.dither_enabled = (bool) value; 662 dsp->dither_enabled = (bool) value;
642 break; 663 break;
643 664
644 case DSP_SET_TRACK_GAIN: 665 case DSP_SET_TRACK_GAIN:
645 dsp.track_gain = (long) value; 666 dsp->track_gain = (long) value;
646 dsp.new_gain = true; 667 dsp->new_gain = true;
647 break; 668 break;
648 669
649 case DSP_SET_ALBUM_GAIN: 670 case DSP_SET_ALBUM_GAIN:
650 dsp.album_gain = (long) value; 671 dsp->album_gain = (long) value;
651 dsp.new_gain = true; 672 dsp->new_gain = true;
652 break; 673 break;
653 674
654 case DSP_SET_TRACK_PEAK: 675 case DSP_SET_TRACK_PEAK:
655 dsp.track_peak = (long) value; 676 dsp->track_peak = (long) value;
656 dsp.new_gain = true; 677 dsp->new_gain = true;
657 break; 678 break;
658 679
659 case DSP_SET_ALBUM_PEAK: 680 case DSP_SET_ALBUM_PEAK:
660 dsp.album_peak = (long) value; 681 dsp->album_peak = (long) value;
661 dsp.new_gain = true; 682 dsp->new_gain = true;
662 break; 683 break;
663 684
664 default: 685 default:
@@ -670,11 +691,13 @@ bool dsp_configure(int setting, void *value)
670 691
671void dsp_set_replaygain(bool always) 692void dsp_set_replaygain(bool always)
672{ 693{
673 if (always || dsp.new_gain) 694 dsp = &dsp_conf[current_codec];
695
696 if (always || dsp->new_gain)
674 { 697 {
675 long gain = 0; 698 long gain = 0;
676 699
677 dsp.new_gain = false; 700 dsp->new_gain = false;
678 701
679 if (global_settings.replaygain || global_settings.replaygain_noclip) 702 if (global_settings.replaygain || global_settings.replaygain_noclip)
680 { 703 {
@@ -682,8 +705,8 @@ void dsp_set_replaygain(bool always)
682 705
683 if (global_settings.replaygain) 706 if (global_settings.replaygain)
684 { 707 {
685 gain = (global_settings.replaygain_track || !dsp.album_gain) 708 gain = (global_settings.replaygain_track || !dsp->album_gain)
686 ? dsp.track_gain : dsp.album_gain; 709 ? dsp->track_gain : dsp->album_gain;
687 710
688 if (global_settings.replaygain_preamp) 711 if (global_settings.replaygain_preamp)
689 { 712 {
@@ -694,8 +717,8 @@ void dsp_set_replaygain(bool always)
694 } 717 }
695 } 718 }
696 719
697 peak = (global_settings.replaygain_track || !dsp.album_peak) 720 peak = (global_settings.replaygain_track || !dsp->album_peak)
698 ? dsp.track_peak : dsp.album_peak; 721 ? dsp->track_peak : dsp->album_peak;
699 722
700 if (gain == 0) 723 if (gain == 0)
701 { 724 {
@@ -718,6 +741,6 @@ void dsp_set_replaygain(bool always)
718 } 741 }
719 742
720 /* Store in S8.23 format to simplify calculations. */ 743 /* Store in S8.23 format to simplify calculations. */
721 dsp.replaygain = gain >> 1; 744 dsp->replaygain = gain >> 1;
722 } 745 }
723} 746}