Index: apps/settings.c =================================================================== --- apps/settings.c (revision 25939) +++ apps/settings.c (working copy) @@ -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" @@ -713,13 +713,51 @@ } #endif /* HAVE_LCD_BITMAP */ +#ifdef AUDIOHW_HAVE_EQ +static inline void sound_settings_apply_hw_eq(void) +{ + int b; +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + int f = SOUND_EQ_BAND1_GAIN + AUDIOHW_EQ_NUM_BANDS; +#endif +#ifdef AUDIOHW_HAVE_EQ_WIDTH + int w = SOUND_EQ_BAND1_GAIN + AUDIOHW_EQ_NUM_BANDS + + AUDIOHW_EQ_NUM_FREQUENCY; +#endif + + for (b = 0; b < AUDIOHW_EQ_NUM_BANDS; b++) + { + sound_set(SOUND_EQ_BAND1_GAIN + b, + global_settings.hw_eq_bands[b][AUDIOHW_EQ_GAIN]); +#ifdef AUDIOHW_HAVE_EQ_FREQUENCY + if ((EQ_CAP << b) & AUDIOHW_EQ_FREQUENCY_CAPS) + { + sound_set(f, global_settings.hw_eq_bands[b][AUDIOHW_EQ_FREQUENCY]); + f++; + } +#endif +#ifdef AUDIOHW_HAVE_EQ_WIDTH + if ((EQ_CAP << b) & AUDIOHW_EQ_WIDTH_CAPS) + { + sound_set(w, global_settings.hw_eq_bands[b][AUDIOHW_EQ_WIDTH]); + w++; + } +#endif + } +} +#endif /* AUDIOHW_HAVE_EQ */ + 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,14 +772,20 @@ 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_EQ + sound_settings_apply_hw_eq(); +#endif +#ifdef AUDIOHW_HAVE_DEPTH_3D + sound_set(SOUND_DEPTH_3D, global_settings.depth_3d); +#endif } - void settings_apply(bool read_disk) { Index: apps/plugins/mpegplayer/mpeg_settings.c =================================================================== --- apps/plugins/mpegplayer/mpeg_settings.c (revision 25939) +++ apps/plugins/mpegplayer/mpeg_settings.c (working copy) @@ -403,18 +403,48 @@ 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 < AUDIOHW_EQ_NUM_BANDS; val1++) + { + if (global || settings.tone_controls) + { + val0 = rb->global_settings->hw_eq_bands[val1][AUDIOHW_EQ_GAIN]; + } + else + { + val0 = rb->sound_default(val1 + SOUND_EQ_BAND1_GAIN); + } + + rb->sound_set(val1 + SOUND_EQ_BAND1_GAIN, val0); + } + #endif /* AUDIOHW_HAVE_EQ */ break; case MPEG_AUDIO_CHANNEL_MODES: Index: apps/lang/english.lang =================================================================== --- apps/lang/english.lang (revision 25939) +++ apps/lang/english.lang (working copy) @@ -13530,3 +13530,139 @@ swcodec: "Rewind before resume" + + 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" + + Index: apps/settings.h =================================================================== --- apps/settings.h (revision 25939) +++ apps/settings.h (working copy) @@ -336,7 +336,7 @@ bool superbass; /* true/false */ #endif -#ifdef HAVE_WM8758 +#if defined(HAVE_WM8758) || defined(HAVE_WM8978) int bass_cutoff; int treble_cutoff; #endif @@ -827,6 +827,15 @@ /* When resuming playback (after a stop), rewind this number of seconds */ int resume_rewind; #endif + +#ifdef AUDIOHW_HAVE_EQ + /** Hardware EQ tone controls **/ + /* For each band: gain, frequency, width */ + int hw_eq_bands[AUDIOHW_EQ_NUM_BANDS][AUDIOHW_EQ_NUM_SETTINGS]; +#endif +#ifdef AUDIOHW_HAVE_DEPTH_3D + int depth_3d; +#endif }; /** global variables **/ Index: apps/menus/sound_menu.c =================================================================== --- apps/menus/sound_menu.c (revision 25939) +++ apps/menus/sound_menu.c (working copy) @@ -22,9 +22,11 @@ #include #include #include +#include #include "config.h" #include "lang.h" #include "action.h" +#include "sound.h" #include "settings.h" #include "menu.h" #include "sound_menu.h" @@ -34,10 +36,12 @@ #include "splash.h" #include "kernel.h" #include "dsp.h" +#include "talk.h" /***********************************/ /* 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 +49,14 @@ 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 +64,13 @@ 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 +87,10 @@ #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 +154,225 @@ MENUITEM_SETTING(speaker_enabled, &global_settings.speaker_enabled, NULL); #endif +#ifdef AUDIOHW_HAVE_EQ +static unsigned short hw_eq_setting_lang_ids[AUDIOHW_EQ_NUM_SETTINGS] = +{ + 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[(uintptr_t)data >> 8]), + (uint8_t)(uintptr_t)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[(uintptr_t)data >> 8], false); + talk_number((uint8_t)(uintptr_t)data + 1, true); + return 0; + (void)selected_item; +} + +static int hw_eq_do_band_setting(void *param) +{ + int setting = (uintptr_t)param >> 8; + int band = (uint8_t)(uintptr_t)param; + char desc[MAX_PATH]; + struct menu_callback_with_desc cbadesc = + { + .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][setting] }, + { .callback_and_desc = &cbadesc } + }; + do_setting_from_menu(&item, NULL); + return 0; +} + +/* 1 */ +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band1_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, (void*)0x0000, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0000, 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, (void*)0x0100, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0100, NULL, Icon_NOICON); +#endif +/* 2 */ +#if AUDIOHW_EQ_NUM_BANDS >= 2 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band2_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, (void*)0x0001, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0001, 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, (void*)0x0101, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0101, 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, (void*)0x0201, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0201, NULL, Icon_NOICON); +#endif +/* 3 */ +#if AUDIOHW_EQ_NUM_BANDS >= 3 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band3_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, (void*)0x0002, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0002, 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, (void*)0x0102, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0102, 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, (void*)0x0202, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0202, NULL, Icon_NOICON); +#endif +/* 4 */ +#if AUDIOHW_EQ_NUM_BANDS >= 4 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band4_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, (void*)0x0003, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0003, 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, (void*)0x0103, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0103, 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, (void*)0x0203, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0203, NULL, Icon_NOICON); +#endif +/* 5 */ +#if AUDIOHW_EQ_NUM_BANDS >= 5 +MENUITEM_FUNCTION_DYNTEXT(hw_eq_band5_gain, MENU_FUNC_USEPARAM, + hw_eq_do_band_setting, (void*)0x0004, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0004, 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, (void*)0x0104, + hw_eq_get_name, hw_eq_speak_item, + (void*)0x0104, NULL, Icon_NOICON); +#endif +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ + +/* 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 +/* 2 */ +#if AUDIOHW_EQ_NUM_BANDS >= 2 + ,&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 +/* 3 */ +#if AUDIOHW_EQ_NUM_BANDS >= 3 + ,&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 +/* 4 */ +#if AUDIOHW_EQ_NUM_BANDS >= 4 + ,&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 +/* 5 */ +#if AUDIOHW_EQ_NUM_BANDS >= 5 + ,&hw_eq_band5_gain +#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY + ,&hw_eq_band5_frequency +#endif +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ + ); +/* Shows only the gains + advanced settings submenu */ +MAKE_MENU(hardware_eq_tone_controls, ID2P(LANG_HW_EQ_TONE_CONTROLS), + NULL, Icon_NOICON + ,&hw_eq_band1_gain +#if AUDIOHW_EQ_NUM_BANDS >= 2 + ,&hw_eq_band2_gain +#if AUDIOHW_EQ_NUM_BANDS >= 3 + ,&hw_eq_band3_gain +#if AUDIOHW_EQ_NUM_BANDS >= 4 + ,&hw_eq_band4_gain +#if AUDIOHW_EQ_NUM_BANDS >= 5 + ,&hw_eq_band5_gain +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ + ,&hardware_eq_tone_controls_advanced + ); + +#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 - &treble, -#ifdef HAVE_WM8758 - &treble_cutoff, +#ifdef AUDIOHW_HAVE_BASS_CUTOFF + ,&bass_cutoff #endif - &balance,&channel_config,&stereo_width +#ifdef AUDIOHW_HAVE_TREBLE + ,&treble +#endif +#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF + ,&treble_cutoff +#endif +#ifdef AUDIOHW_HAVE_EQ + ,&hardware_eq_tone_controls +#endif + ,&balance,&channel_config,&stereo_width +#ifdef AUDIOHW_HAVE_DEPTH_3D + ,&depth_3d +#endif #if CONFIG_CODEC == SWCODEC ,&crossfeed_menu, &equalizer_menu, &dithering_enabled ,×tretch_enabled Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 25939) +++ apps/settings_list.c (working copy) @@ -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" @@ -551,9 +551,78 @@ /* 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 +/* 1 */ + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[0][0], LANG_HW_EQ_GAIN, + "eq tone band1 gain", SOUND_EQ_BAND1_GAIN), +#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY + SOUND_SETTING(0, hw_eq_bands[0][1], LANG_HW_EQ_FREQUENCY, + "eq tone band1 frequency", SOUND_EQ_BAND1_FREQUENCY), +#endif +/* 2 */ +#if AUDIOHW_EQ_NUM_BANDS >= 2 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[1][0], LANG_HW_EQ_GAIN, + "eq tone band2 gain", SOUND_EQ_BAND2_GAIN), +#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY + SOUND_SETTING(0, hw_eq_bands[1][1], LANG_HW_EQ_FREQUENCY, + "eq tone band2 frequency", SOUND_EQ_BAND2_FREQUENCY), +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH + CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[1][2], LANG_HW_EQ_WIDTH, 0, + "eq tone band2 width", "narrow,wide", + sound_set_eq_band2_width, 2, + ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)), +#endif +/* 3 */ +#if AUDIOHW_EQ_NUM_BANDS >= 3 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[2][0], LANG_HW_EQ_GAIN, + "eq tone band3 gain", SOUND_EQ_BAND3_GAIN), +#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY + SOUND_SETTING(0, hw_eq_bands[2][1], LANG_HW_EQ_FREQUENCY, + "eq tone band3 frequency", SOUND_EQ_BAND3_FREQUENCY), +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH + CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[2][2], LANG_HW_EQ_WIDTH, 0, + "eq tone band3 width", "narrow,wide", + sound_set_eq_band3_width, 2, + ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)), +#endif +/* 4 */ +#if AUDIOHW_EQ_NUM_BANDS >= 4 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[3][0], LANG_HW_EQ_GAIN, + "eq tone band4 gain", SOUND_EQ_BAND4_GAIN), +#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY + SOUND_SETTING(0, hw_eq_bands[3][1], LANG_HW_EQ_FREQUENCY, + "eq tone band4 frequency", SOUND_EQ_BAND4_FREQUENCY), +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH + CHOICE_SETTING(F_SOUNDSETTING, hw_eq_bands[3][2], LANG_HW_EQ_WIDTH, 0, + "eq tone band4 width", "narrow,wide", + sound_set_eq_band4_width, 2, + ID2P(LANG_HW_EQ_WIDTH_NARROW), ID2P(LANG_HW_EQ_WIDTH_WIDE)), +#endif +/* 5 */ +#if AUDIOHW_EQ_NUM_BANDS >= 5 + SOUND_SETTING(F_NO_WRAP, hw_eq_bands[4][0], LANG_HW_EQ_GAIN, + "eq tone band5 gain", SOUND_EQ_BAND5_GAIN), +#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY + SOUND_SETTING(0, hw_eq_bands[4][1], LANG_HW_EQ_FREQUENCY, + "eq tone band5 frequency", SOUND_EQ_BAND5_FREQUENCY), +#endif +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ +#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", @@ -573,6 +642,10 @@ 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(F_NO_WRAP,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), @@ -1331,9 +1404,11 @@ "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 Index: firmware/export/wm8978.h =================================================================== --- firmware/export/wm8978.h (revision 25939) +++ firmware/export/wm8978.h (working copy) @@ -26,6 +26,18 @@ #define VOLUME_MIN -900 #define VOLUME_MAX 60 +#define AUDIOHW_CAPS (EQ_CAP | PRESCALER_CAP | DEPTH_3D_CAP) +/* 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)) +#define AUDIOHW_EQ_NUM_BANDS 5 +#define AUDIOHW_EQ_NUM_FREQUENCY 5 +#define AUDIOHW_EQ_NUM_WIDTH 3 + int tenthdb2master(int db); void audiohw_set_headphone_vol(int vol_l, int vol_r); void audiohw_set_recsrc(int source, bool recording); @@ -103,13 +115,9 @@ /* Volume masks and macros for digital volumes */ #define WMC_DVOL 0xff -#define WMC_DVOLr(x) ((x) & WMC_DVOL) -#define WMC_DVOLw(x) ((x) & WMC_DVOL) /* Volums masks and macros for analogue volumes */ #define WMC_AVOL 0x3f -#define WMC_AVOLr(x) ((x) & WMC_AVOL) -#define WMC_AVOLw(x) ((x) & WMC_AVOL) /* WMC_SOFTWARE_RESET (0x00) */ #define WMC_RESET @@ -274,14 +282,18 @@ /* 0.5dB steps: Mute:0x00, -127dB:0x01...0dB:0xff */ /*Use WMC_DVOL* macros */ -/* Macros for EQ gain and cutoff */ -#define WMC_EQGC 0x1f -#define WMC_EQGCr(x) ((x) & WMC_EQGC) -#define WMC_EQGCw(x) ((x) & WMC_EQGC) +/* Gain */ +#define WMC_EQG 0x1f +/* Cutoff/Center */ +#define WMC_EQC (0x3 << 5) +#define WMC_EQC_POS (5) + +/* Bandwidth */ +#define WMC_EQBW (1 << 8) + /* WMC_EQ1_LOW_SHELF (0x12) */ #define WMC_EQ3DMODE (1 << 8) -#define WMC_EQ1C (3 << 5) /* Cutoff */ #define WMC_EQ1C_80HZ (0 << 5) /* 80Hz */ #define WMC_EQ1C_105HZ (1 << 5) /* 105Hz */ #define WMC_EQ1C_135HZ (2 << 5) /* 135Hz */ @@ -289,8 +301,6 @@ /* 00000=+12dB, 00001=+11dB...(-1dB steps)...11000=-12dB, 11001-11111=reserved */ /* WMC_EQ2_PEAK1 (0x13) */ -#define WMC_EQ2BW (1 << 8) -#define WMC_EQ2C (3 << 5) /* Center */ #define WMC_EQ2C_230HZ (0 << 5) /* 230Hz */ #define WMC_EQ2C_300HZ (1 << 5) /* 300Hz */ #define WMC_EQ2C_385HZ (2 << 5) /* 385Hz */ @@ -299,8 +309,6 @@ 11001-11111=reserved */ /* WMC_EQ3_PEAK2 (0x14) */ -#define WMC_EQ3BW (1 << 8) -#define WMC_EQ3C (3 << 5) /* Center */ #define WMC_EQ3C_650HZ (0 << 5) /* 650Hz */ #define WMC_EQ3C_850HZ (1 << 5) /* 850Hz */ #define WMC_EQ3C_1_1KHZ (2 << 5) /* 1.1kHz */ @@ -309,8 +317,6 @@ 11001-11111=reserved */ /* WMC_EQ4_PEAK3 (0x15) */ -#define WMC_EQ4BW (1 << 8) -#define WMC_EQ4C (3 << 5) /* Center */ #define WMC_EQ4C_1_8KHZ (0 << 5) /* 1.8kHz */ #define WMC_EQ4C_2_4KHZ (1 << 5) /* 2.4kHz */ #define WMC_EQ4C_3_2KHZ (2 << 5) /* 3.2kHz */ @@ -319,7 +325,6 @@ 11001-11111=reserved */ /* WMC_EQ5_HIGH_SHELF (0x16) */ -#define WMC_EQ5C (3 << 5) /* Cutoff */ #define WMC_EQ5C_5_3KHZ (0 << 5) /* 5.3kHz */ #define WMC_EQ5C_6_9KHZ (1 << 5) /* 6.9kHz */ #define WMC_EQ5C_9KHZ (2 << 5) /* 9.0kHz */ @@ -331,29 +336,20 @@ #define WMC_LIMEN (1 << 8) /* 0000=750uS, 0001=1.5mS...(x2 each step)...1010-1111=768mS */ #define WMC_LIMDCY (0xf << 4) - #define WMC_LIMDCYr(x) (((x) & WMC_LIMDCY) >> 4) - #define WMC_LIMDCYw(x) (((x) << 4) & WMC_LIMDCY) +#define WMC_LIMDCY_POS (4) /* 0000=94uS, 0001=188uS...(x2 each step)...1011-1111=192mS */ #define WMC_LIMATK (0xf << 0) - #define WMC_LIMATKr(x) ((x) & WMC_LIMATK) - #define WMC_LIMATKw(x) ((x) & WMC_LIMATK) /* WMC_DAC_LIMITER2 (0x19) */ -#define WMC_LIMLVL (7 << 4) /* 000=-1dB, 001=-2dB...(-1dB steps)...101-111:-6dB */ - #define WMC_LIMLVLr(x) (((x) & WMC_LIMLVL) >> 4) - #define WMC_LIMLVLw(x) (((x) << 4) & WMC_LIMLVL) -#define WMC_LIMBOOST (0xf << 0) +#define WMC_LIMLVL (7 << 4) +#define WMC_LIMLVL_POS (4) /* 0000=0dB, 0001=+1dB...1100=+12dB, 1101-1111=reserved */ - #define WMC_LIMBOOSTr(x) (((x) & WMC_LIMBOOST) - #define WMC_LIMBOOSTw(x) (((x) & WMC_LIMBOOST) +#define WMC_LIMBOOST (0xf << 0) - /* Generic notch filter bits and macros */ #define WMC_NFU (1 << 8) #define WMC_NFA (0x7f << 0) -#define WMC_NFAr(x) ((x) & WMC_NFA) -#define WMC_NFAw(x) ((x) & WMC_NFA) /* WMC_NOTCH_FILTER1 (0x1b) */ #define WMC_NFEN (1 << 7) @@ -369,24 +365,19 @@ #define WMC_ALCSEL_BOTH_ON (3 << 7) /* 000=-6.75dB, 001=-0.75dB...(6dB steps)...111=+35.25dB */ #define WMC_ALCMAXGAIN (7 << 3) - #define WMC_ALCMAXGAINr(x) (((x) & WMC_ALCMAXGAIN) >> 3) - #define WMC_ALCMAXGAINw(x) (((x) << 3) & WMC_ALCMAXGAIN) +#define WMC_ALCMAXGAIN_POS (3) /* 000:-12dB...(6dB steps)...111:+30dB */ #define WMC_ALCMINGAIN (7 << 0) - #define WMC_ALCMINGAINr(x) ((x) & WMC_ALCMINGAIN) - #define WMC_ALCMINGAINw(x) ((x) & WMC_ALCMINGAIN) /* WMC_ALC_CONTROL2 (0x21) */ /* 0000=0ms, 0001=2.67ms, 0010=5.33ms... (2x with every step)...43.691s */ #define WMC_ALCHLD (0xf << 4) - #define WMC_ALCHLDr(x) (((x) & WMC_ALCHLD) >> 4) - #define WMC_ALCHLDw(x) (((x) << 4) & WMC_ALCHLD) +#define WMC_ALCHLD_POS (4) /* 1111:-1.5dBFS, 1110:-1.5dBFS, 1101:-3dBFS, 1100:-4.5dBFS... (-1.5dB steps)...0001:-21dBFS, 0000:-22.5dBFS */ #define WMC_ALCLVL (0xf << 0) - #define WMC_ALCLVLr(x) ((x) & WMC_ALCLVL) - #define WMC_ALCLVLw(x) ((x) & WMC_ALCLVL) +#define WMC_ALCLVL_POS (0) /* WMC_ALC_CONTROL3 (0x22) */ #define WMC_ALCMODE (1 << 8) @@ -397,43 +388,30 @@ #define WMC_NGEN (1 << 3) /* 000=-39dB, 001=-45dB, 010=-51dB...(6dB steps)...111=-81dB */ #define WMC_NGTH (7 << 0) - #define WMC_NGTHr(x) ((x) & WMC_NGTH) - #define WMC_NGTHw(x) ((x) & WMC_NGTH) /* WMC_PLL_N (0x24) */ #define WMC_PLL_PRESCALE (1 << 4) #define WMC_PLLN (0xf << 0) - #define WMC_PLLNr(x) ((x) & WMC_PLLN) - #define WMC_PLLNw(x) ((x) & WMC_PLLN) /* WMC_PLL_K1 (0x25) */ #define WMC_PLLK_23_18 (0x3f << 0) - #define WMC_PLLK_23_18r(x) ((x) & WMC_PLLK_23_18) - #define WMC_PLLK_23_18w(x) ((x) & WMC_PLLK_23_18) /* WMC_PLL_K2 (0x26) */ #define WMC_PLLK_17_9 (0x1ff << 0) - #define WMC_PLLK_17_9r(x) ((x) & WMC_PLLK_17_9) - #define WMC_PLLK_17_9w(x) ((x) & WMC_PLLK_17_9) /* WMC_PLL_K3 (0x27) */ #define WMC_PLLK_8_0 (0x1ff << 0) - #define WMC_PLLK_8_0r(x) ((x) & WMC_PLLK_8_0) - #define WMC_PLLK_8_0w(x) ((x) & WMC_PLLK_8_0) /* WMC_3D_CONTROL (0x29) */ /* 0000: 0%, 0001: 6.67%...1110: 93.3%, 1111: 100% */ #define WMC_DEPTH3D (0xf << 0) - #define WMC_DEPTH3Dw(x) ((x) & WMC_DEPTH3D) - #define WMC_DEPTH3Dr(x) ((x) & WMC_DEPTH3D) /* WMC_BEEP_CONTROL (0x2b) */ #define WMC_MUTERPGA2INV (1 << 5) #define WMC_INVROUT2 (1 << 4) /* 000=-15dB, 001=-12dB...111=+6dB */ #define WMC_BEEPVOL (7 << 1) - #define WMC_BEEPVOLr(x) (((x) & WMC_BEEPVOL) >> 1) - #define WMC_BEEPVOLw(x) (((x) << 1) & WMC_BEEPVOL) +#define WMC_BEEPVOL_POS (1) #define WMC_BEEPEN (1 << 0) /* WMC_INPUT_CTRL (0x2c) */ @@ -457,23 +435,17 @@ #define WMC_PGABOOSTL (1 << 8) /* 000=disabled, 001=-12dB, 010=-9dB...111=+6dB */ #define WMC_L2_2BOOSTVOL (7 << 4) - #define WMC_L2_2BOOSTVOLr(x) (((x) & WMC_L2_2BOOSTVOL) >> 4) - #define WMC_L2_2BOOSTVOLw(x) (((x) << 4) & WMC_L2_2BOOSTVOL) +#define WMC_L2_2BOOSTVOL_POS (4) /* 000=disabled, 001=-12dB, 010=-9dB...111=+6dB */ #define WMC_AUXL2BOOSTVOL (7 << 0) - #define WMC_AUXL2BOOSTVOLr(x) ((x) & WMC_AUXL2BOOSTVOL) - #define WMC_AUXL2BOOSTVOLw(x) ((x) & WMC_AUXL2BOOSTVOL) /* WMC_RIGHT_ADC_BOOST_CTRL (0x30) */ #define WMC_PGABOOSTR (1 << 8) /* 000=disabled, 001=-12dB, 010=-9dB...111=+6dB */ -#define WMC_R2_2BOOSTVOL (7 << 4) - #define WMC_R2_2BOOSTVOLr(x) (((x) & WMC_R2_2BOOSTVOL) >> 4) - #define WMC_R2_2BOOSTVOLw(x) (((x) << 4) & WMC_R2_2BOOSTVOL) +#define WMC_R2_2BOOSTVOL (7 << 4) +#define WMC_R2_2BOOSTVOL_POS (4) /* 000=disabled, 001=-12dB, 010=-9dB...111=+6dB */ #define WMC_AUXR2BOOSTVOL (7 << 0) - #define WMC_AUXR2BOOSTVOLr(x) ((x) & WMC_AUXR2BOOSTVOL) - #define WMC_AUXR2BOOSTVOLw(x) ((x) & WMC_AUXR2BOOSTVOL) /* WMC_OUTPUT_CTRL (0x31) */ #define WMC_DACL2RMIX (1 << 6) @@ -487,26 +459,22 @@ /* WMC_LEFT_MIXER_CTRL (0x32) */ /* 000=-15dB, 001=-12dB...101=0dB, 110=+3dB, 111=+6dB */ #define WMC_AUXLMIXVOL (7 << 6) - #define WMC_AUXLMIXVOLr(x) (((x) & WMC_AUXLMIXVOL) >> 6) - #define WMC_AUXLMIXVOLw(x) (((x) << 6) & WMC_AUXLMIXVOL) +#define WMC_AUXLMIXVOL_POS (6) #define WMC_AUXL2LMIX (1 << 5) /* 000=-15dB, 001=-12dB...101=0dB, 110=+3dB, 111=+6dB */ #define WMC_BYPLMIXVOL (7 << 2) - #define WMC_BYPLMIXVOLr(x) (((x) & WMC_BYPLMIXVOL) >> 2) - #define WMC_BYPLMIXVOLw(x) (((x) << 2) & WMC_BYPLMIXVOL) +#define WMC_BYPLMIXVOL_POS (2) #define WMC_BYPL2LMIX (1 << 1) #define WMC_DACL2LMIX (1 << 0) /* WMC_RIGHT_MIXER_CTRL (0x33) */ /* 000=-15dB, 001=-12dB...101=0dB, 110=+3dB, 111=+6dB */ #define WMC_AUXRMIXVOL (7 << 6) - #define WMC_AUXRMIXVOLr(x) (((x) & WMC_AUXRMIXVOL) >> 6) - #define WMC_AUXRMIXVOLw(x) (((x) << 6) & WMC_AUXRMIXVOL) +#define WMC_AUXRMIXVOL_POS (6) #define WMC_AUXR2RMIX (1 << 5) /* 000=-15dB, 001=-12dB...101=0dB, 110=+3dB, 111=+6dB */ #define WMC_BYPRMIXVOL (7 << 2) - #define WMC_BYPRMIXVOLr(x) (((x) & WMC_BYPRMIXVOL) >> 2) - #define WMC_BYPRMIXVOLw(x) (((x) << 2) & WMC_BYPRMIXVOL) +#define WMC_BYPRMIXVOL_POS (2) #define WMC_BYPR2RMIX (1 << 1) #define WMC_DACR2RMIX (1 << 0) Index: firmware/export/audiohw.h =================================================================== --- firmware/export/audiohw.h (revision 25939) +++ firmware/export/audiohw.h (working copy) @@ -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 DEPTH_3D_CAP (1 << 7) +#define EQ_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,91 @@ #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 */ +#define AUDIOHW_EQ_BAND1 0 +#if AUDIOHW_EQ_NUM_BANDS >= 2 +#define AUDIOHW_EQ_BAND2 1 +#if AUDIOHW_EQ_NUM_BANDS >= 3 +#define AUDIOHW_EQ_BAND3 2 +#if AUDIOHW_EQ_NUM_BANDS >= 4 +#define AUDIOHW_EQ_BAND4 3 +#if AUDIOHW_EQ_NUM_BANDS >= 5 +#define AUDIOHW_EQ_BAND5 4 +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ + +#ifdef AUDIOHW_EQ_FREQUENCY_CAPS +/* One or more bands supports frequency cutoff or center adjustment */ +#define AUDIOHW_HAVE_EQ_FREQUENCY +#if (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 0)) +#define AUDIOHW_HAVE_EQ_BAND1_FREQUENCY #endif +#if (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 1)) +#define AUDIOHW_HAVE_EQ_BAND2_FREQUENCY +#endif +#if (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 2)) +#define AUDIOHW_HAVE_EQ_BAND3_FREQUENCY +#endif +#if (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 3)) +#define AUDIOHW_HAVE_EQ_BAND4_FREQUENCY +#endif +#if (AUDIOHW_EQ_FREQUENCY_CAPS & (EQ_CAP << 4)) +#define AUDIOHW_HAVE_EQ_BAND5_FREQUENCY +#endif +#endif /* AUDIOHW_EQ_FREQUENCY_CAPS */ -#if (AUDIOHW_CAPS & TREBLE_CUTOFF_CAP) -#define AUDIOHW_HAVE_TREBLE_CUTOFF +#ifdef AUDIOHW_EQ_WIDTH_CAPS +/* One or more bands supports bandwidth adjustment */ +#define AUDIOHW_HAVE_EQ_WIDTH +#if (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 1)) +#define AUDIOHW_HAVE_EQ_BAND2_WIDTH #endif +#if (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 2)) +#define AUDIOHW_HAVE_EQ_BAND3_WIDTH +#endif +#if (AUDIOHW_EQ_WIDTH_CAPS & (EQ_CAP << 3)) +#define AUDIOHW_HAVE_EQ_BAND4_WIDTH +#endif +#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_NUM_SETTINGS +}; + +#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 +219,61 @@ 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 */ +/* Important! Keep gain, frequency and width togther and in G,F,W order. */ +/* Bands */ +#if defined(AUDIOHW_HAVE_EQ) + SOUND_EQ_BAND1_GAIN, +#if AUDIOHW_EQ_NUM_BANDS >= 2 + SOUND_EQ_BAND2_GAIN, +#if AUDIOHW_EQ_NUM_BANDS >= 3 + SOUND_EQ_BAND3_GAIN, +#if AUDIOHW_EQ_NUM_BANDS >= 4 + SOUND_EQ_BAND4_GAIN, +#if AUDIOHW_EQ_NUM_BANDS >= 5 + SOUND_EQ_BAND5_GAIN, +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ +/* 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 +/* 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 +398,50 @@ void audiohw_set_treble_cutoff(int val); #endif +#ifdef AUDIOHW_HAVE_EQ +/** + * Set new band gain value. + * @param val to set. + * NOTE: AUDIOHW_CAPS need to contain one or more of: + * BANDx_EQ_CAP + * where "x" is the band number + */ +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 val to set. + * NOTE: AUDIOHW_EQ_FREQUENCY_CAPS need to contain one or more of: + * BANDx_EQ_CAP + * where "x" is the band number + */ +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 val to set. + * NOTE: AUDIOHW_EQ_WIDTH_CAPS need to contain one or more of: + * BANDx_EQ_CAP + * where "x" is the band number + */ +void audiohw_set_eq_band_width(unsigned int band, int val); +#endif + +#ifdef AUDIOHW_HAVE_DEPTH_3D +/** + * Set new 3-d enhancement 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 Index: firmware/export/config/gigabeats.h =================================================================== --- firmware/export/config/gigabeats.h (revision 25939) +++ firmware/export/config/gigabeats.h (working copy) @@ -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 Index: firmware/export/sound.h =================================================================== --- firmware/export/sound.h (revision 25939) +++ firmware/export/sound.h (working copy) @@ -55,10 +55,62 @@ 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 1 */ +void sound_set_eq_band1_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY +void sound_set_eq_band1_frequency(int value); +#endif +#if AUDIOHW_EQ_NUM_BANDS >= 2 +/* Band 2 */ +void sound_set_eq_band2_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY +void sound_set_eq_band2_frequency(int value); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH +void sound_set_eq_band2_width(int value); +#endif +#if AUDIOHW_EQ_NUM_BANDS >= 3 +/* Band 3 */ +void sound_set_eq_band3_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY +void sound_set_eq_band3_frequency(int value); +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) +void sound_set_eq_band3_width(int value); +#endif +#if AUDIOHW_EQ_NUM_BANDS >= 4 +/* Band 4 */ +void sound_set_eq_band4_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY +void sound_set_eq_band4_frequency(int value); +#endif +#ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH +void sound_set_eq_band4_width(int value); +#endif +#if AUDIOHW_EQ_NUM_BANDS >= 5 +/* Band 5 */ +void sound_set_eq_band5_gain(int value); +#ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY +void sound_set_eq_band5_frequency(int value); +#endif +#endif /* AUDIOHW_EQ_NUM_BANDS >= 5 */ +#endif /* AUDIOHW_EQ_NUM_BANDS >= 4 */ +#endif /* AUDIOHW_EQ_NUM_BANDS >= 3 */ +#endif /* AUDIOHW_EQ_NUM_BANDS >= 2 */ +#endif /* AUDIOHW_HAVE_EQ */ + #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) void sound_set_loudness(int value); void sound_set_avc(int value); Index: firmware/sound.c =================================================================== --- firmware/sound.c (revision 25941) +++ firmware/sound.c (working copy) @@ -48,8 +48,29 @@ /* 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 +/* 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 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, @@ -58,12 +79,39 @@ [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, #endif +/* Bass and treble tone controls */ #if defined(AUDIOHW_HAVE_BASS_CUTOFF) [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, #endif #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, #endif +/* Hardware EQ tone controls */ +#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 +159,12 @@ { [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 +184,53 @@ #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_eq_band1_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) + [SOUND_EQ_BAND1_FREQUENCY] = sound_set_eq_band1_frequency, +#endif +/* 2 */ +#if AUDIOHW_EQ_NUM_BANDS >= 2 + [SOUND_EQ_BAND2_GAIN] = sound_set_eq_band2_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) + [SOUND_EQ_BAND2_FREQUENCY] = sound_set_eq_band2_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) + [SOUND_EQ_BAND2_WIDTH] = sound_set_eq_band2_width, +#endif +/* 3 */ +#if AUDIOHW_EQ_NUM_BANDS >= 3 + [SOUND_EQ_BAND3_GAIN] = sound_set_eq_band3_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) + [SOUND_EQ_BAND3_FREQUENCY] = sound_set_eq_band3_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) + [SOUND_EQ_BAND3_WIDTH] = sound_set_eq_band3_width, +#endif +/* 4 */ +#if AUDIOHW_EQ_NUM_BANDS >= 4 + [SOUND_EQ_BAND4_GAIN] = sound_set_eq_band4_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) + [SOUND_EQ_BAND4_FREQUENCY] = sound_set_eq_band4_frequency, +#endif +#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) + [SOUND_EQ_BAND4_WIDTH] = sound_set_eq_band4_width, +#endif +/* 5 */ +#if AUDIOHW_EQ_NUM_BANDS >= 5 + [SOUND_EQ_BAND5_GAIN] = sound_set_eq_band5_gain, +#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) + [SOUND_EQ_BAND5_FREQUENCY] = sound_set_eq_band5_frequency, +#endif +#endif /* 5 */ +#endif /* 4 */ +#endif /* 3 */ +#endif /* 2 */ +#endif /* AUDIOHW_HAVE_EQ */ }; sound_set_type* sound_get_fn(int setting) @@ -174,8 +273,15 @@ /* 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_NUM_BANDS]; +#endif static void set_prescaled_volume(void) { @@ -191,10 +297,18 @@ || 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_NUM_BANDS; 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 +403,7 @@ #endif } +#ifdef AUDIOHW_HAVE_BASS void sound_set_bass(int value) { if(!audio_is_initialized) @@ -302,17 +417,19 @@ #endif #endif -#if defined(AUDIOHW_HAVE_BASS) +#if defined(HAVE_SW_TONE_CONTROLS) + dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); +#else audiohw_set_bass(value); -#else - dsp_callback(DSP_CALLBACK_SET_BASS, current_bass); #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,17 +443,38 @@ #endif #endif -#if defined(AUDIOHW_HAVE_TREBLE) +#if defined(HAVE_SW_TONE_CONTROLS) + dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); +#else audiohw_set_treble(value); -#else - dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble); #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) { if(!audio_is_initialized) @@ -361,26 +499,141 @@ #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) +static void sound_set_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_eq_band1_gain(int value) +{ + sound_set_eq_band_gain(AUDIOHW_EQ_BAND1, value); +} + +#if defined(AUDIOHW_EQ_BAND2) +void sound_set_eq_band2_gain(int value) +{ + sound_set_eq_band_gain(AUDIOHW_EQ_BAND2, value); +} #endif +#if defined(AUDIOHW_EQ_BAND3) +void sound_set_eq_band3_gain(int value) +{ + sound_set_eq_band_gain(AUDIOHW_EQ_BAND3, value); +} +#endif + +#if defined(AUDIOHW_EQ_BAND4) +void sound_set_eq_band4_gain(int value) +{ + sound_set_eq_band_gain(AUDIOHW_EQ_BAND4, value); +} +#endif + +#if defined(AUDIOHW_EQ_BAND5) +void sound_set_eq_band5_gain(int value) +{ + sound_set_eq_band_gain(AUDIOHW_EQ_BAND5, value); +} +#endif + +#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) +void sound_set_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_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_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_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_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_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_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_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) { Index: firmware/drivers/audio/wm8978.c =================================================================== --- firmware/drivers/audio/wm8978.c (revision 25939) +++ firmware/drivers/audio/wm8978.c (working copy) @@ -37,27 +37,35 @@ 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, 1, 4, 1}, + [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1}, + [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1}, + [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1}, + [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1}, + [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 @@ { 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) @@ -216,9 +234,13 @@ 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 */ wmc_write(WMC_POWER_MANAGEMENT1, WMC_BUFIOEN | WMC_VMIDSEL_300K); @@ -305,17 +327,23 @@ 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_write_masked(WMC_LEFT_MIXER_CTRL, WMC_BYPLMIXVOLw(mix_l), + 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, - WMC_L2_2BOOSTVOLw(boost_l), WMC_L2_2BOOSTVOL); + boost_l << WMC_L2_2BOOSTVOL_POS, WMC_L2_2BOOSTVOL); wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, dac_l, WMC_DVOL); wmc_write_masked(WMC_LOUT1_HP_VOLUME_CTRL, hp_l, WMC_AVOL); - wmc_write_masked(WMC_RIGHT_MIXER_CTRL, WMC_BYPRMIXVOLw(mix_r), + wmc_write_masked(WMC_RIGHT_MIXER_CTRL, mix_r << WMC_BYPRMIXVOL_POS, WMC_BYPRMIXVOL); wmc_write_masked(WMC_RIGHT_ADC_BOOST_CTRL, - WMC_R2_2BOOSTVOLw(boost_r), WMC_R2_2BOOSTVOL); + boost_r << WMC_R2_2BOOSTVOL_POS, WMC_R2_2BOOSTVOL); wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, dac_r, WMC_DVOL); wmc_write_masked(WMC_ROUT1_HP_VOLUME_CTRL, hp_r, WMC_AVOL); @@ -367,6 +395,55 @@ } } +/* Equalizer - set the eq band level -12 to +12 dB. */ +void audiohw_set_eq_band_gain(unsigned int band, int val) +{ + 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) +{ + wmc_write_masked(band + WMC_EQ1_LOW_SHELF, + (val - 1) << 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) +{ + 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 */ @@ -400,10 +477,10 @@ { [HW_FREQ_8] = /* PLL = 65.536MHz */ { - .plln = WMC_PLLNw(7) | WMC_PLL_PRESCALE, - .pllk1 = WMC_PLLK_23_18w(12414886ul >> 18), - .pllk2 = WMC_PLLK_17_9w(12414886ul >> 9), - .pllk3 = WMC_PLLK_8_0w(12414886ul >> 0), + .plln = 7 | WMC_PLL_PRESCALE, + .pllk1 = (12414886ul >> 18) & WMC_PLLK_23_18, + .pllk2 = (12414886ul >> 9) & WMC_PLLK_17_9, + .pllk3 = (12414886ul >> 0) & WMC_PLLK_8_0, .mclkdiv = WMC_MCLKDIV_8, /* 2.0480 MHz */ .filter = WMC_SR_8KHZ, }, @@ -414,19 +491,19 @@ }, [HW_FREQ_12] = /* PLL = 73.728 MHz */ { - .plln = WMC_PLLNw(8) | WMC_PLL_PRESCALE, - .pllk1 = WMC_PLLK_23_18w(11869595ul >> 18), - .pllk2 = WMC_PLLK_17_9w(11869595ul >> 9), - .pllk3 = WMC_PLLK_8_0w(11869595ul >> 0), + .plln = 8 | WMC_PLL_PRESCALE, + .pllk1 = (11869595ul >> 18) & WMC_PLLK_23_18, + .pllk2 = (11869595ul >> 9) & WMC_PLLK_17_9, + .pllk3 = (11869595ul >> 0) & WMC_PLLK_8_0, .mclkdiv = WMC_MCLKDIV_6, /* 3.0720 MHz */ .filter = WMC_SR_12KHZ, }, [HW_FREQ_16] = /* PLL = 65.536MHz */ { - .plln = WMC_PLLNw(7) | WMC_PLL_PRESCALE, - .pllk1 = WMC_PLLK_23_18w(12414886ul >> 18), - .pllk2 = WMC_PLLK_17_9w(12414886ul >> 9), - .pllk3 = WMC_PLLK_8_0w(12414886ul >> 0), + .plln = 7 | WMC_PLL_PRESCALE, + .pllk1 = (12414886ul >> 18) & WMC_PLLK_23_18, + .pllk2 = (12414886ul >> 9) & WMC_PLLK_17_9, + .pllk3 = (12414886ul >> 0) & WMC_PLLK_8_0, .mclkdiv = WMC_MCLKDIV_4, /* 4.0960 MHz */ .filter = WMC_SR_16KHZ, }, @@ -437,19 +514,19 @@ }, [HW_FREQ_24] = /* PLL = 73.728 MHz */ { - .plln = WMC_PLLNw(8) | WMC_PLL_PRESCALE, - .pllk1 = WMC_PLLK_23_18w(11869595ul >> 18), - .pllk2 = WMC_PLLK_17_9w(11869595ul >> 9), - .pllk3 = WMC_PLLK_8_0w(11869595ul >> 0), + .plln = 8 | WMC_PLL_PRESCALE, + .pllk1 = (11869595ul >> 18) & WMC_PLLK_23_18, + .pllk2 = (11869595ul >> 9) & WMC_PLLK_17_9, + .pllk3 = (11869595ul >> 0) & WMC_PLLK_8_0, .mclkdiv = WMC_MCLKDIV_3, /* 6.1440 MHz */ .filter = WMC_SR_24KHZ, }, [HW_FREQ_32] = /* PLL = 65.536MHz */ { - .plln = WMC_PLLNw(7) | WMC_PLL_PRESCALE, - .pllk1 = WMC_PLLK_23_18w(12414886ul >> 18), - .pllk2 = WMC_PLLK_17_9w(12414886ul >> 9), - .pllk3 = WMC_PLLK_8_0w(12414886ul >> 0), + .plln = 7 | WMC_PLL_PRESCALE, + .pllk1 = (12414886ul >> 18) & WMC_PLLK_23_18, + .pllk2 = (12414886ul >> 9) & WMC_PLLK_17_9, + .pllk3 = (12414886ul >> 0) & WMC_PLLK_8_0, .mclkdiv = WMC_MCLKDIV_2, /* 8.1920 MHz */ .filter = WMC_SR_32KHZ, }, @@ -460,10 +537,10 @@ }, [HW_FREQ_48] = /* PLL = 73.728 MHz */ { - .plln = WMC_PLLNw(8) | WMC_PLL_PRESCALE, - .pllk1 = WMC_PLLK_23_18w(11869595ul >> 18), - .pllk2 = WMC_PLLK_17_9w(11869595ul >> 9), - .pllk3 = WMC_PLLK_8_0w(11869595ul >> 0), + .plln = 8 | WMC_PLL_PRESCALE, + .pllk1 = (11869595ul >> 18) & WMC_PLLK_23_18, + .pllk2 = (11869595ul >> 9) & WMC_PLLK_17_9, + .pllk3 = (11869595ul >> 0) & WMC_PLLK_8_0, .mclkdiv = WMC_MCLKDIV_1_5, /* 12.2880 MHz */ .filter = WMC_SR_48KHZ, }, Index: uisimulator/sdl/sound.c =================================================================== --- uisimulator/sdl/sound.c (revision 25939) +++ uisimulator/sdl/sound.c (working copy) @@ -386,6 +386,23 @@ #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) {