summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/dsp.c93
-rw-r--r--apps/dsp.h3
-rw-r--r--apps/eq_menu.c71
-rw-r--r--apps/lang/english.lang7
-rw-r--r--apps/settings.c9
-rw-r--r--apps/settings.h45
6 files changed, 150 insertions, 78 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index e5696bc7cd..b199d4e693 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -192,6 +192,7 @@ struct dsp_config
192 bool new_gain; 192 bool new_gain;
193 bool crossfeed_enabled; 193 bool crossfeed_enabled;
194 bool eq_enabled; 194 bool eq_enabled;
195 long eq_precut; /* Note that this is in S8.23 format. */
195}; 196};
196 197
197struct resample_data 198struct resample_data
@@ -589,15 +590,31 @@ static void apply_crossfeed(int32_t* src[], int count)
589} 590}
590#endif 591#endif
591 592
592/* Synchronize the EQ filters with the global settings */ 593/**
593void dsp_eq_update_data(bool enabled, int band) 594 * Use to enable the equalizer and set any pregain.
595 *
596 * @param enable true to enable the equalizer
597 * @param precut to apply in decibels (multiplied by 10)
598 */
599void dsp_eq_set(bool enable, unsigned int precut)
600{
601 dsp->eq_enabled = enable;
602
603 /* Needs to be in s8.23 format amplitude for apply_gain() */
604 dsp->eq_precut = get_replaygain_int(precut * -10) >> 1;
605}
606
607/**
608 * Synchronize the equalizer filter coefficients with the global settings.
609 *
610 * @param band the equalizer band to synchronize
611 */
612void dsp_eq_update_filter_coefs(int band)
594{ 613{
595 const int *setting; 614 const int *setting;
596 long gain; 615 long gain;
597 unsigned long cutoff, q; 616 unsigned long cutoff, q;
598 617
599 dsp->eq_enabled = enabled;
600
601 /* Adjust setting pointer to the band we actually want to change */ 618 /* Adjust setting pointer to the band we actually want to change */
602 setting = &global_settings.eq_band0_cutoff + (band * 3); 619 setting = &global_settings.eq_band0_cutoff + (band * 3);
603 620
@@ -640,7 +657,7 @@ static void eq_process(int32_t **x, unsigned num)
640 int i; 657 int i;
641 unsigned int channels = dsp->stereo_mode != STEREO_MONO ? 2 : 1; 658 unsigned int channels = dsp->stereo_mode != STEREO_MONO ? 2 : 1;
642 unsigned shift; 659 unsigned shift;
643 660
644 /* filter configuration currently is 1 low shelf filter, 3 band peaking 661 /* filter configuration currently is 1 low shelf filter, 3 band peaking
645 filters and 1 high shelf filter, in that order. we need to know this 662 filters and 1 high shelf filter, in that order. we need to know this
646 so we can choose the correct shift factor. 663 so we can choose the correct shift factor.
@@ -662,39 +679,51 @@ static void eq_process(int32_t **x, unsigned num)
662 */ 679 */
663static void apply_gain(int32_t* _src[], int _count) 680static void apply_gain(int32_t* _src[], int _count)
664{ 681{
665 struct dsp_config *my_dsp = dsp; 682 int32_t** src = _src;
666 if (my_dsp->replaygain) 683 int count = _count;
684 int32_t* s0 = src[0];
685 int32_t* s1 = src[1];
686 long gain = 0;
687 int32_t s;
688 int i;
689 int32_t *d;
690
691 if (dsp->replaygain)
667 { 692 {
668 int32_t** src = _src; 693 gain = dsp->replaygain;
669 int count = _count; 694 }
670 int32_t* s0 = src[0];
671 int32_t* s1 = src[1];
672 long gain = my_dsp->replaygain;
673 int32_t s;
674 int i;
675 int32_t *d;
676 695
677 if (s0 != s1) 696 if (dsp->eq_enabled)
678 { 697 {
679 d = &sample_buf[SAMPLE_BUF_SIZE / 2]; 698 gain += dsp->eq_precut; /* FIXME: This isn't that easy right? */
680 src[1] = d; 699 }
681 s = *s1++;
682 700
683 for (i = 0; i < count; i++) 701 /* Don't bother if the gain is zero */
684 FRACMUL_8_LOOP(s, gain, s1, d); 702 if (gain == 0)
685 } 703 {
686 else 704 return;
687 { 705 }
688 src[1] = &sample_buf[0];
689 }
690 706
691 d = &sample_buf[0]; 707 if (s0 != s1)
692 src[0] = d; 708 {
693 s = *s0++; 709 d = &sample_buf[SAMPLE_BUF_SIZE / 2];
710 src[1] = d;
711 s = *s1++;
694 712
695 for (i = 0; i < count; i++) 713 for (i = 0; i < count; i++)
696 FRACMUL_8_LOOP(s, gain, s0, d); 714 FRACMUL_8_LOOP(s, gain, s1, d);
697 } 715 }
716 else
717 {
718 src[1] = &sample_buf[0];
719 }
720
721 d = &sample_buf[0];
722 src[0] = d;
723 s = *s0++;
724
725 for (i = 0; i < count; i++)
726 FRACMUL_8_LOOP(s, gain, s0, d);
698} 727}
699 728
700void channels_set(int value) 729void channels_set(int value)
@@ -815,7 +844,7 @@ long dsp_process(char* dst, const char* src[], long size)
815 unsigned long old_macsr = coldfire_get_macsr(); 844 unsigned long old_macsr = coldfire_get_macsr();
816 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); 845 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
817 #endif 846 #endif
818 847
819 dsp = &dsp_conf[current_codec]; 848 dsp = &dsp_conf[current_codec];
820 849
821 factor = (dsp->stereo_mode != STEREO_MONO) ? 2 : 1; 850 factor = (dsp->stereo_mode != STEREO_MONO) ? 2 : 1;
diff --git a/apps/dsp.h b/apps/dsp.h
index 8b8b164d6e..35a1e88744 100644
--- a/apps/dsp.h
+++ b/apps/dsp.h
@@ -54,7 +54,8 @@ int dsp_stereo_mode(void);
54bool dsp_configure(int setting, void *value); 54bool dsp_configure(int setting, void *value);
55void dsp_set_replaygain(bool always); 55void dsp_set_replaygain(bool always);
56void dsp_set_crossfeed(bool enable); 56void dsp_set_crossfeed(bool enable);
57void dsp_eq_update_data(bool enabled, int band); 57void dsp_eq_set(bool enable, unsigned int precut);
58void dsp_eq_update_filter_coefs(int band);
58void sound_set_pitch(int r); 59void sound_set_pitch(int r);
59int sound_get_pitch(void); 60int sound_get_pitch(void);
60void channels_set(int value); 61void channels_set(int value);
diff --git a/apps/eq_menu.c b/apps/eq_menu.c
index 82639a54da..61d38f473c 100644
--- a/apps/eq_menu.c
+++ b/apps/eq_menu.c
@@ -97,14 +97,14 @@
97 97
98#endif 98#endif
99 99
100 100/* Various user interface limits and sizes */
101#define EQ_CUTOFF_MIN 20 101#define EQ_CUTOFF_MIN 20
102#define EQ_CUTOFF_MAX 22040 102#define EQ_CUTOFF_MAX 22040
103#define EQ_CUTOFF_STEP 10 103#define EQ_CUTOFF_STEP 10
104#define EQ_CUTOFF_FAST_STEP 100 104#define EQ_CUTOFF_FAST_STEP 100
105#define EQ_GAIN_MIN (-240) 105#define EQ_GAIN_MIN (-240)
106#define EQ_GAIN_MAX 240 106#define EQ_GAIN_MAX 240
107#define EQ_GAIN_STEP 1 107#define EQ_GAIN_STEP 5
108#define EQ_GAIN_FAST_STEP 10 108#define EQ_GAIN_FAST_STEP 10
109#define EQ_Q_MIN 5 109#define EQ_Q_MIN 5
110#define EQ_Q_MAX 64 110#define EQ_Q_MAX 64
@@ -113,32 +113,59 @@
113 113
114#define EQ_USER_DIVISOR 10 114#define EQ_USER_DIVISOR 10
115 115
116/*
117 * Utility functions
118 */
119
120static void eq_gain_format(char* buffer, int buffer_size, int value, const char* unit)
121{
122 int v = abs(value);
123
124 snprintf(buffer, buffer_size, "%s%d.%d %s", value < 0 ? "-" : "",
125 v / EQ_USER_DIVISOR, v % EQ_USER_DIVISOR, unit);
126}
127
128static void eq_q_format(char* buffer, int buffer_size, int value, const char* unit)
129{
130 snprintf(buffer, buffer_size, "%d.%d %s", value / EQ_USER_DIVISOR, value % EQ_USER_DIVISOR, unit);
131}
132
133static void eq_precut_format(char* buffer, int buffer_size, int value, const char* unit)
134{
135 snprintf(buffer, buffer_size, "%s%d.%d %s", value == 0 ? " " : "-",
136 value / EQ_USER_DIVISOR, value % EQ_USER_DIVISOR, unit);
137}
138
139/*
140 * Settings functions
141 */
142
116static bool eq_enabled(void) 143static bool eq_enabled(void)
117{ 144{
118 int i; 145 int i;
119 146
120 bool result = set_bool(str(LANG_EQUALIZER_ENABLED), 147 bool result = set_bool(str(LANG_EQUALIZER_ENABLED),
121 &global_settings.eq_enabled); 148 &global_settings.eq_enabled);
122 149
150 dsp_eq_set(global_settings.eq_enabled, global_settings.eq_precut);
151
123 /* Update all bands */ 152 /* Update all bands */
124 for(i = 0; i < 5; i++) { 153 for(i = 0; i < 5; i++) {
125 dsp_eq_update_data(global_settings.eq_enabled, i); 154 dsp_eq_update_filter_coefs(i);
126 } 155 }
127 156
128 return result; 157 return result;
129} 158}
130 159
131static void eq_gain_format(char* buffer, int buffer_size, int value, const char* unit) 160static bool eq_precut(void)
132{ 161{
133 int v = abs(value); 162 bool result = set_int(str(LANG_EQUALIZER_PRECUT), str(LANG_UNIT_DB),
163 UNIT_DB, &global_settings.eq_precut, NULL, 5, 0, 240,
164 eq_precut_format);
134 165
135 snprintf(buffer, buffer_size, "%s%d.%d %s", value < 0 ? "-" : "", 166 dsp_eq_set(global_settings.eq_enabled, global_settings.eq_precut);
136 v / EQ_USER_DIVISOR, v % EQ_USER_DIVISOR, unit);
137}
138 167
139static void eq_q_format(char* buffer, int buffer_size, int value, const char* unit) 168 return result;
140{
141 snprintf(buffer, buffer_size, "%d.%d %s", value / EQ_USER_DIVISOR, value % EQ_USER_DIVISOR, unit);
142} 169}
143 170
144/* Possibly dodgy way of simplifying the code a bit. */ 171/* Possibly dodgy way of simplifying the code a bit. */
@@ -148,20 +175,20 @@ static void eq_q_format(char* buffer, int buffer_size, int value, const char* un
148#define eq_set_center(band) \ 175#define eq_set_center(band) \
149static bool eq_set_band ## band ## _center(void) \ 176static bool eq_set_band ## band ## _center(void) \
150{ \ 177{ \
151 bool result = set_int(str(LANG_EQUALIZER_BAND_CENTER), "Hertz", UNIT_HERTZ, \ 178 bool result = set_int(str(LANG_EQUALIZER_BAND_CENTER), "Hertz", \
152 &global_settings.eq_band ## band ## _cutoff, NULL, \ 179 UNIT_HERTZ, &global_settings.eq_band ## band ## _cutoff, NULL, \
153 EQ_CUTOFF_STEP, EQ_CUTOFF_MIN, EQ_CUTOFF_MAX, NULL); \ 180 EQ_CUTOFF_STEP, EQ_CUTOFF_MIN, EQ_CUTOFF_MAX, NULL); \
154 dsp_eq_update_data(global_settings.eq_enabled, band); \ 181 dsp_eq_update_filter_coefs(band); \
155 return result; \ 182 return result; \
156} 183}
157 184
158#define eq_set_cutoff(band) \ 185#define eq_set_cutoff(band) \
159static bool eq_set_band ## band ## _cutoff(void) \ 186static bool eq_set_band ## band ## _cutoff(void) \
160{ \ 187{ \
161 bool result = set_int(str(LANG_EQUALIZER_BAND_CUTOFF), "Hertz", UNIT_HERTZ, \ 188 bool result = set_int(str(LANG_EQUALIZER_BAND_CUTOFF), "Hertz", \
162 &global_settings.eq_band ## band ## _cutoff, NULL, \ 189 UNIT_HERTZ, &global_settings.eq_band ## band ## _cutoff, NULL, \
163 EQ_CUTOFF_STEP, EQ_CUTOFF_MIN, EQ_CUTOFF_MAX, NULL); \ 190 EQ_CUTOFF_STEP, EQ_CUTOFF_MIN, EQ_CUTOFF_MAX, NULL); \
164 dsp_eq_update_data(global_settings.eq_enabled, band); \ 191 dsp_eq_update_filter_coefs(band); \
165 return result; \ 192 return result; \
166} 193}
167 194
@@ -171,7 +198,7 @@ static bool eq_set_band ## band ## _q(void) \
171 bool result = set_int(str(LANG_EQUALIZER_BAND_Q), "Q", UNIT_INT, \ 198 bool result = set_int(str(LANG_EQUALIZER_BAND_Q), "Q", UNIT_INT, \
172 &global_settings.eq_band ## band ## _q, NULL, \ 199 &global_settings.eq_band ## band ## _q, NULL, \
173 EQ_Q_STEP, EQ_Q_MIN, EQ_Q_MAX, eq_q_format); \ 200 EQ_Q_STEP, EQ_Q_MIN, EQ_Q_MAX, eq_q_format); \
174 dsp_eq_update_data(global_settings.eq_enabled, band); \ 201 dsp_eq_update_filter_coefs(band); \
175 return result; \ 202 return result; \
176} 203}
177 204
@@ -181,7 +208,7 @@ static bool eq_set_band ## band ## _gain(void) \
181 bool result = set_int("Band " #band, str(LANG_UNIT_DB), UNIT_DB, \ 208 bool result = set_int("Band " #band, str(LANG_UNIT_DB), UNIT_DB, \
182 &global_settings.eq_band ## band ## _gain, NULL, \ 209 &global_settings.eq_band ## band ## _gain, NULL, \
183 EQ_GAIN_STEP, EQ_GAIN_MIN, EQ_GAIN_MAX, eq_gain_format); \ 210 EQ_GAIN_STEP, EQ_GAIN_MIN, EQ_GAIN_MAX, eq_gain_format); \
184 dsp_eq_update_data(global_settings.eq_enabled, band); \ 211 dsp_eq_update_filter_coefs(band); \
185 return result; \ 212 return result; \
186} 213}
187 214
@@ -666,7 +693,7 @@ bool eq_menu_graphical(void)
666 693
667 /* Update the filter if the user changed something */ 694 /* Update the filter if the user changed something */
668 if (has_changed) { 695 if (has_changed) {
669 dsp_eq_update_data(global_settings.eq_enabled, current_band); 696 dsp_eq_update_filter_coefs(current_band);
670 has_changed = false; 697 has_changed = false;
671 } 698 }
672 } 699 }
@@ -706,6 +733,7 @@ static bool eq_save_preset(void)
706 733
707 /* TODO: Should we really do this? */ 734 /* TODO: Should we really do this? */
708 fdprintf(fd, "eq enabled: on\r\n"); 735 fdprintf(fd, "eq enabled: on\r\n");
736 fdprintf(fd, "eq precut: %d\r\n", global_settings.eq_precut);
709 737
710 setting = &global_settings.eq_band0_cutoff; 738 setting = &global_settings.eq_band0_cutoff;
711 739
@@ -737,6 +765,7 @@ bool eq_menu(void)
737 static const struct menu_item items[] = { 765 static const struct menu_item items[] = {
738 { ID2P(LANG_EQUALIZER_ENABLED), eq_enabled }, 766 { ID2P(LANG_EQUALIZER_ENABLED), eq_enabled },
739 { ID2P(LANG_EQUALIZER_GRAPHICAL), eq_menu_graphical }, 767 { ID2P(LANG_EQUALIZER_GRAPHICAL), eq_menu_graphical },
768 { ID2P(LANG_EQUALIZER_PRECUT), eq_precut },
740 { ID2P(LANG_EQUALIZER_GAIN), eq_gain_menu }, 769 { ID2P(LANG_EQUALIZER_GAIN), eq_gain_menu },
741 { ID2P(LANG_EQUALIZER_ADVANCED), eq_advanced_menu }, 770 { ID2P(LANG_EQUALIZER_ADVANCED), eq_advanced_menu },
742 { ID2P(LANG_EQUALIZER_SAVE), eq_save_preset }, 771 { ID2P(LANG_EQUALIZER_SAVE), eq_save_preset },
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 9923fa9caf..c239b9cdd3 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -3880,3 +3880,10 @@ desc: in tag cache settings
3880eng: "Updating in background" 3880eng: "Updating in background"
3881voice: "Updating in background" 3881voice: "Updating in background"
3882new: 3882new:
3883
3884id: LANG_EQUALIZER_PRECUT
3885desc: in eq settings
3886eng: "Precut"
3887voice: "Pre-cut"
3888new:
3889
diff --git a/apps/settings.c b/apps/settings.c
index 6fe9665086..5552eaa70c 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -570,6 +570,10 @@ static const struct bit_entry hd_bits[] =
570 {1, S_O(tagcache_ram), 0, "tagcache_ram", off_on }, 570 {1, S_O(tagcache_ram), 0, "tagcache_ram", off_on },
571#endif 571#endif
572 572
573#if (CONFIG_CODEC == SWCODEC)
574 {8, S_O(eq_precut), 0, "eq precut", NULL },
575#endif
576
573 /* If values are just added to the end, no need to bump the version. */ 577 /* If values are just added to the end, no need to bump the version. */
574 /* new stuff to be added at the end */ 578 /* new stuff to be added at the end */
575 579
@@ -1125,10 +1129,11 @@ void settings_apply(void)
1125 audio_set_crossfade(global_settings.crossfade); 1129 audio_set_crossfade(global_settings.crossfade);
1126 dsp_set_replaygain(true); 1130 dsp_set_replaygain(true);
1127 dsp_set_crossfeed(global_settings.crossfeed); 1131 dsp_set_crossfeed(global_settings.crossfeed);
1128 1132
1133 dsp_eq_set(global_settings.eq_enabled, global_settings.eq_precut);
1129 /* Update all EQ bands */ 1134 /* Update all EQ bands */
1130 for(i = 0; i < 5; i++) { 1135 for(i = 0; i < 5; i++) {
1131 dsp_eq_update_data(global_settings.eq_enabled, i); 1136 dsp_eq_update_filter_coefs(i);
1132 } 1137 }
1133#endif 1138#endif
1134 1139
diff --git a/apps/settings.h b/apps/settings.h
index fb8e11ffde..3616434642 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -432,34 +432,35 @@ struct user_settings
432 432
433#if CONFIG_CODEC == SWCODEC 433#if CONFIG_CODEC == SWCODEC
434 bool eq_enabled; /* Enable equalizer */ 434 bool eq_enabled; /* Enable equalizer */
435 435 unsigned int eq_precut; /* dB */
436
436 /* Order is important here, must be cutoff, q, then gain for each band. 437 /* Order is important here, must be cutoff, q, then gain for each band.
437 See dsp_eq_update_data in dsp.c for why. */ 438 See dsp_eq_update_data in dsp.c for why. */
438 439
439 /* Band 0 settings */ 440 /* Band 0 settings */
440 int eq_band0_cutoff; /* Hz */ 441 int eq_band0_cutoff; /* Hz */
441 int eq_band0_q; 442 int eq_band0_q;
442 int eq_band0_gain; /* +/- dB */ 443 int eq_band0_gain; /* +/- dB */
443 444
444 /* Band 1 settings */ 445 /* Band 1 settings */
445 int eq_band1_cutoff; /* Hz */ 446 int eq_band1_cutoff; /* Hz */
446 int eq_band1_q; 447 int eq_band1_q;
447 int eq_band1_gain; /* +/- dB */ 448 int eq_band1_gain; /* +/- dB */
448 449
449 /* Band 2 settings */ 450 /* Band 2 settings */
450 int eq_band2_cutoff; /* Hz */ 451 int eq_band2_cutoff; /* Hz */
451 int eq_band2_q; 452 int eq_band2_q;
452 int eq_band2_gain; /* +/- dB */ 453 int eq_band2_gain; /* +/- dB */
453 454
454 /* Band 3 settings */ 455 /* Band 3 settings */
455 int eq_band3_cutoff; /* Hz */ 456 int eq_band3_cutoff; /* Hz */
456 int eq_band3_q; 457 int eq_band3_q;
457 int eq_band3_gain; /* +/- dB */ 458 int eq_band3_gain; /* +/- dB */
458 459
459 /* Band 4 settings */ 460 /* Band 4 settings */
460 int eq_band4_cutoff; /* Hz */ 461 int eq_band4_cutoff; /* Hz */
461 int eq_band4_q; 462 int eq_band4_q;
462 int eq_band4_gain; /* +/- dB */ 463 int eq_band4_gain; /* +/- dB */
463#endif 464#endif
464 465
465#ifdef HAVE_LCD_COLOR 466#ifdef HAVE_LCD_COLOR
@@ -472,7 +473,7 @@ struct user_settings
472 int bg_color; /* background color native format */ 473 int bg_color; /* background color native format */
473 int fg_color; /* foreground color native format */ 474 int fg_color; /* foreground color native format */
474#endif 475#endif
475 bool party_mode; /* party mode - unstoppable music */ 476 bool party_mode; /* party mode - unstoppable music */
476 477
477#ifdef CONFIG_BACKLIGHT 478#ifdef CONFIG_BACKLIGHT
478 bool bl_filter_first_keypress; /* filter first keypress when dark? */ 479 bool bl_filter_first_keypress; /* filter first keypress when dark? */