summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dsp.c')
-rw-r--r--apps/dsp.c145
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
210struct crossfeed_data 201struct 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
517void dsp_set_crossfeed(bool enable)
518{
519 dsp->crossfeed_enabled = enable;
520}
521
522void 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
531void 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
531static void apply_crossfeed(int32_t* src[], int count) 546void 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
1071void dsp_set_crossfeed(bool enable)
1072{
1073 if (enable)
1074 memset(&crossfeed_data, 0, sizeof(crossfeed_data));
1075 dsp->crossfeed_enabled = enable;
1076}
1077
1078void dsp_set_replaygain(bool always) 1053void dsp_set_replaygain(bool always)
1079{ 1054{
1080 dsp = &dsp_conf[current_codec]; 1055 dsp = &dsp_conf[current_codec];