diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 4713f6e3fb..51196ae374 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -1142,6 +1142,39 @@ enum audio_mixer_state audio_driver_mixer_get_stream_state(unsigned i) return audio_mixer_streams[i].state; } +static void audio_driver_mixer_play_stream_internal(unsigned i, bool looped) +{ + bool set_state = false; + + if (i >= AUDIO_MIXER_MAX_STREAMS) + return; + + switch (audio_mixer_streams[i].state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_mixer_streams[i].voice = audio_mixer_play(audio_mixer_streams[i].handle, looped, audio_mixer_streams[i].volume, audio_mixer_streams[i].stop_cb); + set_state = true; + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_NONE: + break; + } + + if (set_state) + audio_mixer_streams[i].state = looped ? AUDIO_STREAM_STATE_PLAYING_LOOPED : AUDIO_STREAM_STATE_PLAYING; +} + +void audio_driver_mixer_play_stream(unsigned i) +{ + audio_driver_mixer_play_stream_internal(i, false); +} + +void audio_driver_mixer_play_stream_looped(unsigned i) +{ + audio_driver_mixer_play_stream_internal(i, true); +} + void audio_driver_mixer_stop_stream(unsigned i) { bool set_state = false; diff --git a/audio/audio_driver.h b/audio/audio_driver.h index 2b323bd4bb..0b3f991e4c 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -290,6 +290,10 @@ audio_mixer_stream_t *audio_driver_mixer_get_stream(unsigned i); bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params); +void audio_driver_mixer_play_stream(unsigned i); + +void audio_driver_mixer_play_stream_looped(unsigned i); + void audio_driver_mixer_stop_stream(unsigned i); void audio_driver_mixer_remove_stream(unsigned i); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 590f0afede..282d451178 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1767,6 +1767,44 @@ error: return menu_cbs_exit(); } +static int action_ok_mixer_stream_action_play(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_driver_mixer_play_stream(stream_id); + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + +static int action_ok_mixer_stream_action_play_looped(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned stream_id = type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN; + enum audio_mixer_state state = audio_driver_mixer_get_stream_state(stream_id); + + switch (state) + { + case AUDIO_STREAM_STATE_STOPPED: + audio_driver_mixer_play_stream_looped(stream_id); + break; + case AUDIO_STREAM_STATE_PLAYING: + case AUDIO_STREAM_STATE_PLAYING_LOOPED: + case AUDIO_STREAM_STATE_NONE: + break; + } + return 0; +} + static int action_ok_mixer_stream_action_remove(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -4632,6 +4670,16 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, { BIND_ACTION_OK(cbs, action_ok_lookup_setting); } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play); + } + else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END) + { + BIND_ACTION_OK(cbs, action_ok_mixer_stream_action_play_looped); + } else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN && type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_END) { diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index decce6e57f..abc59c341f 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4260,15 +4260,31 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); { - char lbl_remove[PATH_MAX_LENGTH]; - char lbl_stop[PATH_MAX_LENGTH]; + char lbl_play[128]; + char lbl_play_looped[128]; + char lbl_remove[128]; + char lbl_stop[128]; unsigned id = info->type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN; - lbl_remove[0] = lbl_stop[0] = '\0'; + lbl_remove[0] = lbl_stop[0] = lbl_play[0] = lbl_play_looped[0] = '\0'; snprintf(lbl_stop, sizeof(lbl_stop), "mixer_stream_%d_action_stop", id); snprintf(lbl_remove, sizeof(lbl_remove), "mixer_stream_%d_action_remove", id); + snprintf(lbl_play, sizeof(lbl_play), "mixer_stream_%d_action_play", id); + snprintf(lbl_play_looped, sizeof(lbl_play_looped), "mixer_stream_%d_action_play_looped", id); + menu_entries_append_enum(info->list, + "Play", + lbl_play, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + id), + 0, 0); + menu_entries_append_enum(info->list, + "Play (Looped)", + lbl_play_looped, + MSG_UNKNOWN, + (MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + id), + 0, 0); menu_entries_append_enum(info->list, "Stop", lbl_stop, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 8b9f638645..95a43be1f5 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -197,6 +197,10 @@ enum menu_settings_type MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_STOP_BEGIN + 7, MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN, MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN + 7, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + 7, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN, + MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + 7, MENU_SETTINGS_BIND_BEGIN, MENU_SETTINGS_BIND_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_ANALOG_RIGHT_Y_MINUS, MENU_SETTINGS_BIND_ALL_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_MENU_TOGGLE,