From 380658c21d39cf05ac765a9284da246388cca2a4 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Jul 2020 21:59:14 +1000 Subject: audio_core: Apollo Part 1, AudioRenderer refactor --- src/audio_core/effect_context.h | 114 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/audio_core/effect_context.h (limited to 'src/audio_core/effect_context.h') diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h new file mode 100644 index 000000000..09aedf385 --- /dev/null +++ b/src/audio_core/effect_context.h @@ -0,0 +1,114 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include "audio_core/common.h" +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/swap.h" + +namespace AudioCore { +enum class EffectType : u8 { + Invalid = 0, + BufferMixer = 1, + Aux = 2, + Delay = 3, + Reverb = 4, + I3dl2Reverb = 5, + BiquadFilter = 6, +}; + +enum class UsageStatus : u8 { + Invalid = 0, + New = 1, + Initialized = 2, + Used = 3, + Removed = 4, +}; + +struct BufferMixerParams { + std::array input{}; + std::array output{}; + std::array volume{}; + s32_le count{}; +}; +static_assert(sizeof(BufferMixerParams) == 0x94, "BufferMixerParams is an invalid size"); + +struct AuxInfo { + std::array input_mix_buffers{}; + std::array output_mix_buffers{}; + u32_le count{}; + s32_le sample_rate{}; + s32_le sample_count{}; + s32_le mix_buffer_count{}; + u64_le send_buffer_info{}; + u64_le send_buffer_base{}; + + u64_le return_buffer_info{}; + u64_le return_buffer_base{}; +}; +static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size"); + +class EffectInfo { +public: + struct InParams { + EffectType type{}; + u8 is_new{}; + u8 is_enabled{}; + INSERT_PADDING_BYTES(1); + s32_le mix_id{}; + u64_le buffer_address{}; + u64_le buffer_size{}; + s32_le priority{}; + INSERT_PADDING_BYTES(4); + union { + std::array raw; + }; + }; + static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size"); + + struct OutParams { + UsageStatus status{}; + INSERT_PADDING_BYTES(15); + }; + static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); +}; + +class EffectBase { +public: + EffectBase(); + ~EffectBase(); + + virtual void Update(EffectInfo::InParams& in_params) = 0; + UsageStatus GetUsage() const; + +protected: + UsageStatus usage{UsageStatus::Invalid}; +}; + +class EffectStubbed : public EffectBase { +public: + explicit EffectStubbed(); + ~EffectStubbed(); + + void Update(EffectInfo::InParams& in_params) override; +}; + +class EffectContext { +public: + explicit EffectContext(std::size_t effect_count); + ~EffectContext(); + + std::size_t GetCount() const; + EffectBase* GetInfo(std::size_t i); + +private: + std::size_t effect_count{}; + std::vector> effects; +}; +} // namespace AudioCore -- cgit v1.2.3 From b924c71822225b6de396b687debb93c1af59e2d6 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 25 Jul 2020 12:32:05 +1000 Subject: Address issues --- src/audio_core/effect_context.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/audio_core/effect_context.h') diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index 09aedf385..e3c367296 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h @@ -106,6 +106,7 @@ public: std::size_t GetCount() const; EffectBase* GetInfo(std::size_t i); + const EffectBase* GetInfo(std::size_t i) const; private: std::size_t effect_count{}; -- cgit v1.2.3 From 80ac1331b545d993aa7c205dc24f8b20a4d6d44e Mon Sep 17 00:00:00 2001 From: David Marcec Date: Mon, 17 Aug 2020 01:23:55 +1000 Subject: Preliminary effects --- src/audio_core/effect_context.h | 215 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 211 insertions(+), 4 deletions(-) (limited to 'src/audio_core/effect_context.h') 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 { Removed = 4, }; +enum class UsageState { + Invalid = 0, + Initialized = 1, + Running = 2, + Stopped = 3, +}; + +enum class ParameterStatus : u8 { + Initialized = 0, + Updating = 1, + Updated = 2, +}; + struct BufferMixerParams { std::array input{}; std::array output{}; @@ -39,6 +52,14 @@ struct BufferMixerParams { }; static_assert(sizeof(BufferMixerParams) == 0x94, "BufferMixerParams is an invalid size"); +struct AuxInfoDSP { + u32_le read_offset{}; + u32_le write_offset{}; + u32_le remaining{}; + INSERT_PADDING_WORDS(13); +}; +static_assert(sizeof(AuxInfoDSP) == 0x40, "AuxInfoDSP is an invalid size"); + struct AuxInfo { std::array input_mix_buffers{}; std::array output_mix_buffers{}; @@ -54,6 +75,81 @@ struct AuxInfo { }; static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size"); +struct I3dl2ReverbParams { + std::array input{}; + std::array output{}; + u16_le max_channels{}; + u16_le channel_count{}; + INSERT_PADDING_BYTES(1); + u32_le sample_rate{}; + f32 room_hf{}; + f32 hf_reference{}; + f32 decay_time{}; + f32 hf_decay_ratio{}; + f32 room{}; + f32 reflection{}; + f32 reverb{}; + f32 diffusion{}; + f32 reflection_delay{}; + f32 reverb_delay{}; + f32 density{}; + f32 dry_gain{}; + ParameterStatus status{}; + INSERT_PADDING_BYTES(3); +}; +static_assert(sizeof(I3dl2ReverbParams) == 0x4c, "I3dl2ReverbParams is an invalid size"); + +struct BiquadFilterParams { + std::array input{}; + std::array output{}; + std::array numerator; + std::array denominator; + s8 channel_count{}; + ParameterStatus status{}; +}; +static_assert(sizeof(BiquadFilterParams) == 0x18, "BiquadFilterParams is an invalid size"); + +struct DelayParams { + std::array input{}; + std::array output{}; + u16_le max_channels{}; + u16_le channels{}; + s32_le max_delay{}; + s32_le delay{}; + s32_le sample_rate{}; + s32_le gain{}; + s32_le feedback_gain{}; + s32_le out_gain{}; + s32_le dry_gain{}; + s32_le channel_spread{}; + s32_le low_pass{}; + ParameterStatus status{}; + INSERT_PADDING_BYTES(3); +}; +static_assert(sizeof(DelayParams) == 0x38, "DelayParams is an invalid size"); + +struct ReverbParams { + std::array input{}; + std::array output{}; + u16_le max_channels{}; + u16_le channels{}; + s32_le sample_rate{}; + s32_le mode0{}; + s32_le mode0_gain{}; + s32_le pre_delay{}; + s32_le mode1{}; + s32_le mode1_gain{}; + s32_le decay{}; + s32_le hf_decay_ratio{}; + s32_le coloration{}; + s32_le reverb_gain{}; + s32_le out_gain{}; + s32_le dry_gain{}; + ParameterStatus status{}; + INSERT_PADDING_BYTES(3); +}; +static_assert(sizeof(ReverbParams) == 0x44, "ReverbParams is an invalid size"); + class EffectInfo { public: struct InParams { @@ -64,7 +160,7 @@ public: s32_le mix_id{}; u64_le buffer_address{}; u64_le buffer_size{}; - s32_le priority{}; + s32_le processing_order{}; INSERT_PADDING_BYTES(4); union { std::array raw; @@ -79,16 +175,50 @@ public: static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); }; +struct AuxAddress { + VAddr send_dsp_info{}; + VAddr send_buffer_base{}; + VAddr return_dsp_info{}; + VAddr return_buffer_base{}; +}; + class EffectBase { public: - EffectBase(); + EffectBase(EffectType effect_type); ~EffectBase(); virtual void Update(EffectInfo::InParams& in_params) = 0; - UsageStatus GetUsage() const; + virtual void UpdateForCommandGeneration() = 0; + UsageState GetUsage() const; + EffectType GetType() const; + bool IsEnabled() const; + s32 GetMixID() const; + s32 GetProcessingOrder() const; protected: - UsageStatus usage{UsageStatus::Invalid}; + UsageState usage{UsageState::Invalid}; + EffectType effect_type{}; + s32 mix_id{}; + s32 processing_order{}; + bool enabled = false; +}; + +template +class EffectGeneric : public EffectBase { +public: + EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {} + ~EffectGeneric() = default; + + T& GetParams() { + return internal_params; + } + + const I3dl2ReverbParams& GetParams() const { + return internal_params; + } + +private: + T internal_params{}; }; class EffectStubbed : public EffectBase { @@ -97,6 +227,82 @@ public: ~EffectStubbed(); void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; +}; + +class EffectI3dl2Reverb : public EffectGeneric { +public: + explicit EffectI3dl2Reverb(); + ~EffectI3dl2Reverb(); + + void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; + +private: + bool skipped = false; +}; + +class EffectBiquadFilter : public EffectGeneric { +public: + explicit EffectBiquadFilter(); + ~EffectBiquadFilter(); + + void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; +}; + +class EffectAuxInfo : public EffectGeneric { +public: + explicit EffectAuxInfo(); + ~EffectAuxInfo(); + + void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; + const VAddr GetSendInfo() const; + const VAddr GetSendBuffer() const; + const VAddr GetRecvInfo() const; + const VAddr GetRecvBuffer() const; + +private: + VAddr send_info{}; + VAddr send_buffer{}; + VAddr recv_info{}; + VAddr recv_buffer{}; + bool skipped = false; + AuxAddress addresses{}; +}; + +class EffectDelay : public EffectGeneric { +public: + explicit EffectDelay(); + ~EffectDelay(); + + void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; + +private: + bool skipped = false; +}; + +class EffectBufferMixer : public EffectGeneric { +public: + explicit EffectBufferMixer(); + ~EffectBufferMixer(); + + void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; +}; + +class EffectReverb : public EffectGeneric { +public: + explicit EffectReverb(); + ~EffectReverb(); + + void Update(EffectInfo::InParams& in_params) override; + void UpdateForCommandGeneration() override; + +private: + bool skipped = false; }; class EffectContext { @@ -106,6 +312,7 @@ public: std::size_t GetCount() const; EffectBase* GetInfo(std::size_t i); + EffectBase* RetargetEffect(std::size_t i, EffectType effect); const EffectBase* GetInfo(std::size_t i) const; private: -- cgit v1.2.3