configure_audio.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Copyright 2018 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <memory>
  5. #include <QSignalBlocker>
  6. #include "audio_core/sink.h"
  7. #include "audio_core/sink_details.h"
  8. #include "common/settings.h"
  9. #include "core/core.h"
  10. #include "ui_configure_audio.h"
  11. #include "yuzu/configuration/configuration_shared.h"
  12. #include "yuzu/configuration/configure_audio.h"
  13. ConfigureAudio::ConfigureAudio(QWidget* parent)
  14. : QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
  15. ui->setupUi(this);
  16. InitializeAudioOutputSinkComboBox();
  17. connect(ui->volume_slider, &QSlider::valueChanged, this,
  18. &ConfigureAudio::SetVolumeIndicatorText);
  19. connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
  20. &ConfigureAudio::UpdateAudioDevices);
  21. ui->volume_label->setVisible(Settings::IsConfiguringGlobal());
  22. ui->volume_combo_box->setVisible(!Settings::IsConfiguringGlobal());
  23. SetupPerGameUI();
  24. SetConfiguration();
  25. const bool is_powered_on = Core::System::GetInstance().IsPoweredOn();
  26. ui->output_sink_combo_box->setEnabled(!is_powered_on);
  27. ui->audio_device_combo_box->setEnabled(!is_powered_on);
  28. }
  29. ConfigureAudio::~ConfigureAudio() = default;
  30. void ConfigureAudio::SetConfiguration() {
  31. SetOutputSinkFromSinkID();
  32. // The device list cannot be pre-populated (nor listed) until the output sink is known.
  33. UpdateAudioDevices(ui->output_sink_combo_box->currentIndex());
  34. SetAudioDeviceFromDeviceID();
  35. ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
  36. ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
  37. if (!Settings::IsConfiguringGlobal()) {
  38. if (Settings::values.volume.UsingGlobal()) {
  39. ui->volume_combo_box->setCurrentIndex(0);
  40. ui->volume_slider->setEnabled(false);
  41. } else {
  42. ui->volume_combo_box->setCurrentIndex(1);
  43. ui->volume_slider->setEnabled(true);
  44. }
  45. ConfigurationShared::SetHighlight(ui->volume_layout,
  46. !Settings::values.volume.UsingGlobal());
  47. }
  48. SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
  49. }
  50. void ConfigureAudio::SetOutputSinkFromSinkID() {
  51. [[maybe_unused]] const QSignalBlocker blocker(ui->output_sink_combo_box);
  52. int new_sink_index = 0;
  53. const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
  54. for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
  55. if (ui->output_sink_combo_box->itemText(index) == sink_id) {
  56. new_sink_index = index;
  57. break;
  58. }
  59. }
  60. ui->output_sink_combo_box->setCurrentIndex(new_sink_index);
  61. }
  62. void ConfigureAudio::SetAudioDeviceFromDeviceID() {
  63. int new_device_index = -1;
  64. const QString device_id = QString::fromStdString(Settings::values.audio_device_id.GetValue());
  65. for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
  66. if (ui->audio_device_combo_box->itemText(index) == device_id) {
  67. new_device_index = index;
  68. break;
  69. }
  70. }
  71. ui->audio_device_combo_box->setCurrentIndex(new_device_index);
  72. }
  73. void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
  74. ui->volume_indicator->setText(tr("%1%", "Volume percentage (e.g. 50%)").arg(percentage));
  75. }
  76. void ConfigureAudio::ApplyConfiguration() {
  77. ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
  78. ui->toggle_audio_stretching, enable_audio_stretching);
  79. if (Settings::IsConfiguringGlobal()) {
  80. Settings::values.sink_id =
  81. ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
  82. .toStdString();
  83. Settings::values.audio_device_id.SetValue(
  84. ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
  85. .toStdString());
  86. // Guard if during game and set to game-specific value
  87. if (Settings::values.volume.UsingGlobal()) {
  88. Settings::values.volume.SetValue(
  89. static_cast<float>(ui->volume_slider->sliderPosition()) /
  90. ui->volume_slider->maximum());
  91. }
  92. } else {
  93. if (ui->volume_combo_box->currentIndex() == 0) {
  94. Settings::values.volume.SetGlobal(true);
  95. } else {
  96. Settings::values.volume.SetGlobal(false);
  97. Settings::values.volume.SetValue(
  98. static_cast<float>(ui->volume_slider->sliderPosition()) /
  99. ui->volume_slider->maximum());
  100. }
  101. }
  102. }
  103. void ConfigureAudio::changeEvent(QEvent* event) {
  104. if (event->type() == QEvent::LanguageChange) {
  105. RetranslateUI();
  106. }
  107. QWidget::changeEvent(event);
  108. }
  109. void ConfigureAudio::UpdateAudioDevices(int sink_index) {
  110. ui->audio_device_combo_box->clear();
  111. ui->audio_device_combo_box->addItem(QString::fromUtf8(AudioCore::auto_device_name));
  112. const std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString();
  113. for (const auto& device : AudioCore::GetDeviceListForSink(sink_id)) {
  114. ui->audio_device_combo_box->addItem(QString::fromStdString(device));
  115. }
  116. }
  117. void ConfigureAudio::InitializeAudioOutputSinkComboBox() {
  118. ui->output_sink_combo_box->clear();
  119. ui->output_sink_combo_box->addItem(QString::fromUtf8(AudioCore::auto_device_name));
  120. for (const char* id : AudioCore::GetSinkIDs()) {
  121. ui->output_sink_combo_box->addItem(QString::fromUtf8(id));
  122. }
  123. }
  124. void ConfigureAudio::RetranslateUI() {
  125. ui->retranslateUi(this);
  126. SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
  127. }
  128. void ConfigureAudio::SetupPerGameUI() {
  129. if (Settings::IsConfiguringGlobal()) {
  130. ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal());
  131. ui->toggle_audio_stretching->setEnabled(
  132. Settings::values.enable_audio_stretching.UsingGlobal());
  133. return;
  134. }
  135. ConfigurationShared::SetColoredTristate(ui->toggle_audio_stretching,
  136. Settings::values.enable_audio_stretching,
  137. enable_audio_stretching);
  138. connect(ui->volume_combo_box, qOverload<int>(&QComboBox::activated), this, [this](int index) {
  139. ui->volume_slider->setEnabled(index == 1);
  140. ConfigurationShared::SetHighlight(ui->volume_layout, index == 1);
  141. });
  142. ui->output_sink_combo_box->setVisible(false);
  143. ui->output_sink_label->setVisible(false);
  144. ui->audio_device_combo_box->setVisible(false);
  145. ui->audio_device_label->setVisible(false);
  146. }