summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/SOURCES3
-rw-r--r--apps/lang/english.lang137
-rw-r--r--apps/menus/audiohw_eq_menu.c244
-rw-r--r--apps/menus/exported_menus.h3
-rw-r--r--apps/menus/sound_menu.c50
-rw-r--r--apps/plugin.c3
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c35
-rw-r--r--apps/settings.c35
-rw-r--r--apps/settings.h21
-rw-r--r--apps/settings_list.c100
-rw-r--r--firmware/drivers/audio/wm8978.c122
-rw-r--r--firmware/export/audiohw.h252
-rw-r--r--firmware/export/config/gigabeats.h3
-rw-r--r--firmware/export/sound.h62
-rw-r--r--firmware/export/wm8978.h13
-rw-r--r--firmware/sound.c347
-rw-r--r--uisimulator/sdl/sound.c17
18 files changed, 1389 insertions, 65 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 2642fa16b1..2bd4018751 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -16,6 +16,9 @@ menus/menu_common.c
16menus/display_menu.c 16menus/display_menu.c
17menus/theme_menu.c 17menus/theme_menu.c
18#if CONFIG_CODEC == SWCODEC 18#if CONFIG_CODEC == SWCODEC
19#ifdef HAVE_WM8978
20menus/audiohw_eq_menu.c
21#endif
19menus/eq_menu.c 22menus/eq_menu.c
20buffering.c 23buffering.c
21voice_thread.c 24voice_thread.c
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index c079a4affd..4a4fb2c73a 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -13595,3 +13595,140 @@
13595 radio: "" 13595 radio: ""
13596 </voice> 13596 </voice>
13597</phrase> 13597</phrase>
13598<phrase>
13599 id: LANG_HW_EQ_TONE_CONTROLS
13600 desc: in sound_menu, hardware equalizer tone controls
13601 user: core
13602 <source>
13603 *: none
13604 gigabeats: "Tone Controls"
13605 </source>
13606 <dest>
13607 *: none
13608 gigabeats: "Tone Controls"
13609 </dest>
13610 <voice>
13611 *: none
13612 gigabeats: "Tone Controls"
13613 </voice>
13614</phrase>
13615<phrase>
13616 id: LANG_HW_EQ_TONE_CONTROLS_ADVANCED
13617 desc: in sound_menu, advanced settings for hardware equalizer tone controls
13618 user: core
13619 <source>
13620 *: none
13621 gigabeats: "Advanced Tone Control Settings"
13622 </source>
13623 <dest>
13624 *: none
13625 gigabeats: "Advanced Tone Control Settings"
13626 </dest>
13627 <voice>
13628 *: none
13629 gigabeats: "Advanced Tone Control Settings"
13630 </voice>
13631</phrase>
13632<phrase>
13633 id: LANG_HW_EQ_GAIN
13634 desc: in sound_menu, hardware equalizer tone controls filter gain
13635 user: core
13636 <source>
13637 *: none
13638 gigabeats: "Band %d Gain"
13639 </source>
13640 <dest>
13641 *: none
13642 gigabeats: "Band %d Gain"
13643 </dest>
13644 <voice>
13645 *: none
13646 gigabeats: "Band Gain"
13647 </voice>
13648</phrase>
13649<phrase>
13650 id: LANG_HW_EQ_FREQUENCY
13651 desc: in sound_menu, hardware equalizer tone controls shelf filter cutoff frequency
13652 user: core
13653 <source>
13654 *: none
13655 gigabeats: "Band %d Frequency"
13656 </source>
13657 <dest>
13658 *: none
13659 gigabeats: "Band %d Frequency"
13660 </dest>
13661 <voice>
13662 *: none
13663 gigabeats: "Band Frequency"
13664 </voice>
13665</phrase>
13666<phrase>
13667 id: LANG_HW_EQ_WIDTH
13668 desc: in sound_menu, hardware equalizer tone controls peak bandwith setting
13669 user: core
13670 <source>
13671 *: none
13672 gigabeats: "Band %d Width"
13673 </source>
13674 <dest>
13675 *: none
13676 gigabeats: "Band %d Width"
13677 </dest>
13678 <voice>
13679 *: none
13680 gigabeats: "Band Width"
13681 </voice>
13682</phrase>
13683<phrase>
13684 id: LANG_HW_EQ_WIDTH_NARROW
13685 desc: in sound_menu, hardware equalizer tone controls narrow bandwith setting
13686 user: core
13687 <source>
13688 *: none
13689 gigabeats: "Narrow"
13690 </source>
13691 <dest>
13692 *: none
13693 gigabeats: "Narrow"
13694 </dest>
13695 <voice>
13696 *: none
13697 gigabeats: "Narrow"
13698 </voice>
13699</phrase>
13700<phrase>
13701 id: LANG_HW_EQ_WIDTH_WIDE
13702 desc: in sound_menu, hardware equalizer tone controls wide bandwidth setting
13703 user: core
13704 <source>
13705 *: none
13706 gigabeats: "Wide"
13707 </source>
13708 <dest>
13709 *: none
13710 gigabeats: "Wide"
13711 </dest>
13712 <voice>
13713 *: none
13714 gigabeats: "Wide"
13715 </voice>
13716</phrase>
13717<phrase>
13718 id: LANG_DEPTH_3D
13719 desc: in sound_menu, amount of 3D enhancement effect
13720 user: core
13721 <source>
13722 *: none
13723 gigabeats: "3-D Enhancement"
13724 </source>
13725 <dest>
13726 *: none
13727 gigabeats: "3-D Enhancement"
13728 </dest>
13729 <voice>
13730 *: none
13731 gigabeats: "3-D Enhancement"
13732 </voice>
13733</phrase>
13734
diff --git a/apps/menus/audiohw_eq_menu.c b/apps/menus/audiohw_eq_menu.c
new file mode 100644
index 0000000000..1027d6a0b8
--- /dev/null
+++ b/apps/menus/audiohw_eq_menu.c
@@ -0,0 +1,244 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include "config.h"
23#include "sound.h"
24#include "settings.h"
25#include "lang.h"
26#include "menu.h"
27#include "talk.h"
28
29#define HW_EQ_IDX(band, setting) ((void *)(((setting) << 8) | (band)))
30#define HW_EQ_IDX_BAND(data) ((uint8_t)(uintptr_t)(data))
31#define HW_EQ_IDX_SETTING(data) ((uint8_t)((uintptr_t)(data) >> 8))
32
33static unsigned short hw_eq_setting_lang_ids[AUDIOHW_EQ_SETTING_NUM] =
34{
35 LANG_HW_EQ_GAIN,
36#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
37 LANG_HW_EQ_FREQUENCY,
38#endif
39#ifdef AUDIOHW_HAVE_EQ_WIDTH
40 LANG_HW_EQ_WIDTH,
41#endif
42};
43
44static char * hw_eq_get_name(int selected_item, void * data, char *buffer)
45{
46 snprintf(buffer, MAX_PATH,
47 str(hw_eq_setting_lang_ids[HW_EQ_IDX_SETTING(data)]),
48 HW_EQ_IDX_BAND(data) + 1);
49 return buffer;
50 (void)selected_item;
51}
52
53static int hw_eq_speak_item(int selected_item, void * data)
54{
55 talk_id(hw_eq_setting_lang_ids[HW_EQ_IDX_SETTING(data)], false);
56 talk_number(HW_EQ_IDX_BAND(data) + 1, true);
57 return 0;
58 (void)selected_item;
59}
60
61static int hw_eq_do_band_setting(void *param)
62{
63 int band = HW_EQ_IDX_BAND(param);
64 int setting = HW_EQ_IDX_SETTING(param);
65 char desc[MAX_PATH];
66 struct menu_callback_with_desc cbwdesc =
67 {
68 .menu_callback = NULL,
69 .desc = hw_eq_get_name(0, param, desc),
70 .icon_id = Icon_NOICON
71 };
72 struct menu_item_ex item =
73 {
74 .flags = MT_SETTING_W_TEXT | MENU_HAS_DESC,
75 { .variable = (void*)(&global_settings.hw_eq_bands[band].gain + setting) },
76 { .callback_and_desc = &cbwdesc }
77 };
78 do_setting_from_menu(&item, NULL);
79 return 0;
80}
81
82MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_gain, MENU_FUNC_USEPARAM,
83 hw_eq_do_band_setting,
84 HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_GAIN),
85 hw_eq_get_name, hw_eq_speak_item,
86 HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_GAIN),
87 NULL, Icon_Menu_setting);
88#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
89MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_frequency, MENU_FUNC_USEPARAM,
90 hw_eq_do_band_setting,
91 HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_FREQUENCY),
92 hw_eq_get_name, hw_eq_speak_item,
93 HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_FREQUENCY),
94 NULL, Icon_NOICON);
95#endif
96#ifdef AUDIOHW_HAVE_EQ_BAND2
97MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_gain, MENU_FUNC_USEPARAM,
98 hw_eq_do_band_setting,
99 HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_GAIN),
100 hw_eq_get_name, hw_eq_speak_item,
101 HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_GAIN),
102 NULL, Icon_Menu_setting);
103#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
104MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_frequency, MENU_FUNC_USEPARAM,
105 hw_eq_do_band_setting,
106 HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_FREQUENCY),
107 hw_eq_get_name, hw_eq_speak_item,
108 HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_FREQUENCY),
109 NULL, Icon_NOICON);
110#endif
111#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
112MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_width, MENU_FUNC_USEPARAM,
113 hw_eq_do_band_setting,
114 HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_WIDTH),
115 hw_eq_get_name, hw_eq_speak_item,
116 HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_WIDTH),
117 NULL, Icon_NOICON);
118#endif
119#endif /* AUDIOHW_HAVE_EQ_BAND2 */
120#ifdef AUDIOHW_HAVE_EQ_BAND3
121MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_gain, MENU_FUNC_USEPARAM,
122 hw_eq_do_band_setting,
123 HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_GAIN),
124 hw_eq_get_name, hw_eq_speak_item,
125 HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_GAIN),
126 NULL, Icon_Menu_setting);
127#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
128MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_frequency, MENU_FUNC_USEPARAM,
129 hw_eq_do_band_setting,
130 HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_FREQUENCY),
131 hw_eq_get_name, hw_eq_speak_item,
132 HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_FREQUENCY),
133 NULL, Icon_NOICON);
134#endif
135#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
136MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_width, MENU_FUNC_USEPARAM,
137 hw_eq_do_band_setting,
138 HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_WIDTH),
139 hw_eq_get_name, hw_eq_speak_item,
140 HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_WIDTH),
141 NULL, Icon_NOICON);
142#endif
143#endif /* AUDIOHW_HAVE_EQ_BAND3 */
144#ifdef AUDIOHW_HAVE_EQ_BAND4
145MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_gain, MENU_FUNC_USEPARAM,
146 hw_eq_do_band_setting,
147 HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_GAIN),
148 hw_eq_get_name, hw_eq_speak_item,
149 HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_GAIN),
150 NULL, Icon_Menu_setting);
151#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
152MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_frequency, MENU_FUNC_USEPARAM,
153 hw_eq_do_band_setting,
154 HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_FREQUENCY),
155 hw_eq_get_name, hw_eq_speak_item,
156 HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_FREQUENCY),
157 NULL, Icon_NOICON);
158#endif
159#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
160MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_width, MENU_FUNC_USEPARAM,
161 hw_eq_do_band_setting,
162 HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_WIDTH),
163 hw_eq_get_name, hw_eq_speak_item,
164 HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_WIDTH),
165 NULL, Icon_NOICON);
166#endif
167#endif /* AUDIOHW_HAVE_EQ_BAND4 */
168#ifdef AUDIOHW_HAVE_EQ_BAND5
169MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_gain, MENU_FUNC_USEPARAM,
170 hw_eq_do_band_setting,
171 HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_GAIN),
172 hw_eq_get_name, hw_eq_speak_item,
173 HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_GAIN),
174 NULL, Icon_Menu_setting);
175#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
176MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_frequency, MENU_FUNC_USEPARAM,
177 hw_eq_do_band_setting,
178 HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_FREQUENCY),
179 hw_eq_get_name, hw_eq_speak_item,
180 HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_FREQUENCY),
181 NULL, Icon_NOICON);
182#endif
183#endif /* AUDIOHW_HAVE_EQ_BAND5 */
184
185/* Submenu for multiple "tone controls". Gain + all advanced settings. */
186MAKE_MENU(hardware_eq_tone_controls_advanced, ID2P(LANG_HW_EQ_TONE_CONTROLS_ADVANCED),
187 NULL, Icon_NOICON
188 ,&hw_eq_band1_gain
189#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
190 ,&hw_eq_band1_frequency
191#endif
192#ifdef AUDIOHW_HAVE_EQ_BAND2
193 ,&hw_eq_band2_gain
194#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
195 ,&hw_eq_band2_frequency
196#endif
197#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
198 ,&hw_eq_band2_width
199#endif
200#endif /* AUDIOHW_HAVE_EQ_BAND2 */
201#ifdef AUDIOHW_HAVE_EQ_BAND3
202 ,&hw_eq_band3_gain
203#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
204 ,&hw_eq_band3_frequency
205#endif
206#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
207 ,&hw_eq_band3_width
208#endif
209#endif /* AUDIOHW_HAVE_EQ_BAND3 */
210#ifdef AUDIOHW_HAVE_EQ_BAND4
211 ,&hw_eq_band4_gain
212#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
213 ,&hw_eq_band4_frequency
214#endif
215#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
216 ,&hw_eq_band4_width
217#endif
218#endif /* AUDIOHW_HAVE_EQ_BAND4 */
219#ifdef AUDIOHW_HAVE_EQ_BAND5
220 ,&hw_eq_band5_gain
221#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
222 ,&hw_eq_band5_frequency
223#endif
224#endif /* AUDIOHW_HAVE_EQ_BAND5 */
225 );
226/* Shows only the gains + advanced settings submenu */
227MAKE_MENU(audiohw_eq_tone_controls, ID2P(LANG_HW_EQ_TONE_CONTROLS),
228 NULL, Icon_NOICON
229 ,&hw_eq_band1_gain
230#ifdef AUDIOHW_HAVE_EQ_BAND2
231 ,&hw_eq_band2_gain
232#endif
233#ifdef AUDIOHW_HAVE_EQ_BAND3
234 ,&hw_eq_band3_gain
235#endif
236#ifdef AUDIOHW_HAVE_EQ_BAND4
237 ,&hw_eq_band4_gain
238#endif
239#ifdef AUDIOHW_HAVE_EQ_BAND5
240 ,&hw_eq_band5_gain
241#endif
242 ,&hardware_eq_tone_controls_advanced
243 );
244
diff --git a/apps/menus/exported_menus.h b/apps/menus/exported_menus.h
index 9fb39cbf8f..37b5ff31d0 100644
--- a/apps/menus/exported_menus.h
+++ b/apps/menus/exported_menus.h
@@ -40,6 +40,9 @@ extern const struct menu_item_ex
40 playlist_settings, /* playlist_menu.c */ 40 playlist_settings, /* playlist_menu.c */
41 playlist_options, /* playlist_menu.c */ 41 playlist_options, /* playlist_menu.c */
42 equalizer_menu, /* eq_menu.c */ 42 equalizer_menu, /* eq_menu.c */
43#ifdef AUDIOHW_HAVE_EQ
44 audiohw_eq_tone_controls, /* audiohw_eq_menu.c */
45#endif
43 info_menu, /* info_menu.c */ 46 info_menu, /* info_menu.c */
44 theme_menu; /* theme_menu.c */ 47 theme_menu; /* theme_menu.c */
45 48
diff --git a/apps/menus/sound_menu.c b/apps/menus/sound_menu.c
index 0ce860cb7c..066b1dabae 100644
--- a/apps/menus/sound_menu.c
+++ b/apps/menus/sound_menu.c
@@ -23,6 +23,7 @@
23#include <stddef.h> 23#include <stddef.h>
24#include <limits.h> 24#include <limits.h>
25#include "config.h" 25#include "config.h"
26#include "sound.h"
26#include "lang.h" 27#include "lang.h"
27#include "action.h" 28#include "action.h"
28#include "settings.h" 29#include "settings.h"
@@ -38,6 +39,7 @@
38/***********************************/ 39/***********************************/
39/* SOUND MENU */ 40/* SOUND MENU */
40MENUITEM_SETTING(volume, &global_settings.volume, NULL); 41MENUITEM_SETTING(volume, &global_settings.volume, NULL);
42#ifdef AUDIOHW_HAVE_BASS
41MENUITEM_SETTING(bass, &global_settings.bass, 43MENUITEM_SETTING(bass, &global_settings.bass,
42#ifdef HAVE_SW_TONE_CONTROLS 44#ifdef HAVE_SW_TONE_CONTROLS
43 lowlatency_callback 45 lowlatency_callback
@@ -45,9 +47,14 @@ MENUITEM_SETTING(bass, &global_settings.bass,
45 NULL 47 NULL
46#endif 48#endif
47); 49);
48#ifdef HAVE_WM8758 50
49MENUITEM_SETTING(bass_cutoff, &global_settings.bass_cutoff, NULL); 51#ifdef AUDIOHW_HAVE_BASS_CUTOFF
52MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL);
50#endif 53#endif
54#endif /* AUDIOHW_HAVE_BASS */
55
56
57#ifdef AUDIOHW_HAVE_TREBLE
51MENUITEM_SETTING(treble, &global_settings.treble, 58MENUITEM_SETTING(treble, &global_settings.treble,
52#ifdef HAVE_SW_TONE_CONTROLS 59#ifdef HAVE_SW_TONE_CONTROLS
53 lowlatency_callback 60 lowlatency_callback
@@ -55,9 +62,13 @@ MENUITEM_SETTING(treble, &global_settings.treble,
55 NULL 62 NULL
56#endif 63#endif
57); 64);
58#ifdef HAVE_WM8758 65
66#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
59MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL); 67MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL);
60#endif 68#endif
69#endif /* AUDIOHW_HAVE_TREBLE */
70
71
61MENUITEM_SETTING(balance, &global_settings.balance, NULL); 72MENUITEM_SETTING(balance, &global_settings.balance, NULL);
62MENUITEM_SETTING(channel_config, &global_settings.channel_config, 73MENUITEM_SETTING(channel_config, &global_settings.channel_config,
63#if CONFIG_CODEC == SWCODEC 74#if CONFIG_CODEC == SWCODEC
@@ -74,6 +85,10 @@ MENUITEM_SETTING(stereo_width, &global_settings.stereo_width,
74#endif 85#endif
75); 86);
76 87
88#ifdef AUDIOHW_HAVE_DEPTH_3D
89MENUITEM_SETTING(depth_3d, &global_settings.depth_3d, NULL);
90#endif
91
77#if CONFIG_CODEC == SWCODEC 92#if CONFIG_CODEC == SWCODEC
78 /* Crossfeed Submenu */ 93 /* Crossfeed Submenu */
79 MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, lowlatency_callback); 94 MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, lowlatency_callback);
@@ -137,19 +152,30 @@ static int timestretch_callback(int action,const struct menu_item_ex *this_item)
137 MENUITEM_SETTING(speaker_enabled, &global_settings.speaker_enabled, NULL); 152 MENUITEM_SETTING(speaker_enabled, &global_settings.speaker_enabled, NULL);
138#endif 153#endif
139 154
140 155#ifdef AUDIOHW_HAVE_EQ
156#endif /* AUDIOHW_HAVE_EQ */
141 157
142MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio, 158MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio,
143 &volume, 159 &volume
144 &bass, 160#ifdef AUDIOHW_HAVE_BASS
145#ifdef HAVE_WM8758 161 ,&bass
146 &bass_cutoff, 162#endif
163#ifdef AUDIOHW_HAVE_BASS_CUTOFF
164 ,&bass_cutoff
165#endif
166#ifdef AUDIOHW_HAVE_TREBLE
167 ,&treble
168#endif
169#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
170 ,&treble_cutoff
171#endif
172#ifdef AUDIOHW_HAVE_EQ
173 ,&audiohw_eq_tone_controls
147#endif 174#endif
148 &treble, 175 ,&balance,&channel_config,&stereo_width
149#ifdef HAVE_WM8758 176#ifdef AUDIOHW_HAVE_DEPTH_3D
150 &treble_cutoff, 177 ,&depth_3d
151#endif 178#endif
152 &balance,&channel_config,&stereo_width
153#if CONFIG_CODEC == SWCODEC 179#if CONFIG_CODEC == SWCODEC
154 ,&crossfeed_menu, &equalizer_menu, &dithering_enabled 180 ,&crossfeed_menu, &equalizer_menu, &dithering_enabled
155 ,&timestretch_enabled 181 ,&timestretch_enabled
diff --git a/apps/plugin.c b/apps/plugin.c
index b60e2d6768..90380a0039 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -721,6 +721,9 @@ static const struct plugin_api rockbox_api = {
721 round_value_to_list32, 721 round_value_to_list32,
722#endif 722#endif
723 723
724#ifdef AUDIOHW_HAVE_EQ
725 sound_enum_hw_eq_band_setting,
726#endif
724}; 727};
725 728
726int plugin_load(const char* plugin, const void* parameter) 729int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 5aaa6380b7..108a283596 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -142,7 +142,7 @@ void* plugin_get_buffer(size_t *buffer_size);
142#define PLUGIN_MAGIC 0x526F634B /* RocK */ 142#define PLUGIN_MAGIC 0x526F634B /* RocK */
143 143
144/* increase this every time the api struct changes */ 144/* increase this every time the api struct changes */
145#define PLUGIN_API_VERSION 184 145#define PLUGIN_API_VERSION 185
146 146
147/* update this to latest version if a change to the api struct breaks 147/* update this to latest version if a change to the api struct breaks
148 backwards compatibility (and please take the opportunity to sort in any 148 backwards compatibility (and please take the opportunity to sort in any
@@ -884,6 +884,11 @@ int (*round_value_to_list32)(unsigned long value,
884 int count, 884 int count,
885 bool signd); 885 bool signd);
886#endif 886#endif
887
888#ifdef AUDIOHW_HAVE_EQ
889 int (*sound_enum_hw_eq_band_setting)(unsigned int band,
890 unsigned int band_setting);
891#endif /* AUDIOHW_HAVE_EQ */
887}; 892};
888 893
889/* plugin header */ 894/* plugin header */
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 6c8a2b8e3e..1ac2476b25 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -403,18 +403,53 @@ static void sync_audio_setting(int setting, bool global)
403 switch (setting) 403 switch (setting)
404 { 404 {
405 case MPEG_AUDIO_TONE_CONTROLS: 405 case MPEG_AUDIO_TONE_CONTROLS:
406 #if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE)
406 if (global || settings.tone_controls) 407 if (global || settings.tone_controls)
407 { 408 {
409 #ifdef AUDIOHW_HAVE_BASS
408 val0 = rb->global_settings->bass; 410 val0 = rb->global_settings->bass;
411 #endif
412 #ifdef AUDIOHW_HAVE_TREBLE
409 val1 = rb->global_settings->treble; 413 val1 = rb->global_settings->treble;
414 #endif
410 } 415 }
411 else 416 else
412 { 417 {
418 #ifdef AUDIOHW_HAVE_BASS
413 val0 = rb->sound_default(SOUND_BASS); 419 val0 = rb->sound_default(SOUND_BASS);
420 #endif
421 #ifdef AUDIOHW_HAVE_TREBLE
414 val1 = rb->sound_default(SOUND_TREBLE); 422 val1 = rb->sound_default(SOUND_TREBLE);
423 #endif
415 } 424 }
425 #ifdef AUDIOHW_HAVE_BASS
416 rb->sound_set(SOUND_BASS, val0); 426 rb->sound_set(SOUND_BASS, val0);
427 #endif
428 #ifdef AUDIOHW_HAVE_TREBLE
417 rb->sound_set(SOUND_TREBLE, val1); 429 rb->sound_set(SOUND_TREBLE, val1);
430 #endif
431 #endif /* AUDIOHW_HAVE_BASS || AUDIOHW_HAVE_TREBLE */
432
433 #ifdef AUDIOHW_HAVE_EQ
434 for (val1 = 0;; val1++)
435 {
436 int setting = rb->sound_enum_hw_eq_band_setting(val1, AUDIOHW_EQ_GAIN);
437
438 if (setting == -1)
439 break;
440
441 if (global || settings.tone_controls)
442 {
443 val0 = rb->global_settings->hw_eq_bands[val1].gain;
444 }
445 else
446 {
447 val0 = rb->sound_default(setting);
448 }
449
450 rb->sound_set(setting, val0);
451 }
452 #endif /* AUDIOHW_HAVE_EQ */
418 break; 453 break;
419 454
420 case MPEG_AUDIO_CHANNEL_MODES: 455 case MPEG_AUDIO_CHANNEL_MODES:
diff --git a/apps/settings.c b/apps/settings.c
index 4901957263..6349372326 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -27,6 +27,7 @@
27#include "config.h" 27#include "config.h"
28#include "action.h" 28#include "action.h"
29#include "crc32.h" 29#include "crc32.h"
30#include "sound.h"
30#include "settings.h" 31#include "settings.h"
31#include "debug.h" 32#include "debug.h"
32#include "usb.h" 33#include "usb.h"
@@ -55,7 +56,6 @@
55#include "powermgmt.h" 56#include "powermgmt.h"
56#include "keyboard.h" 57#include "keyboard.h"
57#include "version.h" 58#include "version.h"
58#include "sound.h"
59#include "rbunicode.h" 59#include "rbunicode.h"
60#include "dircache.h" 60#include "dircache.h"
61#include "splash.h" 61#include "splash.h"
@@ -718,8 +718,12 @@ void sound_settings_apply(void)
718#if CONFIG_CODEC == SWCODEC 718#if CONFIG_CODEC == SWCODEC
719 sound_set_dsp_callback(dsp_callback); 719 sound_set_dsp_callback(dsp_callback);
720#endif 720#endif
721#ifdef AUDIOHW_HAVE_BASS
721 sound_set(SOUND_BASS, global_settings.bass); 722 sound_set(SOUND_BASS, global_settings.bass);
723#endif
724#ifdef AUDIOHW_HAVE_TREBLE
722 sound_set(SOUND_TREBLE, global_settings.treble); 725 sound_set(SOUND_TREBLE, global_settings.treble);
726#endif
723 sound_set(SOUND_BALANCE, global_settings.balance); 727 sound_set(SOUND_BALANCE, global_settings.balance);
724 sound_set(SOUND_VOLUME, global_settings.volume); 728 sound_set(SOUND_VOLUME, global_settings.volume);
725 sound_set(SOUND_CHANNELS, global_settings.channel_config); 729 sound_set(SOUND_CHANNELS, global_settings.channel_config);
@@ -734,13 +738,36 @@ void sound_settings_apply(void)
734 sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable); 738 sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable);
735 sound_set(SOUND_SUPERBASS, global_settings.superbass); 739 sound_set(SOUND_SUPERBASS, global_settings.superbass);
736#endif 740#endif
737 741#ifdef AUDIOHW_HAVE_BASS_CUTOFF
738#ifdef HAVE_WM8758
739 sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff); 742 sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff);
743#endif
744#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
740 sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff); 745 sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff);
741#endif 746#endif
742} 747#ifdef AUDIOHW_HAVE_DEPTH_3D
748 sound_set(SOUND_DEPTH_3D, global_settings.depth_3d);
749#endif
750#ifdef AUDIOHW_HAVE_EQ
751 int b;
743 752
753 for (b = 0; b < AUDIOHW_EQ_BAND_NUM; b++)
754 {
755 int setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_GAIN);
756 sound_set(setting, global_settings.hw_eq_bands[b].gain);
757
758#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
759 setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_FREQUENCY);
760 if (setting != -1)
761 sound_set(setting, global_settings.hw_eq_bands[b].frequency);
762#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */
763#ifdef AUDIOHW_HAVE_EQ_WIDTH
764 setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_WIDTH);
765 if (setting != -1)
766 sound_set(setting, global_settings.hw_eq_bands[b].width);
767#endif /* AUDIOHW_HAVE_EQ_WIDTH */
768 }
769#endif
770}
744 771
745void settings_apply(bool read_disk) 772void settings_apply(bool read_disk)
746{ 773{
diff --git a/apps/settings.h b/apps/settings.h
index 2fdff9918a..c8e8d642a2 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -336,7 +336,7 @@ struct user_settings
336 bool superbass; /* true/false */ 336 bool superbass; /* true/false */
337#endif 337#endif
338 338
339#ifdef HAVE_WM8758 339#if defined(HAVE_WM8758) || defined(HAVE_WM8978)
340 int bass_cutoff; 340 int bass_cutoff;
341 int treble_cutoff; 341 int treble_cutoff;
342#endif 342#endif
@@ -831,6 +831,25 @@ struct user_settings
831 /* When resuming playback (after a stop), rewind this number of seconds */ 831 /* When resuming playback (after a stop), rewind this number of seconds */
832 int resume_rewind; 832 int resume_rewind;
833#endif 833#endif
834
835#ifdef AUDIOHW_HAVE_DEPTH_3D
836 int depth_3d;
837#endif
838
839#ifdef AUDIOHW_HAVE_EQ
840 /** Hardware EQ tone controls **/
841 struct hw_eq_band
842 {
843 /* Maintain the order of members or sound_menu has to be changed */
844 int gain;
845#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
846 int frequency;
847#endif
848#ifdef AUDIOHW_HAVE_EQ_WIDTH
849 int width;
850#endif
851 } hw_eq_bands[AUDIOHW_EQ_BAND_NUM];
852#endif /* AUDIOHW_HAVE_EQ */
834}; 853};
835 854
836/** global variables **/ 855/** global variables **/
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 1bc783219f..d6f5f94f66 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -29,10 +29,10 @@
29#include "lcd.h" 29#include "lcd.h"
30#include "button.h" 30#include "button.h"
31#include "backlight.h" 31#include "backlight.h"
32#include "sound.h"
32#include "settings.h" 33#include "settings.h"
33#include "settings_list.h" 34#include "settings_list.h"
34#include "usb.h" 35#include "usb.h"
35#include "sound.h"
36#include "dsp.h" 36#include "dsp.h"
37#include "audio.h" 37#include "audio.h"
38#include "power.h" 38#include "power.h"
@@ -552,9 +552,97 @@ const struct settings_list settings[] = {
552 /* sound settings */ 552 /* sound settings */
553 SOUND_SETTING(F_NO_WRAP,volume, LANG_VOLUME, "volume", SOUND_VOLUME), 553 SOUND_SETTING(F_NO_WRAP,volume, LANG_VOLUME, "volume", SOUND_VOLUME),
554 SOUND_SETTING(0, balance, LANG_BALANCE, "balance", SOUND_BALANCE), 554 SOUND_SETTING(0, balance, LANG_BALANCE, "balance", SOUND_BALANCE),
555/* Tone controls */
556#ifdef AUDIOHW_HAVE_BASS
555 SOUND_SETTING(F_NO_WRAP,bass, LANG_BASS, "bass", SOUND_BASS), 557 SOUND_SETTING(F_NO_WRAP,bass, LANG_BASS, "bass", SOUND_BASS),
558#endif
559#ifdef AUDIOHW_HAVE_TREBLE
556 SOUND_SETTING(F_NO_WRAP,treble, LANG_TREBLE, "treble", SOUND_TREBLE), 560 SOUND_SETTING(F_NO_WRAP,treble, LANG_TREBLE, "treble", SOUND_TREBLE),
557 561#endif
562/* Hardware EQ tone controls */
563#ifdef AUDIOHW_HAVE_EQ
564/* Band gain is generic */
565 SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND1].gain,
566 LANG_HW_EQ_GAIN, "tone band1 gain", SOUND_EQ_BAND1_GAIN),
567#ifdef AUDIOHW_HAVE_EQ_BAND2
568 SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND2].gain,
569 LANG_HW_EQ_GAIN, "tone band2 gain", SOUND_EQ_BAND2_GAIN),
570#endif /* AUDIOHW_HAVE_EQ_BAND2 */
571#ifdef AUDIOHW_HAVE_EQ_BAND3
572 SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND3].gain,
573 LANG_HW_EQ_GAIN, "tone band3 gain", SOUND_EQ_BAND3_GAIN),
574#endif /* AUDIOHW_HAVE_EQ_BAND3 */
575#ifdef AUDIOHW_HAVE_EQ_BAND4
576 SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND4].gain,
577 LANG_HW_EQ_GAIN, "tone band4 gain", SOUND_EQ_BAND4_GAIN),
578#endif /* AUDIOHW_HAVE_EQ_BAND4 */
579#ifdef AUDIOHW_HAVE_EQ_BAND5
580 SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND5].gain,
581 LANG_HW_EQ_GAIN, "tone band5 gain", SOUND_EQ_BAND5_GAIN),
582#endif /* AUDIOHW_HAVE_EQ_BAND5 */
583#ifdef HAVE_WM8978
584 /* Frequencies vary with samplerate but at least the user has an idea
585 * about the bands and it will be correct with normal playback rates. */
586/* Band 1 */
587 STRINGCHOICE_SETTING(F_SOUNDSETTING,
588 hw_eq_bands[AUDIOHW_EQ_BAND1].frequency,
589 LANG_HW_EQ_FREQUENCY, 0,"tone band1 frequency",
590 "80 Hz,105 Hz,135 Hz,175 Hz",
591 sound_set_hw_eq_band1_frequency, 4,
592 TALK_ID(80, UNIT_HERTZ), TALK_ID(105, UNIT_HERTZ),
593 TALK_ID(135, UNIT_HERTZ), TALK_ID(175, UNIT_HERTZ)),
594/* Band 2 */
595 STRINGCHOICE_SETTING(F_SOUNDSETTING,
596 hw_eq_bands[AUDIOHW_EQ_BAND2].frequency,
597 LANG_HW_EQ_FREQUENCY, 0,"tone band2 frequency",
598 "230 Hz,300 Hz,385 Hz,500 Hz",
599 sound_set_hw_eq_band2_frequency, 4,
600 TALK_ID(230, UNIT_HERTZ), TALK_ID(300, UNIT_HERTZ),
601 TALK_ID(385, UNIT_HERTZ), TALK_ID(500, UNIT_HERTZ)),
602 CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[AUDIOHW_EQ_BAND2].width,
603 LANG_HW_EQ_WIDTH, 0, "tone band2 width", "narrow,wide",
604 sound_set_hw_eq_band2_width, 2,
605 ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)),
606/* Band 3 */
607 STRINGCHOICE_SETTING(F_SOUNDSETTING,
608 hw_eq_bands[AUDIOHW_EQ_BAND3].frequency,
609 LANG_HW_EQ_FREQUENCY, 0, "tone band3 frequency",
610 "650 Hz,850 Hz,1.1 kHz,1.4 kHz",
611 sound_set_hw_eq_band3_frequency, 4,
612 TALK_ID(650, UNIT_HERTZ), TALK_ID(850, UNIT_HERTZ),
613 TALK_ID_DECIMAL(11, 1, UNIT_KHZ),
614 TALK_ID_DECIMAL(14, 1, UNIT_KHZ)),
615 CHOICE_SETTING(F_SOUNDSETTING,hw_eq_bands[AUDIOHW_EQ_BAND3].width,
616 LANG_HW_EQ_WIDTH, 0, "tone band3 width", "narrow,wide",
617 sound_set_hw_eq_band3_width, 2,
618 ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)),
619/* Band 4 */
620 STRINGCHOICE_SETTING(F_SOUNDSETTING,
621 hw_eq_bands[AUDIOHW_EQ_BAND4].frequency,
622 LANG_HW_EQ_FREQUENCY, 0, "tone band4 frequency",
623 "1.8 kHz,2.4 kHz,3.2 kHz,4.1 kHz",
624 sound_set_hw_eq_band4_frequency, 4,
625 TALK_ID_DECIMAL(18, 1, UNIT_KHZ),
626 TALK_ID_DECIMAL(24, 1, UNIT_KHZ),
627 TALK_ID_DECIMAL(32, 1, UNIT_KHZ),
628 TALK_ID_DECIMAL(41, 1, UNIT_KHZ)),
629 CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[AUDIOHW_EQ_BAND4].width,
630 LANG_HW_EQ_WIDTH, 0, "tone band4 width", "narrow,wide",
631 sound_set_hw_eq_band4_width, 2,
632 ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)),
633/* Band 5 */
634 STRINGCHOICE_SETTING(F_SOUNDSETTING,
635 hw_eq_bands[AUDIOHW_EQ_BAND5].frequency,
636 LANG_HW_EQ_FREQUENCY, 0, "tone band5 frequency",
637 "5.3 kHz,6.9 kHz,9.0 kHz,11.7 kHz",
638 sound_set_hw_eq_band5_frequency, 4,
639 TALK_ID_DECIMAL(53, 1, UNIT_KHZ),
640 TALK_ID_DECIMAL(69, 1, UNIT_KHZ),
641 TALK_ID_DECIMAL(90, 1, UNIT_KHZ),
642 TALK_ID_DECIMAL(117, 1, UNIT_KHZ)),
643#endif /* HAVE_WM8978 */
644#endif /* AUDIOHW_HAVE_EQ */
645/* 3-d enhancement effect */
558#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 646#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
559 SOUND_SETTING(0,loudness, LANG_LOUDNESS, "loudness", SOUND_LOUDNESS), 647 SOUND_SETTING(0,loudness, LANG_LOUDNESS, "loudness", SOUND_LOUDNESS),
560 STRINGCHOICE_SETTING(F_SOUNDSETTING,avc,LANG_AUTOVOL,0,"auto volume", 648 STRINGCHOICE_SETTING(F_SOUNDSETTING,avc,LANG_AUTOVOL,0,"auto volume",
@@ -574,6 +662,10 @@ const struct settings_list settings[] = {
574 ID2P(LANG_CHANNEL_RIGHT), ID2P(LANG_CHANNEL_KARAOKE)), 662 ID2P(LANG_CHANNEL_RIGHT), ID2P(LANG_CHANNEL_KARAOKE)),
575 SOUND_SETTING(F_SOUNDSETTING, stereo_width, LANG_STEREO_WIDTH, 663 SOUND_SETTING(F_SOUNDSETTING, stereo_width, LANG_STEREO_WIDTH,
576 "stereo_width", SOUND_STEREO_WIDTH), 664 "stereo_width", SOUND_STEREO_WIDTH),
665#ifdef AUDIOHW_HAVE_DEPTH_3D
666 SOUND_SETTING(0,depth_3d, LANG_DEPTH_3D, "3-d enhancement",
667 SOUND_DEPTH_3D),
668#endif
577 /* playback */ 669 /* playback */
578 OFFON_SETTING(0, playlist_shuffle, LANG_SHUFFLE, false, "shuffle", NULL), 670 OFFON_SETTING(0, playlist_shuffle, LANG_SHUFFLE, false, "shuffle", NULL),
579 SYSTEM_SETTING(NVRAM(4), resume_index, -1), 671 SYSTEM_SETTING(NVRAM(4), resume_index, -1),
@@ -1332,9 +1424,11 @@ const struct settings_list settings[] = {
1332 "compressor release time", UNIT_MS, 100, 1000, 1424 "compressor release time", UNIT_MS, 100, 1000,
1333 100, NULL, NULL, compressor_set), 1425 100, NULL, NULL, compressor_set),
1334#endif 1426#endif
1335#ifdef HAVE_WM8758 1427#ifdef AUDIOHW_HAVE_BASS_CUTOFF
1336 SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF, 1428 SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF,
1337 "bass cutoff", SOUND_BASS_CUTOFF), 1429 "bass cutoff", SOUND_BASS_CUTOFF),
1430#endif
1431#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
1338 SOUND_SETTING(F_NO_WRAP, treble_cutoff, LANG_TREBLE_CUTOFF, 1432 SOUND_SETTING(F_NO_WRAP, treble_cutoff, LANG_TREBLE_CUTOFF,
1339 "treble cutoff", SOUND_TREBLE_CUTOFF), 1433 "treble cutoff", SOUND_TREBLE_CUTOFF),
1340#endif 1434#endif
diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c
index a2dbf5a8fb..2d57ce3f10 100644
--- a/firmware/drivers/audio/wm8978.c
+++ b/firmware/drivers/audio/wm8978.c
@@ -37,27 +37,35 @@ extern void audiohw_enable_headphone_jack(bool enable);
37 37
38const struct sound_settings_info audiohw_settings[] = 38const struct sound_settings_info audiohw_settings[] =
39{ 39{
40 [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, 40 [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25},
41 [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, 41 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
42 [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0}, 42 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
43 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, 43 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
44 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, 44 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
45 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, 45 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
46 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
47 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
48 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
49 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 0, 3, 0},
50 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 0, 3, 0},
51 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 0, 3, 0},
52 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 0, 3, 0},
53 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 0, 3, 0},
54 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
55 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
56 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
57 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
46#ifdef HAVE_RECORDING 58#ifdef HAVE_RECORDING
47 /* Digital: -119.0dB to +8.0dB in 0.5dB increments 59 /* Digital: -119.0dB to +8.0dB in 0.5dB increments
48 * Analog: Relegated to volume control 60 * Analog: Relegated to volume control
49 * Circumstances unfortunately do not allow a great deal of positive 61 * Circumstances unfortunately do not allow a great deal of positive
50 * gain. */ 62 * gain. */
51 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-238, 16, 0}, 63 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-238, 16, 0},
52 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-238, 16, 0}, 64 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-238, 16, 0},
53#if 0 65#if 0
54 [SOUND_MIC_GAIN] = {"dB", 1, 1,-238, 16, 0}, 66 [SOUND_MIC_GAIN] = {"dB", 1, 1,-238, 16, 0},
55#endif 67#endif
56#endif 68#endif
57#if 0
58 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
59 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
60#endif
61}; 69};
62 70
63static uint16_t wmc_regs[WMC_NUM_REGISTERS] = 71static uint16_t wmc_regs[WMC_NUM_REGISTERS] =
@@ -123,10 +131,20 @@ struct
123{ 131{
124 int vol_l; 132 int vol_l;
125 int vol_r; 133 int vol_r;
134 int dac_l;
135 int dac_r;
126 bool ahw_mute; 136 bool ahw_mute;
137 int prescaler;
138 int enhance_3d_prescaler;
127} wmc_vol = 139} wmc_vol =
128{ 140{
129 0, 0, false 141 .vol_l = 0,
142 .vol_r = 0,
143 .dac_l = 0,
144 .dac_r = 0,
145 .ahw_mute = false,
146 .prescaler = 0,
147 .enhance_3d_prescaler = 0,
130}; 148};
131 149
132static void wmc_write(unsigned int reg, unsigned int val) 150static void wmc_write(unsigned int reg, unsigned int val)
@@ -191,6 +209,10 @@ int sound_val2phys(int setting, int value)
191 break; 209 break;
192#endif 210#endif
193 211
212 case SOUND_DEPTH_3D:
213 result = (100 * value + 8) / 15;
214 break;
215
194 default: 216 default:
195 result = value; 217 result = value;
196 } 218 }
@@ -216,8 +238,12 @@ void audiohw_preinit(void)
216 wmc_set(WMC_OUT4_MONO_MIXER_CTRL, WMC_MUTE); 238 wmc_set(WMC_OUT4_MONO_MIXER_CTRL, WMC_MUTE);
217 239
218 /* 3. Set L/RMIXEN = 1 and DACENL/R = 1 in register R3. */ 240 /* 3. Set L/RMIXEN = 1 and DACENL/R = 1 in register R3. */
219 wmc_write(WMC_POWER_MANAGEMENT3, 241 wmc_write(WMC_POWER_MANAGEMENT3, WMC_RMIXEN | WMC_LMIXEN);
220 WMC_RMIXEN | WMC_LMIXEN | WMC_DACENR | WMC_DACENL); 242
243 /* EQ and 3D applied to DAC (Set before DAC enable!) */
244 wmc_set(WMC_EQ1_LOW_SHELF, WMC_EQ3DMODE);
245
246 wmc_set(WMC_POWER_MANAGEMENT3, WMC_DACENR | WMC_DACENL);
221 247
222 /* 4. Set BUFIOEN = 1 and VMIDSEL[1:0] to required value in register 248 /* 4. Set BUFIOEN = 1 and VMIDSEL[1:0] to required value in register
223 * R1. Wait for VMID supply to settle */ 249 * R1. Wait for VMID supply to settle */
@@ -305,6 +331,12 @@ void audiohw_set_headphone_vol(int vol_l, int vol_r)
305 get_headphone_levels(vol_l, &dac_l, &hp_l, &mix_l, &boost_l); 331 get_headphone_levels(vol_l, &dac_l, &hp_l, &mix_l, &boost_l);
306 get_headphone_levels(vol_r, &dac_r, &hp_r, &mix_r, &boost_r); 332 get_headphone_levels(vol_r, &dac_r, &hp_r, &mix_r, &boost_r);
307 333
334 wmc_vol.dac_l = dac_l;
335 wmc_vol.dac_r = dac_r;
336
337 dac_l -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler;
338 dac_r -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler;
339
308 wmc_write_masked(WMC_LEFT_MIXER_CTRL, mix_l << WMC_BYPLMIXVOL_POS, 340 wmc_write_masked(WMC_LEFT_MIXER_CTRL, mix_l << WMC_BYPLMIXVOL_POS,
309 WMC_BYPLMIXVOL); 341 WMC_BYPLMIXVOL);
310 wmc_write_masked(WMC_LEFT_ADC_BOOST_CTRL, 342 wmc_write_masked(WMC_LEFT_ADC_BOOST_CTRL,
@@ -367,6 +399,64 @@ static void audiohw_mute(bool mute)
367 } 399 }
368} 400}
369 401
402/* Equalizer - set the eq band level -12 to +12 dB. */
403void audiohw_set_eq_band_gain(unsigned int band, int val)
404{
405 if (band > 4)
406 return;
407
408 wmc_write_masked(band + WMC_EQ1_LOW_SHELF, 12 - val, WMC_EQG);
409}
410
411/* Equalizer - set the eq band frequency index. */
412void audiohw_set_eq_band_frequency(unsigned int band, int val)
413{
414 if (band > 4)
415 return;
416
417 wmc_write_masked(band + WMC_EQ1_LOW_SHELF,
418 val << WMC_EQC_POS, WMC_EQC);
419}
420
421/* Equalizer - set bandwidth for peaking filters to wide (!= 0) or
422 * narrow (0); only valid for peaking filter bands 1-3. */
423void audiohw_set_eq_band_width(unsigned int band, int val)
424{
425 if (band < 1 || band > 3)
426 return;
427
428 wmc_write_masked(band + WMC_EQ1_LOW_SHELF,
429 (val == 0) ? 0 : WMC_EQBW, WMC_EQBW);
430}
431
432/* Set prescaler to prevent clipping the output amp when applying positive
433 * gain to EQ bands. */
434void audiohw_set_prescaler(int val)
435{
436 val *= 2;
437 wmc_vol.prescaler = val;
438 val += wmc_vol.enhance_3d_prescaler; /* Combine with 3D attenuation */
439
440 wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - val,
441 WMC_DVOL);
442 wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - val,
443 WMC_DVOL);
444}
445
446/* Set the depth of the 3D effect */
447void audiohw_set_depth_3d(int val)
448{
449 int att = 10*val / 15; /* -5 dB @ full setting */
450 wmc_vol.enhance_3d_prescaler = att;
451 att += wmc_vol.prescaler; /* Combine with prescaler attenuation */
452
453 wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - att,
454 WMC_DVOL);
455 wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - att,
456 WMC_DVOL);
457 wmc_write_masked(WMC_3D_CONTROL, val, WMC_DEPTH3D);
458}
459
370void audiohw_close(void) 460void audiohw_close(void)
371{ 461{
372 /* 1. Mute all analogue outputs */ 462 /* 1. Mute all analogue outputs */
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index 22f6e68562..12c4738f7c 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -26,13 +26,15 @@
26#include <stdbool.h> 26#include <stdbool.h>
27 27
28/* define some audiohw caps */ 28/* define some audiohw caps */
29#define TREBLE_CAP (1 << 0) 29#define TREBLE_CAP (1 << 0)
30#define BASS_CAP (1 << 1) 30#define BASS_CAP (1 << 1)
31#define BALANCE_CAP (1 << 2) 31#define BALANCE_CAP (1 << 2)
32#define CLIPPING_CAP (1 << 3) 32#define CLIPPING_CAP (1 << 3)
33#define PRESCALER_CAP (1 << 4) 33#define PRESCALER_CAP (1 << 4)
34#define BASS_CUTOFF_CAP (1 << 5) 34#define BASS_CUTOFF_CAP (1 << 5)
35#define TREBLE_CUTOFF_CAP (1 << 6) 35#define TREBLE_CUTOFF_CAP (1 << 6)
36#define EQ_CAP (1 << 7)
37#define DEPTH_3D_CAP (1 << 8)
36 38
37#ifdef HAVE_UDA1380 39#ifdef HAVE_UDA1380
38#include "uda1380.h" 40#include "uda1380.h"
@@ -75,12 +77,17 @@
75#define VOLUME_MAX 0 77#define VOLUME_MAX 0
76#endif 78#endif
77 79
80#ifndef AUDIOHW_NUM_TONE_CONTROLS
81#define AUDIOHW_NUM_TONE_CONTROLS 0
82#endif
83
78/* volume/balance/treble/bass interdependency main part */ 84/* volume/balance/treble/bass interdependency main part */
79#define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) 85#define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
80 86
81 87
82/* convert caps into defines */ 88/* convert caps into defines */
83#ifdef AUDIOHW_CAPS 89#ifdef AUDIOHW_CAPS
90/* Tone controls */
84#if (AUDIOHW_CAPS & TREBLE_CAP) 91#if (AUDIOHW_CAPS & TREBLE_CAP)
85#define AUDIOHW_HAVE_TREBLE 92#define AUDIOHW_HAVE_TREBLE
86#endif 93#endif
@@ -89,6 +96,14 @@
89#define AUDIOHW_HAVE_BASS 96#define AUDIOHW_HAVE_BASS
90#endif 97#endif
91 98
99#if (AUDIOHW_CAPS & BASS_CUTOFF_CAP)
100#define AUDIOHW_HAVE_BASS_CUTOFF
101#endif
102
103#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP)
104#define AUDIOHW_HAVE_TREBLE_CUTOFF
105#endif
106
92#if (AUDIOHW_CAPS & BALANCE_CAP) 107#if (AUDIOHW_CAPS & BALANCE_CAP)
93#define AUDIOHW_HAVE_BALANCE 108#define AUDIOHW_HAVE_BALANCE
94#endif 109#endif
@@ -101,19 +116,127 @@
101#define AUDIOHW_HAVE_PRESCALER 116#define AUDIOHW_HAVE_PRESCALER
102#endif 117#endif
103 118
104#if (AUDIOHW_CAPS & BASS_CUTOFF_CAP) 119/* Hardware EQ tone controls */
105#define AUDIOHW_HAVE_BASS_CUTOFF 120#if (AUDIOHW_CAPS & EQ_CAP)
121/* A hardware equalizer is present (or perhaps some tone control variation
122 * that is not Bass and/or Treble) */
123#define AUDIOHW_HAVE_EQ
124
125/* Defined band indexes for supported bands */
126enum
127{
128 /* Band 1 is implied; bands must be contiguous, 1 to N */
129 AUDIOHW_EQ_BAND1 = 0,
130#define AUDIOHW_HAVE_EQ_BAND1
131#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 1))
132 AUDIOHW_EQ_BAND2,
133#define AUDIOHW_HAVE_EQ_BAND2
134#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 2))
135 AUDIOHW_EQ_BAND3,
136#define AUDIOHW_HAVE_EQ_BAND3
137#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 3))
138 AUDIOHW_EQ_BAND4,
139#define AUDIOHW_HAVE_EQ_BAND4
140#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 4))
141 AUDIOHW_EQ_BAND5,
142#define AUDIOHW_HAVE_EQ_BAND5
143#endif /* 5 */
144#endif /* 4 */
145#endif /* 3 */
146#endif /* 2 */
147 AUDIOHW_EQ_BAND_NUM, /* Keep last */
148};
149
150#ifdef AUDIOHW_EQ_FREQUENCY_CAPS
151/* One or more bands supports frequency cutoff or center adjustment */
152#define AUDIOHW_HAVE_EQ_FREQUENCY
153enum
154{
155 __AUDIOHW_EQ_BAND_FREQUENCY = -1,
156#if defined(AUDIOHW_HAVE_EQ_BAND1) && \
157 (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 0))
158 AUDIOHW_EQ_BAND1_FREQUENCY,
159#define AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
160#endif
161#if defined(AUDIOHW_HAVE_EQ_BAND2) && \
162 (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 1))
163 AUDIOHW_EQ_BAND2_FREQUENCY,
164#define AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
106#endif 165#endif
166#if defined(AUDIOHW_HAVE_EQ_BAND3) && \
167 (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 2))
168 AUDIOHW_EQ_BAND3_FREQUENCY,
169#define AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
170#endif
171#if defined(AUDIOHW_HAVE_EQ_BAND4) && \
172 (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 3))
173 AUDIOHW_EQ_BAND4_FREQUENCY,
174#define AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
175#endif
176#if defined(AUDIOHW_HAVE_EQ_BAND5) && \
177 (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 4))
178 AUDIOHW_EQ_BAND5_FREQUENCY,
179#define AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
180#endif
181 AUDIOHW_EQ_FREQUENCY_NUM,
182};
183#endif /* AUDIOHW_EQ_FREQUENCY_CAPS */
184
185#ifdef AUDIOHW_EQ_WIDTH_CAPS
186/* One or more bands supports bandwidth adjustment */
187#define AUDIOHW_HAVE_EQ_WIDTH
188enum
189{
190 __AUDIOHW_EQ_BAND_WIDTH = -1,
191#if defined(AUDIOHW_HAVE_EQ_BAND1) && \
192 (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 1))
193 AUDIOHW_EQ_BAND2_WIDTH,
194#define AUDIOHW_HAVE_EQ_BAND2_WIDTH
195#endif
196#if defined(AUDIOHW_HAVE_EQ_BAND2) && \
197 (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 2))
198 AUDIOHW_EQ_BAND3_WIDTH,
199#define AUDIOHW_HAVE_EQ_BAND3_WIDTH
200#endif
201#if defined(AUDIOHW_HAVE_EQ_BAND3) && \
202 (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 3))
203 AUDIOHW_EQ_BAND4_WIDTH,
204#define AUDIOHW_HAVE_EQ_BAND4_WIDTH
205#endif
206 AUDIOHW_EQ_WIDTH_NUM, /* Keep last */
207};
208#endif /* AUDIOHW_EQ_WIDTH_CAPS */
209
210/* Types and number of settings types (gain, frequency, width) */
211enum AUDIOHW_EQ_SETTINGS
212{
213 AUDIOHW_EQ_GAIN = 0,
214#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
215 AUDIOHW_EQ_FREQUENCY,
216#endif
217#ifdef AUDIOHW_HAVE_EQ_WIDTH
218 AUDIOHW_EQ_WIDTH,
219#endif
220 AUDIOHW_EQ_SETTING_NUM
221};
107 222
108#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP) 223#endif /* (AUDIOHW_CAPS & EQ_CAP) */
109#define AUDIOHW_HAVE_TREBLE_CUTOFF 224
225#if (AUDIOHW_CAPS & DEPTH_3D_CAP)
226#define AUDIOHW_HAVE_DEPTH_3D
110#endif 227#endif
228
111#endif /* AUDIOHW_CAPS */ 229#endif /* AUDIOHW_CAPS */
112 230
113enum { 231enum {
114 SOUND_VOLUME = 0, 232 SOUND_VOLUME = 0,
233/* Tone control */
234#if defined(AUDIOHW_HAVE_BASS)
115 SOUND_BASS, 235 SOUND_BASS,
236#endif
237#if defined(AUDIOHW_HAVE_TREBLE)
116 SOUND_TREBLE, 238 SOUND_TREBLE,
239#endif
117 SOUND_BALANCE, 240 SOUND_BALANCE,
118 SOUND_CHANNELS, 241 SOUND_CHANNELS,
119 SOUND_STEREO_WIDTH, 242 SOUND_STEREO_WIDTH,
@@ -132,12 +255,61 @@ enum {
132 SOUND_RIGHT_GAIN, 255 SOUND_RIGHT_GAIN,
133 SOUND_MIC_GAIN, 256 SOUND_MIC_GAIN,
134#endif 257#endif
258/* Bass and treble tone controls */
135#if defined(AUDIOHW_HAVE_BASS_CUTOFF) 259#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
136 SOUND_BASS_CUTOFF, 260 SOUND_BASS_CUTOFF,
137#endif 261#endif
138#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 262#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
139 SOUND_TREBLE_CUTOFF, 263 SOUND_TREBLE_CUTOFF,
140#endif 264#endif
265/* 3D effect */
266#if defined(AUDIOHW_HAVE_DEPTH_3D)
267 SOUND_DEPTH_3D,
268#endif
269/* Hardware EQ tone controls */
270/* Band gains */
271#if defined(AUDIOHW_HAVE_EQ)
272 /* Band 1 implied */
273 SOUND_EQ_BAND1_GAIN,
274#if defined(AUDIOHW_HAVE_EQ_BAND2)
275 SOUND_EQ_BAND2_GAIN,
276#endif
277#if defined(AUDIOHW_HAVE_EQ_BAND3)
278 SOUND_EQ_BAND3_GAIN,
279#endif
280#if defined(AUDIOHW_HAVE_EQ_BAND4)
281 SOUND_EQ_BAND4_GAIN,
282#endif
283#if defined(AUDIOHW_HAVE_EQ_BAND5)
284 SOUND_EQ_BAND5_GAIN,
285#endif
286/* Band frequencies */
287#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
288 SOUND_EQ_BAND1_FREQUENCY,
289#endif
290#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
291 SOUND_EQ_BAND2_FREQUENCY,
292#endif
293#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
294 SOUND_EQ_BAND3_FREQUENCY,
295#endif
296#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
297 SOUND_EQ_BAND4_FREQUENCY,
298#endif
299#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
300 SOUND_EQ_BAND5_FREQUENCY,
301#endif
302/* Band widths */
303#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
304 SOUND_EQ_BAND2_WIDTH,
305#endif
306#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
307 SOUND_EQ_BAND3_WIDTH,
308#endif
309#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
310 SOUND_EQ_BAND4_WIDTH,
311#endif
312#endif /* AUDIOHW_HAVE_EQ */
141 SOUND_LAST_SETTING, /* Keep this last */ 313 SOUND_LAST_SETTING, /* Keep this last */
142}; 314};
143 315
@@ -262,6 +434,64 @@ void audiohw_set_bass_cutoff(int val);
262void audiohw_set_treble_cutoff(int val); 434void audiohw_set_treble_cutoff(int val);
263#endif 435#endif
264 436
437#ifdef AUDIOHW_HAVE_EQ
438/**
439 * Set new band gain value.
440 * @param band index to which val is set
441 * @param val to set.
442 * NOTE: AUDIOHW_CAPS need to contain
443 * EQ_CAP
444 *
445 * AUDIOHW_EQ_BAND_CAPS must be defined as a bitmask
446 * of EQ_CAP each shifted by the zero-based band number
447 * for each band. Bands 1 to N are indexed 0 to N-1.
448 */
449void audiohw_set_eq_band_gain(unsigned int band, int val);
450#endif
451
452#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
453/**
454 * Set new band cutoff or center frequency value.
455 * @param band index to which val is set
456 * @param val to set.
457 * NOTE: AUDIOHW_CAPS need to contain
458 * EQ_CAP
459 *
460 * AUDIOHW_EQ_FREQUENCY_CAPS must be defined as a bitmask
461 * of EQ_CAP each shifted by the zero-based band number
462 * for each band that supports frequency adjustment.
463 * Bands 1 to N are indexed 0 to N-1.
464 */
465void audiohw_set_eq_band_frequency(unsigned int band, int val);
466#endif
467
468#ifdef AUDIOHW_HAVE_EQ_WIDTH
469/**
470 * Set new band cutoff or center frequency value.
471 * @param band index to which val is set
472 * @param val to set.
473 * NOTE: AUDIOHW_CAPS need to contain
474 * EQ_CAP
475 *
476 * AUDIOHW_EQ_WIDTH_CAPS must be defined as a bitmask
477 * of EQ_CAP each shifted by the zero-based band number
478 * for each band that supports width adjustment.
479 * Bands 1 to N are indexed 0 to N-1.
480 */
481void audiohw_set_eq_band_width(unsigned int band, int val);
482#endif
483
484#ifdef AUDIOHW_HAVE_DEPTH_3D
485/**
486 * Set new 3-d enhancement (stereo expansion) effect value.
487 * @param val to set.
488 * NOTE: AUDIOHW_CAPS need to contain
489 * DEPTH_3D_CAP
490 */
491void audiohw_set_depth_3d(int val);
492#endif
493
494
265void audiohw_set_frequency(int fsel); 495void audiohw_set_frequency(int fsel);
266 496
267#ifdef HAVE_RECORDING 497#ifdef HAVE_RECORDING
diff --git a/firmware/export/config/gigabeats.h b/firmware/export/config/gigabeats.h
index 2bc56ec98c..73eb79ce90 100644
--- a/firmware/export/config/gigabeats.h
+++ b/firmware/export/config/gigabeats.h
@@ -90,9 +90,6 @@
90/* Define this if you have the WM8978 audio codec */ 90/* Define this if you have the WM8978 audio codec */
91#define HAVE_WM8978 91#define HAVE_WM8978
92 92
93/* Tone controls for WM8978 have not been implemented yet */
94#define HAVE_SW_TONE_CONTROLS
95
96/* Define bitmask of input sources - recordable bitmask can be defined 93/* Define bitmask of input sources - recordable bitmask can be defined
97 explicitly if different */ 94 explicitly if different */
98#define INPUT_SRC_CAPS SRC_CAP_FMRADIO 95#define INPUT_SRC_CAPS SRC_CAP_FMRADIO
diff --git a/firmware/export/sound.h b/firmware/export/sound.h
index e68ae23774..7243f48e79 100644
--- a/firmware/export/sound.h
+++ b/firmware/export/sound.h
@@ -55,10 +55,70 @@ void sound_set_bass(int value);
55void sound_set_treble(int value); 55void sound_set_treble(int value);
56void sound_set_channels(int value); 56void sound_set_channels(int value);
57void sound_set_stereo_width(int value); 57void sound_set_stereo_width(int value);
58#if defined(HAVE_WM8758) || defined(HAVE_WM8985) 58#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
59void sound_set_bass_cutoff(int value); 59void sound_set_bass_cutoff(int value);
60#endif
61#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
60void sound_set_treble_cutoff(int value); 62void sound_set_treble_cutoff(int value);
61#endif 63#endif
64
65#if defined(AUDIOHW_HAVE_DEPTH_3D)
66void sound_set_depth_3d(int value);
67#endif
68
69#ifdef AUDIOHW_HAVE_EQ
70/*
71 * band = SOUND_EQ_BANDb
72 * band_setting = AUDIOHW_EQ_s
73 *
74 * Returns SOUND_EQ_BANDb_s or -1 if it doesn't exist.
75 *
76 * b: band number
77 * s: one of GAIN, FREQUENCY, WIDTH
78 */
79int sound_enum_hw_eq_band_setting(unsigned int band,
80 unsigned int band_setting);
81/* Band1 implied */
82void sound_set_hw_eq_band1_gain(int value);
83#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
84void sound_set_hw_eq_band1_frequency(int value);
85#endif
86#ifdef AUDIOHW_HAVE_EQ_BAND2
87void sound_set_hw_eq_band2_gain(int value);
88#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
89void sound_set_hw_eq_band2_frequency(int value);
90#endif
91#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
92void sound_set_hw_eq_band2_width(int value);
93#endif
94#endif /* AUDIOHW_HAVE_EQ_BAND2 */
95#ifdef AUDIOHW_HAVE_EQ_BAND3
96/* Band 3 */
97void sound_set_hw_eq_band3_gain(int value);
98#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
99void sound_set_hw_eq_band3_frequency(int value);
100#endif
101#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
102void sound_set_hw_eq_band3_width(int value);
103#endif
104#endif /* AUDIOHW_HAVE_EQ_BAND3 */
105#ifdef AUDIOHW_HAVE_EQ_BAND4
106void sound_set_hw_eq_band4_gain(int value);
107#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
108void sound_set_hw_eq_band4_frequency(int value);
109#endif
110#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
111void sound_set_hw_eq_band4_width(int value);
112#endif
113#endif /* AUDIOHW_HAVE_EQ_BAND4 */
114#ifdef AUDIOHW_HAVE_EQ_BAND5
115void sound_set_hw_eq_band5_gain(int value);
116#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
117void sound_set_hw_eq_band5_frequency(int value);
118#endif
119#endif /* AUDIOHW_HAVE_EQ_BAND5 */
120#endif /* AUDIOHW_HAVE_EQ */
121
62#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 122#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
63void sound_set_loudness(int value); 123void sound_set_loudness(int value);
64void sound_set_avc(int value); 124void sound_set_avc(int value);
diff --git a/firmware/export/wm8978.h b/firmware/export/wm8978.h
index 270c666a4a..4081d05a89 100644
--- a/firmware/export/wm8978.h
+++ b/firmware/export/wm8978.h
@@ -26,6 +26,19 @@
26#define VOLUME_MIN -900 26#define VOLUME_MIN -900
27#define VOLUME_MAX 60 27#define VOLUME_MAX 60
28 28
29#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP)
30/* Filter bitmask */
31#define AUDIOHW_EQ_BAND_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \
32 (EQ_CAP << 2) | (EQ_CAP << 3) | \
33 (EQ_CAP << 4))
34/* Filters that can adjust cutoff and center frequency */
35#define AUDIOHW_EQ_FREQUENCY_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \
36 (EQ_CAP << 2) | (EQ_CAP << 3) | \
37 (EQ_CAP << 4))
38/* Filters that can adjust band width */
39#define AUDIOHW_EQ_WIDTH_CAPS ((EQ_CAP << 1) | (EQ_CAP << 2) | \
40 (EQ_CAP << 3))
41
29int tenthdb2master(int db); 42int tenthdb2master(int db);
30void audiohw_set_headphone_vol(int vol_l, int vol_r); 43void audiohw_set_headphone_vol(int vol_l, int vol_r);
31void audiohw_set_recsrc(int source, bool recording); 44void audiohw_set_recsrc(int source, bool recording);
diff --git a/firmware/sound.c b/firmware/sound.c
index b56e610034..fb2f353d71 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -48,8 +48,13 @@ extern void audiohw_set_volume(int value);
48/* dummy for sim */ 48/* dummy for sim */
49const struct sound_settings_info audiohw_settings[] = { 49const struct sound_settings_info audiohw_settings[] = {
50 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25}, 50 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
51/* Bass and treble tone controls */
52#ifdef AUDIOHW_HAVE_BASS
51 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, 53 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
54#endif
55#ifdef AUDIOHW_HAVE_TREBLE
52 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, 56 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
57#endif
53 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, 58 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
54 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, 59 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
55 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, 60 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
@@ -64,6 +69,50 @@ const struct sound_settings_info audiohw_settings[] = {
64#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 69#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
65 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, 70 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
66#endif 71#endif
72#if defined(AUDIOHW_HAVE_DEPTH_3D)
73 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
74#endif
75/* Hardware EQ tone controls */
76#if defined(AUDIOHW_HAVE_EQ_BAND1)
77 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
78#endif
79#if defined(AUDIOHW_HAVE_EQ_BAND2)
80 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
81#endif
82#if defined(AUDIOHW_HAVE_EQ_BAND3)
83 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
84#endif
85#if defined(AUDIOHW_HAVE_EQ_BAND4)
86 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
87#endif
88#if defined(AUDIOHW_HAVE_EQ_BAND5)
89 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
90#endif
91#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
92 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1},
93#endif
94#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
95 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1},
96#endif
97#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
98 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1},
99#endif
100#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
101 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1},
102#endif
103#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
104 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1},
105#endif
106#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
107 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
108#endif
109#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
110 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
111#endif
112#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
113 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
114#endif
115
67#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 116#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
68 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0}, 117 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
69 [SOUND_AVC] = {"", 0, 1, -1, 4, 0}, 118 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
@@ -111,8 +160,12 @@ static sound_set_type * const sound_set_fns[] =
111{ 160{
112 [0 ... SOUND_LAST_SETTING-1] = NULL, 161 [0 ... SOUND_LAST_SETTING-1] = NULL,
113 [SOUND_VOLUME] = sound_set_volume, 162 [SOUND_VOLUME] = sound_set_volume,
163#if defined(AUDIOHW_HAVE_BASS)
114 [SOUND_BASS] = sound_set_bass, 164 [SOUND_BASS] = sound_set_bass,
165#endif
166#if defined(AUDIOHW_HAVE_TREBLE)
115 [SOUND_TREBLE] = sound_set_treble, 167 [SOUND_TREBLE] = sound_set_treble,
168#endif
116 [SOUND_BALANCE] = sound_set_balance, 169 [SOUND_BALANCE] = sound_set_balance,
117 [SOUND_CHANNELS] = sound_set_channels, 170 [SOUND_CHANNELS] = sound_set_channels,
118 [SOUND_STEREO_WIDTH] = sound_set_stereo_width, 171 [SOUND_STEREO_WIDTH] = sound_set_stereo_width,
@@ -132,6 +185,49 @@ static sound_set_type * const sound_set_fns[] =
132#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 185#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
133 [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff, 186 [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff,
134#endif 187#endif
188#if defined(AUDIOHW_HAVE_DEPTH_3D)
189 [SOUND_DEPTH_3D] = sound_set_depth_3d,
190#endif
191/* Hardware EQ tone controls */
192#if defined(AUDIOHW_HAVE_EQ)
193 [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain,
194#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
195 [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency,
196#endif
197#if defined(AUDIOHW_HAVE_EQ_BAND2)
198 [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain,
199#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
200 [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency,
201#endif
202#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
203 [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width,
204#endif
205#endif /* AUDIOHW_HAVE_EQ_BAND2 */
206#if defined(AUDIOHW_HAVE_EQ_BAND3)
207 [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain,
208#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
209 [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency,
210#endif
211#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
212 [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width,
213#endif
214#endif /* AUDIOHW_HAVE_EQ_BAND3 */
215#if defined(AUDIOHW_HAVE_EQ_BAND4)
216 [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain,
217#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
218 [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency,
219#endif
220#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
221 [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width,
222#endif
223#endif /* AUDIOHW_HAVE_EQ_BAND4 */
224#if defined(AUDIOHW_HAVE_EQ_BAND5)
225 [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain,
226#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
227 [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency,
228#endif
229#endif /* AUDIOHW_HAVE_EQ_BAND5 */
230#endif /* AUDIOHW_HAVE_EQ */
135}; 231};
136 232
137sound_set_type* sound_get_fn(int setting) 233sound_set_type* sound_get_fn(int setting)
@@ -174,8 +270,15 @@ static int tenthdb2reg(int db)
174/* all values in tenth of dB MAS3507D UDA1380 */ 270/* all values in tenth of dB MAS3507D UDA1380 */
175int current_volume = 0; /* -780..+180 -840.. 0 */ 271int current_volume = 0; /* -780..+180 -840.. 0 */
176int current_balance = 0; /* -960..+960 -840..+840 */ 272int current_balance = 0; /* -960..+960 -840..+840 */
273#ifdef AUDIOHW_HAVE_TREBLE
177int current_treble = 0; /* -150..+150 0.. +60 */ 274int current_treble = 0; /* -150..+150 0.. +60 */
275#endif
276#ifdef AUDIOHW_HAVE_BASS
178int current_bass = 0; /* -150..+150 0..+240 */ 277int current_bass = 0; /* -150..+150 0..+240 */
278#endif
279#ifdef AUDIOHW_HAVE_EQ
280int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM];
281#endif
179 282
180static void set_prescaled_volume(void) 283static void set_prescaled_volume(void)
181{ 284{
@@ -191,10 +294,18 @@ static void set_prescaled_volume(void)
191 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \ 294 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
192 || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341)) 295 || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341))
193 296
297#if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE)
194 prescale = MAX(current_bass, current_treble); 298 prescale = MAX(current_bass, current_treble);
299#endif
300#if defined(AUDIOHW_HAVE_EQ)
301 int i;
302 for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++)
303 prescale = MAX(current_eq_band_gain[i], prescale);
304#endif
305
195 if (prescale < 0) 306 if (prescale < 0)
196 prescale = 0; /* no need to prescale if we don't boost 307 prescale = 0; /* no need to prescale if we don't boost
197 bass or treble */ 308 bass, treble or eq band */
198 309
199 /* Gain up the analog volume to compensate the prescale gain reduction, 310 /* Gain up the analog volume to compensate the prescale gain reduction,
200 * but if this would push the volume over the top, reduce prescaling 311 * but if this would push the volume over the top, reduce prescaling
@@ -289,6 +400,7 @@ void sound_set_balance(int value)
289#endif 400#endif
290} 401}
291 402
403#ifdef AUDIOHW_HAVE_BASS
292void sound_set_bass(int value) 404void sound_set_bass(int value)
293{ 405{
294 if(!audio_is_initialized) 406 if(!audio_is_initialized)
@@ -302,17 +414,19 @@ void sound_set_bass(int value)
302#endif 414#endif
303#endif 415#endif
304 416
305#if defined(AUDIOHW_HAVE_BASS) 417#if defined(HAVE_SW_TONE_CONTROLS)
306 audiohw_set_bass(value);
307#else
308 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); 418 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
419#else
420 audiohw_set_bass(value);
309#endif 421#endif
310 422
311#if !defined(AUDIOHW_HAVE_CLIPPING) 423#if !defined(AUDIOHW_HAVE_CLIPPING)
312 set_prescaled_volume(); 424 set_prescaled_volume();
313#endif 425#endif
314} 426}
427#endif /* AUDIOHW_HAVE_BASS */
315 428
429#ifdef AUDIOHW_HAVE_TREBLE
316void sound_set_treble(int value) 430void sound_set_treble(int value)
317{ 431{
318 if(!audio_is_initialized) 432 if(!audio_is_initialized)
@@ -326,16 +440,37 @@ void sound_set_treble(int value)
326#endif 440#endif
327#endif 441#endif
328 442
329#if defined(AUDIOHW_HAVE_TREBLE) 443#if defined(HAVE_SW_TONE_CONTROLS)
330 audiohw_set_treble(value);
331#else
332 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); 444 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
445#else
446 audiohw_set_treble(value);
333#endif 447#endif
334 448
335#if !defined(AUDIOHW_HAVE_CLIPPING) 449#if !defined(AUDIOHW_HAVE_CLIPPING)
336 set_prescaled_volume(); 450 set_prescaled_volume();
337#endif 451#endif
338} 452}
453#endif /* AUDIOHW_HAVE_TREBLE */
454
455#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
456void sound_set_bass_cutoff(int value)
457{
458 if(!audio_is_initialized)
459 return;
460
461 audiohw_set_bass_cutoff(value);
462}
463#endif
464
465#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
466void sound_set_treble_cutoff(int value)
467{
468 if(!audio_is_initialized)
469 return;
470
471 audiohw_set_treble_cutoff(value);
472}
473#endif
339 474
340void sound_set_channels(int value) 475void sound_set_channels(int value)
341{ 476{
@@ -361,26 +496,208 @@ void sound_set_stereo_width(int value)
361#endif 496#endif
362} 497}
363 498
364#if defined(AUDIOHW_HAVE_BASS_CUTOFF) 499#if defined(AUDIOHW_HAVE_DEPTH_3D)
365void sound_set_bass_cutoff(int value) 500void sound_set_depth_3d(int value)
366{ 501{
367 if(!audio_is_initialized) 502 if(!audio_is_initialized)
368 return; 503 return;
369 504
370 audiohw_set_bass_cutoff(value); 505 audiohw_set_depth_3d(value);
371} 506}
372#endif 507#endif
373 508
374#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 509#if defined(AUDIOHW_HAVE_EQ)
375void sound_set_treble_cutoff(int value) 510int sound_enum_hw_eq_band_setting(unsigned int band,
511 unsigned int band_setting)
512{
513 static const int8_t
514 sound_hw_eq_band_setting[AUDIOHW_EQ_SETTING_NUM][AUDIOHW_EQ_BAND_NUM] =
515 {
516 [AUDIOHW_EQ_GAIN] =
517 {
518 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
519 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_GAIN,
520 #ifdef AUDIOHW_HAVE_EQ_BAND2
521 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_GAIN,
522 #endif
523 #ifdef AUDIOHW_HAVE_EQ_BAND3
524 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_GAIN,
525 #endif
526 #ifdef AUDIOHW_HAVE_EQ_BAND4
527 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_GAIN,
528 #endif
529 #ifdef AUDIOHW_HAVE_EQ_BAND5
530 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_GAIN,
531 #endif
532 },
533#ifdef AUDIOHW_HAVE_EQ_FREQUENCY
534 [AUDIOHW_EQ_FREQUENCY] =
535 {
536 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
537 #ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
538 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_FREQUENCY,
539 #endif
540 #ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
541 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_FREQUENCY,
542 #endif
543 #ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
544 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_FREQUENCY,
545 #endif
546 #ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
547 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_FREQUENCY,
548 #endif
549 #ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
550 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_FREQUENCY,
551 #endif
552 },
553#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */
554#ifdef AUDIOHW_HAVE_EQ_WIDTH
555 [AUDIOHW_EQ_WIDTH] =
556 {
557 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
558 #ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
559 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_WIDTH,
560 #endif
561 #ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
562 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_WIDTH,
563 #endif
564 #ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
565 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_WIDTH,
566 #endif
567 },
568#endif /* AUDIOHW_HAVE_EQ_WIDTH */
569 };
570
571 if (band < AUDIOHW_EQ_BAND_NUM && band_setting < AUDIOHW_EQ_SETTING_NUM)
572 return sound_hw_eq_band_setting[band_setting][band];
573
574 return -1;
575}
576
577static void sound_set_hw_eq_band_gain(unsigned int band, int value)
376{ 578{
377 if(!audio_is_initialized) 579 if(!audio_is_initialized)
378 return; 580 return;
379 581
380 audiohw_set_treble_cutoff(value); 582 current_eq_band_gain[band] = value;
583 audiohw_set_eq_band_gain(band, value);
584 set_prescaled_volume();
585}
586
587void sound_set_hw_eq_band1_gain(int value)
588{
589 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND1, value);
590}
591
592#if defined(AUDIOHW_HAVE_EQ_BAND2)
593void sound_set_hw_eq_band2_gain(int value)
594{
595 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND2, value);
596}
597#endif
598
599#if defined(AUDIOHW_HAVE_EQ_BAND3)
600void sound_set_hw_eq_band3_gain(int value)
601{
602 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND3, value);
381} 603}
382#endif 604#endif
383 605
606#if defined(AUDIOHW_HAVE_EQ_BAND4)
607void sound_set_hw_eq_band4_gain(int value)
608{
609 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND4, value);
610}
611#endif
612
613#if defined(AUDIOHW_HAVE_EQ_BAND5)
614void sound_set_hw_eq_band5_gain(int value)
615{
616 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND5, value);
617}
618#endif
619
620#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
621void sound_set_hw_eq_band1_frequency(int value)
622{
623 if(!audio_is_initialized)
624 return;
625
626 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value);
627}
628#endif
629
630#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
631void sound_set_hw_eq_band2_frequency(int value)
632{
633 if(!audio_is_initialized)
634 return;
635
636 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value);
637}
638#endif
639
640#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
641void sound_set_hw_eq_band3_frequency(int value)
642{
643 if(!audio_is_initialized)
644 return;
645
646 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value);
647}
648#endif
649
650#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
651void sound_set_hw_eq_band4_frequency(int value)
652{
653 if(!audio_is_initialized)
654 return;
655
656 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value);
657}
658#endif
659
660#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
661void sound_set_hw_eq_band5_frequency(int value)
662{
663 if(!audio_is_initialized)
664 return;
665
666 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value);
667}
668#endif
669
670#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
671void sound_set_hw_eq_band2_width(int value)
672{
673 if(!audio_is_initialized)
674 return;
675
676 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value);
677}
678#endif
679
680#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
681void sound_set_hw_eq_band3_width(int value)
682{
683 if(!audio_is_initialized)
684 return;
685
686 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value);
687}
688#endif
689
690#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
691void sound_set_hw_eq_band4_width(int value)
692{
693 if(!audio_is_initialized)
694 return;
695
696 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value);
697}
698#endif
699#endif /* AUDIOHW_HAVE_EQ */
700
384#if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) 701#if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F))
385void sound_set_loudness(int value) 702void sound_set_loudness(int value)
386{ 703{
@@ -572,6 +889,10 @@ int sound_val2phys(int setting, int value)
572 break; 889 break;
573#endif 890#endif
574 891
892 case SOUND_DEPTH_3D:
893 result = (100 * value + 8) / 15;
894 break;
895
575 default: 896 default:
576 result = value; 897 result = value;
577 } 898 }
diff --git a/uisimulator/sdl/sound.c b/uisimulator/sdl/sound.c
index dd5e4345aa..0f8d5d4934 100644
--- a/uisimulator/sdl/sound.c
+++ b/uisimulator/sdl/sound.c
@@ -385,6 +385,23 @@ void audiohw_set_bass_cutoff(int value) { (void)value; }
385#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 385#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
386void audiohw_set_treble_cutoff(int value){ (void)value; } 386void audiohw_set_treble_cutoff(int value){ (void)value; }
387#endif 387#endif
388/* EQ-based tone controls */
389#if defined(AUDIOHW_HAVE_EQ)
390void audiohw_set_eq_band_gain(unsigned int band, int value)
391 { (void)band; (void)value; }
392#endif
393#if defined(AUDIOHW_HAVE_EQ_FREQUENCY)
394void audiohw_set_eq_band_frequency(unsigned int band, int value)
395 { (void)band; (void)value; }
396#endif
397#if defined(AUDIOHW_HAVE_EQ_WIDTH)
398void audiohw_set_eq_band_width(unsigned int band, int value)
399 { (void)band; (void)value; }
400#endif
401#if defined(AUDIOHW_HAVE_DEPTH_3D)
402void audiohw_set_depth_3d(int value)
403 { (void)value; }
404#endif
388#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 405#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
389int mas_codec_readreg(int reg) 406int mas_codec_readreg(int reg)
390{ 407{