f852369986
* Initial Commit Added Device logic to Sinks Started on UI for selecting devices Removed redundant import * Audio Core: Complete Device Switching Complete the device switching implementation by allowing the output device to be loaded, changed and saved through the configurations menu. Worked with the Sink abstraction and tuned the "Device Selection" configuration so that the Device List is automatically populated when the Sink is changed. This hopefully addresses the concerns and recommendations mentioned in the comments of the PR. * Clean original implementation. * Refactor GetSinkDetails
72 lines
2.5 KiB
C++
72 lines
2.5 KiB
C++
// Copyright 2016 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include "audio_core/audio_core.h"
|
|
#include "audio_core/hle/dsp.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/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()) {
|
|
// TODO(merry): Signal all the other interrupts as appropriate.
|
|
Service::DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Audio);
|
|
// HACK(merry): Added to prevent regressions. Will remove soon.
|
|
Service::DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Binary);
|
|
}
|
|
|
|
// 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) {
|
|
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);
|
|
|
|
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();
|
|
address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
|
|
}
|
|
|
|
void SelectSink(std::string sink_id) {
|
|
const SinkDetails& sink_details = GetSinkDetails(sink_id);
|
|
DSP::HLE::SetSink(sink_details.factory());
|
|
}
|
|
|
|
void EnableStretching(bool enable) {
|
|
DSP::HLE::EnableStretching(enable);
|
|
}
|
|
|
|
void Shutdown() {
|
|
CoreTiming::UnscheduleEvent(tick_event, 0);
|
|
DSP::HLE::Shutdown();
|
|
}
|
|
|
|
} // namespace AudioCore
|