forked from eden-emu/eden
		
	Merge pull request #12868 from t895/engine-per-game
settings: Allow audio sink, input, and output to be set per game
This commit is contained in:
		
						commit
						c0eb2563ca
					
				
					 3 changed files with 110 additions and 26 deletions
				
			
		|  | @ -134,12 +134,12 @@ struct Values { | ||||||
|     Linkage linkage{}; |     Linkage linkage{}; | ||||||
| 
 | 
 | ||||||
|     // Audio
 |     // Audio
 | ||||||
|     Setting<AudioEngine> sink_id{linkage, AudioEngine::Auto, "output_engine", Category::Audio, |     SwitchableSetting<AudioEngine> sink_id{linkage, AudioEngine::Auto, "output_engine", | ||||||
|                                  Specialization::RuntimeList}; |                                            Category::Audio, Specialization::RuntimeList}; | ||||||
|     Setting<std::string> audio_output_device_id{linkage, "auto", "output_device", Category::Audio, |     SwitchableSetting<std::string> audio_output_device_id{ | ||||||
|                                                 Specialization::RuntimeList}; |         linkage, "auto", "output_device", Category::Audio, Specialization::RuntimeList}; | ||||||
|     Setting<std::string> audio_input_device_id{linkage, "auto", "input_device", Category::Audio, |     SwitchableSetting<std::string> audio_input_device_id{ | ||||||
|                                                Specialization::RuntimeList}; |         linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList}; | ||||||
|     SwitchableSetting<AudioMode, true> sound_index{ |     SwitchableSetting<AudioMode, true> sound_index{ | ||||||
|         linkage,       AudioMode::Stereo,     AudioMode::Mono,         AudioMode::Surround, |         linkage,       AudioMode::Stereo,     AudioMode::Mono,         AudioMode::Surround, | ||||||
|         "sound_index", Category::SystemAudio, Specialization::Default, true, |         "sound_index", Category::SystemAudio, Specialization::Default, true, | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <QComboBox> | #include <QComboBox> | ||||||
|  | #include <QPushButton> | ||||||
| 
 | 
 | ||||||
| #include "audio_core/sink/sink.h" | #include "audio_core/sink/sink.h" | ||||||
| #include "audio_core/sink/sink_details.h" | #include "audio_core/sink/sink_details.h" | ||||||
|  | @ -67,19 +68,99 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) { | ||||||
| 
 | 
 | ||||||
|         hold.emplace(std::pair{setting->Id(), widget}); |         hold.emplace(std::pair{setting->Id(), widget}); | ||||||
| 
 | 
 | ||||||
|  |         auto global_sink_match = [this] { | ||||||
|  |             return static_cast<Settings::AudioEngine>(sink_combo_box->currentIndex()) == | ||||||
|  |                    Settings::values.sink_id.GetValue(true); | ||||||
|  |         }; | ||||||
|         if (setting->Id() == Settings::values.sink_id.Id()) { |         if (setting->Id() == Settings::values.sink_id.Id()) { | ||||||
|             // TODO (lat9nq): Let the system manage sink_id
 |             // TODO (lat9nq): Let the system manage sink_id
 | ||||||
|             sink_combo_box = widget->combobox; |             sink_combo_box = widget->combobox; | ||||||
|             InitializeAudioSinkComboBox(); |             InitializeAudioSinkComboBox(); | ||||||
| 
 | 
 | ||||||
|             connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, |             if (Settings::IsConfiguringGlobal()) { | ||||||
|                     &ConfigureAudio::UpdateAudioDevices); |                 connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, | ||||||
|  |                         &ConfigureAudio::UpdateAudioDevices); | ||||||
|  |             } else { | ||||||
|  |                 restore_sink_button = ConfigurationShared::Widget::CreateRestoreGlobalButton( | ||||||
|  |                     Settings::values.sink_id.UsingGlobal(), widget); | ||||||
|  |                 widget->layout()->addWidget(restore_sink_button); | ||||||
|  |                 connect(restore_sink_button, &QAbstractButton::clicked, [this](bool) { | ||||||
|  |                     Settings::values.sink_id.SetGlobal(true); | ||||||
|  |                     const int sink_index = static_cast<int>(Settings::values.sink_id.GetValue()); | ||||||
|  |                     sink_combo_box->setCurrentIndex(sink_index); | ||||||
|  |                     ConfigureAudio::UpdateAudioDevices(sink_index); | ||||||
|  |                     Settings::values.audio_output_device_id.SetGlobal(true); | ||||||
|  |                     Settings::values.audio_input_device_id.SetGlobal(true); | ||||||
|  |                     restore_sink_button->setVisible(false); | ||||||
|  |                 }); | ||||||
|  |                 connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), | ||||||
|  |                         [this, global_sink_match](const int slot) { | ||||||
|  |                             Settings::values.sink_id.SetGlobal(false); | ||||||
|  |                             Settings::values.audio_output_device_id.SetGlobal(false); | ||||||
|  |                             Settings::values.audio_input_device_id.SetGlobal(false); | ||||||
|  | 
 | ||||||
|  |                             restore_sink_button->setVisible(true); | ||||||
|  |                             restore_sink_button->setEnabled(true); | ||||||
|  |                             output_device_combo_box->setCurrentIndex(0); | ||||||
|  |                             restore_output_device_button->setVisible(true); | ||||||
|  |                             restore_output_device_button->setEnabled(global_sink_match()); | ||||||
|  |                             input_device_combo_box->setCurrentIndex(0); | ||||||
|  |                             restore_input_device_button->setVisible(true); | ||||||
|  |                             restore_input_device_button->setEnabled(global_sink_match()); | ||||||
|  |                             ConfigureAudio::UpdateAudioDevices(slot); | ||||||
|  |                         }); | ||||||
|  |             } | ||||||
|         } else if (setting->Id() == Settings::values.audio_output_device_id.Id()) { |         } else if (setting->Id() == Settings::values.audio_output_device_id.Id()) { | ||||||
|             // Keep track of output (and input) device comboboxes to populate them with system
 |             // Keep track of output (and input) device comboboxes to populate them with system
 | ||||||
|             // devices, which are determined at run time
 |             // devices, which are determined at run time
 | ||||||
|             output_device_combo_box = widget->combobox; |             output_device_combo_box = widget->combobox; | ||||||
|  | 
 | ||||||
|  |             if (!Settings::IsConfiguringGlobal()) { | ||||||
|  |                 restore_output_device_button = | ||||||
|  |                     ConfigurationShared::Widget::CreateRestoreGlobalButton( | ||||||
|  |                         Settings::values.audio_output_device_id.UsingGlobal(), widget); | ||||||
|  |                 restore_output_device_button->setEnabled(global_sink_match()); | ||||||
|  |                 restore_output_device_button->setVisible( | ||||||
|  |                     !Settings::values.audio_output_device_id.UsingGlobal()); | ||||||
|  |                 widget->layout()->addWidget(restore_output_device_button); | ||||||
|  |                 connect(restore_output_device_button, &QAbstractButton::clicked, [this](bool) { | ||||||
|  |                     Settings::values.audio_output_device_id.SetGlobal(true); | ||||||
|  |                     SetOutputDevicesFromDeviceID(); | ||||||
|  |                     restore_output_device_button->setVisible(false); | ||||||
|  |                 }); | ||||||
|  |                 connect(output_device_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), | ||||||
|  |                         [this, global_sink_match](int) { | ||||||
|  |                             if (updating_devices) { | ||||||
|  |                                 return; | ||||||
|  |                             } | ||||||
|  |                             Settings::values.audio_output_device_id.SetGlobal(false); | ||||||
|  |                             restore_output_device_button->setVisible(true); | ||||||
|  |                             restore_output_device_button->setEnabled(global_sink_match()); | ||||||
|  |                         }); | ||||||
|  |             } | ||||||
|         } else if (setting->Id() == Settings::values.audio_input_device_id.Id()) { |         } else if (setting->Id() == Settings::values.audio_input_device_id.Id()) { | ||||||
|             input_device_combo_box = widget->combobox; |             input_device_combo_box = widget->combobox; | ||||||
|  | 
 | ||||||
|  |             if (!Settings::IsConfiguringGlobal()) { | ||||||
|  |                 restore_input_device_button = | ||||||
|  |                     ConfigurationShared::Widget::CreateRestoreGlobalButton( | ||||||
|  |                         Settings::values.audio_input_device_id.UsingGlobal(), widget); | ||||||
|  |                 widget->layout()->addWidget(restore_input_device_button); | ||||||
|  |                 connect(restore_input_device_button, &QAbstractButton::clicked, [this](bool) { | ||||||
|  |                     Settings::values.audio_input_device_id.SetGlobal(true); | ||||||
|  |                     SetInputDevicesFromDeviceID(); | ||||||
|  |                     restore_input_device_button->setVisible(false); | ||||||
|  |                 }); | ||||||
|  |                 connect(input_device_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), | ||||||
|  |                         [this, global_sink_match](int) { | ||||||
|  |                             if (updating_devices) { | ||||||
|  |                                 return; | ||||||
|  |                             } | ||||||
|  |                             Settings::values.audio_input_device_id.SetGlobal(false); | ||||||
|  |                             restore_input_device_button->setVisible(true); | ||||||
|  |                             restore_input_device_button->setEnabled(global_sink_match()); | ||||||
|  |                         }); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -89,16 +170,13 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureAudio::SetConfiguration() { | void ConfigureAudio::SetConfiguration() { | ||||||
|     if (!Settings::IsConfiguringGlobal()) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     SetOutputSinkFromSinkID(); |     SetOutputSinkFromSinkID(); | ||||||
| 
 | 
 | ||||||
|     // The device list cannot be pre-populated (nor listed) until the output sink is known.
 |     // The device list cannot be pre-populated (nor listed) until the output sink is known.
 | ||||||
|     UpdateAudioDevices(sink_combo_box->currentIndex()); |     UpdateAudioDevices(sink_combo_box->currentIndex()); | ||||||
| 
 | 
 | ||||||
|     SetAudioDevicesFromDeviceID(); |     SetOutputDevicesFromDeviceID(); | ||||||
|  |     SetInputDevicesFromDeviceID(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureAudio::SetOutputSinkFromSinkID() { | void ConfigureAudio::SetOutputSinkFromSinkID() { | ||||||
|  | @ -116,8 +194,8 @@ void ConfigureAudio::SetOutputSinkFromSinkID() { | ||||||
|     sink_combo_box->setCurrentIndex(new_sink_index); |     sink_combo_box->setCurrentIndex(new_sink_index); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureAudio::SetAudioDevicesFromDeviceID() { | void ConfigureAudio::SetOutputDevicesFromDeviceID() { | ||||||
|     int new_device_index = -1; |     int new_device_index = 0; | ||||||
| 
 | 
 | ||||||
|     const QString output_device_id = |     const QString output_device_id = | ||||||
|         QString::fromStdString(Settings::values.audio_output_device_id.GetValue()); |         QString::fromStdString(Settings::values.audio_output_device_id.GetValue()); | ||||||
|  | @ -129,8 +207,10 @@ void ConfigureAudio::SetAudioDevicesFromDeviceID() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     output_device_combo_box->setCurrentIndex(new_device_index); |     output_device_combo_box->setCurrentIndex(new_device_index); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     new_device_index = -1; | void ConfigureAudio::SetInputDevicesFromDeviceID() { | ||||||
|  |     int new_device_index = 0; | ||||||
|     const QString input_device_id = |     const QString input_device_id = | ||||||
|         QString::fromStdString(Settings::values.audio_input_device_id.GetValue()); |         QString::fromStdString(Settings::values.audio_input_device_id.GetValue()); | ||||||
|     for (int index = 0; index < input_device_combo_box->count(); index++) { |     for (int index = 0; index < input_device_combo_box->count(); index++) { | ||||||
|  | @ -149,15 +229,12 @@ void ConfigureAudio::ApplyConfiguration() { | ||||||
|         apply_func(is_powered_on); |         apply_func(is_powered_on); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (Settings::IsConfiguringGlobal()) { |     Settings::values.sink_id.LoadString( | ||||||
|         Settings::values.sink_id.LoadString( |         sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString()); | ||||||
|             sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString()); |     Settings::values.audio_output_device_id.SetValue( | ||||||
|         Settings::values.audio_output_device_id.SetValue( |         output_device_combo_box->itemText(output_device_combo_box->currentIndex()).toStdString()); | ||||||
|             output_device_combo_box->itemText(output_device_combo_box->currentIndex()) |     Settings::values.audio_input_device_id.SetValue( | ||||||
|                 .toStdString()); |         input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString()); | ||||||
|         Settings::values.audio_input_device_id.SetValue( |  | ||||||
|             input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString()); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureAudio::changeEvent(QEvent* event) { | void ConfigureAudio::changeEvent(QEvent* event) { | ||||||
|  | @ -169,6 +246,7 @@ void ConfigureAudio::changeEvent(QEvent* event) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureAudio::UpdateAudioDevices(int sink_index) { | void ConfigureAudio::UpdateAudioDevices(int sink_index) { | ||||||
|  |     updating_devices = true; | ||||||
|     output_device_combo_box->clear(); |     output_device_combo_box->clear(); | ||||||
|     output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); |     output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); | ||||||
| 
 | 
 | ||||||
|  | @ -183,6 +261,7 @@ void ConfigureAudio::UpdateAudioDevices(int sink_index) { | ||||||
|     for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) { |     for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) { | ||||||
|         input_device_combo_box->addItem(QString::fromStdString(device)); |         input_device_combo_box->addItem(QString::fromStdString(device)); | ||||||
|     } |     } | ||||||
|  |     updating_devices = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureAudio::InitializeAudioSinkComboBox() { | void ConfigureAudio::InitializeAudioSinkComboBox() { | ||||||
|  |  | ||||||
|  | @ -45,7 +45,8 @@ private: | ||||||
|     void UpdateAudioDevices(int sink_index); |     void UpdateAudioDevices(int sink_index); | ||||||
| 
 | 
 | ||||||
|     void SetOutputSinkFromSinkID(); |     void SetOutputSinkFromSinkID(); | ||||||
|     void SetAudioDevicesFromDeviceID(); |     void SetOutputDevicesFromDeviceID(); | ||||||
|  |     void SetInputDevicesFromDeviceID(); | ||||||
| 
 | 
 | ||||||
|     void Setup(const ConfigurationShared::Builder& builder); |     void Setup(const ConfigurationShared::Builder& builder); | ||||||
| 
 | 
 | ||||||
|  | @ -55,7 +56,11 @@ private: | ||||||
| 
 | 
 | ||||||
|     std::vector<std::function<void(bool)>> apply_funcs{}; |     std::vector<std::function<void(bool)>> apply_funcs{}; | ||||||
| 
 | 
 | ||||||
|  |     bool updating_devices = false; | ||||||
|     QComboBox* sink_combo_box; |     QComboBox* sink_combo_box; | ||||||
|  |     QPushButton* restore_sink_button; | ||||||
|     QComboBox* output_device_combo_box; |     QComboBox* output_device_combo_box; | ||||||
|  |     QPushButton* restore_output_device_button; | ||||||
|     QComboBox* input_device_combo_box; |     QComboBox* input_device_combo_box; | ||||||
|  |     QPushButton* restore_input_device_button; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 liamwhite
						liamwhite