diff options
Diffstat (limited to 'apps/dsp.c')
-rw-r--r-- | apps/dsp.c | 145 |
1 files changed, 60 insertions, 85 deletions
diff --git a/apps/dsp.c b/apps/dsp.c index 29e103afb7..b6d24824b5 100644 --- a/apps/dsp.c +++ b/apps/dsp.c | |||
@@ -47,15 +47,6 @@ | |||
47 | #define RESAMPLE_BUF_SIZE (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ | 47 | #define RESAMPLE_BUF_SIZE (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ |
48 | #define DEFAULT_REPLAYGAIN 0x01000000 | 48 | #define DEFAULT_REPLAYGAIN 0x01000000 |
49 | 49 | ||
50 | /* These are the constants for the filters in the crossfeed */ | ||
51 | |||
52 | #define ATT 0x0CCCCCCDL /* 0.1 */ | ||
53 | #define ATT_COMP 0x73333333L /* 0.9 */ | ||
54 | #define LOW 0x4CCCCCCDL /* 0.6 */ | ||
55 | #define LOW_COMP 0x33333333L /* 0.4 */ | ||
56 | #define HIGH_NEG -0x66666666L /* -0.2 (not unsigned!) */ | ||
57 | #define HIGH_COMP 0x66666666L /* 0.8 */ | ||
58 | |||
59 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | 50 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) |
60 | 51 | ||
61 | /* Multiply two S.31 fractional integers and return the sign bit and the | 52 | /* Multiply two S.31 fractional integers and return the sign bit and the |
@@ -209,10 +200,11 @@ struct dither_data | |||
209 | 200 | ||
210 | struct crossfeed_data | 201 | struct crossfeed_data |
211 | { | 202 | { |
212 | int32_t lowpass[2]; | 203 | int32_t gain; /* Direct path gain */ |
213 | int32_t highpass[2]; | 204 | int32_t coefs[3]; /* Coefficients for the shelving filter */ |
214 | int32_t delay[2][13]; | 205 | int32_t history[4]; /* Format is x[n - 1], y[n - 1] for both channels */ |
215 | int index; | 206 | int32_t delay[13][2]; |
207 | int index; /* Current index into the delay line */ | ||
216 | }; | 208 | }; |
217 | 209 | ||
218 | /* Current setup is one lowshelf filters, three peaking filters and one | 210 | /* Current setup is one lowshelf filters, three peaking filters and one |
@@ -522,71 +514,71 @@ static long dither_sample(int32_t sample, int32_t bias, int32_t mask, | |||
522 | return output; | 514 | return output; |
523 | } | 515 | } |
524 | 516 | ||
517 | void dsp_set_crossfeed(bool enable) | ||
518 | { | ||
519 | dsp->crossfeed_enabled = enable; | ||
520 | } | ||
521 | |||
522 | void dsp_set_crossfeed_direct_gain(int gain) | ||
523 | { | ||
524 | /* Work around bug in get_replaygain_int which returns 0 for 0 dB */ | ||
525 | if (gain == 0) | ||
526 | crossfeed_data.gain = 0x7fffffff; | ||
527 | else | ||
528 | crossfeed_data.gain = get_replaygain_int(gain * -10) << 7; | ||
529 | } | ||
530 | |||
531 | void dsp_set_crossfeed_cross_params(long lf_gain, long hf_gain, long cutoff) | ||
532 | { | ||
533 | long g1 = get_replaygain_int(lf_gain * -10) << 3; | ||
534 | long g2 = get_replaygain_int(hf_gain * -10) << 3; | ||
535 | |||
536 | filter_bishelf_coefs(0xffffffff/NATIVE_FREQUENCY*cutoff, g1, g2, | ||
537 | crossfeed_data.coefs); | ||
538 | } | ||
539 | |||
525 | /* Applies crossfeed to the stereo signal in src. | 540 | /* Applies crossfeed to the stereo signal in src. |
526 | * Crossfeed is a process where listening over speakers is simulated. This | 541 | * Crossfeed is a process where listening over speakers is simulated. This |
527 | * is good for old hard panned stereo records, which might be quite fatiguing | 542 | * is good for old hard panned stereo records, which might be quite fatiguing |
528 | * to listen to on headphones with no crossfeed. | 543 | * to listen to on headphones with no crossfeed. |
529 | */ | 544 | */ |
530 | #ifndef DSP_HAVE_ASM_CROSSFEED | 545 | #ifndef DSP_HAVE_ASM_CROSSFEED |
531 | static void apply_crossfeed(int32_t* src[], int count) | 546 | void apply_crossfeed(int32_t* src[], int count) |
532 | { | 547 | { |
533 | int32_t a; /* accumulator */ | 548 | int32_t *hist_l = &crossfeed_data.history[0]; |
534 | 549 | int32_t *hist_r = &crossfeed_data.history[2]; | |
535 | int32_t low_left = crossfeed_data.lowpass[0]; | 550 | int32_t *delay = &crossfeed_data.delay[0][0]; |
536 | int32_t low_right = crossfeed_data.lowpass[1]; | 551 | int32_t *coefs = &crossfeed_data.coefs[0]; |
537 | int32_t high_left = crossfeed_data.highpass[0]; | 552 | int32_t gain = crossfeed_data.gain; |
538 | int32_t high_right = crossfeed_data.highpass[1]; | 553 | int di = crossfeed_data.index; |
539 | unsigned int index = crossfeed_data.index; | 554 | |
540 | 555 | int32_t acc; | |
541 | int32_t left, right; | 556 | int32_t left, right; |
542 | |||
543 | int32_t* delay_l = crossfeed_data.delay[0]; | ||
544 | int32_t* delay_r = crossfeed_data.delay[1]; | ||
545 | |||
546 | int i; | 557 | int i; |
547 | 558 | ||
548 | for (i = 0; i < count; i++) | 559 | for (i = 0; i < count; i++) { |
549 | { | ||
550 | /* use a low-pass filter on the signal */ | ||
551 | left = src[0][i]; | 560 | left = src[0][i]; |
552 | right = src[1][i]; | 561 | right = src[1][i]; |
553 | 562 | ||
554 | ACC_INIT(a, LOW, low_left); ACC(a, LOW_COMP, left); | 563 | ACC_INIT(acc, delay[di*2], coefs[0]); |
555 | low_left = GET_ACC(a); | 564 | ACC(acc, hist_l[0], coefs[1]); |
556 | 565 | ACC(acc, hist_l[1], coefs[2]); | |
557 | ACC_INIT(a, LOW, low_right); ACC(a, LOW_COMP, right); | 566 | hist_l[1] = GET_ACC(acc) << 0; |
558 | low_right = GET_ACC(a); | 567 | hist_l[0] = delay[di*2]; |
559 | 568 | ACC_INIT(acc, delay[di*2 + 1], coefs[0]); | |
560 | /* use a high-pass filter on the signal */ | 569 | ACC(acc, hist_r[0], coefs[1]); |
561 | 570 | ACC(acc, hist_r[1], coefs[2]); | |
562 | ACC_INIT(a, HIGH_NEG, high_left); ACC(a, HIGH_COMP, left); | 571 | hist_r[1] = GET_ACC(acc) << 0; |
563 | high_left = GET_ACC(a); | 572 | hist_r[0] = delay[di*2 + 1]; |
564 | 573 | delay[di*2] = left; | |
565 | ACC_INIT(a, HIGH_NEG, high_right); ACC(a, HIGH_COMP, right); | 574 | delay[di*2 + 1] = right; |
566 | high_right = GET_ACC(a); | 575 | src[0][i] = FRACMUL(left, gain) + hist_r[1]; |
567 | 576 | src[1][i] = FRACMUL(right, gain) + hist_l[1]; | |
568 | /* New data is the high-passed signal + delayed and attenuated | 577 | |
569 | * low-passed signal from the other channel */ | 578 | if (++di > 12) |
570 | 579 | di = 0; | |
571 | ACC_INIT(a, ATT, delay_r[index]); ACC(a, ATT_COMP, high_left); | ||
572 | src[0][i] = GET_ACC(a); | ||
573 | |||
574 | ACC_INIT(a, ATT, delay_l[index]); ACC(a, ATT_COMP, high_right); | ||
575 | src[1][i] = GET_ACC(a); | ||
576 | |||
577 | /* Store the low-passed signal in the ringbuffer */ | ||
578 | |||
579 | delay_l[index] = low_left; | ||
580 | delay_r[index] = low_right; | ||
581 | |||
582 | index = (index + 1) % 13; | ||
583 | } | 580 | } |
584 | 581 | crossfeed_data.index = di; | |
585 | crossfeed_data.index = index; | ||
586 | crossfeed_data.lowpass[0] = low_left; | ||
587 | crossfeed_data.lowpass[1] = low_right; | ||
588 | crossfeed_data.highpass[0] = high_left; | ||
589 | crossfeed_data.highpass[1] = high_right; | ||
590 | } | 582 | } |
591 | #endif | 583 | #endif |
592 | 584 | ||
@@ -633,13 +625,8 @@ void dsp_set_eq_coefs(int band) | |||
633 | if (q == 0) | 625 | if (q == 0) |
634 | q = 1; | 626 | q = 1; |
635 | 627 | ||
636 | /* The coef functions assume the EMAC unit is in fractional mode */ | 628 | /* NOTE: The coef functions assume the EMAC unit is in fractional mode, |
637 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | 629 | which it should be, since we're executed from the main thread. */ |
638 | /* set emac unit for dsp processing, and save old macsr, we're running in | ||
639 | codec thread context at this point, so can't clobber it */ | ||
640 | unsigned long old_macsr = coldfire_get_macsr(); | ||
641 | coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE | EMAC_ROUND); | ||
642 | #endif | ||
643 | 630 | ||
644 | /* Assume a band is disabled if the gain is zero */ | 631 | /* Assume a band is disabled if the gain is zero */ |
645 | if (gain == 0) { | 632 | if (gain == 0) { |
@@ -654,11 +641,6 @@ void dsp_set_eq_coefs(int band) | |||
654 | 641 | ||
655 | eq_data.enabled[band] = 1; | 642 | eq_data.enabled[band] = 1; |
656 | } | 643 | } |
657 | |||
658 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | ||
659 | /* set old macsr again */ | ||
660 | coldfire_set_macsr(old_macsr); | ||
661 | #endif | ||
662 | } | 644 | } |
663 | 645 | ||
664 | /* Apply EQ filters to those bands that have got it switched on. */ | 646 | /* Apply EQ filters to those bands that have got it switched on. */ |
@@ -1068,13 +1050,6 @@ bool dsp_configure(int setting, void *value) | |||
1068 | return 1; | 1050 | return 1; |
1069 | } | 1051 | } |
1070 | 1052 | ||
1071 | void dsp_set_crossfeed(bool enable) | ||
1072 | { | ||
1073 | if (enable) | ||
1074 | memset(&crossfeed_data, 0, sizeof(crossfeed_data)); | ||
1075 | dsp->crossfeed_enabled = enable; | ||
1076 | } | ||
1077 | |||
1078 | void dsp_set_replaygain(bool always) | 1053 | void dsp_set_replaygain(bool always) |
1079 | { | 1054 | { |
1080 | dsp = &dsp_conf[current_codec]; | 1055 | dsp = &dsp_conf[current_codec]; |