diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 1d27c36571..7a9ccb042d 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -639,7 +639,7 @@ bool audio_driver_init_internal( audio_driver_st.current_audio)) { RARCH_ERR("Cannot open threaded audio driver ... Exiting ...\n"); - return false; + return false; } } else @@ -794,8 +794,8 @@ void audio_driver_sample(int16_t left, int16_t right) } if (!( (runloop_flags & RUNLOOP_FLAG_PAUSED) - || !(audio_st->flags & AUDIO_FLAG_ACTIVE) - || !(audio_st->output_samples_buf))) + || !(audio_st->flags & AUDIO_FLAG_ACTIVE) + || !(audio_st->output_samples_buf))) audio_driver_flush(audio_st, config_get_ptr()->floats.slowmotion_ratio, config_get_ptr()->bools.audio_fastforward_mute, diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index dda4eefa41..4befe929b8 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -951,6 +951,10 @@ MSG_HASH( MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_NETPLAY_MITM_SERVER, "deferred_dropdown_box_list_netplay_mitm_server" ) +MSG_HASH( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE, + "deferred_dropdown_box_list_audio_device" + ) MSG_HASH( MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, "deferred_configurations_list" diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 895d4ee567..bf89a7dab7 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -632,6 +632,7 @@ GENERIC_DEFERRED_PUSH_GENERAL(deferred_contentless_cores_list, PUSH_DEFAULT, DIS GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST) GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_special, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_SPECIAL) GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_resolution, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_RESOLUTION) +GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_audio_device, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_AUDIO_DEVICE) GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_video_shader_num_passes, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_VIDEO_SHADER_NUM_PASSES) GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_shader_parameter, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_VIDEO_SHADER_PARAMETER) GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_shader_preset_parameter, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_VIDEO_SHADER_PRESET_PARAMETER) @@ -649,7 +650,6 @@ GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_input_description_ #ifdef ANDROID GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_input_select_physical_keyboard, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_INPUT_SELECT_PHYSICAL_KEYBOARD) #endif - #ifdef HAVE_NETWORKING GENERIC_DEFERRED_PUSH_GENERAL(deferred_push_dropdown_box_list_netplay_mitm_server, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_NETPLAY_MITM_SERVER) #endif @@ -675,6 +675,7 @@ static int menu_cbs_init_bind_deferred_push_compare_label( {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST, deferred_push_dropdown_box_list}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL, deferred_push_dropdown_box_list_special}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION, deferred_push_dropdown_box_list_resolution}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE, deferred_push_dropdown_box_list_audio_device}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES, deferred_push_dropdown_box_list_video_shader_num_passes}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER, deferred_push_dropdown_box_list_shader_parameter}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER, deferred_push_dropdown_box_list_shader_preset_parameter}, diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 6cef48cad0..3860f5dc75 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -279,6 +279,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL; case ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION: return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_AUDIO_DEVICE: + return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE; case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE: return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE; case ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE: @@ -831,6 +833,15 @@ int generic_action_ok_displaylist_push(const char *path, info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_INPUT_DESCRIPTION_KBD; dl_type = DISPLAYLIST_GENERIC; break; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_AUDIO_DEVICE: + info.type = type; + info.directory_ptr = idx; + info_path = path; + info_label = msg_hash_to_str( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE); + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE; + dl_type = DISPLAYLIST_GENERIC; + break; #ifdef HAVE_NETWORKING case ACTION_OK_DL_DROPDOWN_BOX_LIST_NETPLAY_MITM_SERVER: info.type = type; @@ -6813,6 +6824,26 @@ static int action_ok_push_dropdown_item_disk_index(const char *path, return 0; } +static int action_ok_push_dropdown_item_audio_device(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + const char *menu_path = NULL; + enum msg_hash_enums enum_idx; + rarch_setting_t *setting; + menu_entries_get_last_stack(&menu_path, NULL, NULL, NULL, NULL); + enum_idx = (enum msg_hash_enums)atoi(menu_path); + setting = menu_setting_find_enum(enum_idx); + + if (!setting) + return -1; + + strlcpy(setting->value.target.string, label, setting->size); + + command_event(CMD_EVENT_AUDIO_REINIT, NULL); + + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + static int action_ok_push_dropdown_item_input_device_type(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -8750,6 +8781,9 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, case MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD: BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_input_description_kbd); break; + case MENU_SETTING_DROPDOWN_ITEM_AUDIO_DEVICE: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_audio_device); + break; #ifdef HAVE_NETWORKING case MENU_SETTING_DROPDOWN_ITEM_NETPLAY_MITM_SERVER: BIND_ACTION_OK(cbs, action_ok_push_dropdown_item_netplay_mitm_server); diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 873767c30c..be03e89c18 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -1807,6 +1807,7 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST, action_get_title_dropdown_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL, action_get_title_dropdown_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION, action_get_title_dropdown_resolution_item}, + {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE, action_get_title_dropdown_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER, action_get_title_dropdown_video_shader_parameter_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER, action_get_title_dropdown_video_shader_preset_parameter_item}, {MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES, action_get_title_dropdown_video_shader_num_pass_item}, diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index 784e648354..85a5e95561 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -39,6 +39,7 @@ enum ACTION_OK_DL_DROPDOWN_BOX_LIST, ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL, ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION, + ACTION_OK_DL_DROPDOWN_BOX_LIST_AUDIO_DEVICE, ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PARAMETER, ACTION_OK_DL_DROPDOWN_BOX_LIST_SHADER_PRESET_PARAMETER, ACTION_OK_DL_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 92bb4f1289..db3443dbe6 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5058,6 +5058,102 @@ static unsigned menu_displaylist_parse_disk_options( return count; } +static int menu_displaylist_parse_audio_device_list( + menu_displaylist_info_t *info, settings_t *settings) +{ + enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(info->path); + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + size_t menu_index = 0; + unsigned count = 0; + int i = -1; + int audio_device_index = -1; + struct string_list *ptr = NULL; + + if (!settings || !setting) + goto end; + + if (!audio_driver_get_devices_list((void**)&ptr)) + goto end; + + if (!ptr) + goto end; + + /* Get index in the string list */ + audio_device_index = string_list_find_elem(ptr, setting->value.target.string) - 1; + + /* Add "Default" */ + if (i == -1) + { + bool add = false; + + if (menu_entries_append(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE), + "", + MENU_ENUM_LABEL_AUDIO_DEVICE_LIST, + MENU_SETTING_DROPDOWN_ITEM_AUDIO_DEVICE, + 0, i, NULL)) + add = true; + + if (add) + { + /* Add checkmark if input is currently + * mapped to this entry */ + if (audio_device_index == i) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*)info->list->list[menu_index].actiondata; + if (cbs) + cbs->checked = true; + menu_navigation_set_selection(menu_index); + } + + count++; + menu_index++; + } + } + + for (i = 0; i < ptr->size; i++) + { + bool add = false; + + /* Add menu entry */ + if (menu_entries_append(info->list, + ptr->elems[i].data, + ptr->elems[i].data, + MENU_ENUM_LABEL_AUDIO_DEVICE_LIST, + MENU_SETTING_DROPDOWN_ITEM_AUDIO_DEVICE, + 0, i, NULL)) + add = true; + + if (add) + { + /* Add checkmark if input is currently + * mapped to this entry */ + if (audio_device_index == i) + { + menu_file_list_cbs_t *cbs = (menu_file_list_cbs_t*)info->list->list[menu_index].actiondata; + if (cbs) + cbs->checked = true; + menu_navigation_set_selection(menu_index); + } + + count++; + menu_index++; + } + } + +end: + /* Fallback */ + if (count == 0) + if (menu_entries_append(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY), + MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY, + FILE_TYPE_NONE, 0, 0, NULL)) + count++; + + return count; +} + static int menu_displaylist_parse_input_device_type_list( menu_displaylist_info_t *info, settings_t *settings) { @@ -13169,6 +13265,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, info->flags |= MD_FLAG_NEED_REFRESH | MD_FLAG_NEED_PUSH; break; + case DISPLAYLIST_DROPDOWN_LIST_AUDIO_DEVICE: + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + count = menu_displaylist_parse_audio_device_list(info, settings); + info->flags |= MD_FLAG_NEED_REFRESH + | MD_FLAG_NEED_PUSH; + break; #ifdef HAVE_NETWORKING case DISPLAYLIST_DROPDOWN_LIST_NETPLAY_MITM_SERVER: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index d6e52fd312..76ec5c7250 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -57,6 +57,7 @@ enum menu_displaylist_ctl_state DISPLAYLIST_DROPDOWN_LIST, DISPLAYLIST_DROPDOWN_LIST_SPECIAL, DISPLAYLIST_DROPDOWN_LIST_RESOLUTION, + DISPLAYLIST_DROPDOWN_LIST_AUDIO_DEVICE, DISPLAYLIST_DROPDOWN_LIST_VIDEO_SHADER_PARAMETER, DISPLAYLIST_DROPDOWN_LIST_VIDEO_SHADER_PRESET_PARAMETER, DISPLAYLIST_DROPDOWN_LIST_VIDEO_SHADER_NUM_PASSES, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index e2ad966258..e7fe155a99 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -113,6 +113,7 @@ enum menu_settings_type #endif MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION, MENU_SETTING_DROPDOWN_ITEM_INPUT_DESCRIPTION_KBD, + MENU_SETTING_DROPDOWN_ITEM_AUDIO_DEVICE, #ifdef HAVE_NETWORKING MENU_SETTING_DROPDOWN_ITEM_NETPLAY_MITM_SERVER, #endif diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ed0d75b6e7..6aa2236def 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2908,6 +2908,35 @@ static int setting_action_ok_select_physical_keyboard( } #endif +#if !defined(RARCH_CONSOLE) +static int setting_string_action_ok_audio_device( + rarch_setting_t *setting, size_t idx, bool wraparound) +{ + char enum_idx[16]; + if (!setting) + return -1; + + snprintf(enum_idx, sizeof(enum_idx), "%d", setting->enum_idx); + + generic_action_ok_displaylist_push( + enum_idx, /* we will pass the enumeration index of the string as a path */ + NULL, NULL, 0, idx, 0, + ACTION_OK_DL_DROPDOWN_BOX_LIST_AUDIO_DEVICE); + return 0; +} + +static int setting_string_action_start_audio_device(rarch_setting_t *setting) +{ + if (!setting) + return -1; + + strlcpy(setting->value.target.string, "", setting->size); + + command_event(CMD_EVENT_AUDIO_REINIT, NULL); + return 0; +} +#endif + static int setting_string_action_left_string_options( rarch_setting_t* setting, size_t idx, bool wraparound) { @@ -5093,6 +5122,18 @@ static void setting_get_string_representation_int_audio_wasapi_sh_buffer_length( } #endif +static void setting_get_string_representation_string_audio_device(rarch_setting_t *setting, + char *s, size_t len) +{ + if (!setting) + return; + + if (string_is_empty(setting->value.target.string)) + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE), len); + else + strlcpy(s, setting->value.target.string, len); +} + static void setting_get_string_representation_crt_switch_resolution_super( rarch_setting_t *setting, char *s, size_t len) @@ -5850,11 +5891,17 @@ static int setting_string_action_left_audio_device( audio_device_index--; /* Reset index if needed */ - if (audio_device_index < 0) + if (audio_device_index < -1) audio_device_index = (int)(ptr->size - 1); - strlcpy(setting->value.target.string, ptr->elems[audio_device_index].data, setting->size); + if (audio_device_index < 0) + strlcpy(setting->value.target.string, + "", setting->size); + else + strlcpy(setting->value.target.string, + ptr->elems[audio_device_index].data, setting->size); + command_event(CMD_EVENT_AUDIO_REINIT, NULL); return 0; } #endif @@ -6128,16 +6175,21 @@ static int setting_string_action_right_audio_device( return -1; /* Get index in the string list */ - audio_device_index = string_list_find_elem(ptr,setting->value.target.string) -1; + audio_device_index = string_list_find_elem(ptr,setting->value.target.string) - 1; audio_device_index++; /* Reset index if needed */ if (audio_device_index == (signed)ptr->size) - audio_device_index = 0; + audio_device_index = -1; - strlcpy(setting->value.target.string, - ptr->elems[audio_device_index].data, setting->size); + if (audio_device_index < 0) + strlcpy(setting->value.target.string, + "", setting->size); + else + strlcpy(setting->value.target.string, + ptr->elems[audio_device_index].data, setting->size); + command_event(CMD_EVENT_AUDIO_REINIT, NULL); return 0; } #endif @@ -13698,11 +13750,12 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT); - (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_STRING_LINE_EDIT; - (*list)[list_info->index - 1].action_start = setting_generic_action_start_default; + (*list)[list_info->index - 1].action_start = &setting_string_action_start_audio_device; (*list)[list_info->index - 1].action_left = &setting_string_action_left_audio_device; (*list)[list_info->index - 1].action_right = &setting_string_action_right_audio_device; + (*list)[list_info->index - 1].action_ok = &setting_string_action_ok_audio_device; + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_string_audio_device; #endif CONFIG_UINT( diff --git a/msg_hash.h b/msg_hash.h index 11a9e27e9e..0a912c474b 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1778,6 +1778,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION, + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_AUDIO_DEVICE, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PARAMETER, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_PRESET_PARAMETER, MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_VIDEO_SHADER_NUM_PASSES, @@ -2056,6 +2057,7 @@ enum msg_hash_enums MENU_LBL_H(AUDIO_MAX_TIMING_SKEW), MENU_LABEL(AUDIO_OUTPUT_RATE), MENU_LBL_H(AUDIO_DEVICE), + MENU_ENUM_LABEL_AUDIO_DEVICE_LIST, MENU_ENUM_LABEL_HELP_AUDIO_DEVICE_ALSA, MENU_ENUM_LABEL_HELP_AUDIO_DEVICE_OSS, MENU_ENUM_LABEL_HELP_AUDIO_DEVICE_JACK,