| | |
| | |
| |
|
| | #include <map> |
| | #include <memory> |
| | #include <vector> |
| | #include <QComboBox> |
| | #include <QPushButton> |
| |
|
| | #include "audio_core/sink/sink.h" |
| | #include "audio_core/sink/sink_details.h" |
| | #include "common/common_types.h" |
| | #include "common/settings.h" |
| | #include "common/settings_common.h" |
| | #include "core/core.h" |
| | #include "ui_configure_audio.h" |
| | #include "yuzu/configuration/configuration_shared.h" |
| | #include "yuzu/configuration/configure_audio.h" |
| | #include "yuzu/configuration/shared_translation.h" |
| | #include "yuzu/configuration/shared_widget.h" |
| | #include "yuzu/uisettings.h" |
| |
|
| | ConfigureAudio::ConfigureAudio(const Core::System& system_, |
| | std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_, |
| | const ConfigurationShared::Builder& builder, QWidget* parent) |
| | : Tab(group_, parent), ui(std::make_unique<Ui::ConfigureAudio>()), system{system_} { |
| | ui->setupUi(this); |
| | Setup(builder); |
| |
|
| | SetConfiguration(); |
| | } |
| |
|
| | ConfigureAudio::~ConfigureAudio() = default; |
| |
|
| | void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) { |
| | auto& layout = *ui->audio_widget->layout(); |
| |
|
| | std::vector<Settings::BasicSetting*> settings; |
| |
|
| | std::map<u32, QWidget*> hold; |
| |
|
| | auto push_settings = [&](Settings::Category category) { |
| | for (auto* setting : Settings::values.linkage.by_category[category]) { |
| | settings.push_back(setting); |
| | } |
| | }; |
| |
|
| | auto push_ui_settings = [&](Settings::Category category) { |
| | for (auto* setting : UISettings::values.linkage.by_category[category]) { |
| | settings.push_back(setting); |
| | } |
| | }; |
| |
|
| | push_settings(Settings::Category::Audio); |
| | push_settings(Settings::Category::SystemAudio); |
| | push_ui_settings(Settings::Category::UiAudio); |
| |
|
| | for (auto* setting : settings) { |
| | auto* widget = builder.BuildWidget(setting, apply_funcs); |
| |
|
| | if (widget == nullptr) { |
| | continue; |
| | } |
| | if (!widget->Valid()) { |
| | widget->deleteLater(); |
| | continue; |
| | } |
| |
|
| | 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()) { |
| | |
| | sink_combo_box = widget->combobox; |
| | InitializeAudioSinkComboBox(); |
| |
|
| | if (Settings::IsConfiguringGlobal()) { |
| | 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()) { |
| | |
| | |
| | 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()) { |
| | 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()); |
| | }); |
| | } |
| | } |
| | } |
| |
|
| | for (const auto& [id, widget] : hold) { |
| | layout.addWidget(widget); |
| | } |
| | } |
| |
|
| | void ConfigureAudio::SetConfiguration() { |
| | SetOutputSinkFromSinkID(); |
| |
|
| | |
| | UpdateAudioDevices(sink_combo_box->currentIndex()); |
| |
|
| | SetOutputDevicesFromDeviceID(); |
| | SetInputDevicesFromDeviceID(); |
| | } |
| |
|
| | void ConfigureAudio::SetOutputSinkFromSinkID() { |
| | [[maybe_unused]] const QSignalBlocker blocker(sink_combo_box); |
| |
|
| | int new_sink_index = 0; |
| | const QString sink_id = QString::fromStdString(Settings::values.sink_id.ToString()); |
| | for (int index = 0; index < sink_combo_box->count(); index++) { |
| | if (sink_combo_box->itemText(index) == sink_id) { |
| | new_sink_index = index; |
| | break; |
| | } |
| | } |
| |
|
| | sink_combo_box->setCurrentIndex(new_sink_index); |
| | } |
| |
|
| | void ConfigureAudio::SetOutputDevicesFromDeviceID() { |
| | int new_device_index = 0; |
| |
|
| | const QString output_device_id = |
| | QString::fromStdString(Settings::values.audio_output_device_id.GetValue()); |
| | for (int index = 0; index < output_device_combo_box->count(); index++) { |
| | if (output_device_combo_box->itemText(index) == output_device_id) { |
| | new_device_index = index; |
| | break; |
| | } |
| | } |
| |
|
| | output_device_combo_box->setCurrentIndex(new_device_index); |
| | } |
| |
|
| | void ConfigureAudio::SetInputDevicesFromDeviceID() { |
| | int new_device_index = 0; |
| | const QString input_device_id = |
| | QString::fromStdString(Settings::values.audio_input_device_id.GetValue()); |
| | for (int index = 0; index < input_device_combo_box->count(); index++) { |
| | if (input_device_combo_box->itemText(index) == input_device_id) { |
| | new_device_index = index; |
| | break; |
| | } |
| | } |
| |
|
| | input_device_combo_box->setCurrentIndex(new_device_index); |
| | } |
| |
|
| | void ConfigureAudio::ApplyConfiguration() { |
| | const bool is_powered_on = system.IsPoweredOn(); |
| | for (const auto& apply_func : apply_funcs) { |
| | apply_func(is_powered_on); |
| | } |
| |
|
| | Settings::values.sink_id.LoadString( |
| | sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString()); |
| | Settings::values.audio_output_device_id.SetValue( |
| | output_device_combo_box->itemText(output_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) { |
| | if (event->type() == QEvent::LanguageChange) { |
| | RetranslateUI(); |
| | } |
| |
|
| | QWidget::changeEvent(event); |
| | } |
| |
|
| | void ConfigureAudio::UpdateAudioDevices(int sink_index) { |
| | updating_devices = true; |
| | output_device_combo_box->clear(); |
| | output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); |
| |
|
| | const auto sink_id = |
| | Settings::ToEnum<Settings::AudioEngine>(sink_combo_box->itemText(sink_index).toStdString()); |
| | for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, false)) { |
| | output_device_combo_box->addItem(QString::fromStdString(device)); |
| | } |
| |
|
| | input_device_combo_box->clear(); |
| | input_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); |
| | for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) { |
| | input_device_combo_box->addItem(QString::fromStdString(device)); |
| | } |
| | updating_devices = false; |
| | } |
| |
|
| | void ConfigureAudio::InitializeAudioSinkComboBox() { |
| | sink_combo_box->clear(); |
| | sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name)); |
| |
|
| | for (const auto& id : AudioCore::Sink::GetSinkIDs()) { |
| | sink_combo_box->addItem(QString::fromStdString(Settings::CanonicalizeEnum(id))); |
| | } |
| | } |
| |
|
| | void ConfigureAudio::RetranslateUI() { |
| | ui->retranslateUi(this); |
| | } |
| |
|