From: jethead71 Date: Sat, 15 May 2010 13:09:45 +0000 (+0000) Subject: Gigabeat S: Fully enable access to hardware tone controls and 3-D effect feature... X-Git-Url: https://repo.or.cz/w/kugel-rb.git/commitdiff_plain/17e0fb873ae7de721755b343836aeac1eafa6698 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 --- diff --git a/apps/SOURCES b/apps/SOURCES index 2642fa16b..2bd401875 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 c079a4aff..4a4fb2c73 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -13595,3 +13595,140 @@ radio: "" + + id: LANG_HW_EQ_TONE_CONTROLS + desc: in sound_menu, hardware equalizer tone controls + user: core + + *: none + gigabeats: "Tone Controls" + + + *: none + gigabeats: "Tone Controls" + + + *: none + gigabeats: "Tone Controls" + + + + id: LANG_HW_EQ_TONE_CONTROLS_ADVANCED + desc: in sound_menu, advanced settings for hardware equalizer tone controls + user: core + + *: none + gigabeats: "Advanced Tone Control Settings" + + + *: none + gigabeats: "Advanced Tone Control Settings" + + + *: none + gigabeats: "Advanced Tone Control Settings" + + + + id: LANG_HW_EQ_GAIN + desc: in sound_menu, hardware equalizer tone controls filter gain + user: core + + *: none + gigabeats: "Band %d Gain" + + + *: none + gigabeats: "Band %d Gain" + + + *: none + gigabeats: "Band Gain" + + + + id: LANG_HW_EQ_FREQUENCY + desc: in sound_menu, hardware equalizer tone controls shelf filter cutoff frequency + user: core + + *: none + gigabeats: "Band %d Frequency" + + + *: none + gigabeats: "Band %d Frequency" + + + *: none + gigabeats: "Band Frequency" + + + + id: LANG_HW_EQ_WIDTH + desc: in sound_menu, hardware equalizer tone controls peak bandwith setting + user: core + + *: none + gigabeats: "Band %d Width" + + + *: none + gigabeats: "Band %d Width" + + + *: none + gigabeats: "Band Width" + + + + id: LANG_HW_EQ_WIDTH_NARROW + desc: in sound_menu, hardware equalizer tone controls narrow bandwith setting + user: core + + *: none + gigabeats: "Narrow" + + + *: none + gigabeats: "Narrow" + + + *: none + gigabeats: "Narrow" + + + + id: LANG_HW_EQ_WIDTH_WIDE + desc: in sound_menu, hardware equalizer tone controls wide bandwidth setting + user: core + + *: none + gigabeats: "Wide" + + + *: none + gigabeats: "Wide" + + + *: none + gigabeats: "Wide" + + + + id: LANG_DEPTH_3D + desc: in sound_menu, amount of 3D enhancement effect + user: core + + *: none + gigabeats: "3-D Enhancement" + + + *: none + gigabeats: "3-D Enhancement" + + + *: none + gigabeats: "3-D Enhancement" + + + diff --git a/apps/menus/audiohw_eq_menu.c b/apps/menus/audiohw_eq_menu.c new file mode 100644 index 000000000..1027d6a0b --- /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 +#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 9fb39cbf8..37b5ff31d 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 0ce860cb7..066b1daba 100644 --- a/apps/menus/sound_menu.c +++ b/apps/menus/sound_menu.c @@ -23,6 +23,7 @@ #include #include #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 b60e2d676..90380a003 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 5aaa6380b..108a28359 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 6c8a2b8e3..1ac2476b2 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 490195726..634937232 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 2fdff9918..c8e8d642a 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 1bc783219..d6f5f94f6 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 a2dbf5a8f..2d57ce3f1 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 22f6e6856..12c4738f7 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -26,13 +26,15 @@ #include /* 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 2bc56ec98..73eb79ce9 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 e68ae2377..7243f48e7 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 270c666a4..4081d05a8 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 b56e61003..fb2f353d7 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 dd5e4345a..0f8d5d493 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) {