diff options
-rw-r--r-- | apps/SOURCES | 3 | ||||
-rw-r--r-- | apps/lang/english.lang | 137 | ||||
-rw-r--r-- | apps/menus/audiohw_eq_menu.c | 244 | ||||
-rw-r--r-- | apps/menus/exported_menus.h | 3 | ||||
-rw-r--r-- | apps/menus/sound_menu.c | 50 | ||||
-rw-r--r-- | apps/plugin.c | 3 | ||||
-rw-r--r-- | apps/plugin.h | 7 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpeg_settings.c | 35 | ||||
-rw-r--r-- | apps/settings.c | 35 | ||||
-rw-r--r-- | apps/settings.h | 21 | ||||
-rw-r--r-- | apps/settings_list.c | 100 | ||||
-rw-r--r-- | firmware/drivers/audio/wm8978.c | 122 | ||||
-rw-r--r-- | firmware/export/audiohw.h | 252 | ||||
-rw-r--r-- | firmware/export/config/gigabeats.h | 3 | ||||
-rw-r--r-- | firmware/export/sound.h | 62 | ||||
-rw-r--r-- | firmware/export/wm8978.h | 13 | ||||
-rw-r--r-- | firmware/sound.c | 347 | ||||
-rw-r--r-- | uisimulator/sdl/sound.c | 17 |
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 menus/display_menu.c menus/theme_menu.c #if CONFIG_CODEC == SWCODEC +#ifdef HAVE_WM8978 +menus/audiohw_eq_menu.c +#endif menus/eq_menu.c buffering.c voice_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 @@ radio: "" </voice> </phrase> +<phrase> + id: LANG_HW_EQ_TONE_CONTROLS + desc: in sound_menu, hardware equalizer tone controls + user: core + <source> + *: none + gigabeats: "Tone Controls" + </source> + <dest> + *: none + gigabeats: "Tone Controls" + </dest> + <voice> + *: none + gigabeats: "Tone Controls" + </voice> +</phrase> +<phrase> + id: LANG_HW_EQ_TONE_CONTROLS_ADVANCED + desc: in sound_menu, advanced settings for hardware equalizer tone controls + user: core + <source> + *: none + gigabeats: "Advanced Tone Control Settings" + </source> + <dest> + *: none + gigabeats: "Advanced Tone Control Settings" + </dest> + <voice> + *: none + gigabeats: "Advanced Tone Control Settings" + </voice> +</phrase> +<phrase> + id: LANG_HW_EQ_GAIN + desc: in sound_menu, hardware equalizer tone controls filter gain + user: core + <source> + *: none + gigabeats: "Band %d Gain" + </source> + <dest> + *: none + gigabeats: "Band %d Gain" + </dest> + <voice> + *: none + gigabeats: "Band Gain" + </voice> +</phrase> +<phrase> + id: LANG_HW_EQ_FREQUENCY + desc: in sound_menu, hardware equalizer tone controls shelf filter cutoff frequency + user: core + <source> + *: none + gigabeats: "Band %d Frequency" + </source> + <dest> + *: none + gigabeats: "Band %d Frequency" + </dest> + <voice> + *: none + gigabeats: "Band Frequency" + </voice> +</phrase> +<phrase> + id: LANG_HW_EQ_WIDTH + desc: in sound_menu, hardware equalizer tone controls peak bandwith setting + user: core + <source> + *: none + gigabeats: "Band %d Width" + </source> + <dest> + *: none + gigabeats: "Band %d Width" + </dest> + <voice> + *: none + gigabeats: "Band Width" + </voice> +</phrase> +<phrase> + id: LANG_HW_EQ_WIDTH_NARROW + desc: in sound_menu, hardware equalizer tone controls narrow bandwith setting + user: core + <source> + *: none + gigabeats: "Narrow" + </source> + <dest> + *: none + gigabeats: "Narrow" + </dest> + <voice> + *: none + gigabeats: "Narrow" + </voice> +</phrase> +<phrase> + id: LANG_HW_EQ_WIDTH_WIDE + desc: in sound_menu, hardware equalizer tone controls wide bandwidth setting + user: core + <source> + *: none + gigabeats: "Wide" + </source> + <dest> + *: none + gigabeats: "Wide" + </dest> + <voice> + *: none + gigabeats: "Wide" + </voice> +</phrase> +<phrase> + id: LANG_DEPTH_3D + desc: in sound_menu, amount of 3D enhancement effect + user: core + <source> + *: none + gigabeats: "3-D Enhancement" + </source> + <dest> + *: none + gigabeats: "3-D Enhancement" + </dest> + <voice> + *: none + gigabeats: "3-D Enhancement" + </voice> +</phrase> + 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include <stdio.h> +#include "config.h" +#include "sound.h" +#include "settings.h" +#include "lang.h" +#include "menu.h" +#include "talk.h" + +#define HW_EQ_IDX(band, setting) ((void *)(((setting) << 8) | (band))) +#define HW_EQ_IDX_BAND(data) ((uint8_t)(uintptr_t)(data)) +#define HW_EQ_IDX_SETTING(data) ((uint8_t)((uintptr_t)(data) >> 8)) + +static unsigned short hw_eq_setting_lang_ids[AUDIOHW_EQ_SETTING_NUM] = +{ + LANG_HW_EQ_GAIN, +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + LANG_HW_EQ_FREQUENCY, +#endif +#ifdef AUDIOHW_HAVE_EQ_WIDTH + LANG_HW_EQ_WIDTH, +#endif +}; + +static char * hw_eq_get_name(int selected_item, void * data, char *buffer) +{ + snprintf(buffer, MAX_PATH, + str(hw_eq_setting_lang_ids[HW_EQ_IDX_SETTING(data)]), + HW_EQ_IDX_BAND(data) + 1); + return buffer; + (void)selected_item; +} + +static int hw_eq_speak_item(int selected_item, void * data) +{ + talk_id(hw_eq_setting_lang_ids[HW_EQ_IDX_SETTING(data)], false); + talk_number(HW_EQ_IDX_BAND(data) + 1, true); + return 0; + (void)selected_item; +} + +static int hw_eq_do_band_setting(void *param) +{ + int band = HW_EQ_IDX_BAND(param); + int setting = HW_EQ_IDX_SETTING(param); + char desc[MAX_PATH]; + struct menu_callback_with_desc cbwdesc = + { + .menu_callback = NULL, + .desc = hw_eq_get_name(0, param, desc), + .icon_id = Icon_NOICON + }; + struct menu_item_ex item = + { + .flags = MT_SETTING_W_TEXT | MENU_HAS_DESC, + { .variable = (void*)(&global_settings.hw_eq_bands[band].gain + setting) }, + { .callback_and_desc = &cbwdesc } + }; + do_setting_from_menu(&item, NULL); + return 0; +} + +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_GAIN), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_GAIN), + NULL, Icon_Menu_setting); +#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_frequency, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_FREQUENCY), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND1, AUDIOHW_EQ_FREQUENCY), + NULL, Icon_NOICON); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_GAIN), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_GAIN), + NULL, Icon_Menu_setting); +#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_frequency, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_FREQUENCY), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_FREQUENCY), + NULL, Icon_NOICON); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_width, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_WIDTH), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND2, AUDIOHW_EQ_WIDTH), + NULL, Icon_NOICON); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND2 */ +#ifdef AUDIOHW_HAVE_EQ_BAND3 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_GAIN), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_GAIN), + NULL, Icon_Menu_setting); +#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_frequency, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_FREQUENCY), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_FREQUENCY), + NULL, Icon_NOICON); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_width, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_WIDTH), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND3, AUDIOHW_EQ_WIDTH), + NULL, Icon_NOICON); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND3 */ +#ifdef AUDIOHW_HAVE_EQ_BAND4 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_GAIN), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_GAIN), + NULL, Icon_Menu_setting); +#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_frequency, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_FREQUENCY), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_FREQUENCY), + NULL, Icon_NOICON); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_width, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_WIDTH), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND4, AUDIOHW_EQ_WIDTH), + NULL, Icon_NOICON); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND4 */ +#ifdef AUDIOHW_HAVE_EQ_BAND5 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_GAIN), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_GAIN), + NULL, Icon_Menu_setting); +#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_frequency, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, + HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_FREQUENCY), + hw_eq_get_name, hw_eq_speak_item, + HW_EQ_IDX(AUDIOHW_EQ_BAND5, AUDIOHW_EQ_FREQUENCY), + NULL, Icon_NOICON); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND5 */ + +/* Submenu for multiple "tone controls". Gain + all advanced settings. */ +MAKE_MENU(hardware_eq_tone_controls_advanced, ID2P(LANG_HW_EQ_TONE_CONTROLS_ADVANCED), + NULL, Icon_NOICON + ,&hw_eq_band1_gain +#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY + ,&hw_eq_band1_frequency +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2 + ,&hw_eq_band2_gain +#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY + ,&hw_eq_band2_frequency +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH + ,&hw_eq_band2_width +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND2 */ +#ifdef AUDIOHW_HAVE_EQ_BAND3 + ,&hw_eq_band3_gain +#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY + ,&hw_eq_band3_frequency +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH + ,&hw_eq_band3_width +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND3 */ +#ifdef AUDIOHW_HAVE_EQ_BAND4 + ,&hw_eq_band4_gain +#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY + ,&hw_eq_band4_frequency +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH + ,&hw_eq_band4_width +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND4 */ +#ifdef AUDIOHW_HAVE_EQ_BAND5 + ,&hw_eq_band5_gain +#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY + ,&hw_eq_band5_frequency +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND5 */ + ); +/* Shows only the gains + advanced settings submenu */ +MAKE_MENU(audiohw_eq_tone_controls, ID2P(LANG_HW_EQ_TONE_CONTROLS), + NULL, Icon_NOICON + ,&hw_eq_band1_gain +#ifdef AUDIOHW_HAVE_EQ_BAND2 + ,&hw_eq_band2_gain +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND3 + ,&hw_eq_band3_gain +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND4 + ,&hw_eq_band4_gain +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND5 + ,&hw_eq_band5_gain +#endif + ,&hardware_eq_tone_controls_advanced + ); + 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 playlist_settings, /* playlist_menu.c */ playlist_options, /* playlist_menu.c */ equalizer_menu, /* eq_menu.c */ +#ifdef AUDIOHW_HAVE_EQ + audiohw_eq_tone_controls, /* audiohw_eq_menu.c */ +#endif info_menu, /* info_menu.c */ theme_menu; /* theme_menu.c */ 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 @@ #include <stddef.h> #include <limits.h> #include "config.h" +#include "sound.h" #include "lang.h" #include "action.h" #include "settings.h" @@ -38,6 +39,7 @@ /***********************************/ /* SOUND MENU */ MENUITEM_SETTING(volume, &global_settings.volume, NULL); +#ifdef AUDIOHW_HAVE_BASS MENUITEM_SETTING(bass, &global_settings.bass, #ifdef HAVE_SW_TONE_CONTROLS lowlatency_callback @@ -45,9 +47,14 @@ MENUITEM_SETTING(bass, &global_settings.bass, NULL #endif ); -#ifdef HAVE_WM8758 -MENUITEM_SETTING(bass_cutoff, &global_settings.bass_cutoff, NULL); + +#ifdef AUDIOHW_HAVE_BASS_CUTOFF +MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL); #endif +#endif /* AUDIOHW_HAVE_BASS */ + + +#ifdef AUDIOHW_HAVE_TREBLE MENUITEM_SETTING(treble, &global_settings.treble, #ifdef HAVE_SW_TONE_CONTROLS lowlatency_callback @@ -55,9 +62,13 @@ MENUITEM_SETTING(treble, &global_settings.treble, NULL #endif ); -#ifdef HAVE_WM8758 + +#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF MENUITEM_SETTING(treble_cutoff, &global_settings.treble_cutoff, NULL); #endif +#endif /* AUDIOHW_HAVE_TREBLE */ + + MENUITEM_SETTING(balance, &global_settings.balance, NULL); MENUITEM_SETTING(channel_config, &global_settings.channel_config, #if CONFIG_CODEC == SWCODEC @@ -74,6 +85,10 @@ MENUITEM_SETTING(stereo_width, &global_settings.stereo_width, #endif ); +#ifdef AUDIOHW_HAVE_DEPTH_3D +MENUITEM_SETTING(depth_3d, &global_settings.depth_3d, NULL); +#endif + #if CONFIG_CODEC == SWCODEC /* Crossfeed Submenu */ 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) MENUITEM_SETTING(speaker_enabled, &global_settings.speaker_enabled, NULL); #endif - +#ifdef AUDIOHW_HAVE_EQ +#endif /* AUDIOHW_HAVE_EQ */ MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio, - &volume, - &bass, -#ifdef HAVE_WM8758 - &bass_cutoff, + &volume +#ifdef AUDIOHW_HAVE_BASS + ,&bass +#endif +#ifdef AUDIOHW_HAVE_BASS_CUTOFF + ,&bass_cutoff +#endif +#ifdef AUDIOHW_HAVE_TREBLE + ,&treble +#endif +#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF + ,&treble_cutoff +#endif +#ifdef AUDIOHW_HAVE_EQ + ,&audiohw_eq_tone_controls #endif - &treble, -#ifdef HAVE_WM8758 - &treble_cutoff, + ,&balance,&channel_config,&stereo_width +#ifdef AUDIOHW_HAVE_DEPTH_3D + ,&depth_3d #endif - &balance,&channel_config,&stereo_width #if CONFIG_CODEC == SWCODEC ,&crossfeed_menu, &equalizer_menu, &dithering_enabled ,×tretch_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 = { round_value_to_list32, #endif +#ifdef AUDIOHW_HAVE_EQ + sound_enum_hw_eq_band_setting, +#endif }; int 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); #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 184 +#define PLUGIN_API_VERSION 185 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -884,6 +884,11 @@ int (*round_value_to_list32)(unsigned long value, int count, bool signd); #endif + +#ifdef AUDIOHW_HAVE_EQ + int (*sound_enum_hw_eq_band_setting)(unsigned int band, + unsigned int band_setting); +#endif /* AUDIOHW_HAVE_EQ */ }; /* 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) switch (setting) { case MPEG_AUDIO_TONE_CONTROLS: + #if defined(AUDIOHW_HAVE_BASS) || defined(AUDIOHW_HAVE_TREBLE) if (global || settings.tone_controls) { + #ifdef AUDIOHW_HAVE_BASS val0 = rb->global_settings->bass; + #endif + #ifdef AUDIOHW_HAVE_TREBLE val1 = rb->global_settings->treble; + #endif } else { + #ifdef AUDIOHW_HAVE_BASS val0 = rb->sound_default(SOUND_BASS); + #endif + #ifdef AUDIOHW_HAVE_TREBLE val1 = rb->sound_default(SOUND_TREBLE); + #endif } + #ifdef AUDIOHW_HAVE_BASS rb->sound_set(SOUND_BASS, val0); + #endif + #ifdef AUDIOHW_HAVE_TREBLE rb->sound_set(SOUND_TREBLE, val1); + #endif + #endif /* AUDIOHW_HAVE_BASS || AUDIOHW_HAVE_TREBLE */ + + #ifdef AUDIOHW_HAVE_EQ + for (val1 = 0;; val1++) + { + int setting = rb->sound_enum_hw_eq_band_setting(val1, AUDIOHW_EQ_GAIN); + + if (setting == -1) + break; + + if (global || settings.tone_controls) + { + val0 = rb->global_settings->hw_eq_bands[val1].gain; + } + else + { + val0 = rb->sound_default(setting); + } + + rb->sound_set(setting, val0); + } + #endif /* AUDIOHW_HAVE_EQ */ break; 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 @@ #include "config.h" #include "action.h" #include "crc32.h" +#include "sound.h" #include "settings.h" #include "debug.h" #include "usb.h" @@ -55,7 +56,6 @@ #include "powermgmt.h" #include "keyboard.h" #include "version.h" -#include "sound.h" #include "rbunicode.h" #include "dircache.h" #include "splash.h" @@ -718,8 +718,12 @@ void sound_settings_apply(void) #if CONFIG_CODEC == SWCODEC sound_set_dsp_callback(dsp_callback); #endif +#ifdef AUDIOHW_HAVE_BASS sound_set(SOUND_BASS, global_settings.bass); +#endif +#ifdef AUDIOHW_HAVE_TREBLE sound_set(SOUND_TREBLE, global_settings.treble); +#endif sound_set(SOUND_BALANCE, global_settings.balance); sound_set(SOUND_VOLUME, global_settings.volume); sound_set(SOUND_CHANNELS, global_settings.channel_config); @@ -734,13 +738,36 @@ void sound_settings_apply(void) sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable); sound_set(SOUND_SUPERBASS, global_settings.superbass); #endif - -#ifdef HAVE_WM8758 +#ifdef AUDIOHW_HAVE_BASS_CUTOFF sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff); +#endif +#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff); #endif -} +#ifdef AUDIOHW_HAVE_DEPTH_3D + sound_set(SOUND_DEPTH_3D, global_settings.depth_3d); +#endif +#ifdef AUDIOHW_HAVE_EQ + int b; + for (b = 0; b < AUDIOHW_EQ_BAND_NUM; b++) + { + int setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_GAIN); + sound_set(setting, global_settings.hw_eq_bands[b].gain); + +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_FREQUENCY); + if (setting != -1) + sound_set(setting, global_settings.hw_eq_bands[b].frequency); +#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */ +#ifdef AUDIOHW_HAVE_EQ_WIDTH + setting = sound_enum_hw_eq_band_setting(b, AUDIOHW_EQ_WIDTH); + if (setting != -1) + sound_set(setting, global_settings.hw_eq_bands[b].width); +#endif /* AUDIOHW_HAVE_EQ_WIDTH */ + } +#endif +} void settings_apply(bool read_disk) { 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 bool superbass; /* true/false */ #endif -#ifdef HAVE_WM8758 +#if defined(HAVE_WM8758) || defined(HAVE_WM8978) int bass_cutoff; int treble_cutoff; #endif @@ -831,6 +831,25 @@ struct user_settings /* When resuming playback (after a stop), rewind this number of seconds */ int resume_rewind; #endif + +#ifdef AUDIOHW_HAVE_DEPTH_3D + int depth_3d; +#endif + +#ifdef AUDIOHW_HAVE_EQ + /** Hardware EQ tone controls **/ + struct hw_eq_band + { + /* Maintain the order of members or sound_menu has to be changed */ + int gain; +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + int frequency; +#endif +#ifdef AUDIOHW_HAVE_EQ_WIDTH + int width; +#endif + } hw_eq_bands[AUDIOHW_EQ_BAND_NUM]; +#endif /* AUDIOHW_HAVE_EQ */ }; /** 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 @@ #include "lcd.h" #include "button.h" #include "backlight.h" +#include "sound.h" #include "settings.h" #include "settings_list.h" #include "usb.h" -#include "sound.h" #include "dsp.h" #include "audio.h" #include "power.h" @@ -552,9 +552,97 @@ const struct settings_list settings[] = { /* sound settings */ SOUND_SETTING(F_NO_WRAP,volume, LANG_VOLUME, "volume", SOUND_VOLUME), SOUND_SETTING(0, balance, LANG_BALANCE, "balance", SOUND_BALANCE), +/* Tone controls */ +#ifdef AUDIOHW_HAVE_BASS SOUND_SETTING(F_NO_WRAP,bass, LANG_BASS, "bass", SOUND_BASS), +#endif +#ifdef AUDIOHW_HAVE_TREBLE SOUND_SETTING(F_NO_WRAP,treble, LANG_TREBLE, "treble", SOUND_TREBLE), - +#endif +/* Hardware EQ tone controls */ +#ifdef AUDIOHW_HAVE_EQ +/* Band gain is generic */ + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND1].gain, + LANG_HW_EQ_GAIN, "tone band1 gain", SOUND_EQ_BAND1_GAIN), +#ifdef AUDIOHW_HAVE_EQ_BAND2 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND2].gain, + LANG_HW_EQ_GAIN, "tone band2 gain", SOUND_EQ_BAND2_GAIN), +#endif /* AUDIOHW_HAVE_EQ_BAND2 */ +#ifdef AUDIOHW_HAVE_EQ_BAND3 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND3].gain, + LANG_HW_EQ_GAIN, "tone band3 gain", SOUND_EQ_BAND3_GAIN), +#endif /* AUDIOHW_HAVE_EQ_BAND3 */ +#ifdef AUDIOHW_HAVE_EQ_BAND4 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND4].gain, + LANG_HW_EQ_GAIN, "tone band4 gain", SOUND_EQ_BAND4_GAIN), +#endif /* AUDIOHW_HAVE_EQ_BAND4 */ +#ifdef AUDIOHW_HAVE_EQ_BAND5 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[AUDIOHW_EQ_BAND5].gain, + LANG_HW_EQ_GAIN, "tone band5 gain", SOUND_EQ_BAND5_GAIN), +#endif /* AUDIOHW_HAVE_EQ_BAND5 */ +#ifdef HAVE_WM8978 + /* Frequencies vary with samplerate but at least the user has an idea + * about the bands and it will be correct with normal playback rates. */ +/* Band 1 */ + STRINGCHOICE_SETTING(F_SOUNDSETTING, + hw_eq_bands[AUDIOHW_EQ_BAND1].frequency, + LANG_HW_EQ_FREQUENCY, 0,"tone band1 frequency", + "80 Hz,105 Hz,135 Hz,175 Hz", + sound_set_hw_eq_band1_frequency, 4, + TALK_ID(80, UNIT_HERTZ), TALK_ID(105, UNIT_HERTZ), + TALK_ID(135, UNIT_HERTZ), TALK_ID(175, UNIT_HERTZ)), +/* Band 2 */ + STRINGCHOICE_SETTING(F_SOUNDSETTING, + hw_eq_bands[AUDIOHW_EQ_BAND2].frequency, + LANG_HW_EQ_FREQUENCY, 0,"tone band2 frequency", + "230 Hz,300 Hz,385 Hz,500 Hz", + sound_set_hw_eq_band2_frequency, 4, + TALK_ID(230, UNIT_HERTZ), TALK_ID(300, UNIT_HERTZ), + TALK_ID(385, UNIT_HERTZ), TALK_ID(500, UNIT_HERTZ)), + CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[AUDIOHW_EQ_BAND2].width, + LANG_HW_EQ_WIDTH, 0, "tone band2 width", "narrow,wide", + sound_set_hw_eq_band2_width, 2, + ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)), +/* Band 3 */ + STRINGCHOICE_SETTING(F_SOUNDSETTING, + hw_eq_bands[AUDIOHW_EQ_BAND3].frequency, + LANG_HW_EQ_FREQUENCY, 0, "tone band3 frequency", + "650 Hz,850 Hz,1.1 kHz,1.4 kHz", + sound_set_hw_eq_band3_frequency, 4, + TALK_ID(650, UNIT_HERTZ), TALK_ID(850, UNIT_HERTZ), + TALK_ID_DECIMAL(11, 1, UNIT_KHZ), + TALK_ID_DECIMAL(14, 1, UNIT_KHZ)), + CHOICE_SETTING(F_SOUNDSETTING,hw_eq_bands[AUDIOHW_EQ_BAND3].width, + LANG_HW_EQ_WIDTH, 0, "tone band3 width", "narrow,wide", + sound_set_hw_eq_band3_width, 2, + ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)), +/* Band 4 */ + STRINGCHOICE_SETTING(F_SOUNDSETTING, + hw_eq_bands[AUDIOHW_EQ_BAND4].frequency, + LANG_HW_EQ_FREQUENCY, 0, "tone band4 frequency", + "1.8 kHz,2.4 kHz,3.2 kHz,4.1 kHz", + sound_set_hw_eq_band4_frequency, 4, + TALK_ID_DECIMAL(18, 1, UNIT_KHZ), + TALK_ID_DECIMAL(24, 1, UNIT_KHZ), + TALK_ID_DECIMAL(32, 1, UNIT_KHZ), + TALK_ID_DECIMAL(41, 1, UNIT_KHZ)), + CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[AUDIOHW_EQ_BAND4].width, + LANG_HW_EQ_WIDTH, 0, "tone band4 width", "narrow,wide", + sound_set_hw_eq_band4_width, 2, + ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)), +/* Band 5 */ + STRINGCHOICE_SETTING(F_SOUNDSETTING, + hw_eq_bands[AUDIOHW_EQ_BAND5].frequency, + LANG_HW_EQ_FREQUENCY, 0, "tone band5 frequency", + "5.3 kHz,6.9 kHz,9.0 kHz,11.7 kHz", + sound_set_hw_eq_band5_frequency, 4, + TALK_ID_DECIMAL(53, 1, UNIT_KHZ), + TALK_ID_DECIMAL(69, 1, UNIT_KHZ), + TALK_ID_DECIMAL(90, 1, UNIT_KHZ), + TALK_ID_DECIMAL(117, 1, UNIT_KHZ)), +#endif /* HAVE_WM8978 */ +#endif /* AUDIOHW_HAVE_EQ */ +/* 3-d enhancement effect */ #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) SOUND_SETTING(0,loudness, LANG_LOUDNESS, "loudness", SOUND_LOUDNESS), STRINGCHOICE_SETTING(F_SOUNDSETTING,avc,LANG_AUTOVOL,0,"auto volume", @@ -574,6 +662,10 @@ const struct settings_list settings[] = { ID2P(LANG_CHANNEL_RIGHT), ID2P(LANG_CHANNEL_KARAOKE)), SOUND_SETTING(F_SOUNDSETTING, stereo_width, LANG_STEREO_WIDTH, "stereo_width", SOUND_STEREO_WIDTH), +#ifdef AUDIOHW_HAVE_DEPTH_3D + SOUND_SETTING(0,depth_3d, LANG_DEPTH_3D, "3-d enhancement", + SOUND_DEPTH_3D), +#endif /* playback */ OFFON_SETTING(0, playlist_shuffle, LANG_SHUFFLE, false, "shuffle", NULL), SYSTEM_SETTING(NVRAM(4), resume_index, -1), @@ -1332,9 +1424,11 @@ const struct settings_list settings[] = { "compressor release time", UNIT_MS, 100, 1000, 100, NULL, NULL, compressor_set), #endif -#ifdef HAVE_WM8758 +#ifdef AUDIOHW_HAVE_BASS_CUTOFF SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF, "bass cutoff", SOUND_BASS_CUTOFF), +#endif +#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF SOUND_SETTING(F_NO_WRAP, treble_cutoff, LANG_TREBLE_CUTOFF, "treble cutoff", SOUND_TREBLE_CUTOFF), #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); const struct sound_settings_info audiohw_settings[] = { - [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, - [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 0}, - [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, - [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, - [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, + [SOUND_VOLUME] = {"dB", 0, 1, -90, 6, -25}, + [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, + [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, + [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, + [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0}, + [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0}, + [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0}, + [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0}, + [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0}, + [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 0, 3, 0}, + [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 0, 3, 0}, + [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 0, 3, 0}, + [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 0, 3, 0}, + [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 0, 3, 0}, + [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0}, + [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0}, + [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0}, + [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, #ifdef HAVE_RECORDING /* Digital: -119.0dB to +8.0dB in 0.5dB increments * Analog: Relegated to volume control * Circumstances unfortunately do not allow a great deal of positive * gain. */ - [SOUND_LEFT_GAIN] = {"dB", 1, 1,-238, 16, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-238, 16, 0}, + [SOUND_LEFT_GAIN] = {"dB", 1, 1,-238, 16, 0}, + [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-238, 16, 0}, #if 0 - [SOUND_MIC_GAIN] = {"dB", 1, 1,-238, 16, 0}, + [SOUND_MIC_GAIN] = {"dB", 1, 1,-238, 16, 0}, #endif #endif -#if 0 - [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, - [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, -#endif }; static uint16_t wmc_regs[WMC_NUM_REGISTERS] = @@ -123,10 +131,20 @@ struct { int vol_l; int vol_r; + int dac_l; + int dac_r; bool ahw_mute; + int prescaler; + int enhance_3d_prescaler; } wmc_vol = { - 0, 0, false + .vol_l = 0, + .vol_r = 0, + .dac_l = 0, + .dac_r = 0, + .ahw_mute = false, + .prescaler = 0, + .enhance_3d_prescaler = 0, }; static void wmc_write(unsigned int reg, unsigned int val) @@ -191,6 +209,10 @@ int sound_val2phys(int setting, int value) break; #endif + case SOUND_DEPTH_3D: + result = (100 * value + 8) / 15; + break; + default: result = value; } @@ -216,8 +238,12 @@ void audiohw_preinit(void) wmc_set(WMC_OUT4_MONO_MIXER_CTRL, WMC_MUTE); /* 3. Set L/RMIXEN = 1 and DACENL/R = 1 in register R3. */ - wmc_write(WMC_POWER_MANAGEMENT3, - WMC_RMIXEN | WMC_LMIXEN | WMC_DACENR | WMC_DACENL); + wmc_write(WMC_POWER_MANAGEMENT3, WMC_RMIXEN | WMC_LMIXEN); + + /* EQ and 3D applied to DAC (Set before DAC enable!) */ + wmc_set(WMC_EQ1_LOW_SHELF, WMC_EQ3DMODE); + + wmc_set(WMC_POWER_MANAGEMENT3, WMC_DACENR | WMC_DACENL); /* 4. Set BUFIOEN = 1 and VMIDSEL[1:0] to required value in register * R1. Wait for VMID supply to settle */ @@ -305,6 +331,12 @@ void audiohw_set_headphone_vol(int vol_l, int vol_r) get_headphone_levels(vol_l, &dac_l, &hp_l, &mix_l, &boost_l); get_headphone_levels(vol_r, &dac_r, &hp_r, &mix_r, &boost_r); + wmc_vol.dac_l = dac_l; + wmc_vol.dac_r = dac_r; + + dac_l -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler; + dac_r -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler; + wmc_write_masked(WMC_LEFT_MIXER_CTRL, mix_l << WMC_BYPLMIXVOL_POS, WMC_BYPLMIXVOL); wmc_write_masked(WMC_LEFT_ADC_BOOST_CTRL, @@ -367,6 +399,64 @@ static void audiohw_mute(bool mute) } } +/* Equalizer - set the eq band level -12 to +12 dB. */ +void audiohw_set_eq_band_gain(unsigned int band, int val) +{ + if (band > 4) + return; + + wmc_write_masked(band + WMC_EQ1_LOW_SHELF, 12 - val, WMC_EQG); +} + +/* Equalizer - set the eq band frequency index. */ +void audiohw_set_eq_band_frequency(unsigned int band, int val) +{ + if (band > 4) + return; + + wmc_write_masked(band + WMC_EQ1_LOW_SHELF, + val << WMC_EQC_POS, WMC_EQC); +} + +/* Equalizer - set bandwidth for peaking filters to wide (!= 0) or + * narrow (0); only valid for peaking filter bands 1-3. */ +void audiohw_set_eq_band_width(unsigned int band, int val) +{ + if (band < 1 || band > 3) + return; + + wmc_write_masked(band + WMC_EQ1_LOW_SHELF, + (val == 0) ? 0 : WMC_EQBW, WMC_EQBW); +} + +/* Set prescaler to prevent clipping the output amp when applying positive + * gain to EQ bands. */ +void audiohw_set_prescaler(int val) +{ + val *= 2; + wmc_vol.prescaler = val; + val += wmc_vol.enhance_3d_prescaler; /* Combine with 3D attenuation */ + + wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - val, + WMC_DVOL); + wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - val, + WMC_DVOL); +} + +/* Set the depth of the 3D effect */ +void audiohw_set_depth_3d(int val) +{ + int att = 10*val / 15; /* -5 dB @ full setting */ + wmc_vol.enhance_3d_prescaler = att; + att += wmc_vol.prescaler; /* Combine with prescaler attenuation */ + + wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - att, + WMC_DVOL); + wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - att, + WMC_DVOL); + wmc_write_masked(WMC_3D_CONTROL, val, WMC_DEPTH3D); +} + void audiohw_close(void) { /* 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 @@ #include <stdbool.h> /* define some audiohw caps */ -#define TREBLE_CAP (1 << 0) -#define BASS_CAP (1 << 1) -#define BALANCE_CAP (1 << 2) -#define CLIPPING_CAP (1 << 3) -#define PRESCALER_CAP (1 << 4) -#define BASS_CUTOFF_CAP (1 << 5) -#define TREBLE_CUTOFF_CAP (1 << 6) +#define TREBLE_CAP (1 << 0) +#define BASS_CAP (1 << 1) +#define BALANCE_CAP (1 << 2) +#define CLIPPING_CAP (1 << 3) +#define PRESCALER_CAP (1 << 4) +#define BASS_CUTOFF_CAP (1 << 5) +#define TREBLE_CUTOFF_CAP (1 << 6) +#define EQ_CAP (1 << 7) +#define DEPTH_3D_CAP (1 << 8) #ifdef HAVE_UDA1380 #include "uda1380.h" @@ -75,12 +77,17 @@ #define VOLUME_MAX 0 #endif +#ifndef AUDIOHW_NUM_TONE_CONTROLS +#define AUDIOHW_NUM_TONE_CONTROLS 0 +#endif + /* volume/balance/treble/bass interdependency main part */ #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) /* convert caps into defines */ #ifdef AUDIOHW_CAPS +/* Tone controls */ #if (AUDIOHW_CAPS & TREBLE_CAP) #define AUDIOHW_HAVE_TREBLE #endif @@ -89,6 +96,14 @@ #define AUDIOHW_HAVE_BASS #endif +#if (AUDIOHW_CAPS & BASS_CUTOFF_CAP) +#define AUDIOHW_HAVE_BASS_CUTOFF +#endif + +#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP) +#define AUDIOHW_HAVE_TREBLE_CUTOFF +#endif + #if (AUDIOHW_CAPS & BALANCE_CAP) #define AUDIOHW_HAVE_BALANCE #endif @@ -101,19 +116,127 @@ #define AUDIOHW_HAVE_PRESCALER #endif -#if (AUDIOHW_CAPS & BASS_CUTOFF_CAP) -#define AUDIOHW_HAVE_BASS_CUTOFF +/* Hardware EQ tone controls */ +#if (AUDIOHW_CAPS & EQ_CAP) +/* A hardware equalizer is present (or perhaps some tone control variation + * that is not Bass and/or Treble) */ +#define AUDIOHW_HAVE_EQ + +/* Defined band indexes for supported bands */ +enum +{ + /* Band 1 is implied; bands must be contiguous, 1 to N */ + AUDIOHW_EQ_BAND1 = 0, +#define AUDIOHW_HAVE_EQ_BAND1 +#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 1)) + AUDIOHW_EQ_BAND2, +#define AUDIOHW_HAVE_EQ_BAND2 +#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 2)) + AUDIOHW_EQ_BAND3, +#define AUDIOHW_HAVE_EQ_BAND3 +#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 3)) + AUDIOHW_EQ_BAND4, +#define AUDIOHW_HAVE_EQ_BAND4 +#if (AUDIOHW_EQ_BAND_CAPS & (EQ_CAP << 4)) + AUDIOHW_EQ_BAND5, +#define AUDIOHW_HAVE_EQ_BAND5 +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ + AUDIOHW_EQ_BAND_NUM, /* Keep last */ +}; + +#ifdef AUDIOHW_EQ_FREQUENCY_CAPS +/* One or more bands supports frequency cutoff or center adjustment */ +#define AUDIOHW_HAVE_EQ_FREQUENCY +enum +{ + __AUDIOHW_EQ_BAND_FREQUENCY = -1, +#if defined(AUDIOHW_HAVE_EQ_BAND1) && \ + (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 0)) + AUDIOHW_EQ_BAND1_FREQUENCY, +#define AUDIOHW_HAVE_EQ_BAND1_FREQUENCY +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2) && \ + (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 1)) + AUDIOHW_EQ_BAND2_FREQUENCY, +#define AUDIOHW_HAVE_EQ_BAND2_FREQUENCY #endif +#if defined(AUDIOHW_HAVE_EQ_BAND3) && \ + (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 2)) + AUDIOHW_EQ_BAND3_FREQUENCY, +#define AUDIOHW_HAVE_EQ_BAND3_FREQUENCY +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4) && \ + (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 3)) + AUDIOHW_EQ_BAND4_FREQUENCY, +#define AUDIOHW_HAVE_EQ_BAND4_FREQUENCY +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND5) && \ + (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 4)) + AUDIOHW_EQ_BAND5_FREQUENCY, +#define AUDIOHW_HAVE_EQ_BAND5_FREQUENCY +#endif + AUDIOHW_EQ_FREQUENCY_NUM, +}; +#endif /* AUDIOHW_EQ_FREQUENCY_CAPS */ + +#ifdef AUDIOHW_EQ_WIDTH_CAPS +/* One or more bands supports bandwidth adjustment */ +#define AUDIOHW_HAVE_EQ_WIDTH +enum +{ + __AUDIOHW_EQ_BAND_WIDTH = -1, +#if defined(AUDIOHW_HAVE_EQ_BAND1) && \ + (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 1)) + AUDIOHW_EQ_BAND2_WIDTH, +#define AUDIOHW_HAVE_EQ_BAND2_WIDTH +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2) && \ + (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 2)) + AUDIOHW_EQ_BAND3_WIDTH, +#define AUDIOHW_HAVE_EQ_BAND3_WIDTH +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3) && \ + (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 3)) + AUDIOHW_EQ_BAND4_WIDTH, +#define AUDIOHW_HAVE_EQ_BAND4_WIDTH +#endif + AUDIOHW_EQ_WIDTH_NUM, /* Keep last */ +}; +#endif /* AUDIOHW_EQ_WIDTH_CAPS */ + +/* Types and number of settings types (gain, frequency, width) */ +enum AUDIOHW_EQ_SETTINGS +{ + AUDIOHW_EQ_GAIN = 0, +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + AUDIOHW_EQ_FREQUENCY, +#endif +#ifdef AUDIOHW_HAVE_EQ_WIDTH + AUDIOHW_EQ_WIDTH, +#endif + AUDIOHW_EQ_SETTING_NUM +}; -#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP) -#define AUDIOHW_HAVE_TREBLE_CUTOFF +#endif /* (AUDIOHW_CAPS & EQ_CAP) */ + +#if (AUDIOHW_CAPS & DEPTH_3D_CAP) +#define AUDIOHW_HAVE_DEPTH_3D #endif + #endif /* AUDIOHW_CAPS */ enum { SOUND_VOLUME = 0, +/* Tone control */ +#if defined(AUDIOHW_HAVE_BASS) SOUND_BASS, +#endif +#if defined(AUDIOHW_HAVE_TREBLE) SOUND_TREBLE, +#endif SOUND_BALANCE, SOUND_CHANNELS, SOUND_STEREO_WIDTH, @@ -132,12 +255,61 @@ enum { SOUND_RIGHT_GAIN, SOUND_MIC_GAIN, #endif +/* Bass and treble tone controls */ #if defined(AUDIOHW_HAVE_BASS_CUTOFF) SOUND_BASS_CUTOFF, #endif #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) SOUND_TREBLE_CUTOFF, #endif +/* 3D effect */ +#if defined(AUDIOHW_HAVE_DEPTH_3D) + SOUND_DEPTH_3D, +#endif +/* Hardware EQ tone controls */ +/* Band gains */ +#if defined(AUDIOHW_HAVE_EQ) + /* Band 1 implied */ + SOUND_EQ_BAND1_GAIN, +#if defined(AUDIOHW_HAVE_EQ_BAND2) + SOUND_EQ_BAND2_GAIN, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3) + SOUND_EQ_BAND3_GAIN, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4) + SOUND_EQ_BAND4_GAIN, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND5) + SOUND_EQ_BAND5_GAIN, +#endif +/* Band frequencies */ +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) + SOUND_EQ_BAND1_FREQUENCY, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) + SOUND_EQ_BAND2_FREQUENCY, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) + SOUND_EQ_BAND3_FREQUENCY, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) + SOUND_EQ_BAND4_FREQUENCY, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) + SOUND_EQ_BAND5_FREQUENCY, +#endif +/* Band widths */ +#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) + SOUND_EQ_BAND2_WIDTH, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) + SOUND_EQ_BAND3_WIDTH, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) + SOUND_EQ_BAND4_WIDTH, +#endif +#endif /* AUDIOHW_HAVE_EQ */ SOUND_LAST_SETTING, /* Keep this last */ }; @@ -262,6 +434,64 @@ void audiohw_set_bass_cutoff(int val); void audiohw_set_treble_cutoff(int val); #endif +#ifdef AUDIOHW_HAVE_EQ +/** + * Set new band gain value. + * @param band index to which val is set + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain + * EQ_CAP + * + * AUDIOHW_EQ_BAND_CAPS must be defined as a bitmask + * of EQ_CAP each shifted by the zero-based band number + * for each band. Bands 1 to N are indexed 0 to N-1. + */ +void audiohw_set_eq_band_gain(unsigned int band, int val); +#endif + +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY +/** + * Set new band cutoff or center frequency value. + * @param band index to which val is set + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain + * EQ_CAP + * + * AUDIOHW_EQ_FREQUENCY_CAPS must be defined as a bitmask + * of EQ_CAP each shifted by the zero-based band number + * for each band that supports frequency adjustment. + * Bands 1 to N are indexed 0 to N-1. + */ +void audiohw_set_eq_band_frequency(unsigned int band, int val); +#endif + +#ifdef AUDIOHW_HAVE_EQ_WIDTH +/** + * Set new band cutoff or center frequency value. + * @param band index to which val is set + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain + * EQ_CAP + * + * AUDIOHW_EQ_WIDTH_CAPS must be defined as a bitmask + * of EQ_CAP each shifted by the zero-based band number + * for each band that supports width adjustment. + * Bands 1 to N are indexed 0 to N-1. + */ +void audiohw_set_eq_band_width(unsigned int band, int val); +#endif + +#ifdef AUDIOHW_HAVE_DEPTH_3D +/** + * Set new 3-d enhancement (stereo expansion) effect value. + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain + * DEPTH_3D_CAP + */ +void audiohw_set_depth_3d(int val); +#endif + + void audiohw_set_frequency(int fsel); #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 @@ /* Define this if you have the WM8978 audio codec */ #define HAVE_WM8978 -/* Tone controls for WM8978 have not been implemented yet */ -#define HAVE_SW_TONE_CONTROLS - /* Define bitmask of input sources - recordable bitmask can be defined explicitly if different */ #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); void sound_set_treble(int value); void sound_set_channels(int value); void sound_set_stereo_width(int value); -#if defined(HAVE_WM8758) || defined(HAVE_WM8985) +#if defined(AUDIOHW_HAVE_BASS_CUTOFF) void sound_set_bass_cutoff(int value); +#endif +#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) void sound_set_treble_cutoff(int value); #endif + +#if defined(AUDIOHW_HAVE_DEPTH_3D) +void sound_set_depth_3d(int value); +#endif + +#ifdef AUDIOHW_HAVE_EQ +/* + * band = SOUND_EQ_BANDb + * band_setting = AUDIOHW_EQ_s + * + * Returns SOUND_EQ_BANDb_s or -1 if it doesn't exist. + * + * b: band number + * s: one of GAIN, FREQUENCY, WIDTH + */ +int sound_enum_hw_eq_band_setting(unsigned int band, + unsigned int band_setting); +/* Band1 implied */ +void sound_set_hw_eq_band1_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY +void sound_set_hw_eq_band1_frequency(int value); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2 +void sound_set_hw_eq_band2_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY +void sound_set_hw_eq_band2_frequency(int value); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH +void sound_set_hw_eq_band2_width(int value); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND2 */ +#ifdef AUDIOHW_HAVE_EQ_BAND3 +/* Band 3 */ +void sound_set_hw_eq_band3_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY +void sound_set_hw_eq_band3_frequency(int value); +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) +void sound_set_hw_eq_band3_width(int value); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND3 */ +#ifdef AUDIOHW_HAVE_EQ_BAND4 +void sound_set_hw_eq_band4_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY +void sound_set_hw_eq_band4_frequency(int value); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH +void sound_set_hw_eq_band4_width(int value); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND4 */ +#ifdef AUDIOHW_HAVE_EQ_BAND5 +void sound_set_hw_eq_band5_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY +void sound_set_hw_eq_band5_frequency(int value); +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND5 */ +#endif /* AUDIOHW_HAVE_EQ */ + #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void sound_set_loudness(int value); void 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 @@ #define VOLUME_MIN -900 #define VOLUME_MAX 60 +#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP) +/* Filter bitmask */ +#define AUDIOHW_EQ_BAND_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \ + (EQ_CAP << 2) | (EQ_CAP << 3) | \ + (EQ_CAP << 4)) +/* Filters that can adjust cutoff and center frequency */ +#define AUDIOHW_EQ_FREQUENCY_CAPS ((EQ_CAP << 0) | (EQ_CAP << 1) | \ + (EQ_CAP << 2) | (EQ_CAP << 3) | \ + (EQ_CAP << 4)) +/* Filters that can adjust band width */ +#define AUDIOHW_EQ_WIDTH_CAPS ((EQ_CAP << 1) | (EQ_CAP << 2) | \ + (EQ_CAP << 3)) + int tenthdb2master(int db); void audiohw_set_headphone_vol(int vol_l, int vol_r); void 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); /* dummy for sim */ const struct sound_settings_info audiohw_settings[] = { [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25}, +/* Bass and treble tone controls */ +#ifdef AUDIOHW_HAVE_BASS [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, +#endif +#ifdef AUDIOHW_HAVE_TREBLE [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, +#endif [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, @@ -64,6 +69,50 @@ const struct sound_settings_info audiohw_settings[] = { #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, #endif +#if defined(AUDIOHW_HAVE_DEPTH_3D) + [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, +#endif +/* Hardware EQ tone controls */ +#if defined(AUDIOHW_HAVE_EQ_BAND1) + [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2) + [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3) + [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4) + [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND5) + [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) + [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) + [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) + [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) + [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) + [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) + [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) + [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0}, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) + [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0}, +#endif + #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0}, [SOUND_AVC] = {"", 0, 1, -1, 4, 0}, @@ -111,8 +160,12 @@ static sound_set_type * const sound_set_fns[] = { [0 ... SOUND_LAST_SETTING-1] = NULL, [SOUND_VOLUME] = sound_set_volume, +#if defined(AUDIOHW_HAVE_BASS) [SOUND_BASS] = sound_set_bass, +#endif +#if defined(AUDIOHW_HAVE_TREBLE) [SOUND_TREBLE] = sound_set_treble, +#endif [SOUND_BALANCE] = sound_set_balance, [SOUND_CHANNELS] = sound_set_channels, [SOUND_STEREO_WIDTH] = sound_set_stereo_width, @@ -132,6 +185,49 @@ static sound_set_type * const sound_set_fns[] = #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff, #endif +#if defined(AUDIOHW_HAVE_DEPTH_3D) + [SOUND_DEPTH_3D] = sound_set_depth_3d, +#endif +/* Hardware EQ tone controls */ +#if defined(AUDIOHW_HAVE_EQ) + [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) + [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2) + [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) + [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) + [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width, +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND2 */ +#if defined(AUDIOHW_HAVE_EQ_BAND3) + [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) + [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) + [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width, +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND3 */ +#if defined(AUDIOHW_HAVE_EQ_BAND4) + [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) + [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) + [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width, +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND4 */ +#if defined(AUDIOHW_HAVE_EQ_BAND5) + [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) + [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency, +#endif +#endif /* AUDIOHW_HAVE_EQ_BAND5 */ +#endif /* AUDIOHW_HAVE_EQ */ }; sound_set_type* sound_get_fn(int setting) @@ -174,8 +270,15 @@ static int tenthdb2reg(int db) /* all values in tenth of dB MAS3507D UDA1380 */ int current_volume = 0; /* -780..+180 -840.. 0 */ int current_balance = 0; /* -960..+960 -840..+840 */ +#ifdef AUDIOHW_HAVE_TREBLE int current_treble = 0; /* -150..+150 0.. +60 */ +#endif +#ifdef AUDIOHW_HAVE_BASS int current_bass = 0; /* -150..+150 0..+240 */ +#endif +#ifdef AUDIOHW_HAVE_EQ +int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM]; +#endif static void set_prescaled_volume(void) { @@ -191,10 +294,18 @@ static void set_prescaled_volume(void) || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \ || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341)) +#if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE) prescale = MAX(current_bass, current_treble); +#endif +#if defined(AUDIOHW_HAVE_EQ) + int i; + for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++) + prescale = MAX(current_eq_band_gain[i], prescale); +#endif + if (prescale < 0) prescale = 0; /* no need to prescale if we don't boost - bass or treble */ + bass, treble or eq band */ /* Gain up the analog volume to compensate the prescale gain reduction, * but if this would push the volume over the top, reduce prescaling @@ -289,6 +400,7 @@ void sound_set_balance(int value) #endif } +#ifdef AUDIOHW_HAVE_BASS void sound_set_bass(int value) { if(!audio_is_initialized) @@ -302,17 +414,19 @@ void sound_set_bass(int value) #endif #endif -#if defined(AUDIOHW_HAVE_BASS) - audiohw_set_bass(value); -#else +#if defined(HAVE_SW_TONE_CONTROLS) dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); +#else + audiohw_set_bass(value); #endif #if !defined(AUDIOHW_HAVE_CLIPPING) set_prescaled_volume(); #endif } +#endif /* AUDIOHW_HAVE_BASS */ +#ifdef AUDIOHW_HAVE_TREBLE void sound_set_treble(int value) { if(!audio_is_initialized) @@ -326,16 +440,37 @@ void sound_set_treble(int value) #endif #endif -#if defined(AUDIOHW_HAVE_TREBLE) - audiohw_set_treble(value); -#else +#if defined(HAVE_SW_TONE_CONTROLS) dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); +#else + audiohw_set_treble(value); #endif #if !defined(AUDIOHW_HAVE_CLIPPING) set_prescaled_volume(); #endif } +#endif /* AUDIOHW_HAVE_TREBLE */ + +#if defined(AUDIOHW_HAVE_BASS_CUTOFF) +void sound_set_bass_cutoff(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_bass_cutoff(value); +} +#endif + +#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) +void sound_set_treble_cutoff(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_treble_cutoff(value); +} +#endif void sound_set_channels(int value) { @@ -361,26 +496,208 @@ void sound_set_stereo_width(int value) #endif } -#if defined(AUDIOHW_HAVE_BASS_CUTOFF) -void sound_set_bass_cutoff(int value) +#if defined(AUDIOHW_HAVE_DEPTH_3D) +void sound_set_depth_3d(int value) { if(!audio_is_initialized) return; - audiohw_set_bass_cutoff(value); + audiohw_set_depth_3d(value); } #endif -#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) -void sound_set_treble_cutoff(int value) +#if defined(AUDIOHW_HAVE_EQ) +int sound_enum_hw_eq_band_setting(unsigned int band, + unsigned int band_setting) +{ + static const int8_t + sound_hw_eq_band_setting[AUDIOHW_EQ_SETTING_NUM][AUDIOHW_EQ_BAND_NUM] = + { + [AUDIOHW_EQ_GAIN] = + { + [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1, + [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_GAIN, + #ifdef AUDIOHW_HAVE_EQ_BAND2 + [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_GAIN, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND3 + [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_GAIN, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND4 + [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_GAIN, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND5 + [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_GAIN, + #endif + }, +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + [AUDIOHW_EQ_FREQUENCY] = + { + [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1, + #ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY + [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_FREQUENCY, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY + [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_FREQUENCY, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY + [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_FREQUENCY, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY + [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_FREQUENCY, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY + [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_FREQUENCY, + #endif + }, +#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */ +#ifdef AUDIOHW_HAVE_EQ_WIDTH + [AUDIOHW_EQ_WIDTH] = + { + [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1, + #ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH + [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_WIDTH, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH + [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_WIDTH, + #endif + #ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH + [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_WIDTH, + #endif + }, +#endif /* AUDIOHW_HAVE_EQ_WIDTH */ + }; + + if (band < AUDIOHW_EQ_BAND_NUM && band_setting < AUDIOHW_EQ_SETTING_NUM) + return sound_hw_eq_band_setting[band_setting][band]; + + return -1; +} + +static void sound_set_hw_eq_band_gain(unsigned int band, int value) { if(!audio_is_initialized) return; - audiohw_set_treble_cutoff(value); + current_eq_band_gain[band] = value; + audiohw_set_eq_band_gain(band, value); + set_prescaled_volume(); +} + +void sound_set_hw_eq_band1_gain(int value) +{ + sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND1, value); +} + +#if defined(AUDIOHW_HAVE_EQ_BAND2) +void sound_set_hw_eq_band2_gain(int value) +{ + sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND2, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND3) +void sound_set_hw_eq_band3_gain(int value) +{ + sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND3, value); } #endif +#if defined(AUDIOHW_HAVE_EQ_BAND4) +void sound_set_hw_eq_band4_gain(int value) +{ + sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND4, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND5) +void sound_set_hw_eq_band5_gain(int value) +{ + sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND5, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) +void sound_set_hw_eq_band1_frequency(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) +void sound_set_hw_eq_band2_frequency(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) +void sound_set_hw_eq_band3_frequency(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) +void sound_set_hw_eq_band4_frequency(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) +void sound_set_hw_eq_band5_frequency(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) +void sound_set_hw_eq_band2_width(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) +void sound_set_hw_eq_band3_width(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) +void sound_set_hw_eq_band4_width(int value) +{ + if(!audio_is_initialized) + return; + + audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value); +} +#endif +#endif /* AUDIOHW_HAVE_EQ */ + #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)) void sound_set_loudness(int value) { @@ -572,6 +889,10 @@ int sound_val2phys(int setting, int value) break; #endif + case SOUND_DEPTH_3D: + result = (100 * value + 8) / 15; + break; + default: result = value; } 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; } #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) void audiohw_set_treble_cutoff(int value){ (void)value; } #endif +/* EQ-based tone controls */ +#if defined(AUDIOHW_HAVE_EQ) +void audiohw_set_eq_band_gain(unsigned int band, int value) + { (void)band; (void)value; } +#endif +#if defined(AUDIOHW_HAVE_EQ_FREQUENCY) +void audiohw_set_eq_band_frequency(unsigned int band, int value) + { (void)band; (void)value; } +#endif +#if defined(AUDIOHW_HAVE_EQ_WIDTH) +void audiohw_set_eq_band_width(unsigned int band, int value) + { (void)band; (void)value; } +#endif +#if defined(AUDIOHW_HAVE_DEPTH_3D) +void audiohw_set_depth_3d(int value) + { (void)value; } +#endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) int mas_codec_readreg(int reg) { |