From 6542c606023164d5c9c028bb2a2409d91b3ecb9e Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 27 Apr 2016 07:22:39 +0100 Subject: DSP/HLE: Implement mixer processing --- src/audio_core/hle/dsp.cpp | 54 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'src/audio_core/hle/dsp.cpp') diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp index 5113ad8ca..1c00ed472 100644 --- a/src/audio_core/hle/dsp.cpp +++ b/src/audio_core/hle/dsp.cpp @@ -6,6 +6,7 @@ #include #include "audio_core/hle/dsp.h" +#include "audio_core/hle/mixers.h" #include "audio_core/hle/pipe.h" #include "audio_core/hle/source.h" #include "audio_core/sink.h" @@ -14,6 +15,8 @@ namespace DSP { namespace HLE { +// Region management + std::array g_regions; static size_t CurrentRegionIndex() { @@ -41,16 +44,52 @@ static SharedMemory& WriteRegion() { return g_regions[1 - CurrentRegionIndex()]; } +// Audio processing and mixing + static std::array sources = { 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(12), Source(13), Source(14), Source(15), Source(16), Source(17), Source(18), Source(19), Source(20), Source(21), Source(22), Source(23) }; +static Mixers mixers; + +static StereoFrame16 GenerateCurrentFrame() { + SharedMemory& read = ReadRegion(); + SharedMemory& write = WriteRegion(); + + std::array intermediate_mixes = {}; + + // Generate intermediate mixes + for (size_t i = 0; i < num_sources; i++) { + write.source_statuses.status[i] = sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]); + for (size_t mix = 0; mix < 3; mix++) { + sources[i].MixInto(intermediate_mixes[mix], mix); + } + } + + // Generate final mix + write.dsp_status = mixers.Tick(read.dsp_configuration, read.intermediate_mix_samples, write.intermediate_mix_samples, intermediate_mixes); + + StereoFrame16 output_frame = mixers.GetOutput(); + + // Write current output frame to the shared memory region + for (size_t samplei = 0; samplei < output_frame.size(); samplei++) { + for (size_t channeli = 0; channeli < output_frame[0].size(); channeli++) { + write.final_samples.pcm16[samplei][channeli] = s16_le(output_frame[samplei][channeli]); + } + } + + return output_frame; +} + +// Audio output static std::unique_ptr sink; static AudioCore::TimeStretcher time_stretcher; +// Public Interface + void Init() { DSP::HLE::ResetPipes(); @@ -58,6 +97,8 @@ void Init() { source.Reset(); } + mixers.Reset(); + time_stretcher.Reset(); if (sink) { time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate()); @@ -75,17 +116,10 @@ void Shutdown() { } bool Tick() { - SharedMemory& read = ReadRegion(); - SharedMemory& write = WriteRegion(); + StereoFrame16 current_frame = {}; - std::array intermediate_mixes = {}; - - for (size_t i = 0; i < num_sources; i++) { - write.source_statuses.status[i] = sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]); - for (size_t mix = 0; mix < 3; mix++) { - sources[i].MixInto(intermediate_mixes[mix], mix); - } - } + // TODO: Check dsp::DSP semaphore (which indicates emulated application has finished writing to shared memory region) + current_frame = GenerateCurrentFrame(); return true; } -- cgit v1.2.3 From f4d364a60e77c1423b4bb9ea9d0b0a58cbac29e7 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 15 May 2016 12:51:04 +0100 Subject: DSP/HLE: Audio output --- src/audio_core/hle/dsp.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/audio_core/hle/dsp.cpp') diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp index 1c00ed472..0640e1eff 100644 --- a/src/audio_core/hle/dsp.cpp +++ b/src/audio_core/hle/dsp.cpp @@ -88,6 +88,11 @@ static StereoFrame16 GenerateCurrentFrame() { static std::unique_ptr sink; static AudioCore::TimeStretcher time_stretcher; +static void OutputCurrentFrame(const StereoFrame16& frame) { + time_stretcher.AddSamples(&frame[0][0], frame.size()); + sink->EnqueueSamples(time_stretcher.Process(sink->SamplesInQueue())); +} + // Public Interface void Init() { @@ -121,6 +126,8 @@ bool Tick() { // TODO: Check dsp::DSP semaphore (which indicates emulated application has finished writing to shared memory region) current_frame = GenerateCurrentFrame(); + OutputCurrentFrame(current_frame); + return true; } -- cgit v1.2.3