summaryrefslogtreecommitdiff
path: root/src/audio_core/effect_context.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/effect_context.h')
-rw-r--r--src/audio_core/effect_context.h349
1 files changed, 0 insertions, 349 deletions
diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h
deleted file mode 100644
index cb47df472..000000000
--- a/src/audio_core/effect_context.h
+++ /dev/null
@@ -1,349 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7#include <memory>
8#include <vector>
9#include "audio_core/common.h"
10#include "audio_core/delay_line.h"
11#include "common/common_funcs.h"
12#include "common/common_types.h"
13#include "common/swap.h"
14
15namespace AudioCore {
16enum class EffectType : u8 {
17 Invalid = 0,
18 BufferMixer = 1,
19 Aux = 2,
20 Delay = 3,
21 Reverb = 4,
22 I3dl2Reverb = 5,
23 BiquadFilter = 6,
24};
25
26enum class UsageStatus : u8 {
27 Invalid = 0,
28 New = 1,
29 Initialized = 2,
30 Used = 3,
31 Removed = 4,
32};
33
34enum class UsageState {
35 Invalid = 0,
36 Initialized = 1,
37 Running = 2,
38 Stopped = 3,
39};
40
41enum class ParameterStatus : u8 {
42 Initialized = 0,
43 Updating = 1,
44 Updated = 2,
45};
46
47struct BufferMixerParams {
48 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> input{};
49 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> output{};
50 std::array<float_le, AudioCommon::MAX_MIX_BUFFERS> volume{};
51 s32_le count{};
52};
53static_assert(sizeof(BufferMixerParams) == 0x94, "BufferMixerParams is an invalid size");
54
55struct AuxInfoDSP {
56 u32_le read_offset{};
57 u32_le write_offset{};
58 u32_le remaining{};
59 INSERT_PADDING_WORDS(13);
60};
61static_assert(sizeof(AuxInfoDSP) == 0x40, "AuxInfoDSP is an invalid size");
62
63struct AuxInfo {
64 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> input_mix_buffers{};
65 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> output_mix_buffers{};
66 u32_le count{};
67 s32_le sample_rate{};
68 s32_le sample_count{};
69 s32_le mix_buffer_count{};
70 u64_le send_buffer_info{};
71 u64_le send_buffer_base{};
72
73 u64_le return_buffer_info{};
74 u64_le return_buffer_base{};
75};
76static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size");
77
78struct I3dl2ReverbParams {
79 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> input{};
80 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> output{};
81 u16_le max_channels{};
82 u16_le channel_count{};
83 INSERT_PADDING_BYTES(1);
84 u32_le sample_rate{};
85 f32 room_hf{};
86 f32 hf_reference{};
87 f32 decay_time{};
88 f32 hf_decay_ratio{};
89 f32 room{};
90 f32 reflection{};
91 f32 reverb{};
92 f32 diffusion{};
93 f32 reflection_delay{};
94 f32 reverb_delay{};
95 f32 density{};
96 f32 dry_gain{};
97 ParameterStatus status{};
98 INSERT_PADDING_BYTES(3);
99};
100static_assert(sizeof(I3dl2ReverbParams) == 0x4c, "I3dl2ReverbParams is an invalid size");
101
102struct BiquadFilterParams {
103 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> input{};
104 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> output{};
105 std::array<s16_le, 3> numerator;
106 std::array<s16_le, 2> denominator;
107 s8 channel_count{};
108 ParameterStatus status{};
109};
110static_assert(sizeof(BiquadFilterParams) == 0x18, "BiquadFilterParams is an invalid size");
111
112struct DelayParams {
113 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> input{};
114 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> output{};
115 u16_le max_channels{};
116 u16_le channels{};
117 s32_le max_delay{};
118 s32_le delay{};
119 s32_le sample_rate{};
120 s32_le gain{};
121 s32_le feedback_gain{};
122 s32_le out_gain{};
123 s32_le dry_gain{};
124 s32_le channel_spread{};
125 s32_le low_pass{};
126 ParameterStatus status{};
127 INSERT_PADDING_BYTES(3);
128};
129static_assert(sizeof(DelayParams) == 0x38, "DelayParams is an invalid size");
130
131struct ReverbParams {
132 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> input{};
133 std::array<s8, AudioCommon::MAX_CHANNEL_COUNT> output{};
134 u16_le max_channels{};
135 u16_le channels{};
136 s32_le sample_rate{};
137 s32_le mode0{};
138 s32_le mode0_gain{};
139 s32_le pre_delay{};
140 s32_le mode1{};
141 s32_le mode1_gain{};
142 s32_le decay{};
143 s32_le hf_decay_ratio{};
144 s32_le coloration{};
145 s32_le reverb_gain{};
146 s32_le out_gain{};
147 s32_le dry_gain{};
148 ParameterStatus status{};
149 INSERT_PADDING_BYTES(3);
150};
151static_assert(sizeof(ReverbParams) == 0x44, "ReverbParams is an invalid size");
152
153class EffectInfo {
154public:
155 struct InParams {
156 EffectType type{};
157 u8 is_new{};
158 u8 is_enabled{};
159 INSERT_PADDING_BYTES(1);
160 s32_le mix_id{};
161 u64_le buffer_address{};
162 u64_le buffer_size{};
163 s32_le processing_order{};
164 INSERT_PADDING_BYTES(4);
165 union {
166 std::array<u8, 0xa0> raw;
167 };
168 };
169 static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size");
170
171 struct OutParams {
172 UsageStatus status{};
173 INSERT_PADDING_BYTES(15);
174 };
175 static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
176};
177
178struct AuxAddress {
179 VAddr send_dsp_info{};
180 VAddr send_buffer_base{};
181 VAddr return_dsp_info{};
182 VAddr return_buffer_base{};
183};
184
185class EffectBase {
186public:
187 explicit EffectBase(EffectType effect_type_);
188 virtual ~EffectBase();
189
190 virtual void Update(EffectInfo::InParams& in_params) = 0;
191 virtual void UpdateForCommandGeneration() = 0;
192 [[nodiscard]] UsageState GetUsage() const;
193 [[nodiscard]] EffectType GetType() const;
194 [[nodiscard]] bool IsEnabled() const;
195 [[nodiscard]] s32 GetMixID() const;
196 [[nodiscard]] s32 GetProcessingOrder() const;
197 [[nodiscard]] std::vector<u8>& GetWorkBuffer();
198 [[nodiscard]] const std::vector<u8>& GetWorkBuffer() const;
199
200protected:
201 UsageState usage{UsageState::Invalid};
202 EffectType effect_type{};
203 s32 mix_id{};
204 s32 processing_order{};
205 bool enabled = false;
206 std::vector<u8> work_buffer{};
207};
208
209template <typename T>
210class EffectGeneric : public EffectBase {
211public:
212 explicit EffectGeneric(EffectType effect_type_) : EffectBase(effect_type_) {}
213
214 T& GetParams() {
215 return internal_params;
216 }
217
218 const T& GetParams() const {
219 return internal_params;
220 }
221
222private:
223 T internal_params{};
224};
225
226class EffectStubbed : public EffectBase {
227public:
228 explicit EffectStubbed();
229 ~EffectStubbed() override;
230
231 void Update(EffectInfo::InParams& in_params) override;
232 void UpdateForCommandGeneration() override;
233};
234
235struct I3dl2ReverbState {
236 f32 lowpass_0{};
237 f32 lowpass_1{};
238 f32 lowpass_2{};
239
240 DelayLineBase early_delay_line{};
241 std::array<u32, AudioCommon::I3DL2REVERB_TAPS> early_tap_steps{};
242 f32 early_gain{};
243 f32 late_gain{};
244
245 u32 early_to_late_taps{};
246 std::array<DelayLineBase, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> fdn_delay_line{};
247 std::array<DelayLineAllPass, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> decay_delay_line0{};
248 std::array<DelayLineAllPass, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> decay_delay_line1{};
249 f32 last_reverb_echo{};
250 DelayLineBase center_delay_line{};
251 std::array<std::array<f32, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT>, 3> lpf_coefficients{};
252 std::array<f32, AudioCommon::I3DL2REVERB_DELAY_LINE_COUNT> shelf_filter{};
253 f32 dry_gain{};
254};
255
256class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> {
257public:
258 explicit EffectI3dl2Reverb();
259 ~EffectI3dl2Reverb() override;
260
261 void Update(EffectInfo::InParams& in_params) override;
262 void UpdateForCommandGeneration() override;
263
264 I3dl2ReverbState& GetState();
265 const I3dl2ReverbState& GetState() const;
266
267private:
268 bool skipped = false;
269 I3dl2ReverbState state{};
270};
271
272class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> {
273public:
274 explicit EffectBiquadFilter();
275 ~EffectBiquadFilter() override;
276
277 void Update(EffectInfo::InParams& in_params) override;
278 void UpdateForCommandGeneration() override;
279};
280
281class EffectAuxInfo : public EffectGeneric<AuxInfo> {
282public:
283 explicit EffectAuxInfo();
284 ~EffectAuxInfo() override;
285
286 void Update(EffectInfo::InParams& in_params) override;
287 void UpdateForCommandGeneration() override;
288 [[nodiscard]] VAddr GetSendInfo() const;
289 [[nodiscard]] VAddr GetSendBuffer() const;
290 [[nodiscard]] VAddr GetRecvInfo() const;
291 [[nodiscard]] VAddr GetRecvBuffer() const;
292
293private:
294 VAddr send_info{};
295 VAddr send_buffer{};
296 VAddr recv_info{};
297 VAddr recv_buffer{};
298 bool skipped = false;
299 AuxAddress addresses{};
300};
301
302class EffectDelay : public EffectGeneric<DelayParams> {
303public:
304 explicit EffectDelay();
305 ~EffectDelay() override;
306
307 void Update(EffectInfo::InParams& in_params) override;
308 void UpdateForCommandGeneration() override;
309
310private:
311 bool skipped = false;
312};
313
314class EffectBufferMixer : public EffectGeneric<BufferMixerParams> {
315public:
316 explicit EffectBufferMixer();
317 ~EffectBufferMixer() override;
318
319 void Update(EffectInfo::InParams& in_params) override;
320 void UpdateForCommandGeneration() override;
321};
322
323class EffectReverb : public EffectGeneric<ReverbParams> {
324public:
325 explicit EffectReverb();
326 ~EffectReverb() override;
327
328 void Update(EffectInfo::InParams& in_params) override;
329 void UpdateForCommandGeneration() override;
330
331private:
332 bool skipped = false;
333};
334
335class EffectContext {
336public:
337 explicit EffectContext(std::size_t effect_count_);
338 ~EffectContext();
339
340 [[nodiscard]] std::size_t GetCount() const;
341 [[nodiscard]] EffectBase* GetInfo(std::size_t i);
342 [[nodiscard]] EffectBase* RetargetEffect(std::size_t i, EffectType effect);
343 [[nodiscard]] const EffectBase* GetInfo(std::size_t i) const;
344
345private:
346 std::size_t effect_count{};
347 std::vector<std::unique_ptr<EffectBase>> effects;
348};
349} // namespace AudioCore