DSP: dsp::DSP semaphore indicates completion of audio frame config
This commit is contained in:
parent
feecc76333
commit
52e4a0f745
4 changed files with 64 additions and 17 deletions
|
@ -24,12 +24,13 @@ static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles
|
||||||
|
|
||||||
static void AudioTickCallback(u64 /*userdata*/, int cycles_late) {
|
static void AudioTickCallback(u64 /*userdata*/, int cycles_late) {
|
||||||
if (DSP::HLE::Tick()) {
|
if (DSP::HLE::Tick()) {
|
||||||
// TODO(merry): Signal all the other interrupts as appropriate.
|
|
||||||
DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Audio);
|
DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Audio);
|
||||||
// HACK(merry): Added to prevent regressions. Will remove soon.
|
|
||||||
DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Binary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(merry): Signal all the other interrupts as appropriate.
|
||||||
|
// HACK(merry): Added to prevent regressions. Will remove soon.
|
||||||
|
DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Binary);
|
||||||
|
|
||||||
// Reschedule recurrent event
|
// Reschedule recurrent event
|
||||||
CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
|
CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,13 @@
|
||||||
#include "audio_core/hle/source.h"
|
#include "audio_core/hle/source.h"
|
||||||
#include "audio_core/sink.h"
|
#include "audio_core/sink.h"
|
||||||
|
|
||||||
|
#include "core/hle/service/dsp_dsp.h"
|
||||||
|
|
||||||
namespace DSP {
|
namespace DSP {
|
||||||
namespace HLE {
|
namespace HLE {
|
||||||
|
|
||||||
|
// Region management
|
||||||
|
|
||||||
std::array<SharedMemory, 2> g_regions;
|
std::array<SharedMemory, 2> g_regions;
|
||||||
|
|
||||||
static size_t CurrentRegionIndex() {
|
static size_t CurrentRegionIndex() {
|
||||||
|
@ -40,6 +44,8 @@ static SharedMemory& WriteRegion() {
|
||||||
return g_regions[1 - CurrentRegionIndex()];
|
return g_regions[1 - CurrentRegionIndex()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Audio processing and mixing
|
||||||
|
|
||||||
static std::array<Source, num_sources> sources = {
|
static std::array<Source, num_sources> sources = {
|
||||||
Source(0), Source(1), Source(2), Source(3), Source(4), Source(5),
|
Source(0), Source(1), Source(2), Source(3), Source(4), Source(5),
|
||||||
Source(6), Source(7), Source(8), Source(9), Source(10), Source(11),
|
Source(6), Source(7), Source(8), Source(9), Source(10), Source(11),
|
||||||
|
@ -47,19 +53,7 @@ static std::array<Source, num_sources> sources = {
|
||||||
Source(18), Source(19), Source(20), Source(21), Source(22), Source(23)
|
Source(18), Source(19), Source(20), Source(21), Source(22), Source(23)
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<AudioCore::Sink> sink;
|
static StereoFrame16 GenerateCurrentFrame() {
|
||||||
|
|
||||||
void Init() {
|
|
||||||
DSP::HLE::ResetPipes();
|
|
||||||
for (auto& source : sources) {
|
|
||||||
source.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown() {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Tick() {
|
|
||||||
SharedMemory& read = ReadRegion();
|
SharedMemory& read = ReadRegion();
|
||||||
SharedMemory& write = WriteRegion();
|
SharedMemory& write = WriteRegion();
|
||||||
|
|
||||||
|
@ -72,7 +66,45 @@ bool Tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
StereoFrame16 current_frame = {};
|
||||||
|
|
||||||
|
// TODO(merry): Reverb, Delay, Mixing
|
||||||
|
|
||||||
|
return current_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio output
|
||||||
|
|
||||||
|
static std::unique_ptr<AudioCore::Sink> sink;
|
||||||
|
|
||||||
|
// Public interface
|
||||||
|
|
||||||
|
void Init() {
|
||||||
|
DSP::HLE::ResetPipes();
|
||||||
|
for (auto& source : sources) {
|
||||||
|
source.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tick() {
|
||||||
|
bool signal_interrupt = false;
|
||||||
|
StereoFrame16 current_frame = {};
|
||||||
|
|
||||||
|
if (DSP_DSP::IsSemaphoreSignalled() && GetDspState() == DspState::On) {
|
||||||
|
// The ARM11 has finished writing to the shared memory region.
|
||||||
|
DSP_DSP::ResetSemaphore();
|
||||||
|
|
||||||
|
// Signal that we are done processing that shared memory region.
|
||||||
|
signal_interrupt = true;
|
||||||
|
current_frame = GenerateCurrentFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(merry): Audio output
|
||||||
|
|
||||||
|
return signal_interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSink(std::unique_ptr<AudioCore::Sink> sink_) {
|
void SetSink(std::unique_ptr<AudioCore::Sink> sink_) {
|
||||||
|
|
|
@ -89,6 +89,14 @@ void SignalPipeInterrupt(DspPipe pipe) {
|
||||||
interrupt_events.Signal(InterruptType::Pipe, pipe);
|
interrupt_events.Signal(InterruptType::Pipe, pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetSemaphore() {
|
||||||
|
semaphore_event->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSemaphoreSignalled() {
|
||||||
|
return semaphore_event->signaled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DSP_DSP::ConvertProcessAddressFromDspDram service function
|
* DSP_DSP::ConvertProcessAddressFromDspDram service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
|
|
|
@ -35,4 +35,10 @@ public:
|
||||||
*/
|
*/
|
||||||
void SignalPipeInterrupt(DSP::HLE::DspPipe pipe);
|
void SignalPipeInterrupt(DSP::HLE::DspPipe pipe);
|
||||||
|
|
||||||
|
/// Reset the dsp::DSP semaphore.
|
||||||
|
void ResetSemaphore();
|
||||||
|
|
||||||
|
/// Has the dsp::DSP semaphore been signalled?
|
||||||
|
bool IsSemaphoreSignalled();
|
||||||
|
|
||||||
} // namespace DSP_DSP
|
} // namespace DSP_DSP
|
||||||
|
|
Loading…
Reference in a new issue