SDL: Switch audio device when plugged in.

This commit is contained in:
Unknown W. Brackets 2019-09-15 13:42:56 -07:00
parent c30bc4ee7d
commit a1ee226c39
4 changed files with 41 additions and 4 deletions

View File

@ -779,6 +779,7 @@ static ConfigSetting soundSettings[] = {
ConfigSetting("GlobalVolume", &g_Config.iGlobalVolume, VOLUME_MAX, true, true),
ConfigSetting("AltSpeedVolume", &g_Config.iAltSpeedVolume, -1, true, true),
ConfigSetting("AudioDevice", &g_Config.sAudioDevice, "", true, false),
ConfigSetting("AutoAudioDevice", &g_Config.bAutoAudioDevice, true, true, false),
ConfigSetting(false),
};

View File

@ -198,6 +198,7 @@ public:
int iAltSpeedVolume;
bool bExtraAudioBuffering; // For bluetooth
std::string sAudioDevice;
bool bAutoAudioDevice;
// UI
bool bShowDebuggerOnLoad;

View File

@ -88,7 +88,7 @@ extern void mixaudio(void *userdata, Uint8 *stream, int len) {
static SDL_AudioDeviceID audioDev = 0;
// Must be called after NativeInit().
static void InitSDLAudioDevice() {
static void InitSDLAudioDevice(const std::string &name = "") {
SDL_AudioSpec fmt, ret_fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.freq = 44100;
@ -98,11 +98,16 @@ static void InitSDLAudioDevice() {
fmt.callback = &mixaudio;
fmt.userdata = nullptr;
std::string startDevice = name;
if (startDevice.empty()) {
startDevice = g_Config.sAudioDevice;
}
audioDev = 0;
if (!g_Config.sAudioDevice.empty()) {
audioDev = SDL_OpenAudioDevice(g_Config.sAudioDevice.c_str(), 0, &fmt, &ret_fmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
if (!startDevice.empty()) {
audioDev = SDL_OpenAudioDevice(startDevice.c_str(), 0, &fmt, &ret_fmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
if (audioDev <= 0) {
WLOG("Failed to open preferred audio device %s", g_Config.sAudioDevice.c_str());
WLOG("Failed to open audio device: %s", startDevice.c_str());
}
}
if (audioDev <= 0) {
@ -896,6 +901,29 @@ int main(int argc, char *argv[]) {
break;
}
break;
#if SDL_VERSION_ATLEAST(2, 0, 4)
case SDL_AUDIODEVICEADDED:
// Automatically switch to the new device.
if (event.adevice.iscapture == 0) {
const char *name = SDL_GetAudioDeviceName(event.adevice.which, 0);
if (!name) {
break;
}
if (g_Config.bAutoAudioDevice || g_Config.sAudioDevice == name) {
StopSDLAudioDevice();
InitSDLAudioDevice(name ? name : "");
}
}
break;
case SDL_AUDIODEVICEREMOVED:
if (event.adevice.iscapture == 0 && event.adevice.which == audioDev) {
StopSDLAudioDevice();
InitSDLAudioDevice();
}
break;
#endif
default:
if (joystick) {
joystick->ProcessInput(event);

View File

@ -495,8 +495,11 @@ void GameSettingsScreen::CreateViews() {
#if defined(SDL)
std::vector<std::string> audioDeviceList;
SplitString(System_GetProperty(SYSPROP_AUDIO_DEVICE_LIST), '\0', audioDeviceList);
audioDeviceList.insert(audioDeviceList.begin(), a->T("Auto"));
PopupMultiChoiceDynamic *audioDevice = audioSettings->Add(new PopupMultiChoiceDynamic(&g_Config.sAudioDevice, a->T("Device"), audioDeviceList, nullptr, screenManager()));
audioDevice->OnChoice.Handle(this, &GameSettingsScreen::OnAudioDevice);
audioSettings->Add(new CheckBox(&g_Config.bAutoAudioDevice, a->T("Switch on new audio device")));
#endif
static const char *latency[] = { "Low", "Medium", "High" };
@ -1189,6 +1192,10 @@ UI::EventReturn GameSettingsScreen::OnRenderingDevice(UI::EventParams &e) {
}
UI::EventReturn GameSettingsScreen::OnAudioDevice(UI::EventParams &e) {
I18NCategory *a = GetI18NCategory("Audio");
if (g_Config.sAudioDevice == a->T("Auto")) {
g_Config.sAudioDevice.clear();
}
System_SendMessage("audio_resetDevice", "");
return UI::EVENT_DONE;
}