Implement speaker enable/disable on jack (un)plug

The implementation is not very complicated but there are a few things worth
noting. There was a previous "speaker enable" setting but it was a boolean.
I decided to replace it with a choice setting that has 2 options (on, off)
if headphones cannot be detect on this target, or 3 options (on, off, auto)
if we can detect headphones. This will break the old setting on target that
cannot detect jack but it makes the code more uniform and avoid maintaining
two settings with more #ifdef. The third option (auto) uses the LANG_AUTO
text, which I think is clear enough (disable speaker on jack plug).
In order to avoid code duplication (both in apps and firmware), I decided to
keep the audiohw_enable_speaker function as-is: it takes a boolean and doesn't
care about the speaker policy. I introduced a new audio_enable_speaker that
takes directly the mode (which follows the setting encoding): 0=off, 1=on
and 2=auto. This way one calls audio_enable_speaker and it changes the speaker
once to reflect the request mode. The apps code then uses this function in the
places where it makes sense: on setting load, setting change and jack (un)plug
event.

Change-Id: I027873f698eb4bc365d7c02b515297806355d9e2
This commit is contained in:
Amaury Pouly 2017-01-14 01:40:12 +01:00
parent d052f13999
commit 1245c5fe61
9 changed files with 43 additions and 12 deletions

View file

@ -164,3 +164,16 @@ int audio_get_spdif_sample_rate(void)
#endif /* HAVE_SPDIF_IN */ #endif /* HAVE_SPDIF_IN */
#endif /* PLATFORM_NATIVE */ #endif /* PLATFORM_NATIVE */
#ifdef HAVE_SPEAKER
void audio_enable_speaker(int mode)
{
#ifdef HAVE_HEADPHONE_DETECTION
/* if needed, query jack state */
if(mode == 2)
mode = !headphones_inserted();
#endif
/* treat any nonzero value as enable */
audiohw_enable_speaker(mode);
}
#endif

View file

@ -225,7 +225,7 @@ static int timestretch_callback(int action,const struct menu_item_ex *this_item)
#endif #endif
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
MENUITEM_SETTING(speaker_enabled, &global_settings.speaker_enabled, NULL); MENUITEM_SETTING(speaker_mode, &global_settings.speaker_mode, NULL);
#endif #endif
#ifdef AUDIOHW_HAVE_EQ #ifdef AUDIOHW_HAVE_EQ
@ -269,7 +269,7 @@ MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio,
,&mdb_harmonics,&mdb_center,&mdb_shape ,&mdb_harmonics,&mdb_center,&mdb_shape
#endif #endif
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
,&speaker_enabled ,&speaker_mode
#endif #endif
); );

View file

@ -522,6 +522,11 @@ static void unplug_change(bool inserted)
} }
} }
} }
#ifdef HAVE_SPEAKER
/* update speaker status */
audio_enable_speaker(global_settings.speaker_mode);
#endif
} }
#endif #endif

View file

@ -160,12 +160,12 @@ void* plugin_get_buffer(size_t *buffer_size);
#define PLUGIN_MAGIC 0x526F634B /* RocK */ #define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */ /* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 233 #define PLUGIN_API_VERSION 234
/* update this to latest version if a change to the api struct breaks /* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */ new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 233 #define PLUGIN_MIN_API_VERSION 234
/* plugin return codes */ /* plugin return codes */
/* internal returns start at 0x100 to make exit(1..255) work */ /* internal returns start at 0x100 to make exit(1..255) work */

View file

@ -1097,7 +1097,7 @@ bool recording_screen(bool no_source)
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
/* Disable speaker to prevent feedback */ /* Disable speaker to prevent feedback */
audiohw_enable_speaker(false); audio_enable_speaker(0);
#endif #endif
audio_init_recording(); audio_init_recording();
@ -1959,7 +1959,7 @@ rec_abort:
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
/* Re-enable speaker */ /* Re-enable speaker */
audiohw_enable_speaker(global_settings.speaker_enabled); audio_enable_speaker(global_settings.speaker_mode);
#endif #endif
/* make sure the trigger is really turned off */ /* make sure the trigger is really turned off */

View file

@ -927,7 +927,7 @@ void settings_apply(bool read_disk)
#endif #endif
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
audiohw_enable_speaker(global_settings.speaker_enabled); audio_enable_speaker(global_settings.speaker_mode);
#endif #endif
if (read_disk) if (read_disk)

View file

@ -746,8 +746,8 @@ struct user_settings
#endif #endif
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
bool speaker_enabled; int speaker_mode; /* 0: off, 1: on, 2: auto (only if headphone detection) */
#endif #endif /* HAVE_SPEAKER */
bool prevent_skip; bool prevent_skip;
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN

View file

@ -2118,9 +2118,13 @@ const struct settings_list settings[] = {
false, "shortcuts instead of quickscreen", NULL), false, "shortcuts instead of quickscreen", NULL),
#endif #endif
#ifdef HAVE_SPEAKER #ifdef HAVE_SPEAKER
OFFON_SETTING(0, speaker_enabled, LANG_ENABLE_SPEAKER, false, "speaker", CHOICE_SETTING(0, speaker_mode, LANG_ENABLE_SPEAKER, 0, "speaker mode",
audiohw_enable_speaker), # ifdef HAVE_HEADPHONE_DETECTION
#endif "on,off,auto", audio_enable_speaker, 3, ID2P(LANG_OFF), ID2P(LANG_ON), ID2P(LANG_AUTO)),
#else /* HAVE_HEADPHONE_DETECTION */
"on,off", audio_enable_speaker, 2, ID2P(LANG_OFF), ID2P(LANG_ON)),
#endif /* HAVE_HEADPHONE_DETECTION */
#endif /* HAVE_SPEAKER */
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
CHOICE_SETTING(0, touch_mode, LANG_TOUCHSCREEN_MODE, DEFAULT_TOUCHSCREEN_MODE, CHOICE_SETTING(0, touch_mode, LANG_TOUCHSCREEN_MODE, DEFAULT_TOUCHSCREEN_MODE,
"touchscreen mode", "point,grid", NULL, 2, "touchscreen mode", "point,grid", NULL, 2,

View file

@ -232,6 +232,15 @@ int audio_get_spdif_sample_rate(void);
void audio_spdif_set_monitor(int monitor_spdif); void audio_spdif_set_monitor(int monitor_spdif);
#endif /* HAVE_SPDIF_IN */ #endif /* HAVE_SPDIF_IN */
#ifdef HAVE_SPEAKER
/* enable/disable the speaker: 0=off, 1=on, 2=on if jack unpluged, off otherwise
* NOTE this is a one time thing, this function doesn't implement the logic to
* check for jack events, it merely changes the speaker state to the expected
* state based on the requested mode.
*/
void audio_enable_speaker(int mode);
#endif
/***********************************************************************/ /***********************************************************************/
/* audio event handling */ /* audio event handling */
enum track_event_flags enum track_event_flags