diff --git a/source/gui-sdl/audio_frontend_sdl.hpp b/source/gui-sdl/audio_frontend_sdl.hpp new file mode 100644 index 0000000..b2f3477 --- /dev/null +++ b/source/gui-sdl/audio_frontend_sdl.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +class SDLAudioFrontend : public AudioFrontend { +public: + void OutputSamples(std::array samples) override {} + SDLAudioFrontend() = default; +}; diff --git a/source/gui-sdl/main.cpp b/source/gui-sdl/main.cpp index 65093ba..fc8eea4 100644 --- a/source/gui-sdl/main.cpp +++ b/source/gui-sdl/main.cpp @@ -1,3 +1,5 @@ +#include "audio_frontend_sdl.hpp" + #include #include "platform/file_formats/cia.hpp" @@ -361,6 +363,7 @@ if (bootstrap_nand) // Experimental system bootstrapper //exit(1); g_samples.reserve(32768); + auto audio_frontend = std::make_unique(); #ifndef DISABLE_AUDIO static std::ofstream ofs("samples.raw", std::ios_base::binary); static std::ofstream ofs2("samples2.raw", std::ios_base::binary); @@ -531,7 +534,7 @@ if (bootstrap_nand) // Experimental system bootstrapper } auto gamecard = LoadGameCard(*frontend_logger, settings); - session = std::make_unique(*log_manager, settings, *display, *display, keydb, std::move(gamecard)); + session = std::make_unique(*log_manager, settings, *audio_frontend, *display, *display, keydb, std::move(gamecard)); emuthread = std::thread { [&emuthread_exception, &session]() { diff --git a/source/memory.cpp b/source/memory.cpp index 722858e..7554317 100644 --- a/source/memory.cpp +++ b/source/memory.cpp @@ -10,6 +10,8 @@ #include "framework/logging.hpp" #include "framework/meta_tools.hpp" +#include + #include #include @@ -842,6 +844,8 @@ static bool just_reset = false; struct DSPMMIO : MemoryAccessHandler { std::shared_ptr logger; + AudioFrontend* frontend = nullptr; + DSPConfig config {}; DSPStatus status { DSPStatus{}.write_fifo_empty()(true) }; @@ -1032,7 +1036,7 @@ struct DSPMMIO : MemoryAccessHandler { static std::ofstream ofs2("samples2.raw", std::ios_base::binary); static std::vector data; static std::vector data2; - static auto audio_callback = [](std::array samples) { + auto audio_callback = [this](std::array samples) { data.push_back(samples[0]); data2.push_back(samples[1]); if (data.size() == 0x10000) { @@ -1044,10 +1048,9 @@ struct DSPMMIO : MemoryAccessHandler { data2.clear(); } - TeakraAudioCallback(samples); + frontend->OutputSamples(samples); }; g_teakra->SetAudioCallback(audio_callback); -// g_teakra->SetAudioCallback(TeakraAudioCallback); // NOTE: These don't seem to be needed (only for unaligned memory accesses?) static Teakra::AHBMCallback ahbm; @@ -1265,6 +1268,10 @@ PhysicalMemory::PhysicalMemory(LogManager& log_manager) g_mem = this; } +void PhysicalMemory::InjectDependency(AudioFrontend& frontend) { + std::get(memory).handler->frontend = &frontend; +} + void PhysicalMemory::InjectDependency(PicaContext& context) { std::get(memory).handler->context = context.context.get(); } diff --git a/source/memory.h b/source/memory.h index f88c384..d430865 100644 --- a/source/memory.h +++ b/source/memory.h @@ -15,6 +15,8 @@ #include #include +struct AudioFrontend; + class LogManager; class PicaContext; @@ -343,7 +345,8 @@ struct PhysicalMemory { */ PhysicalMemory(LogManager& log_manager); - void InjectDependency(PicaContext& pica); + void InjectDependency(AudioFrontend&); + void InjectDependency(PicaContext&); void InjectDependency(InputSource&); }; diff --git a/source/os.cpp b/source/os.cpp index ba9b313..eaffbf0 100644 --- a/source/os.cpp +++ b/source/os.cpp @@ -1942,8 +1942,11 @@ const uint32_t num_firm_modules = 5; // See MakeNewProcessId for details. // TODO: Instead of this workaround, we should just not launch // FakeDebugProcess before the FIRM modules. -OS::OS(Profiler::Profiler& profiler, Settings::Settings& settings, Interpreter::Setup& setup_, LogManager& log_manager, PicaContext& pica, EmuDisplay::EmuDisplay& display) - : next_pid(num_firm_modules), +OS::OS( Profiler::Profiler& profiler, Settings::Settings& settings, + Interpreter::Setup& setup_, LogManager& log_manager, + AudioFrontend& audio, PicaContext& pica, EmuDisplay::EmuDisplay& display) + : hypervisor(settings, audio), + next_pid(num_firm_modules), internal_memory_owner(std::make_shared()), memory_regions { MemoryManager { ApplicationMemoryStart(settings), ApplicationMemorySize(settings) }, @@ -2020,8 +2023,8 @@ OS::~OS() { debug_process.reset(); // TODO: Not needed } -std::pair, std::unique_ptr<::ConsoleModule>> OS::Create(Settings::Settings& settings, Interpreter::Setup& setup, LogManager& log_manager, Profiler::Profiler& profiler, PicaContext& pica, EmuDisplay::EmuDisplay& display) { - auto&& os = std::make_unique(profiler, settings, setup, log_manager, pica, display); +std::pair, std::unique_ptr<::ConsoleModule>> OS::Create(Settings::Settings& settings, Interpreter::Setup& setup, LogManager& log_manager, Profiler::Profiler& profiler, AudioFrontend& audio, PicaContext& pica, EmuDisplay::EmuDisplay& display) { + auto&& os = std::make_unique(profiler, settings, setup, log_manager, audio, pica, display); auto&& console_module = std::unique_ptr<::ConsoleModule>(new ConsoleModule(*os)); return std::make_pair(std::move(os), std::move(console_module)); } diff --git a/source/os.hpp b/source/os.hpp index 870c41a..ae4d422 100644 --- a/source/os.hpp +++ b/source/os.hpp @@ -1563,7 +1563,8 @@ public: // TODO: privatize this again! [[deprecated]] MemoryManager& memory_base() { return memory_regions[2]; } MemoryManager& FindMemoryRegionContaining(uint32_t paddr, uint32_t size); - OS(Profiler::Profiler&, Settings::Settings&, Interpreter::Setup&, LogManager&, PicaContext&, EmuDisplay::EmuDisplay&); + OS( Profiler::Profiler&, Settings::Settings&, Interpreter::Setup&, + LogManager&, AudioFrontend&, PicaContext&, EmuDisplay::EmuDisplay&); ~OS(); Profiler::Profiler& profiler; @@ -1869,7 +1870,7 @@ public: */ SVCEmptyFuture SVCAddThread(std::shared_ptr thread); - static std::pair, std::unique_ptr> Create(Settings::Settings& settings, Interpreter::Setup& setup, LogManager& log_manager, Profiler::Profiler&, PicaContext&, EmuDisplay::EmuDisplay&); + static std::pair, std::unique_ptr> Create(Settings::Settings& settings, Interpreter::Setup& setup, LogManager& log_manager, Profiler::Profiler&, AudioFrontend&, PicaContext&, EmuDisplay::EmuDisplay&); /** * Initialized the OS, spawning all service processes along the way. diff --git a/source/os_hypervisor.cpp b/source/os_hypervisor.cpp index a5a7fc6..7ce0e92 100644 --- a/source/os_hypervisor.cpp +++ b/source/os_hypervisor.cpp @@ -79,7 +79,9 @@ struct State { } -Hypervisor::Hypervisor() : state(new HPV::State) { +Hypervisor::Hypervisor(Settings::Settings& settings, AudioFrontend& audio_frontend) : state(new HPV::State) { + state->dsp_context.settings = &settings; + state->dsp_context.frontend = &audio_frontend; } Hypervisor::~Hypervisor() = default; diff --git a/source/os_hypervisor.hpp b/source/os_hypervisor.hpp index fdea6b0..7dc1480 100644 --- a/source/os_hypervisor.hpp +++ b/source/os_hypervisor.hpp @@ -1,9 +1,14 @@ #pragma once #include -#include #include +struct AudioFrontend; + +namespace Settings { +struct Settings; +} + namespace HLE { namespace OS { @@ -32,7 +37,7 @@ class Hypervisor { std::unique_ptr state; public: - Hypervisor(); + Hypervisor(Settings::Settings&, AudioFrontend&); ~Hypervisor(); // "thread" refers to the target (i.e. server) thread diff --git a/source/processes/dsp_hpv.cpp b/source/processes/dsp_hpv.cpp index edc6c35..30f2cde 100644 --- a/source/processes/dsp_hpv.cpp +++ b/source/processes/dsp_hpv.cpp @@ -1,6 +1,7 @@ #include "dsp_hpv.hpp" #include "os_hypervisor_private.hpp" #include "os.hpp" +#include #include @@ -28,6 +29,10 @@ struct DspService : SessionToPort { DspService(RefCounted port_, DSPContext& context_) : SessionToPort(port_, context_) { } + DSPContext& GetContext() { + return static_cast(context); + } + void OnRequest(Hypervisor& hypervisor, Thread& thread, Handle session) override { using namespace Platform::CTR::DSP; diff --git a/source/processes/dsp_hpv.hpp b/source/processes/dsp_hpv.hpp index e905719..fae458b 100644 --- a/source/processes/dsp_hpv.hpp +++ b/source/processes/dsp_hpv.hpp @@ -2,6 +2,12 @@ #include "os_hypervisor_private.hpp" +struct AudioFrontend; + +namespace Settings { +struct Settings; +} + namespace HLE { namespace OS { @@ -9,6 +15,8 @@ namespace OS { namespace HPV { struct DSPContext : SessionContext { + Settings::Settings* settings = nullptr; + AudioFrontend* frontend = nullptr; }; HPV::RefCounted CreateDspService(RefCounted port, DSPContext&); diff --git a/source/session.cpp b/source/session.cpp index a5af94d..9711dee 100644 --- a/source/session.cpp +++ b/source/session.cpp @@ -63,16 +63,19 @@ std::unique_ptr LoadGameCard(spdlog::logger& logger, Settings: } EmuSession::EmuSession( LogManager& log_manager, Settings::Settings& settings, - VulkanDeviceManager& vulkan_device_manager, EmuDisplay::EmuDisplay& display, - const KeyDatabase& keydb, std::unique_ptr gamecard) + AudioFrontend& audio, VulkanDeviceManager& vulkan_device_manager, + EmuDisplay::EmuDisplay& display, const KeyDatabase& keydb, + std::unique_ptr gamecard) : setup(std::make_shared(log_manager, keydb, std::move(gamecard), profiler, debug_server)), pica { log_manager.RegisterLogger("Pica"), debug_server, settings, setup->mem, profiler, vulkan_device_manager.physical_device, *vulkan_device_manager.device, vulkan_device_manager.graphics_queue_index, vulkan_device_manager.graphics_queue } { setup->cpus[0].cpu.cpsr.mode = ARM::InternalProcessorMode::User; + setup->mem.InjectDependency(audio); + std::unique_ptr os_module; - std::tie(setup->os, os_module) = HLE::OS::OS::Create(settings, *setup, log_manager, profiler, pica, display); + std::tie(setup->os, os_module) = HLE::OS::OS::Create(settings, *setup, log_manager, profiler, audio, pica, display); for (auto& cpu : setup->cpus) cpu.os = setup->os.get(); setup->os->Initialize(); diff --git a/source/session.hpp b/source/session.hpp index 1f33faa..4d1f7e8 100644 --- a/source/session.hpp +++ b/source/session.hpp @@ -9,6 +9,8 @@ #include +struct AudioFrontend; + class NetworkConsole; namespace Loader { @@ -36,7 +38,7 @@ struct EmuSession { std::thread console_thread; EmuSession( LogManager&, Settings::Settings&, - VulkanDeviceManager&, EmuDisplay::EmuDisplay&, + AudioFrontend&, VulkanDeviceManager&, EmuDisplay::EmuDisplay&, const KeyDatabase&, std::unique_ptr); void Run(); diff --git a/source/ui/audio_frontend.hpp b/source/ui/audio_frontend.hpp new file mode 100644 index 0000000..73e0132 --- /dev/null +++ b/source/ui/audio_frontend.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +struct AudioFrontend { + virtual void OutputSamples(std::array samples) = 0; + +};