From c329f58afe8c24279a6717947c321e2edebdf20f Mon Sep 17 00:00:00 2001 From: Connor McLaughlin <stenzek@gmail.com> Date: Sun, 10 May 2020 00:44:37 +1000 Subject: [PATCH] HostInterface: Add audio buffer/count/volume/mute settings --- src/core/host_interface.cpp | 112 +++++++++++++++++------------------- src/core/host_interface.h | 14 +++-- src/core/settings.cpp | 9 +++ src/core/settings.h | 4 ++ 4 files changed, 75 insertions(+), 64 deletions(-) diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 26f1db588..f931a8b68 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -52,15 +52,24 @@ void HostInterface::Shutdown() {} void HostInterface::CreateAudioStream() { + Log_InfoPrintf("Creating '%s' audio stream, sample rate = %u, channels = %u, buffer size = %u, buffer count = %u", + Settings::GetAudioBackendName(m_settings.audio_backend), AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, + m_settings.audio_buffer_size, m_settings.audio_buffer_count); + m_audio_stream = CreateAudioStream(m_settings.audio_backend); - if (m_audio_stream && m_audio_stream->Reconfigure(AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, AUDIO_BUFFER_SIZE, 4)) + if (m_audio_stream && m_audio_stream->Reconfigure(AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, m_settings.audio_buffer_size, + m_settings.audio_buffer_count)) + { + m_audio_stream->SetOutputVolume(m_settings.audio_output_volume); return; + } ReportFormattedError("Failed to create or configure audio stream, falling back to null output."); m_audio_stream.reset(); m_audio_stream = AudioStream::CreateNullAudioStream(); - m_audio_stream->Reconfigure(AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, AUDIO_BUFFER_SIZE, 4); + m_audio_stream->Reconfigure(AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, m_settings.audio_buffer_size, + m_settings.audio_buffer_count); } bool HostInterface::BootSystem(const SystemBootParameters& parameters) @@ -971,6 +980,10 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("CDROM", "RegionCheck", true); si.SetStringValue("Audio", "Backend", Settings::GetAudioBackendName(AudioBackend::Cubeb)); + si.SetIntValue("Audio", "OutputVolume", 100); + si.SetIntValue("Audio", "BufferSize", DEFAULT_AUDIO_BUFFER_SIZE); + si.SetIntValue("Audio", "BufferCount", DEFAULT_AUDIO_BUFFER_COUNT); + si.SetIntValue("Audio", "OutputMuted", false); si.SetBoolValue("Audio", "Sync", true); si.SetBoolValue("Audio", "DumpOnBoot", false); @@ -1015,53 +1028,26 @@ void HostInterface::ExportSettings(SettingsInterface& si) void HostInterface::UpdateSettings(SettingsInterface& si) { - const bool old_increase_timer_resolution = m_settings.increase_timer_resolution; - const float old_emulation_speed = m_settings.emulation_speed; - const CPUExecutionMode old_cpu_execution_mode = m_settings.cpu_execution_mode; - const AudioBackend old_audio_backend = m_settings.audio_backend; - const GPURenderer old_gpu_renderer = m_settings.gpu_renderer; - const u32 old_gpu_resolution_scale = m_settings.gpu_resolution_scale; - const u32 old_gpu_fifo_size = m_settings.gpu_fifo_size; - const TickCount old_gpu_max_run_ahead = m_settings.gpu_max_run_ahead; - const bool old_gpu_true_color = m_settings.gpu_true_color; - const bool old_gpu_scaled_dithering = m_settings.gpu_scaled_dithering; - const bool old_gpu_texture_filtering = m_settings.gpu_texture_filtering; - const bool old_gpu_disable_interlacing = m_settings.gpu_disable_interlacing; - const bool old_gpu_force_ntsc_timings = m_settings.gpu_force_ntsc_timings; - const bool old_gpu_debug_device = m_settings.gpu_use_debug_device; - const bool old_vsync_enabled = m_settings.video_sync_enabled; - const bool old_audio_sync_enabled = m_settings.audio_sync_enabled; - const bool old_speed_limiter_enabled = m_settings.speed_limiter_enabled; - const DisplayCropMode old_display_crop_mode = m_settings.display_crop_mode; - const DisplayAspectRatio old_display_aspect_ratio = m_settings.display_aspect_ratio; - const bool old_display_linear_filtering = m_settings.display_linear_filtering; - const bool old_display_integer_scaling = m_settings.display_integer_scaling; - const bool old_cdrom_read_thread = m_settings.cdrom_read_thread; - std::array<ControllerType, NUM_CONTROLLER_AND_CARD_PORTS> old_controller_types = m_settings.controller_types; - std::array<MemoryCardType, NUM_CONTROLLER_AND_CARD_PORTS> old_memory_card_types = m_settings.memory_card_types; - std::array<std::string, NUM_CONTROLLER_AND_CARD_PORTS> old_memory_card_paths = - std::move(m_settings.memory_card_paths); - - const LOGLEVEL old_log_level = m_settings.log_level; - const std::string old_log_filter(std::move(m_settings.log_filter)); - const bool old_log_to_console = m_settings.log_to_console; - const bool old_log_to_window = m_settings.log_to_window; - const bool old_log_to_file = m_settings.log_to_file; - + Settings old_settings(std::move(m_settings)); ApplySettings(si); if (m_system) { - if (m_settings.gpu_renderer != old_gpu_renderer || m_settings.gpu_use_debug_device != old_gpu_debug_device) + if (m_settings.gpu_renderer != old_settings.gpu_renderer || + m_settings.gpu_use_debug_device != old_settings.gpu_use_debug_device) { ReportFormattedMessage("Switching to %s%s GPU renderer.", Settings::GetRendererName(m_settings.gpu_renderer), m_settings.gpu_use_debug_device ? " (debug)" : ""); RecreateSystem(); } - if (m_settings.audio_backend != old_audio_backend) + if (m_settings.audio_backend != old_settings.audio_backend || + m_settings.audio_buffer_size != old_settings.audio_buffer_size || + m_settings.audio_buffer_count != old_settings.audio_buffer_count) { - ReportFormattedMessage("Switching to %s audio backend.", Settings::GetAudioBackendName(m_settings.audio_backend)); + if (m_settings.audio_backend != old_settings.audio_backend) + ReportFormattedMessage("Switching to %s audio backend.", + Settings::GetAudioBackendName(m_settings.audio_backend)); DebugAssert(m_audio_stream); m_audio_stream.reset(); CreateAudioStream(); @@ -1069,43 +1055,51 @@ void HostInterface::UpdateSettings(SettingsInterface& si) UpdateSpeedLimiterState(); } - if (m_settings.video_sync_enabled != old_vsync_enabled || m_settings.audio_sync_enabled != old_audio_sync_enabled || - m_settings.speed_limiter_enabled != old_speed_limiter_enabled || - m_settings.increase_timer_resolution != old_increase_timer_resolution) + if (m_settings.video_sync_enabled != old_settings.video_sync_enabled || + m_settings.audio_sync_enabled != old_settings.audio_sync_enabled || + m_settings.speed_limiter_enabled != old_settings.speed_limiter_enabled || + m_settings.increase_timer_resolution != old_settings.increase_timer_resolution) { UpdateSpeedLimiterState(); } - if (m_settings.emulation_speed != old_emulation_speed) + if (m_settings.emulation_speed != old_settings.emulation_speed) { m_system->UpdateThrottlePeriod(); UpdateSpeedLimiterState(); } - if (m_settings.cpu_execution_mode != old_cpu_execution_mode) + if (m_settings.cpu_execution_mode != old_settings.cpu_execution_mode) { ReportFormattedMessage("Switching to %s CPU execution mode.", Settings::GetCPUExecutionModeName(m_settings.cpu_execution_mode)); m_system->SetCPUExecutionMode(m_settings.cpu_execution_mode); } - if (m_settings.gpu_resolution_scale != old_gpu_resolution_scale || m_settings.gpu_fifo_size != old_gpu_fifo_size || - m_settings.gpu_max_run_ahead != old_gpu_max_run_ahead || m_settings.gpu_true_color != old_gpu_true_color || - m_settings.gpu_scaled_dithering != old_gpu_scaled_dithering || - m_settings.gpu_texture_filtering != old_gpu_texture_filtering || - m_settings.gpu_disable_interlacing != old_gpu_disable_interlacing || - m_settings.gpu_force_ntsc_timings != old_gpu_force_ntsc_timings || - m_settings.display_crop_mode != old_display_crop_mode || - m_settings.display_aspect_ratio != old_display_aspect_ratio) + m_audio_stream->SetOutputVolume(m_settings.audio_output_muted ? 0 : m_settings.audio_output_volume); + + if (m_settings.gpu_resolution_scale != old_settings.gpu_resolution_scale || + m_settings.gpu_fifo_size != old_settings.gpu_fifo_size || + m_settings.gpu_max_run_ahead != old_settings.gpu_max_run_ahead || + m_settings.gpu_true_color != old_settings.gpu_true_color || + m_settings.gpu_scaled_dithering != old_settings.gpu_scaled_dithering || + m_settings.gpu_texture_filtering != old_settings.gpu_texture_filtering || + m_settings.gpu_disable_interlacing != old_settings.gpu_disable_interlacing || + m_settings.gpu_force_ntsc_timings != old_settings.gpu_force_ntsc_timings || + m_settings.display_crop_mode != old_settings.display_crop_mode || + m_settings.display_aspect_ratio != old_settings.display_aspect_ratio) { m_system->UpdateGPUSettings(); } - if (m_settings.cdrom_read_thread != old_cdrom_read_thread) + if (m_settings.cdrom_read_thread != old_settings.cdrom_read_thread) m_system->GetCDROM()->SetUseReadThread(m_settings.cdrom_read_thread); - if (m_settings.memory_card_types != old_memory_card_types || m_settings.memory_card_paths != old_memory_card_paths) + if (m_settings.memory_card_types != old_settings.memory_card_types || + m_settings.memory_card_paths != old_settings.memory_card_paths) + { m_system->UpdateMemoryCards(); + } m_system->GetDMA()->SetMaxSliceTicks(m_settings.dma_max_slice_ticks); m_system->GetDMA()->SetHaltTicks(m_settings.dma_halt_ticks); @@ -1114,7 +1108,7 @@ void HostInterface::UpdateSettings(SettingsInterface& si) bool controllers_updated = false; for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++) { - if (m_settings.controller_types[i] != old_controller_types[i]) + if (m_settings.controller_types[i] != old_settings.controller_types[i]) { if (m_system && !controllers_updated) { @@ -1126,15 +1120,15 @@ void HostInterface::UpdateSettings(SettingsInterface& si) } } - if (m_display && m_settings.display_linear_filtering != old_display_linear_filtering) + if (m_display && m_settings.display_linear_filtering != old_settings.display_linear_filtering) m_display->SetDisplayLinearFiltering(m_settings.display_linear_filtering); - if (m_display && m_settings.display_integer_scaling != old_display_integer_scaling) + if (m_display && m_settings.display_integer_scaling != old_settings.display_integer_scaling) m_display->SetDisplayIntegerScaling(m_settings.display_integer_scaling); - if (m_settings.log_level != old_log_level || m_settings.log_filter != old_log_filter || - m_settings.log_to_console != old_log_to_console || m_settings.log_to_window != old_log_to_window || - m_settings.log_to_file != old_log_to_file) + if (m_settings.log_level != old_settings.log_level || m_settings.log_filter != old_settings.log_filter || + m_settings.log_to_console != old_settings.log_to_console || + m_settings.log_to_window != old_settings.log_to_window || m_settings.log_to_file != old_settings.log_to_file) { UpdateLogSettings(m_settings.log_level, m_settings.log_filter.empty() ? nullptr : m_settings.log_filter.c_str(), m_settings.log_to_console, m_settings.log_to_debug, m_settings.log_to_window, diff --git a/src/core/host_interface.h b/src/core/host_interface.h index 9d855fc2e..ce5cd0f4d 100644 --- a/src/core/host_interface.h +++ b/src/core/host_interface.h @@ -34,6 +34,14 @@ public: GLOBAL_SAVE_STATE_SLOTS = 10 }; + enum : u32 + { + AUDIO_SAMPLE_RATE = 44100, + AUDIO_CHANNELS = 2, + DEFAULT_AUDIO_BUFFER_SIZE = 2048, + DEFAULT_AUDIO_BUFFER_COUNT = 4 + }; + struct SaveStateInfo { std::string path; @@ -159,11 +167,7 @@ public: protected: enum : u32 { - SETTINGS_VERSION = 2, - AUDIO_SAMPLE_RATE = 44100, - AUDIO_CHANNELS = 2, - AUDIO_BUFFER_SIZE = 2048, - AUDIO_BUFFERS = 2 + SETTINGS_VERSION = 2 }; struct OSDMessage diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 90f37bf7a..3fbbb2657 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -1,5 +1,6 @@ #include "settings.h" #include "common/string_util.h" +#include "host_interface.h" #include <array> Settings::Settings() = default; @@ -50,6 +51,10 @@ void Settings::Load(SettingsInterface& si) audio_backend = ParseAudioBackend(si.GetStringValue("Audio", "Backend", "Cubeb").c_str()).value_or(AudioBackend::Cubeb); + audio_output_volume = si.GetIntValue("Audio", "OutputVolume", 100); + audio_buffer_size = si.GetIntValue("Audio", "BufferSize", HostInterface::DEFAULT_AUDIO_BUFFER_SIZE); + audio_buffer_count = si.GetIntValue("Audio", "BufferCount", HostInterface::DEFAULT_AUDIO_BUFFER_COUNT); + audio_output_muted = si.GetBoolValue("Audio", "OutputMuted", false); audio_sync_enabled = si.GetBoolValue("Audio", "Sync", true); audio_dump_on_boot = si.GetBoolValue("Audio", "DumpOnBoot", false); @@ -135,6 +140,10 @@ void Settings::Save(SettingsInterface& si) const si.SetBoolValue("CDROM", "RegionCheck", cdrom_region_check); si.SetStringValue("Audio", "Backend", GetAudioBackendName(audio_backend)); + si.SetIntValue("Audio", "OutputVolume", audio_output_volume); + si.SetIntValue("Audio", "BufferSize", audio_buffer_size); + si.SetIntValue("Audio", "BufferCount", audio_buffer_count); + si.SetBoolValue("Audio", "OutputMuted", audio_output_muted); si.SetBoolValue("Audio", "Sync", audio_sync_enabled); si.SetBoolValue("Audio", "DumpOnBoot", audio_dump_on_boot); diff --git a/src/core/settings.h b/src/core/settings.h index 724141577..e0196042b 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -68,6 +68,10 @@ struct Settings bool cdrom_region_check = true; AudioBackend audio_backend = AudioBackend::Cubeb; + s32 audio_output_volume = 100; + u32 audio_buffer_size = 2048; + u32 audio_buffer_count = 4; + bool audio_output_muted = false; bool audio_sync_enabled = true; bool audio_dump_on_boot = true;