2016-02-21 14:13:52 +01:00
|
|
|
// Copyright 2016 Citra Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2016-04-27 14:53:23 +02:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2016-09-21 08:52:38 +02:00
|
|
|
#include "audio_core/audio_core.h"
|
2016-02-21 14:13:52 +01:00
|
|
|
#include "audio_core/hle/dsp.h"
|
2016-04-24 11:21:10 +02:00
|
|
|
#include "audio_core/hle/pipe.h"
|
2016-04-27 14:53:23 +02:00
|
|
|
#include "audio_core/null_sink.h"
|
|
|
|
#include "audio_core/sink.h"
|
|
|
|
#include "audio_core/sink_details.h"
|
2016-02-21 14:13:52 +01:00
|
|
|
#include "core/core_timing.h"
|
|
|
|
#include "core/hle/kernel/vm_manager.h"
|
|
|
|
#include "core/hle/service/dsp_dsp.h"
|
|
|
|
|
|
|
|
namespace AudioCore {
|
|
|
|
|
|
|
|
// Audio Ticks occur about every 5 miliseconds.
|
|
|
|
static int tick_event; ///< CoreTiming event
|
|
|
|
static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles
|
|
|
|
|
|
|
|
static void AudioTickCallback(u64 /*userdata*/, int cycles_late) {
|
|
|
|
if (DSP::HLE::Tick()) {
|
2016-04-24 11:21:10 +02:00
|
|
|
// TODO(merry): Signal all the other interrupts as appropriate.
|
2016-12-10 13:51:50 +01:00
|
|
|
Service::DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Audio);
|
2016-04-24 14:36:44 +02:00
|
|
|
// HACK(merry): Added to prevent regressions. Will remove soon.
|
2016-12-10 13:51:50 +01:00
|
|
|
Service::DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Binary);
|
2016-02-21 14:13:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Reschedule recurrent event
|
|
|
|
CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Init() {
|
|
|
|
DSP::HLE::Init();
|
|
|
|
|
|
|
|
tick_event = CoreTiming::RegisterEvent("AudioCore::tick_event", AudioTickCallback);
|
|
|
|
CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddAddressSpace(Kernel::VMManager& address_space) {
|
2016-09-18 02:38:01 +02:00
|
|
|
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();
|
2016-02-21 14:13:52 +01:00
|
|
|
address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite);
|
|
|
|
|
2016-09-18 02:38:01 +02:00
|
|
|
auto r1_vma = address_space
|
|
|
|
.MapBackingMemory(DSP::HLE::region1_base,
|
|
|
|
reinterpret_cast<u8*>(&DSP::HLE::g_regions[1]),
|
|
|
|
sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO)
|
|
|
|
.MoveFrom();
|
2016-02-21 14:13:52 +01:00
|
|
|
address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
|
|
|
|
}
|
|
|
|
|
2016-04-27 14:53:23 +02:00
|
|
|
void SelectSink(std::string sink_id) {
|
2017-01-26 04:33:26 +01:00
|
|
|
const SinkDetails& sink_details = GetSinkDetails(sink_id);
|
|
|
|
DSP::HLE::SetSink(sink_details.factory());
|
2016-04-27 14:53:23 +02:00
|
|
|
}
|
|
|
|
|
2016-08-31 17:56:30 +02:00
|
|
|
void EnableStretching(bool enable) {
|
|
|
|
DSP::HLE::EnableStretching(enable);
|
|
|
|
}
|
|
|
|
|
2016-02-21 14:13:52 +01:00
|
|
|
void Shutdown() {
|
|
|
|
CoreTiming::UnscheduleEvent(tick_event, 0);
|
|
|
|
DSP::HLE::Shutdown();
|
|
|
|
}
|
|
|
|
|
2016-04-27 14:53:23 +02:00
|
|
|
} // namespace AudioCore
|