Merge pull request #871 from bunnei/audio-config
audio_core: Add configuration settings.
This commit is contained in:
		@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "audio_core/sink_details.h"
 | 
					#include "audio_core/sink_details.h"
 | 
				
			||||||
#include "common/assert.h"
 | 
					#include "common/assert.h"
 | 
				
			||||||
#include "common/logging/log.h"
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
 | 
					#include "core/settings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AudioCore {
 | 
					namespace AudioCore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,8 +30,8 @@ static Stream::Format ChannelsToStreamFormat(u32 num_channels) {
 | 
				
			|||||||
StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels,
 | 
					StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels,
 | 
				
			||||||
                               Stream::ReleaseCallback&& release_callback) {
 | 
					                               Stream::ReleaseCallback&& release_callback) {
 | 
				
			||||||
    if (!sink) {
 | 
					    if (!sink) {
 | 
				
			||||||
        const SinkDetails& sink_details = GetSinkDetails("auto");
 | 
					        const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id);
 | 
				
			||||||
        sink = sink_details.factory("");
 | 
					        sink = sink_details.factory(Settings::values.audio_device_id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return std::make_shared<Stream>(sample_rate, ChannelsToStreamFormat(num_channels),
 | 
					    return std::make_shared<Stream>(sample_rate, ChannelsToStreamFormat(num_channels),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,17 @@
 | 
				
			|||||||
// Licensed under GPLv2 or any later version
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "common/assert.h"
 | 
					#include <algorithm>
 | 
				
			||||||
#include "common/logging/log.h"
 | 
					#include <cmath>
 | 
				
			||||||
#include "core/core_timing.h"
 | 
					 | 
				
			||||||
#include "core/core_timing_util.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "audio_core/sink.h"
 | 
					#include "audio_core/sink.h"
 | 
				
			||||||
#include "audio_core/sink_details.h"
 | 
					#include "audio_core/sink_details.h"
 | 
				
			||||||
#include "audio_core/stream.h"
 | 
					#include "audio_core/stream.h"
 | 
				
			||||||
 | 
					#include "common/assert.h"
 | 
				
			||||||
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
 | 
					#include "core/core_timing.h"
 | 
				
			||||||
 | 
					#include "core/core_timing_util.h"
 | 
				
			||||||
 | 
					#include "core/settings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AudioCore {
 | 
					namespace AudioCore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,6 +59,24 @@ s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
 | 
				
			|||||||
    return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
 | 
					    return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static std::vector<s16> GetVolumeAdjustedSamples(const std::vector<u8>& data) {
 | 
				
			||||||
 | 
					    std::vector<s16> samples(data.size() / sizeof(s16));
 | 
				
			||||||
 | 
					    std::memcpy(samples.data(), data.data(), data.size());
 | 
				
			||||||
 | 
					    const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (volume == 1.0f) {
 | 
				
			||||||
 | 
					        return samples;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Implementation of a volume slider with a dynamic range of 60 dB
 | 
				
			||||||
 | 
					    const float volume_scale_factor{std::exp(6.90775f * volume) * 0.001f};
 | 
				
			||||||
 | 
					    for (auto& sample : samples) {
 | 
				
			||||||
 | 
					        sample = static_cast<s16>(sample * volume_scale_factor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return samples;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Stream::PlayNextBuffer() {
 | 
					void Stream::PlayNextBuffer() {
 | 
				
			||||||
    if (!IsPlaying()) {
 | 
					    if (!IsPlaying()) {
 | 
				
			||||||
        // Ensure we are in playing state before playing the next buffer
 | 
					        // Ensure we are in playing state before playing the next buffer
 | 
				
			||||||
@@ -75,9 +96,9 @@ void Stream::PlayNextBuffer() {
 | 
				
			|||||||
    active_buffer = queued_buffers.front();
 | 
					    active_buffer = queued_buffers.front();
 | 
				
			||||||
    queued_buffers.pop();
 | 
					    queued_buffers.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sink_stream.EnqueueSamples(GetNumChannels(),
 | 
					    const size_t sample_count{active_buffer->GetData().size() / GetSampleSize()};
 | 
				
			||||||
                               reinterpret_cast<const s16*>(active_buffer->GetData().data()),
 | 
					    sink_stream.EnqueueSamples(
 | 
				
			||||||
                               active_buffer->GetData().size() / GetSampleSize());
 | 
					        GetNumChannels(), GetVolumeAdjustedSamples(active_buffer->GetData()).data(), sample_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
 | 
					    CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,6 +137,11 @@ struct Values {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::string log_filter;
 | 
					    std::string log_filter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Audio
 | 
				
			||||||
 | 
					    std::string sink_id;
 | 
				
			||||||
 | 
					    std::string audio_device_id;
 | 
				
			||||||
 | 
					    float volume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Debugging
 | 
					    // Debugging
 | 
				
			||||||
    bool use_gdbstub;
 | 
					    bool use_gdbstub;
 | 
				
			||||||
    u16 gdbstub_port;
 | 
					    u16 gdbstub_port;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,8 @@ add_executable(yuzu
 | 
				
			|||||||
    bootmanager.h
 | 
					    bootmanager.h
 | 
				
			||||||
    configuration/config.cpp
 | 
					    configuration/config.cpp
 | 
				
			||||||
    configuration/config.h
 | 
					    configuration/config.h
 | 
				
			||||||
 | 
					    configuration/configure_audio.cpp
 | 
				
			||||||
 | 
					    configuration/configure_audio.h
 | 
				
			||||||
    configuration/configure_debug.cpp
 | 
					    configuration/configure_debug.cpp
 | 
				
			||||||
    configuration/configure_debug.h
 | 
					    configuration/configure_debug.h
 | 
				
			||||||
    configuration/configure_dialog.cpp
 | 
					    configuration/configure_dialog.cpp
 | 
				
			||||||
@@ -55,6 +57,7 @@ add_executable(yuzu
 | 
				
			|||||||
set(UIS
 | 
					set(UIS
 | 
				
			||||||
    aboutdialog.ui
 | 
					    aboutdialog.ui
 | 
				
			||||||
    configuration/configure.ui
 | 
					    configuration/configure.ui
 | 
				
			||||||
 | 
					    configuration/configure_audio.ui
 | 
				
			||||||
    configuration/configure_debug.ui
 | 
					    configuration/configure_debug.ui
 | 
				
			||||||
    configuration/configure_general.ui
 | 
					    configuration/configure_general.ui
 | 
				
			||||||
    configuration/configure_graphics.ui
 | 
					    configuration/configure_graphics.ui
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,6 +92,13 @@ void Config::ReadValues() {
 | 
				
			|||||||
    Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat();
 | 
					    Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat();
 | 
				
			||||||
    qt_config->endGroup();
 | 
					    qt_config->endGroup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qt_config->beginGroup("Audio");
 | 
				
			||||||
 | 
					    Settings::values.sink_id = qt_config->value("output_engine", "auto").toString().toStdString();
 | 
				
			||||||
 | 
					    Settings::values.audio_device_id =
 | 
				
			||||||
 | 
					        qt_config->value("output_device", "auto").toString().toStdString();
 | 
				
			||||||
 | 
					    Settings::values.volume = qt_config->value("volume", 1).toFloat();
 | 
				
			||||||
 | 
					    qt_config->endGroup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qt_config->beginGroup("Data Storage");
 | 
					    qt_config->beginGroup("Data Storage");
 | 
				
			||||||
    Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
 | 
					    Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
 | 
				
			||||||
    qt_config->endGroup();
 | 
					    qt_config->endGroup();
 | 
				
			||||||
@@ -195,6 +202,12 @@ void Config::SaveValues() {
 | 
				
			|||||||
    qt_config->setValue("bg_blue", (double)Settings::values.bg_blue);
 | 
					    qt_config->setValue("bg_blue", (double)Settings::values.bg_blue);
 | 
				
			||||||
    qt_config->endGroup();
 | 
					    qt_config->endGroup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qt_config->beginGroup("Audio");
 | 
				
			||||||
 | 
					    qt_config->setValue("output_engine", QString::fromStdString(Settings::values.sink_id));
 | 
				
			||||||
 | 
					    qt_config->setValue("output_device", QString::fromStdString(Settings::values.audio_device_id));
 | 
				
			||||||
 | 
					    qt_config->setValue("volume", Settings::values.volume);
 | 
				
			||||||
 | 
					    qt_config->endGroup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qt_config->beginGroup("Data Storage");
 | 
					    qt_config->beginGroup("Data Storage");
 | 
				
			||||||
    qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
 | 
					    qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
 | 
				
			||||||
    qt_config->endGroup();
 | 
					    qt_config->endGroup();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,11 +34,16 @@
 | 
				
			|||||||
       <string>Input</string>
 | 
					       <string>Input</string>
 | 
				
			||||||
      </attribute>
 | 
					      </attribute>
 | 
				
			||||||
     </widget>
 | 
					     </widget>
 | 
				
			||||||
      <widget class="ConfigureGraphics" name="graphicsTab">
 | 
					     <widget class="ConfigureGraphics" name="graphicsTab">
 | 
				
			||||||
        <attribute name="title">
 | 
					      <attribute name="title">
 | 
				
			||||||
          <string>Graphics</string>
 | 
					       <string>Graphics</string>
 | 
				
			||||||
        </attribute>
 | 
					      </attribute>
 | 
				
			||||||
      </widget>
 | 
					     </widget>
 | 
				
			||||||
 | 
					     <widget class="ConfigureAudio" name="audioTab">
 | 
				
			||||||
 | 
					      <attribute name="title">
 | 
				
			||||||
 | 
					       <string>Audio</string>
 | 
				
			||||||
 | 
					      </attribute>
 | 
				
			||||||
 | 
					     </widget>
 | 
				
			||||||
     <widget class="ConfigureDebug" name="debugTab">
 | 
					     <widget class="ConfigureDebug" name="debugTab">
 | 
				
			||||||
      <attribute name="title">
 | 
					      <attribute name="title">
 | 
				
			||||||
       <string>Debug</string>
 | 
					       <string>Debug</string>
 | 
				
			||||||
@@ -68,6 +73,12 @@
 | 
				
			|||||||
   <header>configuration/configure_system.h</header>
 | 
					   <header>configuration/configure_system.h</header>
 | 
				
			||||||
   <container>1</container>
 | 
					   <container>1</container>
 | 
				
			||||||
  </customwidget>
 | 
					  </customwidget>
 | 
				
			||||||
 | 
					  <customwidget>
 | 
				
			||||||
 | 
					   <class>ConfigureAudio</class>
 | 
				
			||||||
 | 
					   <extends>QWidget</extends>
 | 
				
			||||||
 | 
					   <header>configuration/configure_audio.h</header>
 | 
				
			||||||
 | 
					   <container>1</container>
 | 
				
			||||||
 | 
					  </customwidget>
 | 
				
			||||||
  <customwidget>
 | 
					  <customwidget>
 | 
				
			||||||
   <class>ConfigureDebug</class>
 | 
					   <class>ConfigureDebug</class>
 | 
				
			||||||
   <extends>QWidget</extends>
 | 
					   <extends>QWidget</extends>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										90
									
								
								src/yuzu/configuration/configure_audio.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/yuzu/configuration/configure_audio.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					// Copyright 2018 yuzu Emulator Project
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "audio_core/sink.h"
 | 
				
			||||||
 | 
					#include "audio_core/sink_details.h"
 | 
				
			||||||
 | 
					#include "core/core.h"
 | 
				
			||||||
 | 
					#include "core/settings.h"
 | 
				
			||||||
 | 
					#include "ui_configure_audio.h"
 | 
				
			||||||
 | 
					#include "yuzu/configuration/configure_audio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ConfigureAudio::ConfigureAudio(QWidget* parent)
 | 
				
			||||||
 | 
					    : QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
 | 
				
			||||||
 | 
					    ui->setupUi(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ui->output_sink_combo_box->clear();
 | 
				
			||||||
 | 
					    ui->output_sink_combo_box->addItem("auto");
 | 
				
			||||||
 | 
					    for (const auto& sink_detail : AudioCore::g_sink_details) {
 | 
				
			||||||
 | 
					        ui->output_sink_combo_box->addItem(sink_detail.id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connect(ui->volume_slider, &QSlider::valueChanged, [this] {
 | 
				
			||||||
 | 
					        ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition()));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this->setConfiguration();
 | 
				
			||||||
 | 
					    connect(ui->output_sink_combo_box,
 | 
				
			||||||
 | 
					            static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
 | 
				
			||||||
 | 
					            &ConfigureAudio::updateAudioDevices);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ui->output_sink_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
 | 
				
			||||||
 | 
					    ui->audio_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ConfigureAudio::~ConfigureAudio() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ConfigureAudio::setConfiguration() {
 | 
				
			||||||
 | 
					    int new_sink_index = 0;
 | 
				
			||||||
 | 
					    for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
 | 
				
			||||||
 | 
					        if (ui->output_sink_combo_box->itemText(index).toStdString() == Settings::values.sink_id) {
 | 
				
			||||||
 | 
					            new_sink_index = index;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ui->output_sink_combo_box->setCurrentIndex(new_sink_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The device list cannot be pre-populated (nor listed) until the output sink is known.
 | 
				
			||||||
 | 
					    updateAudioDevices(new_sink_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int new_device_index = -1;
 | 
				
			||||||
 | 
					    for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
 | 
				
			||||||
 | 
					        if (ui->audio_device_combo_box->itemText(index).toStdString() ==
 | 
				
			||||||
 | 
					            Settings::values.audio_device_id) {
 | 
				
			||||||
 | 
					            new_device_index = index;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ui->audio_device_combo_box->setCurrentIndex(new_device_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ui->volume_slider->setValue(Settings::values.volume * ui->volume_slider->maximum());
 | 
				
			||||||
 | 
					    ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition()));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ConfigureAudio::applyConfiguration() {
 | 
				
			||||||
 | 
					    Settings::values.sink_id =
 | 
				
			||||||
 | 
					        ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
 | 
				
			||||||
 | 
					            .toStdString();
 | 
				
			||||||
 | 
					    Settings::values.audio_device_id =
 | 
				
			||||||
 | 
					        ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
 | 
				
			||||||
 | 
					            .toStdString();
 | 
				
			||||||
 | 
					    Settings::values.volume =
 | 
				
			||||||
 | 
					        static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ConfigureAudio::updateAudioDevices(int sink_index) {
 | 
				
			||||||
 | 
					    ui->audio_device_combo_box->clear();
 | 
				
			||||||
 | 
					    ui->audio_device_combo_box->addItem(AudioCore::auto_device_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString();
 | 
				
			||||||
 | 
					    std::vector<std::string> device_list = AudioCore::GetSinkDetails(sink_id).list_devices();
 | 
				
			||||||
 | 
					    for (const auto& device : device_list) {
 | 
				
			||||||
 | 
					        ui->audio_device_combo_box->addItem(device.c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ConfigureAudio::retranslateUi() {
 | 
				
			||||||
 | 
					    ui->retranslateUi(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/yuzu/configuration/configure_audio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/yuzu/configuration/configure_audio.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					// Copyright 2018 yuzu Emulator Project
 | 
				
			||||||
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <QWidget>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ui {
 | 
				
			||||||
 | 
					class ConfigureAudio;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ConfigureAudio : public QWidget {
 | 
				
			||||||
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit ConfigureAudio(QWidget* parent = nullptr);
 | 
				
			||||||
 | 
					    ~ConfigureAudio();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void applyConfiguration();
 | 
				
			||||||
 | 
					    void retranslateUi();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public slots:
 | 
				
			||||||
 | 
					    void updateAudioDevices(int sink_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    void setConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::unique_ptr<Ui::ConfigureAudio> ui;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										130
									
								
								src/yuzu/configuration/configure_audio.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/yuzu/configuration/configure_audio.ui
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<ui version="4.0">
 | 
				
			||||||
 | 
					 <class>ConfigureAudio</class>
 | 
				
			||||||
 | 
					 <widget class="QWidget" name="ConfigureAudio">
 | 
				
			||||||
 | 
					  <property name="geometry">
 | 
				
			||||||
 | 
					   <rect>
 | 
				
			||||||
 | 
					    <x>0</x>
 | 
				
			||||||
 | 
					    <y>0</y>
 | 
				
			||||||
 | 
					    <width>188</width>
 | 
				
			||||||
 | 
					    <height>246</height>
 | 
				
			||||||
 | 
					   </rect>
 | 
				
			||||||
 | 
					  </property>
 | 
				
			||||||
 | 
					  <layout class="QVBoxLayout">
 | 
				
			||||||
 | 
					   <item>
 | 
				
			||||||
 | 
					    <widget class="QGroupBox" name="groupBox">
 | 
				
			||||||
 | 
					     <property name="title">
 | 
				
			||||||
 | 
					      <string>Audio</string>
 | 
				
			||||||
 | 
					     </property>
 | 
				
			||||||
 | 
					     <layout class="QVBoxLayout">
 | 
				
			||||||
 | 
					      <item>
 | 
				
			||||||
 | 
					       <layout class="QHBoxLayout">
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QLabel" name="label">
 | 
				
			||||||
 | 
					          <property name="text">
 | 
				
			||||||
 | 
					           <string>Output Engine:</string>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					         </widget>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QComboBox" name="output_sink_combo_box"/>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					       </layout>
 | 
				
			||||||
 | 
					      </item>
 | 
				
			||||||
 | 
					      <item>
 | 
				
			||||||
 | 
					       <layout class="QHBoxLayout">
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QLabel" name="label">
 | 
				
			||||||
 | 
					          <property name="text">
 | 
				
			||||||
 | 
					           <string>Audio Device:</string>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					         </widget>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QComboBox" name="audio_device_combo_box"/>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					       </layout>
 | 
				
			||||||
 | 
					      </item>
 | 
				
			||||||
 | 
					      <item>
 | 
				
			||||||
 | 
					       <layout class="QHBoxLayout" name="horizontalLayout_2">
 | 
				
			||||||
 | 
					        <property name="topMargin">
 | 
				
			||||||
 | 
					         <number>0</number>
 | 
				
			||||||
 | 
					        </property>
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QLabel" name="label">
 | 
				
			||||||
 | 
					          <property name="text">
 | 
				
			||||||
 | 
					           <string>Volume:</string>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					         </widget>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <spacer name="horizontalSpacer">
 | 
				
			||||||
 | 
					          <property name="orientation">
 | 
				
			||||||
 | 
					           <enum>Qt::Horizontal</enum>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="sizeHint" stdset="0">
 | 
				
			||||||
 | 
					           <size>
 | 
				
			||||||
 | 
					            <width>40</width>
 | 
				
			||||||
 | 
					            <height>20</height>
 | 
				
			||||||
 | 
					           </size>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					         </spacer>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QSlider" name="volume_slider">
 | 
				
			||||||
 | 
					          <property name="sizePolicy">
 | 
				
			||||||
 | 
					           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
 | 
				
			||||||
 | 
					            <horstretch>0</horstretch>
 | 
				
			||||||
 | 
					            <verstretch>0</verstretch>
 | 
				
			||||||
 | 
					           </sizepolicy>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="maximum">
 | 
				
			||||||
 | 
					           <number>100</number>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="pageStep">
 | 
				
			||||||
 | 
					           <number>10</number>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="orientation">
 | 
				
			||||||
 | 
					           <enum>Qt::Horizontal</enum>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					         </widget>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					        <item>
 | 
				
			||||||
 | 
					         <widget class="QLabel" name="volume_indicator">
 | 
				
			||||||
 | 
					          <property name="minimumSize">
 | 
				
			||||||
 | 
					           <size>
 | 
				
			||||||
 | 
					            <width>32</width>
 | 
				
			||||||
 | 
					            <height>0</height>
 | 
				
			||||||
 | 
					           </size>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="text">
 | 
				
			||||||
 | 
					           <string>0 %</string>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="alignment">
 | 
				
			||||||
 | 
					           <set>Qt::AlignCenter</set>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
 | 
					         </widget>
 | 
				
			||||||
 | 
					        </item>
 | 
				
			||||||
 | 
					       </layout>
 | 
				
			||||||
 | 
					      </item>
 | 
				
			||||||
 | 
					     </layout>
 | 
				
			||||||
 | 
					    </widget>
 | 
				
			||||||
 | 
					   </item>
 | 
				
			||||||
 | 
					   <item>
 | 
				
			||||||
 | 
					    <spacer>
 | 
				
			||||||
 | 
					     <property name="orientation">
 | 
				
			||||||
 | 
					      <enum>Qt::Vertical</enum>
 | 
				
			||||||
 | 
					     </property>
 | 
				
			||||||
 | 
					     <property name="sizeHint" stdset="0">
 | 
				
			||||||
 | 
					      <size>
 | 
				
			||||||
 | 
					       <width>167</width>
 | 
				
			||||||
 | 
					       <height>55</height>
 | 
				
			||||||
 | 
					      </size>
 | 
				
			||||||
 | 
					     </property>
 | 
				
			||||||
 | 
					    </spacer>
 | 
				
			||||||
 | 
					   </item>
 | 
				
			||||||
 | 
					  </layout>
 | 
				
			||||||
 | 
					 </widget>
 | 
				
			||||||
 | 
					 <resources/>
 | 
				
			||||||
 | 
					 <connections/>
 | 
				
			||||||
 | 
					</ui>
 | 
				
			||||||
@@ -21,6 +21,7 @@ void ConfigureDialog::applyConfiguration() {
 | 
				
			|||||||
    ui->systemTab->applyConfiguration();
 | 
					    ui->systemTab->applyConfiguration();
 | 
				
			||||||
    ui->inputTab->applyConfiguration();
 | 
					    ui->inputTab->applyConfiguration();
 | 
				
			||||||
    ui->graphicsTab->applyConfiguration();
 | 
					    ui->graphicsTab->applyConfiguration();
 | 
				
			||||||
 | 
					    ui->audioTab->applyConfiguration();
 | 
				
			||||||
    ui->debugTab->applyConfiguration();
 | 
					    ui->debugTab->applyConfiguration();
 | 
				
			||||||
    Settings::Apply();
 | 
					    Settings::Apply();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,6 +105,11 @@ void Config::ReadValues() {
 | 
				
			|||||||
    Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0);
 | 
					    Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0);
 | 
				
			||||||
    Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0);
 | 
					    Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Audio
 | 
				
			||||||
 | 
					    Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
 | 
				
			||||||
 | 
					    Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto");
 | 
				
			||||||
 | 
					    Settings::values.volume = sdl2_config->GetReal("Audio", "volume", 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Data Storage
 | 
					    // Data Storage
 | 
				
			||||||
    Settings::values.use_virtual_sd =
 | 
					    Settings::values.use_virtual_sd =
 | 
				
			||||||
        sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
 | 
					        sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,19 +143,17 @@ swap_screen =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[Audio]
 | 
					[Audio]
 | 
				
			||||||
# Which audio output engine to use.
 | 
					# Which audio output engine to use.
 | 
				
			||||||
# auto (default): Auto-select, null: No audio output, sdl2: SDL2 (if available)
 | 
					# auto (default): Auto-select, null: No audio output, cubeb: Cubeb audio engine (if available)
 | 
				
			||||||
output_engine =
 | 
					output_engine =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Whether or not to enable the audio-stretching post-processing effect.
 | 
					 | 
				
			||||||
# This effect adjusts audio speed to match emulation speed and helps prevent audio stutter,
 | 
					 | 
				
			||||||
# at the cost of increasing audio latency.
 | 
					 | 
				
			||||||
# 0: No, 1 (default): Yes
 | 
					 | 
				
			||||||
enable_audio_stretching =
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Which audio device to use.
 | 
					# Which audio device to use.
 | 
				
			||||||
# auto (default): Auto-select
 | 
					# auto (default): Auto-select
 | 
				
			||||||
output_device =
 | 
					output_device =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Output volume.
 | 
				
			||||||
 | 
					# 1.0 (default): 100%, 0.0; mute
 | 
				
			||||||
 | 
					volume =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Data Storage]
 | 
					[Data Storage]
 | 
				
			||||||
# Whether to create a virtual SD card.
 | 
					# Whether to create a virtual SD card.
 | 
				
			||||||
# 1 (default): Yes, 0: No
 | 
					# 1 (default): Yes, 0: No
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user