summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-05-15 13:09:45 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-05-15 13:09:45 +0000
commit80d0d15ca9b253f8a446f50cf25d3d4b850bcfd1 (patch)
tree2598d3a019c33d6f9ea76010fd6d3a8301ef87a0
parent0f77db73469920f0b0006f696ddb36029338c378 (diff)
downloadrockbox-80d0d15ca9b253f8a446f50cf25d3d4b850bcfd1.tar.gz
rockbox-80d0d15ca9b253f8a446f50cf25d3d4b850bcfd1.zip
Gigabeat S: Fully enable access to hardware tone controls and 3-D effect feature. Under the hood, it's designated a hardware equalizer since it is one. Implement code framework for hardware EQ in general. Menu aspect is well abstracted and so the UI and strings can be changed around if taste doesn't quite suit. So far the emphasis is distinction of the UI labelling from the software EQ so that it's clear the settings are for a different thing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26051 a1c6a512-1295-4272-9138-f99709370657
-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{