summaryrefslogtreecommitdiff
path: root/src/audio_core/hle/dsp.cpp
diff options
context:
space:
mode:
authorGravatar MerryMage2016-04-27 07:22:39 +0100
committerGravatar MerryMage2016-05-19 07:24:39 +0100
commit6542c606023164d5c9c028bb2a2409d91b3ecb9e (patch)
treed7405466a62e1e5e60c8f89c92f85c6346d0a395 /src/audio_core/hle/dsp.cpp
parentAudioCore: Implement time stretcher (#1737) (diff)
downloadyuzu-6542c606023164d5c9c028bb2a2409d91b3ecb9e.tar.gz
yuzu-6542c606023164d5c9c028bb2a2409d91b3ecb9e.tar.xz
yuzu-6542c606023164d5c9c028bb2a2409d91b3ecb9e.zip
DSP/HLE: Implement mixer processing
Diffstat (limited to 'src/audio_core/hle/dsp.cpp')
-rw-r--r--src/audio_core/hle/dsp.cpp54
1 files changed, 44 insertions, 10 deletions
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 @@
6#include <memory> 6#include <memory>
7 7
8#include "audio_core/hle/dsp.h" 8#include "audio_core/hle/dsp.h"
9#include "audio_core/hle/mixers.h"
9#include "audio_core/hle/pipe.h" 10#include "audio_core/hle/pipe.h"
10#include "audio_core/hle/source.h" 11#include "audio_core/hle/source.h"
11#include "audio_core/sink.h" 12#include "audio_core/sink.h"
@@ -14,6 +15,8 @@
14namespace DSP { 15namespace DSP {
15namespace HLE { 16namespace HLE {
16 17
18// Region management
19
17std::array<SharedMemory, 2> g_regions; 20std::array<SharedMemory, 2> g_regions;
18 21
19static size_t CurrentRegionIndex() { 22static size_t CurrentRegionIndex() {
@@ -41,16 +44,52 @@ static SharedMemory& WriteRegion() {
41 return g_regions[1 - CurrentRegionIndex()]; 44 return g_regions[1 - CurrentRegionIndex()];
42} 45}
43 46
47// Audio processing and mixing
48
44static std::array<Source, num_sources> sources = { 49static std::array<Source, num_sources> sources = {
45 Source(0), Source(1), Source(2), Source(3), Source(4), Source(5), 50 Source(0), Source(1), Source(2), Source(3), Source(4), Source(5),
46 Source(6), Source(7), Source(8), Source(9), Source(10), Source(11), 51 Source(6), Source(7), Source(8), Source(9), Source(10), Source(11),
47 Source(12), Source(13), Source(14), Source(15), Source(16), Source(17), 52 Source(12), Source(13), Source(14), Source(15), Source(16), Source(17),
48 Source(18), Source(19), Source(20), Source(21), Source(22), Source(23) 53 Source(18), Source(19), Source(20), Source(21), Source(22), Source(23)
49}; 54};
55static Mixers mixers;
56
57static StereoFrame16 GenerateCurrentFrame() {
58 SharedMemory& read = ReadRegion();
59 SharedMemory& write = WriteRegion();
60
61 std::array<QuadFrame32, 3> intermediate_mixes = {};
62
63 // Generate intermediate mixes
64 for (size_t i = 0; i < num_sources; i++) {
65 write.source_statuses.status[i] = sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]);
66 for (size_t mix = 0; mix < 3; mix++) {
67 sources[i].MixInto(intermediate_mixes[mix], mix);
68 }
69 }
70
71 // Generate final mix
72 write.dsp_status = mixers.Tick(read.dsp_configuration, read.intermediate_mix_samples, write.intermediate_mix_samples, intermediate_mixes);
73
74 StereoFrame16 output_frame = mixers.GetOutput();
75
76 // Write current output frame to the shared memory region
77 for (size_t samplei = 0; samplei < output_frame.size(); samplei++) {
78 for (size_t channeli = 0; channeli < output_frame[0].size(); channeli++) {
79 write.final_samples.pcm16[samplei][channeli] = s16_le(output_frame[samplei][channeli]);
80 }
81 }
82
83 return output_frame;
84}
85
86// Audio output
50 87
51static std::unique_ptr<AudioCore::Sink> sink; 88static std::unique_ptr<AudioCore::Sink> sink;
52static AudioCore::TimeStretcher time_stretcher; 89static AudioCore::TimeStretcher time_stretcher;
53 90
91// Public Interface
92
54void Init() { 93void Init() {
55 DSP::HLE::ResetPipes(); 94 DSP::HLE::ResetPipes();
56 95
@@ -58,6 +97,8 @@ void Init() {
58 source.Reset(); 97 source.Reset();
59 } 98 }
60 99
100 mixers.Reset();
101
61 time_stretcher.Reset(); 102 time_stretcher.Reset();
62 if (sink) { 103 if (sink) {
63 time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate()); 104 time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate());
@@ -75,17 +116,10 @@ void Shutdown() {
75} 116}
76 117
77bool Tick() { 118bool Tick() {
78 SharedMemory& read = ReadRegion(); 119 StereoFrame16 current_frame = {};
79 SharedMemory& write = WriteRegion();
80 120
81 std::array<QuadFrame32, 3> intermediate_mixes = {}; 121 // TODO: Check dsp::DSP semaphore (which indicates emulated application has finished writing to shared memory region)
82 122 current_frame = GenerateCurrentFrame();
83 for (size_t i = 0; i < num_sources; i++) {
84 write.source_statuses.status[i] = sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]);
85 for (size_t mix = 0; mix < 3; mix++) {
86 sources[i].MixInto(intermediate_mixes[mix], mix);
87 }
88 }
89 123
90 return true; 124 return true;
91} 125}