summaryrefslogtreecommitdiff
path: root/src/audio_core/effect_context.h
diff options
context:
space:
mode:
authorGravatar David Marcec2020-08-17 01:23:55 +1000
committerGravatar David Marcec2020-08-17 01:23:55 +1000
commit80ac1331b545d993aa7c205dc24f8b20a4d6d44e (patch)
treef0b1138935e239ff7c5766fc26bc259b375ae712 /src/audio_core/effect_context.h
parentDisable biquad filter (diff)
downloadyuzu-80ac1331b545d993aa7c205dc24f8b20a4d6d44e.tar.gz
yuzu-80ac1331b545d993aa7c205dc24f8b20a4d6d44e.tar.xz
yuzu-80ac1331b545d993aa7c205dc24f8b20a4d6d44e.zip
Preliminary effects
Diffstat (limited to 'src/audio_core/effect_context.h')
-rw-r--r--src/audio_core/effect_context.h215
1 files changed, 211 insertions, 4 deletions
diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h
index e3c367296..2f2da72dd 100644
--- a/src/audio_core/effect_context.h
+++ b/src/audio_core/effect_context.h
@@ -31,6 +31,19 @@ enum class UsageStatus : u8 {
31 Removed = 4, 31 Removed = 4,
32}; 32};
33 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
34struct BufferMixerParams { 47struct BufferMixerParams {
35 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> input{}; 48 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> input{};
36 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> output{}; 49 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> output{};
@@ -39,6 +52,14 @@ struct BufferMixerParams {
39}; 52};
40static_assert(sizeof(BufferMixerParams) == 0x94, "BufferMixerParams is an invalid size"); 53static_assert(sizeof(BufferMixerParams) == 0x94, "BufferMixerParams is an invalid size");
41 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
42struct AuxInfo { 63struct AuxInfo {
43 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> input_mix_buffers{}; 64 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> input_mix_buffers{};
44 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> output_mix_buffers{}; 65 std::array<s8, AudioCommon::MAX_MIX_BUFFERS> output_mix_buffers{};
@@ -54,6 +75,81 @@ struct AuxInfo {
54}; 75};
55static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size"); 76static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size");
56 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
57class EffectInfo { 153class EffectInfo {
58public: 154public:
59 struct InParams { 155 struct InParams {
@@ -64,7 +160,7 @@ public:
64 s32_le mix_id{}; 160 s32_le mix_id{};
65 u64_le buffer_address{}; 161 u64_le buffer_address{};
66 u64_le buffer_size{}; 162 u64_le buffer_size{};
67 s32_le priority{}; 163 s32_le processing_order{};
68 INSERT_PADDING_BYTES(4); 164 INSERT_PADDING_BYTES(4);
69 union { 165 union {
70 std::array<u8, 0xa0> raw; 166 std::array<u8, 0xa0> raw;
@@ -79,16 +175,50 @@ public:
79 static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); 175 static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size");
80}; 176};
81 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
82class EffectBase { 185class EffectBase {
83public: 186public:
84 EffectBase(); 187 EffectBase(EffectType effect_type);
85 ~EffectBase(); 188 ~EffectBase();
86 189
87 virtual void Update(EffectInfo::InParams& in_params) = 0; 190 virtual void Update(EffectInfo::InParams& in_params) = 0;
88 UsageStatus GetUsage() const; 191 virtual void UpdateForCommandGeneration() = 0;
192 UsageState GetUsage() const;
193 EffectType GetType() const;
194 bool IsEnabled() const;
195 s32 GetMixID() const;
196 s32 GetProcessingOrder() const;
89 197
90protected: 198protected:
91 UsageStatus usage{UsageStatus::Invalid}; 199 UsageState usage{UsageState::Invalid};
200 EffectType effect_type{};
201 s32 mix_id{};
202 s32 processing_order{};
203 bool enabled = false;
204};
205
206template <typename T>
207class EffectGeneric : public EffectBase {
208public:
209 EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {}
210 ~EffectGeneric() = default;
211
212 T& GetParams() {
213 return internal_params;
214 }
215
216 const I3dl2ReverbParams& GetParams() const {
217 return internal_params;
218 }
219
220private:
221 T internal_params{};
92}; 222};
93 223
94class EffectStubbed : public EffectBase { 224class EffectStubbed : public EffectBase {
@@ -97,6 +227,82 @@ public:
97 ~EffectStubbed(); 227 ~EffectStubbed();
98 228
99 void Update(EffectInfo::InParams& in_params) override; 229 void Update(EffectInfo::InParams& in_params) override;
230 void UpdateForCommandGeneration() override;
231};
232
233class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> {
234public:
235 explicit EffectI3dl2Reverb();
236 ~EffectI3dl2Reverb();
237
238 void Update(EffectInfo::InParams& in_params) override;
239 void UpdateForCommandGeneration() override;
240
241private:
242 bool skipped = false;
243};
244
245class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> {
246public:
247 explicit EffectBiquadFilter();
248 ~EffectBiquadFilter();
249
250 void Update(EffectInfo::InParams& in_params) override;
251 void UpdateForCommandGeneration() override;
252};
253
254class EffectAuxInfo : public EffectGeneric<AuxInfo> {
255public:
256 explicit EffectAuxInfo();
257 ~EffectAuxInfo();
258
259 void Update(EffectInfo::InParams& in_params) override;
260 void UpdateForCommandGeneration() override;
261 const VAddr GetSendInfo() const;
262 const VAddr GetSendBuffer() const;
263 const VAddr GetRecvInfo() const;
264 const VAddr GetRecvBuffer() const;
265
266private:
267 VAddr send_info{};
268 VAddr send_buffer{};
269 VAddr recv_info{};
270 VAddr recv_buffer{};
271 bool skipped = false;
272 AuxAddress addresses{};
273};
274
275class EffectDelay : public EffectGeneric<DelayParams> {
276public:
277 explicit EffectDelay();
278 ~EffectDelay();
279
280 void Update(EffectInfo::InParams& in_params) override;
281 void UpdateForCommandGeneration() override;
282
283private:
284 bool skipped = false;
285};
286
287class EffectBufferMixer : public EffectGeneric<BufferMixerParams> {
288public:
289 explicit EffectBufferMixer();
290 ~EffectBufferMixer();
291
292 void Update(EffectInfo::InParams& in_params) override;
293 void UpdateForCommandGeneration() override;
294};
295
296class EffectReverb : public EffectGeneric<ReverbParams> {
297public:
298 explicit EffectReverb();
299 ~EffectReverb();
300
301 void Update(EffectInfo::InParams& in_params) override;
302 void UpdateForCommandGeneration() override;
303
304private:
305 bool skipped = false;
100}; 306};
101 307
102class EffectContext { 308class EffectContext {
@@ -106,6 +312,7 @@ public:
106 312
107 std::size_t GetCount() const; 313 std::size_t GetCount() const;
108 EffectBase* GetInfo(std::size_t i); 314 EffectBase* GetInfo(std::size_t i);
315 EffectBase* RetargetEffect(std::size_t i, EffectType effect);
109 const EffectBase* GetInfo(std::size_t i) const; 316 const EffectBase* GetInfo(std::size_t i) const;
110 317
111private: 318private: