|
@@ -2,9 +2,15 @@
|
|
|
// 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 <memory>
|
|
|
|
|
+#include <string>
|
|
|
|
|
+
|
|
|
#include "audio_core/audio_core.h"
|
|
#include "audio_core/audio_core.h"
|
|
|
#include "audio_core/hle/dsp.h"
|
|
#include "audio_core/hle/dsp.h"
|
|
|
#include "audio_core/hle/pipe.h"
|
|
#include "audio_core/hle/pipe.h"
|
|
|
|
|
+#include "audio_core/null_sink.h"
|
|
|
|
|
+#include "audio_core/sink.h"
|
|
|
|
|
+#include "audio_core/sink_details.h"
|
|
|
|
|
|
|
|
#include "core/core_timing.h"
|
|
#include "core/core_timing.h"
|
|
|
#include "core/hle/kernel/vm_manager.h"
|
|
#include "core/hle/kernel/vm_manager.h"
|
|
@@ -28,7 +34,6 @@ static void AudioTickCallback(u64 /*userdata*/, int cycles_late) {
|
|
|
CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
|
|
CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/// Initialise Audio
|
|
|
|
|
void Init() {
|
|
void Init() {
|
|
|
DSP::HLE::Init();
|
|
DSP::HLE::Init();
|
|
|
|
|
|
|
@@ -36,7 +41,6 @@ void Init() {
|
|
|
CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event);
|
|
CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/// Add DSP address spaces to Process's address space.
|
|
|
|
|
void AddAddressSpace(Kernel::VMManager& address_space) {
|
|
void AddAddressSpace(Kernel::VMManager& address_space) {
|
|
|
auto r0_vma = address_space.MapBackingMemory(DSP::HLE::region0_base, reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom();
|
|
auto r0_vma = address_space.MapBackingMemory(DSP::HLE::region0_base, reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom();
|
|
|
address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite);
|
|
address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite);
|
|
@@ -45,10 +49,31 @@ void AddAddressSpace(Kernel::VMManager& address_space) {
|
|
|
address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
|
|
address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/// Shutdown Audio
|
|
|
|
|
|
|
+void SelectSink(std::string sink_id) {
|
|
|
|
|
+ if (sink_id == "auto") {
|
|
|
|
|
+ // Auto-select.
|
|
|
|
|
+ // g_sink_details is ordered in terms of desirability, with the best choice at the front.
|
|
|
|
|
+ const auto& sink_detail = g_sink_details.front();
|
|
|
|
|
+ DSP::HLE::SetSink(sink_detail.factory());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ auto iter = std::find_if(g_sink_details.begin(), g_sink_details.end(), [sink_id](const auto& sink_detail) {
|
|
|
|
|
+ return sink_detail.id == sink_id;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if (iter == g_sink_details.end()) {
|
|
|
|
|
+ LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id");
|
|
|
|
|
+ DSP::HLE::SetSink(std::make_unique<NullSink>());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ DSP::HLE::SetSink(iter->factory());
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void Shutdown() {
|
|
void Shutdown() {
|
|
|
CoreTiming::UnscheduleEvent(tick_event, 0);
|
|
CoreTiming::UnscheduleEvent(tick_event, 0);
|
|
|
DSP::HLE::Shutdown();
|
|
DSP::HLE::Shutdown();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-} //namespace
|
|
|
|
|
|
|
+} // namespace AudioCore
|