mirror of
https://github.com/mikage-emu/mikage-dev.git
synced 2025-02-09 13:58:27 +01:00
Add new audio interfaces
This commit is contained in:
parent
8dadaf304c
commit
d66316c917
13 changed files with 78 additions and 18 deletions
9
source/gui-sdl/audio_frontend_sdl.hpp
Normal file
9
source/gui-sdl/audio_frontend_sdl.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <ui/audio_frontend.hpp>
|
||||
|
||||
class SDLAudioFrontend : public AudioFrontend {
|
||||
public:
|
||||
void OutputSamples(std::array<int16_t, 2> samples) override {}
|
||||
SDLAudioFrontend() = default;
|
||||
};
|
|
@ -1,3 +1,5 @@
|
|||
#include "audio_frontend_sdl.hpp"
|
||||
|
||||
#include <ui/key_database.hpp>
|
||||
|
||||
#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<SDLAudioFrontend>();
|
||||
#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<EmuSession>(*log_manager, settings, *display, *display, keydb, std::move(gamecard));
|
||||
session = std::make_unique<EmuSession>(*log_manager, settings, *audio_frontend, *display, *display, keydb, std::move(gamecard));
|
||||
|
||||
emuthread = std::thread {
|
||||
[&emuthread_exception, &session]() {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "framework/logging.hpp"
|
||||
#include "framework/meta_tools.hpp"
|
||||
|
||||
#include <ui/audio_frontend.hpp>
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <boost/endian/arithmetic.hpp>
|
||||
|
@ -842,6 +844,8 @@ static bool just_reset = false;
|
|||
struct DSPMMIO : MemoryAccessHandler {
|
||||
std::shared_ptr<spdlog::logger> 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<uint16_t> data;
|
||||
static std::vector<uint16_t> data2;
|
||||
static auto audio_callback = [](std::array<int16_t, 2> samples) {
|
||||
auto audio_callback = [this](std::array<int16_t, 2> 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<IO_DSP1>(memory).handler->frontend = &frontend;
|
||||
}
|
||||
|
||||
void PhysicalMemory::InjectDependency(PicaContext& context) {
|
||||
std::get<IO_GPU>(memory).handler->context = context.context.get();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
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&);
|
||||
};
|
||||
|
||||
|
|
|
@ -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<MemoryBlockOwner>()),
|
||||
memory_regions {
|
||||
MemoryManager { ApplicationMemoryStart(settings), ApplicationMemorySize(settings) },
|
||||
|
@ -2020,8 +2023,8 @@ OS::~OS() {
|
|||
debug_process.reset(); // TODO: Not needed
|
||||
}
|
||||
|
||||
std::pair<std::unique_ptr<OS>, 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<OS>(profiler, settings, setup, log_manager, pica, display);
|
||||
std::pair<std::unique_ptr<OS>, 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<OS>(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));
|
||||
}
|
||||
|
|
|
@ -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> thread);
|
||||
|
||||
static std::pair<std::unique_ptr<OS>, std::unique_ptr<ConsoleModule>> Create(Settings::Settings& settings, Interpreter::Setup& setup, LogManager& log_manager, Profiler::Profiler&, PicaContext&, EmuDisplay::EmuDisplay&);
|
||||
static std::pair<std::unique_ptr<OS>, std::unique_ptr<ConsoleModule>> 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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
struct AudioFrontend;
|
||||
|
||||
namespace Settings {
|
||||
struct Settings;
|
||||
}
|
||||
|
||||
namespace HLE {
|
||||
|
||||
namespace OS {
|
||||
|
@ -32,7 +37,7 @@ class Hypervisor {
|
|||
std::unique_ptr<HPV::State> state;
|
||||
|
||||
public:
|
||||
Hypervisor();
|
||||
Hypervisor(Settings::Settings&, AudioFrontend&);
|
||||
~Hypervisor();
|
||||
|
||||
// "thread" refers to the target (i.e. server) thread
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "dsp_hpv.hpp"
|
||||
#include "os_hypervisor_private.hpp"
|
||||
#include "os.hpp"
|
||||
#include <ui/audio_frontend.hpp>
|
||||
|
||||
#include <platform/dsp.hpp>
|
||||
|
||||
|
@ -28,6 +29,10 @@ struct DspService : SessionToPort {
|
|||
DspService(RefCounted<Port> port_, DSPContext& context_) : SessionToPort(port_, context_) {
|
||||
}
|
||||
|
||||
DSPContext& GetContext() {
|
||||
return static_cast<DSPContext&>(context);
|
||||
}
|
||||
|
||||
void OnRequest(Hypervisor& hypervisor, Thread& thread, Handle session) override {
|
||||
using namespace Platform::CTR::DSP;
|
||||
|
||||
|
|
|
@ -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<Object> CreateDspService(RefCounted<Port> port, DSPContext&);
|
||||
|
|
|
@ -63,16 +63,19 @@ std::unique_ptr<Loader::GameCard> 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<Loader::GameCard> gamecard)
|
||||
AudioFrontend& audio, VulkanDeviceManager& vulkan_device_manager,
|
||||
EmuDisplay::EmuDisplay& display, const KeyDatabase& keydb,
|
||||
std::unique_ptr<Loader::GameCard> gamecard)
|
||||
: setup(std::make_shared<Interpreter::Setup>(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<ConsoleModule> 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();
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <framework/profiler.hpp>
|
||||
|
||||
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<Loader::GameCard>);
|
||||
|
||||
void Run();
|
||||
|
|
9
source/ui/audio_frontend.hpp
Normal file
9
source/ui/audio_frontend.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
struct AudioFrontend {
|
||||
virtual void OutputSamples(std::array<int16_t, 2> samples) = 0;
|
||||
|
||||
};
|
Loading…
Add table
Reference in a new issue