diff --git a/aegisub/src/audio_player_portaudio.cpp b/aegisub/src/audio_player_portaudio.cpp index cc3a6455a..b98e62330 100644 --- a/aegisub/src/audio_player_portaudio.cpp +++ b/aegisub/src/audio_player_portaudio.cpp @@ -39,13 +39,11 @@ #ifdef WITH_PORTAUDIO - -// Headers #include #include "audio_player_portaudio.h" -#include "include/aegisub/audio_provider.h" #include "charset_conv.h" +#include "include/aegisub/audio_provider.h" #include "main.h" #include "utils.h" @@ -75,14 +73,31 @@ PortAudioPlayer::~PortAudioPlayer() { } void PortAudioPlayer::OpenStream() { - PaDeviceIndex pa_device = OPT_GET("Player/Audio/PortAudio/Device")->GetInt(); + PaDeviceIndex pa_device = paNoDevice; - if (pa_device < 0) { + std::string device_name = OPT_GET("Player/Audio/PortAudio/Device Name")->GetString(); + + if (device_name.size() && device_name != "Default") { + int devices = Pa_GetDeviceCount(); + for (int i = 0; i < devices; i++) { + const PaDeviceInfo *info = Pa_GetDeviceInfo(i); + if (info->maxOutputChannels > 0 && info->name == device_name) { + pa_device = i; + LOG_D("audio/player/portaudio") << "using config device: " << device_name << ": " << pa_device; + break; + } + } + + if (pa_device == paNoDevice) + LOG_D("audio/player/portaudio") << "config device " << device_name << " not found, using default"; + } + + if (pa_device == paNoDevice) { pa_device = Pa_GetDefaultOutputDevice(); + if (pa_device == paNoDevice) + throw PortAudioError("No PortAudio output devices found"); LOG_D("audio/player/portaudio") << "using default output device:" << pa_device; } - else - LOG_D("audio/player/portaudio") << "using config device: " << pa_device; PaStreamParameters pa_output_p; pa_output_p.device = pa_device; @@ -215,9 +230,14 @@ wxArrayString PortAudioPlayer::GetOutputDevices() { PortAudioPlayer player; // temp player to ensure PA is initialized int devices = Pa_GetDeviceCount(); + wxArrayString list; + list.push_back("Default"); + for (int i = 0; i < devices; i++) { - list.push_back(wxString(Pa_GetDeviceInfo(i)->name, wxConvUTF8)); + const PaDeviceInfo *info = Pa_GetDeviceInfo(i); + if (info->maxOutputChannels > 0) + list.push_back(wxString(info->name, wxConvUTF8)); } return list; diff --git a/aegisub/src/libresrc/default_config.json b/aegisub/src/libresrc/default_config.json index e2594e7f4..12a0187a4 100644 --- a/aegisub/src/libresrc/default_config.json +++ b/aegisub/src/libresrc/default_config.json @@ -210,7 +210,7 @@ "Device" : "/dev/dsp" }, "PortAudio" : { - "Device" : -1 + "Device Name" : "Default" } } }, diff --git a/aegisub/src/preferences.cpp b/aegisub/src/preferences.cpp index f97f5fbf9..9c739edba 100644 --- a/aegisub/src/preferences.cpp +++ b/aegisub/src/preferences.cpp @@ -54,6 +54,10 @@ #include "preferences_base.h" #include "video_provider_manager.h" +#ifdef WITH_PORTAUDIO +#include "audio_player_portaudio.h" +#endif + #define CLASS_PAGE(name) \ class name: public OptionPage { \ public: \ @@ -469,6 +473,11 @@ Advanced_Audio::Advanced_Audio(wxTreebook *book, Preferences *parent): OptionPag OptionChoice(windows, _("Avisynth down-mixer"), adm_choice, "Audio/Downmixer"); #endif +#ifdef WITH_PORTAUDIO + wxFlexGridSizer *portaudio = PageSizer(_("Portaudio")); + OptionChoice(portaudio, _("Portaudio device"), PortAudioPlayer::GetOutputDevices(), "Player/Audio/PortAudio/Device Name"); +#endif + SetSizerAndFit(sizer); } diff --git a/aegisub/src/preferences_base.cpp b/aegisub/src/preferences_base.cpp index a5fd8ce61..b0a388bdc 100644 --- a/aegisub/src/preferences_base.cpp +++ b/aegisub/src/preferences_base.cpp @@ -180,7 +180,7 @@ void OptionPage::OptionChoice(wxFlexGridSizer *flex, const wxString &name, const switch (opt->GetType()) { case agi::OptionValue::Type_Int: { int val = opt->GetInt(); - cb->SetValue(choices[val < (int)choices.size() ? val : opt->GetDefaultInt()]); + cb->Select(val < (int)choices.size() ? val : opt->GetDefaultInt()); cb->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, IntCBUpdater(opt_name, parent)); break; }