diff --git a/README.md b/README.md
index dca5d3ee0..abe026c02 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 yuzu emulator early access
 =============
 
-This is the source code for early-access 2829.
+This is the source code for early-access 2830.
 
 ## Legal Notice
 
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index 9e9b3f880..2971c42a2 100755
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -57,6 +57,8 @@ add_library(audio_core STATIC
     renderer/command/effect/biquad_filter.h
     renderer/command/effect/capture.cpp
     renderer/command/effect/capture.h
+    renderer/command/effect/compressor.cpp
+    renderer/command/effect/compressor.h
     renderer/command/effect/delay.cpp
     renderer/command/effect/delay.h
     renderer/command/effect/i3dl2_reverb.cpp
@@ -106,27 +108,29 @@ add_library(audio_core STATIC
     renderer/command/command_processing_time_estimator.h
     renderer/command/commands.h
     renderer/command/icommand.h
-    renderer/effect/effect_aux_info.cpp
-    renderer/effect/effect_aux_info.h
-    renderer/effect/effect_biquad_filter_info.cpp
-    renderer/effect/effect_biquad_filter_info.h
-    renderer/effect/effect_buffer_mixer_info.cpp
-    renderer/effect/effect_buffer_mixer_info.h
-    renderer/effect/effect_capture_info.cpp
-    renderer/effect/effect_capture_info.h
+    renderer/effect/aux_.cpp
+    renderer/effect/aux_.h
+    renderer/effect/biquad_filter.cpp
+    renderer/effect/biquad_filter.h
+    renderer/effect/buffer_mixer.cpp
+    renderer/effect/buffer_mixer.h
+    renderer/effect/capture.cpp
+    renderer/effect/capture.h
+    renderer/effect/compressor.cpp
+    renderer/effect/compressor.h
+    renderer/effect/delay.cpp
+    renderer/effect/delay.h
     renderer/effect/effect_context.cpp
     renderer/effect/effect_context.h
-    renderer/effect/effect_delay_info.cpp
-    renderer/effect/effect_delay_info.h
-    renderer/effect/effect_i3dl2_info.cpp
-    renderer/effect/effect_i3dl2_info.h
-    renderer/effect/effect_reset.h
     renderer/effect/effect_info_base.h
-    renderer/effect/effect_light_limiter_info.cpp
-    renderer/effect/effect_light_limiter_info.h
+    renderer/effect/effect_reset.h
     renderer/effect/effect_result_state.h
-    renderer/effect/effect_reverb_info.h
-    renderer/effect/effect_reverb_info.cpp
+    renderer/effect/i3dl2.cpp
+    renderer/effect/i3dl2.h
+    renderer/effect/light_limiter.cpp
+    renderer/effect/light_limiter.h
+    renderer/effect/reverb.h
+    renderer/effect/reverb.cpp
     renderer/mix/mix_context.cpp
     renderer/mix/mix_context.h
     renderer/mix/mix_info.cpp
diff --git a/src/audio_core/common/common.h b/src/audio_core/common/common.h
index ce3b09480..6abd9be45 100755
--- a/src/audio_core/common/common.h
+++ b/src/audio_core/common/common.h
@@ -4,6 +4,7 @@
 #pragma once
 
 #include <numeric>
+#include <span>
 
 #include "common/assert.h"
 #include "common/common_funcs.h"
@@ -40,6 +41,25 @@ enum class SessionTypes {
     FinalOutputRecorder,
 };
 
+enum class Channels : u32 {
+    FrontLeft,
+    FrontRight,
+    Center,
+    LFE,
+    BackLeft,
+    BackRight,
+};
+
+// These are used by Delay, Reverb and I3dl2Reverb prior to Revision 11.
+enum class OldChannels : u32 {
+    FrontLeft,
+    FrontRight,
+    BackLeft,
+    BackRight,
+    Center,
+    LFE,
+};
+
 constexpr u32 BufferCount = 32;
 
 constexpr u32 MaxRendererSessions = 2;
@@ -66,6 +86,27 @@ constexpr bool IsChannelCountValid(u16 channel_count) {
            (channel_count == 1 || channel_count == 2 || channel_count == 4 || channel_count == 6);
 }
 
+constexpr void UseOldChannelMapping(std::span<s16> inputs, std::span<s16> outputs) {
+    constexpr auto old_center{static_cast<u32>(OldChannels::Center)};
+    constexpr auto new_center{static_cast<u32>(Channels::Center)};
+    constexpr auto old_lfe{static_cast<u32>(OldChannels::LFE)};
+    constexpr auto new_lfe{static_cast<u32>(Channels::LFE)};
+
+    auto center{inputs[old_center]};
+    auto lfe{inputs[old_lfe]};
+    inputs[old_center] = inputs[new_center];
+    inputs[old_lfe] = inputs[new_lfe];
+    inputs[new_center] = center;
+    inputs[new_lfe] = lfe;
+
+    center = outputs[old_center];
+    lfe = outputs[old_lfe];
+    outputs[old_center] = outputs[new_center];
+    outputs[old_lfe] = outputs[new_lfe];
+    outputs[new_center] = center;
+    outputs[new_lfe] = lfe;
+}
+
 constexpr u32 GetSplitterInParamHeaderMagic() {
     return Common::MakeMagic('S', 'N', 'D', 'H');
 }
diff --git a/src/audio_core/common/feature_support.h b/src/audio_core/common/feature_support.h
index ba9e977fd..55c9e690d 100755
--- a/src/audio_core/common/feature_support.h
+++ b/src/audio_core/common/feature_support.h
@@ -12,7 +12,7 @@
 #include "common/common_types.h"
 
 namespace AudioCore {
-constexpr u32 CurrentRevision = 10;
+constexpr u32 CurrentRevision = 11;
 
 enum class SupportTags {
     CommandProcessingTimeEstimatorVersion4,
@@ -40,6 +40,9 @@ enum class SupportTags {
     LongSizePreDelay,
     AudioUsbDeviceOutput,
     DeviceApiVersion2,
+    DelayChannelMappingChange,
+    ReverbChannelMappingChange,
+    I3dl2ReverbChannelMappingChange,
 
     // Not a real tag, just here to get the count.
     Size
@@ -80,6 +83,9 @@ constexpr bool CheckFeatureSupported(SupportTags tag, u32 user_revision) {
             {SupportTags::EffectInfoVer2, 9},
             {SupportTags::CommandProcessingTimeEstimatorVersion4, 10},
             {SupportTags::MultiTapBiquadFilterProcessing, 10},
+            {SupportTags::DelayChannelMappingChange, 11},
+            {SupportTags::ReverbChannelMappingChange, 11},
+            {SupportTags::I3dl2ReverbChannelMappingChange, 11},
         }};
 
     const auto& feature =
diff --git a/src/audio_core/renderer/behavior/behavior_info.cpp b/src/audio_core/renderer/behavior/behavior_info.cpp
index f4e06ab26..c5d4d66d8 100755
--- a/src/audio_core/renderer/behavior/behavior_info.cpp
+++ b/src/audio_core/renderer/behavior/behavior_info.cpp
@@ -104,17 +104,22 @@ bool BehaviorInfo::IsCommandProcessingTimeEstimatorVersion4Supported() const {
                                  user_revision);
 }
 
-bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const {
+bool BehaviorInfo::IsCommandProcessingTimeEstimatorVersion5Supported() const {
+    return CheckFeatureSupported(SupportTags::CommandProcessingTimeEstimatorVersion4,
+                                 user_revision);
+}
+
+bool BehaviorInfo::IsAudioRendererProcessingTimeLimit70PercentSupported() const {
     return CheckFeatureSupported(SupportTags::AudioRendererProcessingTimeLimit70Percent,
                                  user_revision);
 }
 
-bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const {
+bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const {
     return CheckFeatureSupported(SupportTags::AudioRendererProcessingTimeLimit75Percent,
                                  user_revision);
 }
 
-bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const {
+bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const {
     return CheckFeatureSupported(SupportTags::AudioRendererProcessingTimeLimit80Percent,
                                  user_revision);
 }
@@ -147,7 +152,7 @@ bool BehaviorInfo::IsVoicePlayedSampleCountResetAtLoopPointSupported() const {
                                  user_revision);
 }
 
-bool BehaviorInfo::IsBiquadFilterEffectStateClaerBugFixed() const {
+bool BehaviorInfo::IsBiquadFilterEffectStateClearBugFixed() const {
     return CheckFeatureSupported(SupportTags::BiquadFilterEffectStateClearBugFix, user_revision);
 }
 
@@ -171,4 +176,16 @@ bool BehaviorInfo::IsDeviceApiVersion2Supported() const {
     return CheckFeatureSupported(SupportTags::DeviceApiVersion2, user_revision);
 }
 
+bool BehaviorInfo::IsDelayChannelMappingChanged() const {
+    return CheckFeatureSupported(SupportTags::DelayChannelMappingChange, user_revision);
+}
+
+bool BehaviorInfo::IsReverbChannelMappingChanged() const {
+    return CheckFeatureSupported(SupportTags::ReverbChannelMappingChange, user_revision);
+}
+
+bool BehaviorInfo::IsI3dl2ReverbChannelMappingChanged() const {
+    return CheckFeatureSupported(SupportTags::I3dl2ReverbChannelMappingChange, user_revision);
+}
+
 } // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/behavior/behavior_info.h b/src/audio_core/renderer/behavior/behavior_info.h
index 9962ab9b9..7333c297f 100755
--- a/src/audio_core/renderer/behavior/behavior_info.h
+++ b/src/audio_core/renderer/behavior/behavior_info.h
@@ -199,28 +199,32 @@ public:
     bool IsCommandProcessingTimeEstimatorVersion4Supported() const;
 
     /**
-     * Check if the AudioRenderer can use up to 70% of the allocated processing timeslice.
-     * Note: Name is correct, Nintendo have the typo here
+     * Check if the command time estimator version 5 is supported.
      *
      * @return True if supported, otherwise false.
      */
-    bool IsAudioRenererProcessingTimeLimit70PercentSupported() const;
+    bool IsCommandProcessingTimeEstimatorVersion5Supported() const;
+
+    /**
+     * Check if the AudioRenderer can use up to 70% of the allocated processing timeslice.
+     *
+     * @return True if supported, otherwise false.
+     */
+    bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
 
     /**
      * Check if the AudioRenderer can use up to 75% of the allocated processing timeslice.
-     * Note: Name is correct, Nintendo have the typo here
      *
      * @return True if supported, otherwise false.
      */
-    bool IsAudioRenererProcessingTimeLimit75PercentSupported() const;
+    bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
 
     /**
      * Check if the AudioRenderer can use up to 80% of the allocated processing timeslice.
-     * Note: Name is correct, Nintendo have the typo here
      *
      * @return True if supported, otherwise false.
      */
-    bool IsAudioRenererProcessingTimeLimit80PercentSupported() const;
+    bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
 
     /**
      * Check if voice flushing is supported
@@ -279,11 +283,10 @@ public:
      * Check if the clear state bug for biquad filters is fixed.
      * The biquad state was not marked as needing re-initialisation when the effect was updated, it
      * was only initialized once with a new effect.
-     * Note: Name is correct, Nintendo have the typo here
      *
      * @return True if fixed, otherwise false.
      */
-    bool IsBiquadFilterEffectStateClaerBugFixed() const;
+    bool IsBiquadFilterEffectStateClearBugFixed() const;
 
     /**
      * Check if Q23 precision is supported for fixed point.
@@ -322,6 +325,42 @@ public:
      */
     bool IsDeviceApiVersion2Supported() const;
 
+    /**
+     * Check if new channel mappings are used for Delay commands.
+     * Older commands used:
+     *   front left/front right/back left/back right/center/lfe
+     * Whereas everywhere else in the code uses:
+     *   front left/front right/center/lfe/back left/back right
+     * This corrects that and makes everything standardised.
+     *
+     * @return True if supported, otherwise false.
+     */
+    bool IsDelayChannelMappingChanged() const;
+
+    /**
+     * Check if new channel mappings are used for Reverb commands.
+     * Older commands used:
+     *   front left/front right/back left/back right/center/lfe
+     * Whereas everywhere else in the code uses:
+     *   front left/front right/center/lfe/back left/back right
+     * This corrects that and makes everything standardised.
+     *
+     * @return True if supported, otherwise false.
+     */
+    bool IsReverbChannelMappingChanged() const;
+
+    /**
+     * Check if new channel mappings are used for I3dl2Reverb commands.
+     * Older commands used:
+     *   front left/front right/back left/back right/center/lfe
+     * Whereas everywhere else in the code uses:
+     *   front left/front right/center/lfe/back left/back right
+     * This corrects that and makes everything standardised.
+     *
+     * @return True if supported, otherwise false.
+     */
+    bool IsI3dl2ReverbChannelMappingChanged() const;
+
     /// Host version
     u32 process_revision;
     /// User version
diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp
index cd3da472b..40074cf14 100755
--- a/src/audio_core/renderer/command/command_buffer.cpp
+++ b/src/audio_core/renderer/command/command_buffer.cpp
@@ -5,9 +5,9 @@
 #include "audio_core/renderer/command/command_buffer.h"
 #include "audio_core/renderer/command/command_list_header.h"
 #include "audio_core/renderer/command/command_processing_time_estimator.h"
-#include "audio_core/renderer/effect/effect_biquad_filter_info.h"
-#include "audio_core/renderer/effect/effect_delay_info.h"
-#include "audio_core/renderer/effect/effect_reverb_info.h"
+#include "audio_core/renderer/effect/biquad_filter.h"
+#include "audio_core/renderer/effect/delay.h"
+#include "audio_core/renderer/effect/reverb.h"
 #include "audio_core/renderer/memory/memory_pool_info.h"
 #include "audio_core/renderer/mix/mix_info.h"
 #include "audio_core/renderer/sink/circular_buffer_sink_info.h"
@@ -368,9 +368,13 @@ void CommandBuffer::GenerateDelayCommand(const s32 node_id, EffectInfoBase& effe
     if (IsChannelCountValid(parameter.channel_count)) {
         const auto state_buffer{memory_pool->Translate(CpuAddr(state), sizeof(DelayInfo::State))};
         if (state_buffer) {
-            for (s8 channel = 0; channel < parameter.channel_count; channel++) {
-                cmd.inputs[channel] = static_cast<s8>(buffer_offset + parameter.inputs[channel]);
-                cmd.outputs[channel] = static_cast<s8>(buffer_offset + parameter.outputs[channel]);
+            for (s16 channel = 0; channel < parameter.channel_count; channel++) {
+                cmd.inputs[channel] = buffer_offset + parameter.inputs[channel];
+                cmd.outputs[channel] = buffer_offset + parameter.outputs[channel];
+            }
+
+            if (!behavior->IsDelayChannelMappingChanged() && parameter.channel_count == 6) {
+                UseOldChannelMapping(cmd.inputs, cmd.outputs);
             }
 
             cmd.parameter = parameter;
@@ -506,11 +510,15 @@ void CommandBuffer::GenerateReverbCommand(const s32 node_id, EffectInfoBase& eff
     if (IsChannelCountValid(parameter.channel_count)) {
         const auto state_buffer{memory_pool->Translate(CpuAddr(state), sizeof(ReverbInfo::State))};
         if (state_buffer) {
-            for (s8 channel = 0; channel < parameter.channel_count; channel++) {
+            for (s16 channel = 0; channel < parameter.channel_count; channel++) {
                 cmd.inputs[channel] = buffer_offset + parameter.inputs[channel];
                 cmd.outputs[channel] = buffer_offset + parameter.outputs[channel];
             }
 
+            if (!behavior->IsReverbChannelMappingChanged() && parameter.channel_count == 6) {
+                UseOldChannelMapping(cmd.inputs, cmd.outputs);
+            }
+
             cmd.parameter = parameter;
             cmd.effect_enabled = effect_info.IsEnabled();
             cmd.state = state_buffer;
@@ -534,11 +542,15 @@ void CommandBuffer::GenerateI3dl2ReverbCommand(const s32 node_id, EffectInfoBase
         const auto state_buffer{
             memory_pool->Translate(CpuAddr(state), sizeof(I3dl2ReverbInfo::State))};
         if (state_buffer) {
-            for (s8 channel = 0; channel < parameter.channel_count; channel++) {
+            for (s16 channel = 0; channel < parameter.channel_count; channel++) {
                 cmd.inputs[channel] = buffer_offset + parameter.inputs[channel];
                 cmd.outputs[channel] = buffer_offset + parameter.outputs[channel];
             }
 
+            if (!behavior->IsI3dl2ReverbChannelMappingChanged() && parameter.channel_count == 6) {
+                UseOldChannelMapping(cmd.inputs, cmd.outputs);
+            }
+
             cmd.parameter = parameter;
             cmd.effect_enabled = effect_info.IsEnabled();
             cmd.state = state_buffer;
@@ -675,4 +687,28 @@ void CommandBuffer::GenerateCaptureCommand(const s32 node_id, EffectInfoBase& ef
     GenerateEnd<CaptureCommand>(cmd);
 }
 
+void CommandBuffer::GenerateCompressorCommand(s16 buffer_offset, EffectInfoBase& effect_info,
+                                              s32 node_id) {
+    auto& cmd{GenerateStart<CompressorCommand, CommandId::Compressor>(node_id)};
+
+    auto& parameter{
+        *reinterpret_cast<CompressorInfo::ParameterVersion2*>(effect_info.GetParameter())};
+    auto state{reinterpret_cast<CompressorInfo::State*>(effect_info.GetStateBuffer())};
+
+    if (IsChannelCountValid(parameter.channel_count)) {
+        auto state_buffer{memory_pool->Translate(CpuAddr(state), sizeof(CompressorInfo::State))};
+        if (state_buffer) {
+            for (u16 channel = 0; channel < parameter.channel_count; channel++) {
+                cmd.inputs[channel] = buffer_offset + parameter.inputs[channel];
+                cmd.outputs[channel] = buffer_offset + parameter.outputs[channel];
+            }
+            cmd.parameter = parameter;
+            cmd.workbuffer = state_buffer;
+            cmd.enabled = effect_info.IsEnabled();
+        }
+    }
+
+    GenerateEnd<CompressorCommand>(cmd);
+}
+
 } // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/command/command_buffer.h b/src/audio_core/renderer/command/command_buffer.h
index 74e977c50..496b0e50a 100755
--- a/src/audio_core/renderer/command/command_buffer.h
+++ b/src/audio_core/renderer/command/command_buffer.h
@@ -6,7 +6,7 @@
 #include <span>
 
 #include "audio_core/renderer/command/commands.h"
-#include "audio_core/renderer/effect/effect_light_limiter_info.h"
+#include "audio_core/renderer/effect/light_limiter.h"
 #include "audio_core/renderer/performance/performance_manager.h"
 #include "common/common_types.h"
 
@@ -428,6 +428,15 @@ public:
                                 s16 output_index, s16 buffer_offset, u32 update_count,
                                 u32 count_max, u32 write_offset);
 
+    /**
+     * Generate a compressor command, adding it to the command list.
+     *
+     * @param buffer_offset - Base mix buffer offset to use.
+     * @param effect_info   - Capture effect info to generate this command from.
+     * @param node_id       - Node id of the voice this command is generated for.
+     */
+    void GenerateCompressorCommand(s16 buffer_offset, EffectInfoBase& effect_info, s32 node_id);
+
     /// Command list buffer generated commands will be added to
     std::span<u8> command_list{};
     /// Input sample count, unused
diff --git a/src/audio_core/renderer/command/command_generator.cpp b/src/audio_core/renderer/command/command_generator.cpp
index bcd4aca5c..f42d544f8 100755
--- a/src/audio_core/renderer/command/command_generator.cpp
+++ b/src/audio_core/renderer/command/command_generator.cpp
@@ -6,11 +6,12 @@
 #include "audio_core/renderer/command/command_buffer.h"
 #include "audio_core/renderer/command/command_generator.h"
 #include "audio_core/renderer/command/command_list_header.h"
-#include "audio_core/renderer/effect/effect_aux_info.h"
-#include "audio_core/renderer/effect/effect_biquad_filter_info.h"
-#include "audio_core/renderer/effect/effect_buffer_mixer_info.h"
-#include "audio_core/renderer/effect/effect_capture_info.h"
+#include "audio_core/renderer/effect/aux_.h"
+#include "audio_core/renderer/effect/biquad_filter.h"
+#include "audio_core/renderer/effect/buffer_mixer.h"
+#include "audio_core/renderer/effect/capture.h"
 #include "audio_core/renderer/effect/effect_context.h"
+#include "audio_core/renderer/effect/light_limiter.h"
 #include "audio_core/renderer/mix/mix_context.h"
 #include "audio_core/renderer/performance/detail_aspect.h"
 #include "audio_core/renderer/performance/entry_aspect.h"
@@ -371,7 +372,7 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset
             break;
         case EffectInfoBase::ParameterState::Updating:
         case EffectInfoBase::ParameterState::Updated:
-            if (render_context.behavior->IsBiquadFilterEffectStateClaerBugFixed()) {
+            if (render_context.behavior->IsBiquadFilterEffectStateClearBugFixed()) {
                 needs_init = false;
             } else {
                 needs_init = parameter.state == EffectInfoBase::ParameterState::Updating;
@@ -442,6 +443,11 @@ void CommandGenerator::GenerateCaptureCommand(const s16 buffer_offset, EffectInf
     }
 }
 
+void CommandGenerator::GenerateCompressorCommand(const s16 buffer_offset,
+                                                 EffectInfoBase& effect_info, const s32 node_id) {
+    command_buffer.GenerateCompressorCommand(buffer_offset, effect_info, node_id);
+}
+
 void CommandGenerator::GenerateEffectCommand(MixInfo& mix_info) {
     const auto effect_count{effect_context.GetCount()};
     for (u32 i = 0; i < effect_count; i++) {
@@ -550,6 +556,17 @@ void CommandGenerator::GenerateEffectCommand(MixInfo& mix_info) {
             }
         } break;
 
+        case EffectInfoBase::Type::Compressor: {
+            DetailAspect capture_detail_aspect(*this, entry_type, mix_info.node_id,
+                                               PerformanceDetailType::Unk13);
+            GenerateCompressorCommand(mix_info.buffer_offset, effect_info, mix_info.node_id);
+            if (capture_detail_aspect.initialized) {
+                command_buffer.GeneratePerformanceCommand(
+                    capture_detail_aspect.node_id, PerformanceState::Stop,
+                    capture_detail_aspect.performance_entry_address);
+            }
+        } break;
+
         default:
             LOG_ERROR(Service_Audio, "Invalid effect type {}",
                       static_cast<u32>(effect_info.GetType()));
diff --git a/src/audio_core/renderer/command/command_generator.h b/src/audio_core/renderer/command/command_generator.h
index bbad4cff7..d80d9b0d8 100755
--- a/src/audio_core/renderer/command/command_generator.h
+++ b/src/audio_core/renderer/command/command_generator.h
@@ -244,6 +244,16 @@ public:
      */
     void GenerateCaptureCommand(s16 buffer_offset, EffectInfoBase& effect_info, s32 node_id);
 
+    /**
+     * Generate a compressor effect command.
+     *
+     * @param buffer_offset    - Base mix buffer offset to use.
+     * @param effect_info_base - Compressor effect info.
+     * @param node_id          - Node id of the mix this command is generated for.
+     */
+    void GenerateCompressorCommand(const s16 buffer_offset, EffectInfoBase& effect_info,
+                                   const s32 node_id);
+
     /**
      * Generate all effect commands for a mix.
      *
diff --git a/src/audio_core/renderer/command/command_processing_time_estimator.cpp b/src/audio_core/renderer/command/command_processing_time_estimator.cpp
index 617f0ad3c..3091f587a 100755
--- a/src/audio_core/renderer/command/command_processing_time_estimator.cpp
+++ b/src/audio_core/renderer/command/command_processing_time_estimator.cpp
@@ -167,6 +167,11 @@ u32 CommandProcessingTimeEstimatorVersion1::Estimate(
     return 0;
 }
 
+u32 CommandProcessingTimeEstimatorVersion1::Estimate(
+    [[maybe_unused]] const CompressorCommand& command) const {
+    return 0;
+}
+
 u32 CommandProcessingTimeEstimatorVersion2::Estimate(
     const PcmInt16DataSourceVersion1Command& command) const {
     switch (sample_count) {
@@ -748,6 +753,11 @@ u32 CommandProcessingTimeEstimatorVersion2::Estimate(
     return 0;
 }
 
+u32 CommandProcessingTimeEstimatorVersion2::Estimate(
+    [[maybe_unused]] const CompressorCommand& command) const {
+    return 0;
+}
+
 u32 CommandProcessingTimeEstimatorVersion3::Estimate(
     const PcmInt16DataSourceVersion1Command& command) const {
     switch (sample_count) {
@@ -1624,6 +1634,11 @@ u32 CommandProcessingTimeEstimatorVersion3::Estimate(
     return 0;
 }
 
+u32 CommandProcessingTimeEstimatorVersion3::Estimate(
+    [[maybe_unused]] const CompressorCommand& command) const {
+    return 0;
+}
+
 u32 CommandProcessingTimeEstimatorVersion4::Estimate(
     const PcmInt16DataSourceVersion1Command& command) const {
     switch (sample_count) {
@@ -2521,4 +2536,1085 @@ u32 CommandProcessingTimeEstimatorVersion4::Estimate(const CaptureCommand& comma
     }
 }
 
+u32 CommandProcessingTimeEstimatorVersion4::Estimate(
+    [[maybe_unused]] const CompressorCommand& command) const {
+    return 0;
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const PcmInt16DataSourceVersion1Command& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(
+            ((static_cast<f32>(command.sample_rate) / 200.0f / static_cast<f32>(sample_count)) *
+             (command.pitch * 0.000030518f)) *
+                427.52f +
+            6329.442f);
+    case 240:
+        return static_cast<u32>(
+            ((static_cast<f32>(command.sample_rate) / 200.0f / static_cast<f32>(sample_count)) *
+             (command.pitch * 0.000030518f)) *
+                710.143f +
+            7853.286f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const PcmInt16DataSourceVersion2Command& command) const {
+    switch (sample_count) {
+    case 160:
+        switch (command.src_quality) {
+        case SrcQuality::Medium:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        427.52f +
+                                    6329.442f);
+        case SrcQuality::High:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        371.876f +
+                                    8049.415f);
+        case SrcQuality::Low:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        423.43f +
+                                    5062.659f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid SRC quality {}",
+                      static_cast<u32>(command.src_quality));
+            return 0;
+        }
+
+    case 240:
+        switch (command.src_quality) {
+        case SrcQuality::Medium:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        710.143f +
+                                    7853.286f);
+        case SrcQuality::High:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        610.487f +
+                                    10138.842f);
+        case SrcQuality::Low:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        676.722f +
+                                    5810.962f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid SRC quality {}",
+                      static_cast<u32>(command.src_quality));
+            return 0;
+        }
+
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const PcmFloatDataSourceVersion1Command& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(
+            ((static_cast<f32>(command.sample_rate) / 200.0f / static_cast<f32>(sample_count)) *
+             (command.pitch * 0.000030518f)) *
+                1672.026f +
+            7681.211f);
+    case 240:
+        return static_cast<u32>(
+            ((static_cast<f32>(command.sample_rate) / 200.0f / static_cast<f32>(sample_count)) *
+             (command.pitch * 0.000030518f)) *
+                2550.414f +
+            9663.969f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const PcmFloatDataSourceVersion2Command& command) const {
+    switch (sample_count) {
+    case 160:
+        switch (command.src_quality) {
+        case SrcQuality::Medium:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        1672.026f +
+                                    7681.211f);
+        case SrcQuality::High:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        1672.982f +
+                                    9038.011f);
+        case SrcQuality::Low:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        1673.216f +
+                                    6027.577f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid SRC quality {}",
+                      static_cast<u32>(command.src_quality));
+            return 0;
+        }
+
+    case 240:
+        switch (command.src_quality) {
+        case SrcQuality::Medium:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        2550.414f +
+                                    9663.969f);
+        case SrcQuality::High:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        2522.303f +
+                                    11758.571f);
+        case SrcQuality::Low:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        2537.061f +
+                                    7369.309f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid SRC quality {}",
+                      static_cast<u32>(command.src_quality));
+            return 0;
+        }
+
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const AdpcmDataSourceVersion1Command& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(
+            ((static_cast<f32>(command.sample_rate) / 200.0f / static_cast<f32>(sample_count)) *
+             (command.pitch * 0.000030518f)) *
+                1827.665f +
+            7913.808f);
+    case 240:
+        return static_cast<u32>(
+            ((static_cast<f32>(command.sample_rate) / 200.0f / static_cast<f32>(sample_count)) *
+             (command.pitch * 0.000030518f)) *
+                2756.372f +
+            9736.702f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const AdpcmDataSourceVersion2Command& command) const {
+    switch (sample_count) {
+    case 160:
+        switch (command.src_quality) {
+        case SrcQuality::Medium:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        1827.665f +
+                                    7913.808f);
+        case SrcQuality::High:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        1829.285f +
+                                    9607.814f);
+        case SrcQuality::Low:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        1824.609f +
+                                    6517.476f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid SRC quality {}",
+                      static_cast<u32>(command.src_quality));
+            return 0;
+        }
+
+    case 240:
+        switch (command.src_quality) {
+        case SrcQuality::Medium:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        2756.372f +
+                                    9736.702f);
+        case SrcQuality::High:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        2731.308f +
+                                    12154.379f);
+        case SrcQuality::Low:
+            return static_cast<u32>((((static_cast<f32>(command.sample_rate) / 200.0f /
+                                       static_cast<f32>(sample_count)) *
+                                      (command.pitch * 0.000030518f)) -
+                                     1.0f) *
+                                        2732.152f +
+                                    7929.442f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid SRC quality {}",
+                      static_cast<u32>(command.src_quality));
+            return 0;
+        }
+
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const VolumeCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(1311.1f);
+    case 240:
+        return static_cast<u32>(1713.6f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const VolumeRampCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(1425.3f);
+    case 240:
+        return static_cast<u32>(1700.0f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const BiquadFilterCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(4173.2f);
+    case 240:
+        return static_cast<u32>(5585.1f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const MixCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(1402.8f);
+    case 240:
+        return static_cast<u32>(1853.2f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const MixRampCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(1968.7f);
+    case 240:
+        return static_cast<u32>(2459.4f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const MixRampGroupedCommand& command) const {
+    u32 count{0};
+    for (u32 i = 0; i < command.buffer_count; i++) {
+        if (command.volumes[i] != 0.0f || command.prev_volumes[i] != 0.0f) {
+            count++;
+        }
+    }
+
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>((static_cast<f32>(sample_count) * 6.708f) *
+                                static_cast<f32>(count));
+    case 240:
+        return static_cast<u32>((static_cast<f32>(sample_count) * 6.443f) *
+                                static_cast<f32>(count));
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const DepopPrepareCommand& command) const {
+    return 0;
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const DepopForMixBuffersCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(739.64f);
+    case 240:
+        return static_cast<u32>(910.97f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const DelayCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(8929.042f);
+            case 2:
+                return static_cast<u32>(25500.75f);
+            case 4:
+                return static_cast<u32>(47759.617f);
+            case 6:
+                return static_cast<u32>(82203.07f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(1295.206f);
+        case 2:
+            return static_cast<u32>(1213.6f);
+        case 4:
+            return static_cast<u32>(942.028f);
+        case 6:
+            return static_cast<u32>(1001.553f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    case 240:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(11941.051f);
+            case 2:
+                return static_cast<u32>(37197.371f);
+            case 4:
+                return static_cast<u32>(69749.836f);
+            case 6:
+                return static_cast<u32>(120042.398f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(997.668f);
+        case 2:
+            return static_cast<u32>(977.634f);
+        case 4:
+            return static_cast<u32>(792.309f);
+        case 6:
+            return static_cast<u32>(875.427f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const UpsampleCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(312990.0f);
+    case 240:
+        return static_cast<u32>(0.0f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const DownMix6chTo2chCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(9949.7f);
+    case 240:
+        return static_cast<u32>(14679.0f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const AuxCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            return static_cast<u32>(7182.136f);
+        }
+        return static_cast<u32>(472.111f);
+    case 240:
+        if (command.enabled) {
+            return static_cast<u32>(9435.961f);
+        }
+        return static_cast<u32>(462.619f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const DeviceSinkCommand& command) const {
+    switch (command.input_count) {
+    case 2:
+        switch (sample_count) {
+        case 160:
+            return static_cast<u32>(8979.956f);
+        case 240:
+            return static_cast<u32>(9221.907f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+            return 0;
+        }
+    case 6:
+        switch (sample_count) {
+        case 160:
+            return static_cast<u32>(9177.903f);
+        case 240:
+            return static_cast<u32>(9725.897f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid input count {}", command.input_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const CircularBufferSinkCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(static_cast<f32>(command.input_count) * 531.069f + 0.0f);
+    case 240:
+        return static_cast<u32>(static_cast<f32>(command.input_count) * 770.257f + 0.0f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const ReverbCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(81475.055f);
+            case 2:
+                return static_cast<u32>(84975.0f);
+            case 4:
+                return static_cast<u32>(91625.148f);
+            case 6:
+                return static_cast<u32>(95332.266f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(536.298f);
+        case 2:
+            return static_cast<u32>(588.798f);
+        case 4:
+            return static_cast<u32>(643.702f);
+        case 6:
+            return static_cast<u32>(705.999f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    case 240:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(120174.469f);
+            case 2:
+                return static_cast<u32>(125262.219f);
+            case 4:
+                return static_cast<u32>(135751.234f);
+            case 6:
+                return static_cast<u32>(141129.234f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(617.641f);
+        case 2:
+            return static_cast<u32>(659.536f);
+        case 4:
+            return static_cast<u32>(711.438f);
+        case 6:
+            return static_cast<u32>(778.071f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const I3dl2ReverbCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(116754.984f);
+            case 2:
+                return static_cast<u32>(125912.055f);
+            case 4:
+                return static_cast<u32>(146336.031f);
+            case 6:
+                return static_cast<u32>(165812.656f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(735.0f);
+        case 2:
+            return static_cast<u32>(766.615f);
+        case 4:
+            return static_cast<u32>(834.067f);
+        case 6:
+            return static_cast<u32>(875.437f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    case 240:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(170292.344f);
+            case 2:
+                return static_cast<u32>(183875.625f);
+            case 4:
+                return static_cast<u32>(214696.188f);
+            case 6:
+                return static_cast<u32>(243846.766f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(508.473f);
+        case 2:
+            return static_cast<u32>(582.445f);
+        case 4:
+            return static_cast<u32>(626.419f);
+        case 6:
+            return static_cast<u32>(682.468f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const PerformanceCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(498.17f);
+    case 240:
+        return static_cast<u32>(489.42f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const ClearMixBufferCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(static_cast<f32>(buffer_count - 1) * 266.645f + 0.0f);
+    case 240:
+        return static_cast<u32>(static_cast<f32>(buffer_count - 1) * 440.681f + 0.0f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const CopyMixBufferCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(842.59f);
+    case 240:
+        return static_cast<u32>(986.72f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const LightLimiterVersion1Command& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(21508.01f);
+            case 2:
+                return static_cast<u32>(23120.453f);
+            case 4:
+                return static_cast<u32>(26270.053f);
+            case 6:
+                return static_cast<u32>(40471.902f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(897.004f);
+        case 2:
+            return static_cast<u32>(931.549f);
+        case 4:
+            return static_cast<u32>(975.387f);
+        case 6:
+            return static_cast<u32>(1016.778f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    case 240:
+        if (command.enabled) {
+            switch (command.parameter.channel_count) {
+            case 1:
+                return static_cast<u32>(30565.961f);
+            case 2:
+                return static_cast<u32>(32812.91f);
+            case 4:
+                return static_cast<u32>(37354.852f);
+            case 6:
+                return static_cast<u32>(58486.699f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                          command.parameter.channel_count);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(874.429f);
+        case 2:
+            return static_cast<u32>(921.553f);
+        case 4:
+            return static_cast<u32>(945.262f);
+        case 6:
+            return static_cast<u32>(992.26f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    const LightLimiterVersion2Command& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            if (command.parameter.processing_mode == LightLimiterInfo::ProcessingMode::Mode0) {
+                if (command.parameter.statistics_enabled) {
+                    switch (command.parameter.channel_count) {
+                    case 1:
+                        return static_cast<u32>(23639.584f);
+                    case 2:
+                        return static_cast<u32>(24666.725f);
+                    case 4:
+                        return static_cast<u32>(28876.459f);
+                    case 6:
+                        return static_cast<u32>(47096.078f);
+                    default:
+                        LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                  command.parameter.channel_count);
+                        return 0;
+                    }
+                } else {
+                    if (command.parameter.statistics_enabled) {
+                        switch (command.parameter.channel_count) {
+                        case 1:
+                            return static_cast<u32>(21508.01f);
+                        case 2:
+                            return static_cast<u32>(23120.453f);
+                        case 4:
+                            return static_cast<u32>(26270.053f);
+                        case 6:
+                            return static_cast<u32>(40471.902f);
+                        default:
+                            LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                      command.parameter.channel_count);
+                            return 0;
+                        }
+                    }
+                }
+            } else if (command.parameter.processing_mode ==
+                       LightLimiterInfo::ProcessingMode::Mode1) {
+                if (command.parameter.statistics_enabled) {
+                    switch (command.parameter.channel_count) {
+                    case 1:
+                        return static_cast<u32>(23639.584f);
+                    case 2:
+                        return static_cast<u32>(29954.062f);
+                    case 4:
+                        return static_cast<u32>(35807.477f);
+                    case 6:
+                        return static_cast<u32>(58339.773f);
+                    default:
+                        LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                  command.parameter.channel_count);
+                        return 0;
+                    }
+                } else {
+                    if (command.parameter.statistics_enabled) {
+                        switch (command.parameter.channel_count) {
+                        case 1:
+                            return static_cast<u32>(23639.584f);
+                        case 2:
+                            return static_cast<u32>(29954.062f);
+                        case 4:
+                            return static_cast<u32>(35807.477f);
+                        case 6:
+                            return static_cast<u32>(58339.773f);
+                        default:
+                            LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                      command.parameter.channel_count);
+                            return 0;
+                        }
+                    }
+                }
+            } else {
+                LOG_ERROR(Service_Audio, "Invalid processing mode {}",
+                          command.parameter.processing_mode);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(897.004f);
+        case 2:
+            return static_cast<u32>(931.549f);
+        case 4:
+            return static_cast<u32>(975.387f);
+        case 6:
+            return static_cast<u32>(1016.778f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    case 240:
+        if (command.enabled) {
+            if (command.parameter.processing_mode == LightLimiterInfo::ProcessingMode::Mode0) {
+                if (command.parameter.statistics_enabled) {
+                    switch (command.parameter.channel_count) {
+                    case 1:
+                        return static_cast<u32>(33875.023f);
+                    case 2:
+                        return static_cast<u32>(35199.938f);
+                    case 4:
+                        return static_cast<u32>(41371.230f);
+                    case 6:
+                        return static_cast<u32>(68370.914f);
+                    default:
+                        LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                  command.parameter.channel_count);
+                        return 0;
+                    }
+                } else {
+                    switch (command.parameter.channel_count) {
+                    case 1:
+                        return static_cast<u32>(30565.961f);
+                    case 2:
+                        return static_cast<u32>(32812.91f);
+                    case 4:
+                        return static_cast<u32>(37354.852f);
+                    case 6:
+                        return static_cast<u32>(58486.699f);
+                    default:
+                        LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                  command.parameter.channel_count);
+                        return 0;
+                    }
+                }
+            } else if (command.parameter.processing_mode ==
+                       LightLimiterInfo::ProcessingMode::Mode1) {
+                if (command.parameter.statistics_enabled) {
+                    switch (command.parameter.channel_count) {
+                    case 1:
+                        return static_cast<u32>(33942.980f);
+                    case 2:
+                        return static_cast<u32>(28698.893f);
+                    case 4:
+                        return static_cast<u32>(34774.277f);
+                    case 6:
+                        return static_cast<u32>(61897.773f);
+                    default:
+                        LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                  command.parameter.channel_count);
+                        return 0;
+                    }
+                } else {
+                    switch (command.parameter.channel_count) {
+                    case 1:
+                        return static_cast<u32>(30610.248f);
+                    case 2:
+                        return static_cast<u32>(26322.408f);
+                    case 4:
+                        return static_cast<u32>(30369.000f);
+                    case 6:
+                        return static_cast<u32>(51892.090f);
+                    default:
+                        LOG_ERROR(Service_Audio, "Invalid channel count {}",
+                                  command.parameter.channel_count);
+                        return 0;
+                    }
+                }
+            } else {
+                LOG_ERROR(Service_Audio, "Invalid processing mode {}",
+                          command.parameter.processing_mode);
+                return 0;
+            }
+        }
+        switch (command.parameter.channel_count) {
+        case 1:
+            return static_cast<u32>(874.429f);
+        case 2:
+            return static_cast<u32>(921.553f);
+        case 4:
+            return static_cast<u32>(945.262f);
+        case 6:
+            return static_cast<u32>(992.26f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(
+    [[maybe_unused]] const MultiTapBiquadFilterCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        return static_cast<u32>(7424.5f);
+    case 240:
+        return static_cast<u32>(9730.4f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const CaptureCommand& command) const {
+    switch (sample_count) {
+    case 160:
+        if (command.enabled) {
+            return static_cast<u32>(426.982f);
+        }
+        return static_cast<u32>(4261.005f);
+    case 240:
+        if (command.enabled) {
+            return static_cast<u32>(435.204f);
+        }
+        return static_cast<u32>(5858.265f);
+    default:
+        LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+        return 0;
+    }
+}
+
+u32 CommandProcessingTimeEstimatorVersion5::Estimate(const CompressorCommand& command) const {
+    if (command.enabled) {
+        switch (command.parameter.channel_count) {
+        case 1:
+            switch (sample_count) {
+            case 160:
+                return static_cast<u32>(34430.570f);
+            case 240:
+                return static_cast<u32>(51095.348f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+                return 0;
+            }
+        case 2:
+            switch (sample_count) {
+            case 160:
+                return static_cast<u32>(44253.320f);
+            case 240:
+                return static_cast<u32>(65693.094f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+                return 0;
+            }
+        case 4:
+            switch (sample_count) {
+            case 160:
+                return static_cast<u32>(63827.457f);
+            case 240:
+                return static_cast<u32>(95382.852f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+                return 0;
+            }
+        case 6:
+            switch (sample_count) {
+            case 160:
+                return static_cast<u32>(83361.484f);
+            case 240:
+                return static_cast<u32>(124509.906f);
+            default:
+                LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+                return 0;
+            }
+        default:
+            LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+            return 0;
+        }
+    }
+    switch (command.parameter.channel_count) {
+    case 1:
+        switch (sample_count) {
+        case 160:
+            return static_cast<u32>(630.115f);
+        case 240:
+            return static_cast<u32>(840.136f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+            return 0;
+        }
+    case 2:
+        switch (sample_count) {
+        case 160:
+            return static_cast<u32>(638.274f);
+        case 240:
+            return static_cast<u32>(826.098f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+            return 0;
+        }
+    case 4:
+        switch (sample_count) {
+        case 160:
+            return static_cast<u32>(705.862f);
+        case 240:
+            return static_cast<u32>(901.876f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+            return 0;
+        }
+    case 6:
+        switch (sample_count) {
+        case 160:
+            return static_cast<u32>(782.019f);
+        case 240:
+            return static_cast<u32>(965.286f);
+        default:
+            LOG_ERROR(Service_Audio, "Invalid sample count {}", sample_count);
+            return 0;
+        }
+    default:
+        LOG_ERROR(Service_Audio, "Invalid channel count {}", command.parameter.channel_count);
+        return 0;
+    }
+}
+
 } // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/command/command_processing_time_estimator.h b/src/audio_core/renderer/command/command_processing_time_estimator.h
index dd7b29f32..452217196 100755
--- a/src/audio_core/renderer/command/command_processing_time_estimator.h
+++ b/src/audio_core/renderer/command/command_processing_time_estimator.h
@@ -43,6 +43,7 @@ public:
     virtual u32 Estimate(const LightLimiterVersion2Command& command) const = 0;
     virtual u32 Estimate(const MultiTapBiquadFilterCommand& command) const = 0;
     virtual u32 Estimate(const CaptureCommand& command) const = 0;
+    virtual u32 Estimate(const CompressorCommand& command) const = 0;
 };
 
 class CommandProcessingTimeEstimatorVersion1 final : public ICommandProcessingTimeEstimator {
@@ -79,6 +80,7 @@ public:
     u32 Estimate(const LightLimiterVersion2Command& command) const override;
     u32 Estimate(const MultiTapBiquadFilterCommand& command) const override;
     u32 Estimate(const CaptureCommand& command) const override;
+    u32 Estimate(const CompressorCommand& command) const override;
 
 private:
     u32 sample_count{};
@@ -119,6 +121,7 @@ public:
     u32 Estimate(const LightLimiterVersion2Command& command) const override;
     u32 Estimate(const MultiTapBiquadFilterCommand& command) const override;
     u32 Estimate(const CaptureCommand& command) const override;
+    u32 Estimate(const CompressorCommand& command) const override;
 
 private:
     u32 sample_count{};
@@ -159,6 +162,7 @@ public:
     u32 Estimate(const LightLimiterVersion2Command& command) const override;
     u32 Estimate(const MultiTapBiquadFilterCommand& command) const override;
     u32 Estimate(const CaptureCommand& command) const override;
+    u32 Estimate(const CompressorCommand& command) const override;
 
 private:
     u32 sample_count{};
@@ -199,6 +203,48 @@ public:
     u32 Estimate(const LightLimiterVersion2Command& command) const override;
     u32 Estimate(const MultiTapBiquadFilterCommand& command) const override;
     u32 Estimate(const CaptureCommand& command) const override;
+    u32 Estimate(const CompressorCommand& command) const override;
+
+private:
+    u32 sample_count{};
+    u32 buffer_count{};
+};
+
+class CommandProcessingTimeEstimatorVersion5 final : public ICommandProcessingTimeEstimator {
+public:
+    CommandProcessingTimeEstimatorVersion5(u32 sample_count_, u32 buffer_count_)
+        : sample_count{sample_count_}, buffer_count{buffer_count_} {}
+
+    u32 Estimate(const PcmInt16DataSourceVersion1Command& command) const override;
+    u32 Estimate(const PcmInt16DataSourceVersion2Command& command) const override;
+    u32 Estimate(const PcmFloatDataSourceVersion1Command& command) const override;
+    u32 Estimate(const PcmFloatDataSourceVersion2Command& command) const override;
+    u32 Estimate(const AdpcmDataSourceVersion1Command& command) const override;
+    u32 Estimate(const AdpcmDataSourceVersion2Command& command) const override;
+    u32 Estimate(const VolumeCommand& command) const override;
+    u32 Estimate(const VolumeRampCommand& command) const override;
+    u32 Estimate(const BiquadFilterCommand& command) const override;
+    u32 Estimate(const MixCommand& command) const override;
+    u32 Estimate(const MixRampCommand& command) const override;
+    u32 Estimate(const MixRampGroupedCommand& command) const override;
+    u32 Estimate(const DepopPrepareCommand& command) const override;
+    u32 Estimate(const DepopForMixBuffersCommand& command) const override;
+    u32 Estimate(const DelayCommand& command) const override;
+    u32 Estimate(const UpsampleCommand& command) const override;
+    u32 Estimate(const DownMix6chTo2chCommand& command) const override;
+    u32 Estimate(const AuxCommand& command) const override;
+    u32 Estimate(const DeviceSinkCommand& command) const override;
+    u32 Estimate(const CircularBufferSinkCommand& command) const override;
+    u32 Estimate(const ReverbCommand& command) const override;
+    u32 Estimate(const I3dl2ReverbCommand& command) const override;
+    u32 Estimate(const PerformanceCommand& command) const override;
+    u32 Estimate(const ClearMixBufferCommand& command) const override;
+    u32 Estimate(const CopyMixBufferCommand& command) const override;
+    u32 Estimate(const LightLimiterVersion1Command& command) const override;
+    u32 Estimate(const LightLimiterVersion2Command& command) const override;
+    u32 Estimate(const MultiTapBiquadFilterCommand& command) const override;
+    u32 Estimate(const CaptureCommand& command) const override;
+    u32 Estimate(const CompressorCommand& command) const override;
 
 private:
     u32 sample_count{};
diff --git a/src/audio_core/renderer/command/commands.h b/src/audio_core/renderer/command/commands.h
index 45124a548..6d8b8546d 100755
--- a/src/audio_core/renderer/command/commands.h
+++ b/src/audio_core/renderer/command/commands.h
@@ -9,6 +9,7 @@
 #include "audio_core/renderer/command/effect/aux_.h"
 #include "audio_core/renderer/command/effect/biquad_filter.h"
 #include "audio_core/renderer/command/effect/capture.h"
+#include "audio_core/renderer/command/effect/compressor.h"
 #include "audio_core/renderer/command/effect/delay.h"
 #include "audio_core/renderer/command/effect/i3dl2_reverb.h"
 #include "audio_core/renderer/command/effect/light_limiter.h"
diff --git a/src/audio_core/renderer/command/effect/aux_.cpp b/src/audio_core/renderer/command/effect/aux_.cpp
index dae70ac0f..e76db893f 100755
--- a/src/audio_core/renderer/command/effect/aux_.cpp
+++ b/src/audio_core/renderer/command/effect/aux_.cpp
@@ -3,7 +3,7 @@
 
 #include "audio_core/renderer/adsp/command_list_processor.h"
 #include "audio_core/renderer/command/effect/aux_.h"
-#include "audio_core/renderer/effect/effect_aux_info.h"
+#include "audio_core/renderer/effect/aux_.h"
 #include "core/memory.h"
 
 namespace AudioCore::AudioRenderer {
diff --git a/src/audio_core/renderer/command/effect/capture.cpp b/src/audio_core/renderer/command/effect/capture.cpp
index 112ddf60b..042fd286e 100755
--- a/src/audio_core/renderer/command/effect/capture.cpp
+++ b/src/audio_core/renderer/command/effect/capture.cpp
@@ -3,7 +3,7 @@
 
 #include "audio_core/renderer/adsp/command_list_processor.h"
 #include "audio_core/renderer/command/effect/capture.h"
-#include "audio_core/renderer/effect/effect_aux_info.h"
+#include "audio_core/renderer/effect/aux_.h"
 #include "core/memory.h"
 
 namespace AudioCore::AudioRenderer {
diff --git a/src/audio_core/renderer/command/effect/compressor.cpp b/src/audio_core/renderer/command/effect/compressor.cpp
new file mode 100755
index 000000000..2ebc140f1
--- /dev/null
+++ b/src/audio_core/renderer/command/effect/compressor.cpp
@@ -0,0 +1,156 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <cmath>
+#include <span>
+#include <vector>
+
+#include "audio_core/renderer/adsp/command_list_processor.h"
+#include "audio_core/renderer/command/effect/compressor.h"
+#include "audio_core/renderer/effect/compressor.h"
+
+namespace AudioCore::AudioRenderer {
+
+static void SetCompressorEffectParameter(CompressorInfo::ParameterVersion2& params,
+                                         CompressorInfo::State& state) {
+    const auto ratio{1.0f / params.compressor_ratio};
+    auto makeup_gain{0.0f};
+    if (params.makeup_gain_enabled) {
+        makeup_gain = (params.threshold * 0.5f) * (ratio - 1.0f) - 3.0f;
+    }
+    state.makeup_gain = makeup_gain;
+    state.unk_18 = params.unk_28;
+
+    const auto a{(params.out_gain + makeup_gain) / 20.0f * 3.3219f};
+    const auto b{(a - std::trunc(a)) * 0.69315f};
+    const auto c{std::pow(2.0f, b)};
+
+    state.unk_0C = (1.0f - ratio) / 6.0f;
+    state.unk_14 = params.threshold + 1.5f;
+    state.unk_10 = params.threshold - 1.5f;
+    state.unk_20 = c;
+}
+
+static void InitializeCompressorEffect(CompressorInfo::ParameterVersion2& params,
+                                       CompressorInfo::State& state) {
+    std::memset(&state, 0, sizeof(CompressorInfo::State));
+
+    state.unk_00 = 0;
+    state.unk_04 = 1.0f;
+    state.unk_08 = 1.0f;
+
+    SetCompressorEffectParameter(params, state);
+}
+
+static void ApplyCompressorEffect(CompressorInfo::ParameterVersion2& params,
+                                  CompressorInfo::State& state, bool enabled,
+                                  std::vector<std::span<const s32>> input_buffers,
+                                  std::vector<std::span<s32>> output_buffers, u32 sample_count) {
+    if (enabled) {
+        auto state_00{state.unk_00};
+        auto state_04{state.unk_04};
+        auto state_08{state.unk_08};
+        auto state_18{state.unk_18};
+
+        for (u32 i = 0; i < sample_count; i++) {
+            auto a{0.0f};
+            for (s16 channel = 0; channel < params.channel_count; channel++) {
+                const auto input_sample{Common::FixedPoint<49, 15>(input_buffers[channel][i])};
+                a += (input_sample * input_sample).to_float();
+            }
+
+            state_00 += params.unk_24 * ((a / params.channel_count) - state.unk_00);
+
+            auto b{-100.0f};
+            auto c{0.0f};
+            if (state_00 >= 1.0e-10) {
+                b = std::log10(state_00) * 10.0f;
+                c = 1.0f;
+            }
+
+            if (b >= state.unk_10) {
+                const auto d{b >= state.unk_14
+                                 ? ((1.0f / params.compressor_ratio) - 1.0f) *
+                                       (b - params.threshold)
+                                 : (b - state.unk_10) * (b - state.unk_10) * -state.unk_0C};
+                const auto e{d / 20.0f * 3.3219f};
+                const auto f{(e - std::trunc(e)) * 0.69315f};
+                c = std::pow(2.0f, f);
+            }
+
+            state_18 = params.unk_28;
+            auto tmp{c};
+            if ((state_04 - c) <= 0.08f) {
+                state_18 = params.unk_2C;
+                if (((state_04 - c) >= -0.08f) && (std::abs(state_08 - c) >= 0.001f)) {
+                    tmp = state_04;
+                }
+            }
+
+            state_04 = tmp;
+            state_08 += (c - state_08) * state_18;
+
+            for (s16 channel = 0; channel < params.channel_count; channel++) {
+                output_buffers[channel][i] = static_cast<s32>(
+                    static_cast<f32>(input_buffers[channel][i]) * state_08 * state.unk_20);
+            }
+        }
+
+        state.unk_00 = state_00;
+        state.unk_04 = state_04;
+        state.unk_08 = state_08;
+        state.unk_18 = state_18;
+    } else {
+        for (s16 channel = 0; channel < params.channel_count; channel++) {
+            if (params.inputs[channel] != params.outputs[channel]) {
+                std::memcpy((char*)output_buffers[channel].data(),
+                            (char*)input_buffers[channel].data(),
+                            output_buffers[channel].size_bytes());
+            }
+        }
+    }
+}
+
+void CompressorCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
+                             std::string& string) {
+    string += fmt::format("CompressorCommand\n\tenabled {} \n\tinputs: ", effect_enabled);
+    for (s16 i = 0; i < parameter.channel_count; i++) {
+        string += fmt::format("{:02X}, ", inputs[i]);
+    }
+    string += "\n\toutputs: ";
+    for (s16 i = 0; i < parameter.channel_count; i++) {
+        string += fmt::format("{:02X}, ", outputs[i]);
+    }
+    string += "\n";
+}
+
+void CompressorCommand::Process(const ADSP::CommandListProcessor& processor) {
+    std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
+    std::vector<std::span<s32>> output_buffers(parameter.channel_count);
+
+    for (s16 i = 0; i < parameter.channel_count; i++) {
+        input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
+                                                         processor.sample_count);
+        output_buffers[i] = processor.mix_buffers.subspan(outputs[i] * processor.sample_count,
+                                                          processor.sample_count);
+    }
+
+    auto state_{reinterpret_cast<CompressorInfo::State*>(state)};
+
+    if (effect_enabled) {
+        if (parameter.state == CompressorInfo::ParameterState::Updating) {
+            SetCompressorEffectParameter(parameter, *state_);
+        } else if (parameter.state == CompressorInfo::ParameterState::Initialized) {
+            InitializeCompressorEffect(parameter, *state_);
+        }
+    }
+
+    ApplyCompressorEffect(parameter, *state_, effect_enabled, input_buffers, output_buffers,
+                          processor.sample_count);
+}
+
+bool CompressorCommand::Verify(const ADSP::CommandListProcessor& processor) {
+    return true;
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/command/effect/compressor.h b/src/audio_core/renderer/command/effect/compressor.h
new file mode 100755
index 000000000..f8e96cb43
--- /dev/null
+++ b/src/audio_core/renderer/command/effect/compressor.h
@@ -0,0 +1,60 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <string>
+
+#include "audio_core/renderer/command/icommand.h"
+#include "audio_core/renderer/effect/compressor.h"
+#include "common/common_types.h"
+
+namespace AudioCore::AudioRenderer {
+namespace ADSP {
+class CommandListProcessor;
+}
+
+/**
+ * AudioRenderer command for limiting volume between a high and low threshold.
+ * Version 1.
+ */
+struct CompressorCommand : ICommand {
+    /**
+     * Print this command's information to a string.
+     *
+     * @param processor - The CommandListProcessor processing this command.
+     * @param string    - The string to print into.
+     */
+    void Dump(const ADSP::CommandListProcessor& processor, std::string& string) override;
+
+    /**
+     * Process this command.
+     *
+     * @param processor - The CommandListProcessor processing this command.
+     */
+    void Process(const ADSP::CommandListProcessor& processor) override;
+
+    /**
+     * Verify this command's data is valid.
+     *
+     * @param processor - The CommandListProcessor processing this command.
+     * @return True if the command is valid, otherwise false.
+     */
+    bool Verify(const ADSP::CommandListProcessor& processor) override;
+
+    /// Input mix buffer offsets for each channel
+    std::array<s16, MaxChannels> inputs;
+    /// Output mix buffer offsets for each channel
+    std::array<s16, MaxChannels> outputs;
+    /// Input parameters
+    CompressorInfo::ParameterVersion2 parameter;
+    /// State, updated each call
+    CpuAddr state;
+    /// Game-supplied workbuffer (Unused)
+    CpuAddr workbuffer;
+    /// Is this effect enabled?
+    bool effect_enabled;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/command/effect/delay.cpp b/src/audio_core/renderer/command/effect/delay.cpp
index 5329b11ed..a4e408d40 100755
--- a/src/audio_core/renderer/command/effect/delay.cpp
+++ b/src/audio_core/renderer/command/effect/delay.cpp
@@ -65,84 +65,78 @@ static void InitializeDelayEffect(const DelayInfo::ParameterVersion1& params,
  * Delay effect impl, according to the parameters and current state, on the input mix buffers,
  * saving the results to the output mix buffers.
  *
+ * @tparam NumChannels - Number of channels to process. 1-6.
  * @param params       - Input parameters to use.
  * @param state        - State to use, must be initialized (see InitializeDelayEffect).
  * @param inputs       - Input mix buffers to performan the delay on.
  * @param outputs      - Output mix buffers to receive the delayed samples.
  * @param sample_count - Number of samples to process.
  */
-template <size_t Channels>
+template <size_t NumChannels>
 static void ApplyDelay(const DelayInfo::ParameterVersion1& params, DelayInfo::State& state,
                        std::vector<std::span<const s32>>& inputs,
                        std::vector<std::span<s32>>& outputs, const u32 sample_count) {
-    for (u32 i = 0; i < sample_count; i++) {
-        std::array<Common::FixedPoint<50, 14>, Channels> input_samples{};
-        for (u32 channel = 0; channel < Channels; channel++) {
-            input_samples[channel] = inputs[channel][i] * 64;
+    for (u32 sample_index = 0; sample_index < sample_count; sample_index++) {
+        std::array<Common::FixedPoint<50, 14>, NumChannels> input_samples{};
+        for (u32 channel = 0; channel < NumChannels; channel++) {
+            input_samples[channel] = inputs[channel][sample_index] * 64;
         }
 
-        std::array<Common::FixedPoint<50, 14>, Channels> delay_samples{};
-        for (u32 channel = 0; channel < Channels; channel++) {
+        std::array<Common::FixedPoint<50, 14>, NumChannels> delay_samples{};
+        for (u32 channel = 0; channel < NumChannels; channel++) {
             delay_samples[channel] = state.delay_lines[channel].Read();
         }
 
-        std::array<std::array<Common::FixedPoint<18, 14>, Channels>, Channels> matrix{};
-        if constexpr (Channels == 1) {
+        // clang-format off
+        std::array<std::array<Common::FixedPoint<18, 14>, NumChannels>, NumChannels> matrix{};
+        if constexpr (NumChannels == 1) {
             matrix = {{
                 {state.feedback_gain},
             }};
-        } else if constexpr (Channels == 2) {
+        } else if constexpr (NumChannels == 2) {
             matrix = {{
                 {state.delay_feedback_gain, state.delay_feedback_cross_gain},
                 {state.delay_feedback_cross_gain, state.delay_feedback_gain},
             }};
-        } else if constexpr (Channels == 4) {
+        } else if constexpr (NumChannels == 4) {
             matrix = {{
-                {state.delay_feedback_gain, state.delay_feedback_cross_gain,
-                 state.delay_feedback_cross_gain, 0.0f},
-                {state.delay_feedback_cross_gain, state.delay_feedback_gain, 0.0f,
-                 state.delay_feedback_cross_gain},
-                {state.delay_feedback_cross_gain, 0.0f, state.delay_feedback_gain,
-                 state.delay_feedback_cross_gain},
-                {0.0f, state.delay_feedback_cross_gain, state.delay_feedback_cross_gain,
-                 state.delay_feedback_gain},
+                {state.delay_feedback_gain, state.delay_feedback_cross_gain, state.delay_feedback_cross_gain, 0.0f},
+                {state.delay_feedback_cross_gain, state.delay_feedback_gain, 0.0f, state.delay_feedback_cross_gain},
+                {state.delay_feedback_cross_gain, 0.0f, state.delay_feedback_gain, state.delay_feedback_cross_gain},
+                {0.0f, state.delay_feedback_cross_gain, state.delay_feedback_cross_gain, state.delay_feedback_gain},
             }};
-        } else if constexpr (Channels == 6) {
+        } else if constexpr (NumChannels == 6) {
             matrix = {{
-                {state.delay_feedback_gain, 0.0f, 0.0f, 0.0f, state.delay_feedback_cross_gain,
-                 state.delay_feedback_cross_gain},
-                {0.0f, state.delay_feedback_gain, 0.0f, state.delay_feedback_cross_gain,
-                 state.delay_feedback_cross_gain, 0.0f},
-                {state.delay_feedback_cross_gain, 0.0f, state.delay_feedback_gain,
-                 state.delay_feedback_cross_gain, 0.0f, 0.0f},
-                {0.0f, state.delay_feedback_cross_gain, state.delay_feedback_cross_gain,
-                 state.delay_feedback_gain, 0.0f, 0.0f},
-                {state.delay_feedback_cross_gain, state.delay_feedback_cross_gain, 0.0f, 0.0f,
-                 state.delay_feedback_gain, 0.0f},
-                {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, params.feedback_gain},
+                {state.delay_feedback_gain, 0.0f, state.delay_feedback_cross_gain, 0.0f, state.delay_feedback_cross_gain, 0.0f},
+                {0.0f, state.delay_feedback_gain, state.delay_feedback_cross_gain, 0.0f, 0.0f, state.delay_feedback_cross_gain},
+                {state.delay_feedback_cross_gain, state.delay_feedback_cross_gain, state.delay_feedback_gain, 0.0f, 0.0f, 0.0f},
+                {0.0f, 0.0f, 0.0f, params.feedback_gain, 0.0f, 0.0f},
+                {state.delay_feedback_cross_gain, 0.0f, 0.0f, 0.0f, state.delay_feedback_gain, state.delay_feedback_cross_gain},
+                {0.0f, state.delay_feedback_cross_gain, 0.0f, 0.0f, state.delay_feedback_cross_gain, state.delay_feedback_gain},
             }};
         }
+        // clang-format on
 
-        std::array<Common::FixedPoint<50, 14>, Channels> gained_samples{};
-        for (u32 channel = 0; channel < Channels; channel++) {
+        std::array<Common::FixedPoint<50, 14>, NumChannels> gained_samples{};
+        for (u32 channel = 0; channel < NumChannels; channel++) {
             Common::FixedPoint<50, 14> delay{};
-            for (u32 j = 0; j < Channels; j++) {
+            for (u32 j = 0; j < NumChannels; j++) {
                 delay += delay_samples[j] * matrix[j][channel];
             }
             gained_samples[channel] = input_samples[channel] * params.in_gain + delay;
         }
 
-        for (u32 channel = 0; channel < Channels; channel++) {
+        for (u32 channel = 0; channel < NumChannels; channel++) {
             state.lowpass_z[channel] = gained_samples[channel] * state.lowpass_gain +
                                        state.lowpass_z[channel] * state.lowpass_feedback_gain;
             state.delay_lines[channel].Write(state.lowpass_z[channel]);
         }
 
-        for (u32 channel = 0; channel < Channels; channel++) {
-            outputs[channel][i] = (input_samples[channel] * params.dry_gain +
-                                   delay_samples[channel] * params.wet_gain)
-                                      .to_int_floor() /
-                                  64;
+        for (u32 channel = 0; channel < NumChannels; channel++) {
+            outputs[channel][sample_index] = (input_samples[channel] * params.dry_gain +
+                                              delay_samples[channel] * params.wet_gain)
+                                                 .to_int_floor() /
+                                             64;
         }
     }
 }
diff --git a/src/audio_core/renderer/command/effect/delay.h b/src/audio_core/renderer/command/effect/delay.h
index b9c8f3e07..b7a15ae6b 100755
--- a/src/audio_core/renderer/command/effect/delay.h
+++ b/src/audio_core/renderer/command/effect/delay.h
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "audio_core/renderer/command/icommand.h"
-#include "audio_core/renderer/effect/effect_delay_info.h"
+#include "audio_core/renderer/effect/delay.h"
 #include "common/common_types.h"
 
 namespace AudioCore::AudioRenderer {
@@ -44,9 +44,9 @@ struct DelayCommand : ICommand {
     bool Verify(const ADSP::CommandListProcessor& processor) override;
 
     /// Input mix buffer offsets for each channel
-    std::array<s8, MaxChannels> inputs;
+    std::array<s16, MaxChannels> inputs;
     /// Output mix buffer offsets for each channel
-    std::array<s8, MaxChannels> outputs;
+    std::array<s16, MaxChannels> outputs;
     /// Input parameters
     DelayInfo::ParameterVersion1 parameter;
     /// State, updated each call
diff --git a/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp b/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
index fdb59f341..c4bf3943a 100755
--- a/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
+++ b/src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
@@ -232,14 +232,14 @@ static Common::FixedPoint<50, 14> Axfx2AllPassTick(I3dl2ReverbInfo::I3dl2DelayLi
  * Impl. Apply a I3DL2 reverb according to the current state, on the input mix buffers,
  * saving the results to the output mix buffers.
  *
- * @tparam Channels    - Number of channels to process. 1-6.
+ * @tparam NumChannels - Number of channels to process. 1-6.
                          Inputs/outputs should have this many buffers.
  * @param state        - State to use, must be initialized (see InitializeI3dl2ReverbEffect).
  * @param inputs       - Input mix buffers to perform the reverb on.
  * @param outputs      - Output mix buffers to receive the reverbed samples.
  * @param sample_count - Number of samples to process.
  */
-template <size_t Channels>
+template <size_t NumChannels>
 static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state,
                                    std::span<std::span<const s32>> inputs,
                                    std::span<std::span<s32>> outputs, const u32 sample_count) {
@@ -253,46 +253,46 @@ static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state,
         0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3,
     };
     constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
-        4, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2,
+        2, 0, 0, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 0, 0, 0, 0, 5, 5, 5,
     };
 
     std::span<const u8> tap_indexes{};
-    if constexpr (Channels == 1) {
+    if constexpr (NumChannels == 1) {
         tap_indexes = OutTapIndexes1Ch;
-    } else if constexpr (Channels == 2) {
+    } else if constexpr (NumChannels == 2) {
         tap_indexes = OutTapIndexes2Ch;
-    } else if constexpr (Channels == 4) {
+    } else if constexpr (NumChannels == 4) {
         tap_indexes = OutTapIndexes4Ch;
-    } else if constexpr (Channels == 6) {
+    } else if constexpr (NumChannels == 6) {
         tap_indexes = OutTapIndexes6Ch;
     }
 
-    for (u32 i = 0; i < sample_count; i++) {
+    for (u32 sample_index = 0; sample_index < sample_count; sample_index++) {
         Common::FixedPoint<50, 14> early_to_late_tap{
             state.early_delay_line.TapOut(state.early_to_late_taps)};
-        std::array<Common::FixedPoint<50, 14>, Channels> output_samples{};
+        std::array<Common::FixedPoint<50, 14>, NumChannels> output_samples{};
 
         for (u32 early_tap = 0; early_tap < I3dl2ReverbInfo::MaxDelayTaps; early_tap++) {
             output_samples[tap_indexes[early_tap]] +=
                 state.early_delay_line.TapOut(state.early_tap_steps[early_tap]) *
                 EarlyGains[early_tap];
-            if constexpr (Channels == 6) {
-                output_samples[5] +=
+            if constexpr (NumChannels == 6) {
+                output_samples[static_cast<u32>(Channels::LFE)] +=
                     state.early_delay_line.TapOut(state.early_tap_steps[early_tap]) *
                     EarlyGains[early_tap];
             }
         }
 
         Common::FixedPoint<50, 14> current_sample{};
-        for (u32 channel = 0; channel < Channels; channel++) {
-            current_sample += inputs[channel][i];
+        for (u32 channel = 0; channel < NumChannels; channel++) {
+            current_sample += inputs[channel][sample_index];
         }
 
         state.lowpass_0 =
             (current_sample * state.lowpass_2 + state.lowpass_0 * state.lowpass_1).to_float();
         state.early_delay_line.Tick(state.lowpass_0);
 
-        for (u32 channel = 0; channel < Channels; channel++) {
+        for (u32 channel = 0; channel < NumChannels; channel++) {
             output_samples[channel] *= state.early_gain;
         }
 
@@ -321,26 +321,34 @@ static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state,
                 state.fdn_delay_lines[delay_line], mix_matrix[delay_line]);
         }
 
-        const auto out_channels{std::min(Channels, size_t(4))};
-        for (u32 channel = 0; channel < out_channels; channel++) {
-            auto out_sample{output_samples[channel] + allpass_samples[channel] +
-                            state.dry_gain * static_cast<f32>(inputs[channel][i])};
-            outputs[channel][i] =
-                static_cast<s32>(std::clamp(out_sample.to_float(), -8388600.0f, 8388600.0f));
-        }
+        if constexpr (NumChannels == 6) {
+            const std::array<Common::FixedPoint<50, 14>, MaxChannels> allpass_outputs{
+                allpass_samples[0], allpass_samples[1], allpass_samples[2] - allpass_samples[3],
+                allpass_samples[3], allpass_samples[2], allpass_samples[3],
+            };
 
-        if constexpr (Channels == 6) {
-            auto center{
-                state.center_delay_line.Tick((allpass_samples[2] - allpass_samples[3]) * 0.5f)};
-            auto out_sample{static_cast<f32>(inputs[4][i]) * state.dry_gain +
-                            output_samples[4] * state.early_gain + center};
-            outputs[4][i] =
-                static_cast<s32>(std::clamp(out_sample.to_float(), -8388600.0f, 8388600.0f));
+            for (u32 channel = 0; channel < NumChannels; channel++) {
+                Common::FixedPoint<50, 14> allpass{};
 
-            out_sample = static_cast<f32>(inputs[5][i]) * state.dry_gain +
-                         output_samples[5] * state.early_gain + allpass_samples[3];
-            outputs[5][i] =
-                static_cast<s32>(std::clamp(out_sample.to_float(), -8388600.0f, 8388600.0f));
+                if (channel == static_cast<u32>(Channels::Center)) {
+                    allpass = state.center_delay_line.Tick(allpass_outputs[channel] * 0.5f);
+                } else {
+                    allpass = allpass_outputs[channel];
+                }
+
+                auto out_sample{output_samples[channel] + allpass +
+                                state.dry_gain * static_cast<f32>(inputs[channel][sample_index])};
+
+                outputs[channel][sample_index] =
+                    static_cast<s32>(std::clamp(out_sample.to_float(), -8388600.0f, 8388600.0f));
+            }
+        } else {
+            for (u32 channel = 0; channel < NumChannels; channel++) {
+                auto out_sample{output_samples[channel] + allpass_samples[channel] +
+                                state.dry_gain * static_cast<f32>(inputs[channel][sample_index])};
+                outputs[channel][sample_index] =
+                    static_cast<s32>(std::clamp(out_sample.to_float(), -8388600.0f, 8388600.0f));
+            }
         }
     }
 }
diff --git a/src/audio_core/renderer/command/effect/i3dl2_reverb.h b/src/audio_core/renderer/command/effect/i3dl2_reverb.h
index 2836f9b8b..243877056 100755
--- a/src/audio_core/renderer/command/effect/i3dl2_reverb.h
+++ b/src/audio_core/renderer/command/effect/i3dl2_reverb.h
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "audio_core/renderer/command/icommand.h"
-#include "audio_core/renderer/effect/effect_i3dl2_info.h"
+#include "audio_core/renderer/effect/i3dl2.h"
 #include "common/common_types.h"
 
 namespace AudioCore::AudioRenderer {
diff --git a/src/audio_core/renderer/command/effect/light_limiter.cpp b/src/audio_core/renderer/command/effect/light_limiter.cpp
index 604e65299..e8fb0e2fc 100755
--- a/src/audio_core/renderer/command/effect/light_limiter.cpp
+++ b/src/audio_core/renderer/command/effect/light_limiter.cpp
@@ -53,6 +53,15 @@ static void ApplyLightLimiterEffect(const LightLimiterInfo::ParameterVersion2& p
     constexpr s64 min{std::numeric_limits<s32>::min()};
     constexpr s64 max{std::numeric_limits<s32>::max()};
 
+    const auto recip_estimate = [](f64 a) -> f64 {
+        s32 q, s;
+        f64 r;
+        q = (s32)(a * 512.0);               /* a in units of 1/512 rounded down */
+        r = 1.0 / (((f64)q + 0.5) / 512.0); /* reciprocal r */
+        s = (s32)(256.0 * r + 0.5);         /* r in units of 1/256 rounded to nearest */
+        return ((f64)s / 256.0);
+    };
+
     if (enabled) {
         if (statistics && params.statistics_reset_required) {
             for (u32 i = 0; i < params.channel_count; i++) {
@@ -75,9 +84,17 @@ static void ApplyLightLimiterEffect(const LightLimiterInfo::ParameterVersion2& p
                 state.samples_average[channel] +=
                     ((abs_sample - state.samples_average[channel]) * coeff).to_float();
 
+                // Reciprocal estimate
+                auto new_average_sample{Common::FixedPoint<49, 15>(
+                    recip_estimate(state.samples_average[channel].to_double()))};
+                if (params.processing_mode != LightLimiterInfo::ProcessingMode::Mode1) {
+                    // Two Newton-Raphson steps
+                    auto temp{2.0 - (state.samples_average[channel] * new_average_sample)};
+                    new_average_sample = 2.0 - (state.samples_average[channel] * temp);
+                }
+
                 auto above_threshold{state.samples_average[channel] > params.threshold};
-                auto attenuation{above_threshold ? params.threshold / state.samples_average[channel]
-                                                 : 1.0f};
+                auto attenuation{above_threshold ? params.threshold * new_average_sample : 1.0f};
                 coeff = attenuation < state.compression_gain[channel] ? params.attack_coeff
                                                                       : params.release_coeff;
                 state.compression_gain[channel] +=
@@ -173,8 +190,6 @@ void LightLimiterVersion2Command::Dump([[maybe_unused]] const ADSP::CommandListP
 }
 
 void LightLimiterVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
-    auto state_{reinterpret_cast<LightLimiterInfo::State*>(state)};
-
     std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
     std::vector<std::span<s32>> output_buffers(parameter.channel_count);
 
@@ -185,6 +200,8 @@ void LightLimiterVersion2Command::Process(const ADSP::CommandListProcessor& proc
                                                           processor.sample_count);
     }
 
+    auto state_{reinterpret_cast<LightLimiterInfo::State*>(state)};
+
     if (effect_enabled) {
         if (parameter.state == LightLimiterInfo::ParameterState::Updating) {
             UpdateLightLimiterEffectParameter(parameter, *state_);
diff --git a/src/audio_core/renderer/command/effect/light_limiter.h b/src/audio_core/renderer/command/effect/light_limiter.h
index 48c3849ac..5d98272c7 100755
--- a/src/audio_core/renderer/command/effect/light_limiter.h
+++ b/src/audio_core/renderer/command/effect/light_limiter.h
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "audio_core/renderer/command/icommand.h"
-#include "audio_core/renderer/effect/effect_light_limiter_info.h"
+#include "audio_core/renderer/effect/light_limiter.h"
 #include "common/common_types.h"
 
 namespace AudioCore::AudioRenderer {
diff --git a/src/audio_core/renderer/command/effect/reverb.cpp b/src/audio_core/renderer/command/effect/reverb.cpp
index b9b4f43b3..fe2b1eb43 100755
--- a/src/audio_core/renderer/command/effect/reverb.cpp
+++ b/src/audio_core/renderer/command/effect/reverb.cpp
@@ -239,7 +239,7 @@ static Common::FixedPoint<50, 14> Axfx2AllPassTick(ReverbInfo::ReverbDelayLine&
  * Impl. Apply a Reverb according to the current state, on the input mix buffers,
  * saving the results to the output mix buffers.
  *
- * @tparam Channels    - Number of channels to process. 1-6.
+ * @tparam NumChannels - Number of channels to process. 1-6.
                          Inputs/outputs should have this many buffers.
  * @param params       - Input parameters to update the state.
  * @param state        - State to use, must be initialized (see InitializeReverbEffect).
@@ -247,7 +247,7 @@ static Common::FixedPoint<50, 14> Axfx2AllPassTick(ReverbInfo::ReverbDelayLine&
  * @param outputs      - Output mix buffers to receive the reverbed samples.
  * @param sample_count - Number of samples to process.
  */
-template <size_t Channels>
+template <size_t NumChannels>
 static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
                               std::vector<std::span<const s32>>& inputs,
                               std::vector<std::span<s32>>& outputs, const u32 sample_count) {
@@ -261,38 +261,38 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
         0, 0, 1, 1, 0, 1, 2, 2, 3, 3,
     };
     constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
-        0, 0, 1, 1, 4, 4, 2, 2, 3, 3,
+        0, 0, 1, 1, 2, 2, 4, 4, 5, 5,
     };
 
     std::span<const u8> tap_indexes{};
-    if constexpr (Channels == 1) {
+    if constexpr (NumChannels == 1) {
         tap_indexes = OutTapIndexes1Ch;
-    } else if constexpr (Channels == 2) {
+    } else if constexpr (NumChannels == 2) {
         tap_indexes = OutTapIndexes2Ch;
-    } else if constexpr (Channels == 4) {
+    } else if constexpr (NumChannels == 4) {
         tap_indexes = OutTapIndexes4Ch;
-    } else if constexpr (Channels == 6) {
+    } else if constexpr (NumChannels == 6) {
         tap_indexes = OutTapIndexes6Ch;
     }
 
     for (u32 sample_index = 0; sample_index < sample_count; sample_index++) {
-        std::array<Common::FixedPoint<50, 14>, Channels> output_samples{};
+        std::array<Common::FixedPoint<50, 14>, NumChannels> output_samples{};
 
         for (u32 early_tap = 0; early_tap < ReverbInfo::MaxDelayTaps; early_tap++) {
             const auto sample{state.pre_delay_line.TapOut(state.early_delay_times[early_tap]) *
                               state.early_gains[early_tap]};
             output_samples[tap_indexes[early_tap]] += sample;
-            if constexpr (Channels == 6) {
-                output_samples[5] += sample;
+            if constexpr (NumChannels == 6) {
+                output_samples[static_cast<u32>(Channels::LFE)] += sample;
             }
         }
 
-        if constexpr (Channels == 6) {
-            output_samples[5] *= 0.2f;
+        if constexpr (NumChannels == 6) {
+            output_samples[static_cast<u32>(Channels::LFE)] *= 0.2f;
         }
 
         Common::FixedPoint<50, 14> input_sample{};
-        for (u32 channel = 0; channel < Channels; channel++) {
+        for (u32 channel = 0; channel < NumChannels; channel++) {
             input_sample += inputs[channel][sample_index];
         }
 
@@ -316,34 +316,41 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
             state.prev_feedback_output[1] - state.prev_feedback_output[2] + pre_delay_sample,
         };
 
-        std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> out_line_samples{};
+        std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> allpass_samples{};
         for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) {
-            out_line_samples[i] = Axfx2AllPassTick(state.decay_delay_lines[i],
-                                                   state.fdn_delay_lines[i], mix_matrix[i]);
+            allpass_samples[i] = Axfx2AllPassTick(state.decay_delay_lines[i],
+                                                  state.fdn_delay_lines[i], mix_matrix[i]);
         }
+
         const auto dry_gain{Common::FixedPoint<50, 14>::from_base(params.dry_gain)};
         const auto wet_gain{Common::FixedPoint<50, 14>::from_base(params.wet_gain)};
 
-        const auto out_channels{std::min(Channels, size_t(4))};
-        for (u32 channel = 0; channel < out_channels; channel++) {
-            auto in_sample{inputs[channel][channel] * dry_gain};
-            auto out_sample{((output_samples[channel] + out_line_samples[channel]) * wet_gain) /
-                            64};
-            outputs[channel][sample_index] = (in_sample + out_sample).to_int();
-        }
+        if constexpr (NumChannels == 6) {
+            const std::array<Common::FixedPoint<50, 14>, MaxChannels> allpass_outputs{
+                allpass_samples[0], allpass_samples[1], allpass_samples[2] - allpass_samples[3],
+                allpass_samples[3], allpass_samples[2], allpass_samples[3],
+            };
 
-        if constexpr (Channels == 6) {
-            auto center{
-                state.center_delay_line.Tick((out_line_samples[2] - out_line_samples[3]) * 0.5f)};
-            auto in_sample{inputs[4][sample_index] * dry_gain};
-            auto out_sample{((output_samples[4] + center) * wet_gain) / 64};
+            for (u32 channel = 0; channel < NumChannels; channel++) {
+                auto in_sample{inputs[channel][sample_index] * dry_gain};
 
-            outputs[4][sample_index] = (in_sample + out_sample).to_int();
+                Common::FixedPoint<50, 14> allpass{};
+                if (channel == static_cast<u32>(Channels::Center)) {
+                    allpass = state.center_delay_line.Tick(allpass_outputs[channel] * 0.5f);
+                } else {
+                    allpass = allpass_outputs[channel];
+                }
 
-            in_sample = inputs[5][sample_index] * dry_gain;
-            out_sample = ((output_samples[5] + out_line_samples[3]) * wet_gain) / 64;
-
-            outputs[5][sample_index] = (in_sample + out_sample).to_int();
+                auto out_sample{((output_samples[channel] + allpass) * wet_gain) / 64};
+                outputs[channel][sample_index] = (in_sample + out_sample).to_int();
+            }
+        } else {
+            for (u32 channel = 0; channel < NumChannels; channel++) {
+                auto in_sample{inputs[channel][sample_index] * dry_gain};
+                auto out_sample{((output_samples[channel] + allpass_samples[channel]) * wet_gain) /
+                                64};
+                outputs[channel][sample_index] = (in_sample + out_sample).to_int();
+            }
         }
     }
 }
diff --git a/src/audio_core/renderer/command/effect/reverb.h b/src/audio_core/renderer/command/effect/reverb.h
index d9c8f894d..328756150 100755
--- a/src/audio_core/renderer/command/effect/reverb.h
+++ b/src/audio_core/renderer/command/effect/reverb.h
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "audio_core/renderer/command/icommand.h"
-#include "audio_core/renderer/effect/effect_reverb_info.h"
+#include "audio_core/renderer/effect/reverb.h"
 #include "common/common_types.h"
 
 namespace AudioCore::AudioRenderer {
diff --git a/src/audio_core/renderer/command/icommand.h b/src/audio_core/renderer/command/icommand.h
index fdbb99f5e..f2dd41254 100755
--- a/src/audio_core/renderer/command/icommand.h
+++ b/src/audio_core/renderer/command/icommand.h
@@ -42,6 +42,7 @@ enum class CommandId : u8 {
     /* 0x1B */ LightLimiterVersion2,
     /* 0x1C */ MultiTapBiquadFilter,
     /* 0x1D */ Capture,
+    /* 0x1E */ Compressor,
 };
 
 constexpr u32 CommandMagic{0xCAFEBABE};
diff --git a/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp b/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp
index d68227dc5..c2bc10061 100755
--- a/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp
+++ b/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp
@@ -43,8 +43,9 @@ void DepopForMixBuffersCommand::Dump([[maybe_unused]] const ADSP::CommandListPro
 }
 
 void DepopForMixBuffersCommand::Process(const ADSP::CommandListProcessor& processor) {
-    std::span<s32> depop_buff{reinterpret_cast<s32*>(depop_buffer), MaxMixBuffers};
     auto end_index{std::min(processor.buffer_count, input + count)};
+    std::span<s32> depop_buff{reinterpret_cast<s32*>(depop_buffer), end_index};
+
     for (u32 index = input; index < end_index; index++) {
         const auto depop_sample{depop_buff[index]};
         if (depop_sample != 0) {
diff --git a/src/audio_core/renderer/command/resample/downmix_6ch_to_2ch.h b/src/audio_core/renderer/command/resample/downmix_6ch_to_2ch.h
index fa6207f6f..dc133a73b 100755
--- a/src/audio_core/renderer/command/resample/downmix_6ch_to_2ch.h
+++ b/src/audio_core/renderer/command/resample/downmix_6ch_to_2ch.h
@@ -16,7 +16,7 @@ class CommandListProcessor;
 
 /**
  * AudioRenderer command for downmixing 6 channels to 2.
- * Channels:
+ * Channel layout (SMPTE):
  *     0 - front left
  *     1 - front right
  *     2 - center
diff --git a/src/audio_core/renderer/effect/aux_.cpp b/src/audio_core/renderer/effect/aux_.cpp
new file mode 100755
index 000000000..51e780ef1
--- /dev/null
+++ b/src/audio_core/renderer/effect/aux_.cpp
@@ -0,0 +1,93 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/aux_.h"
+
+namespace AudioCore::AudioRenderer {
+
+void AuxInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                     const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+    if (buffer_unmapped || in_params.is_new) {
+        const bool send_unmapped{!pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[0], in_specific->send_buffer_info_address,
+            sizeof(AuxBufferInfo) + in_specific->count_max * sizeof(s32))};
+        const bool return_unmapped{!pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[1], in_specific->return_buffer_info_address,
+            sizeof(AuxBufferInfo) + in_specific->count_max * sizeof(s32))};
+
+        buffer_unmapped = send_unmapped || return_unmapped;
+
+        if (!buffer_unmapped) {
+            auto send{workbuffers[0].GetReference(false)};
+            send_buffer_info = send + sizeof(AuxInfoDsp);
+            send_buffer = send + sizeof(AuxBufferInfo);
+
+            auto ret{workbuffers[1].GetReference(false)};
+            return_buffer_info = ret + sizeof(AuxInfoDsp);
+            return_buffer = ret + sizeof(AuxBufferInfo);
+        }
+    } else {
+        error_info.error_code = ResultSuccess;
+        error_info.address = CpuAddr(0);
+    }
+}
+
+void AuxInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                     const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion2*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion2*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion2));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    if (buffer_unmapped || in_params.is_new) {
+        const bool send_unmapped{!pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[0], params->send_buffer_info_address,
+            sizeof(AuxBufferInfo) + params->count_max * sizeof(s32))};
+        const bool return_unmapped{!pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[1], params->return_buffer_info_address,
+            sizeof(AuxBufferInfo) + params->count_max * sizeof(s32))};
+
+        buffer_unmapped = send_unmapped || return_unmapped;
+
+        if (!buffer_unmapped) {
+            auto send{workbuffers[0].GetReference(false)};
+            send_buffer_info = send + sizeof(AuxInfoDsp);
+            send_buffer = send + sizeof(AuxBufferInfo);
+
+            auto ret{workbuffers[1].GetReference(false)};
+            return_buffer_info = ret + sizeof(AuxInfoDsp);
+            return_buffer = ret + sizeof(AuxBufferInfo);
+        }
+    } else {
+        error_info.error_code = ResultSuccess;
+        error_info.address = CpuAddr(0);
+    }
+}
+
+void AuxInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+}
+
+void AuxInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void AuxInfo::UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) {}
+
+CpuAddr AuxInfo::GetWorkbuffer(s32 index) {
+    return workbuffers[index].GetReference(true);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/aux_.h b/src/audio_core/renderer/effect/aux_.h
new file mode 100755
index 000000000..4d3d9e3d9
--- /dev/null
+++ b/src/audio_core/renderer/effect/aux_.h
@@ -0,0 +1,123 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+
+namespace AudioCore::AudioRenderer {
+/**
+ * Auxiliary Buffer used for Aux commands.
+ * Send and return buffers are available (names from the game's perspective).
+ * Send is read by the host, containing a buffer of samples to be used for whatever purpose.
+ * Return is written by the host, writing a mix buffer back to the game.
+ * This allows the game to use pre-processed samples skipping the other render processing,
+ * and to examine or modify what the audio renderer has generated.
+ */
+class AuxInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxMixBuffers> inputs;
+        /* 0x18 */ std::array<s8, MaxMixBuffers> outputs;
+        /* 0x30 */ u32 mix_buffer_count;
+        /* 0x34 */ u32 sample_rate;
+        /* 0x38 */ u32 count_max;
+        /* 0x3C */ u32 mix_buffer_count_max;
+        /* 0x40 */ CpuAddr send_buffer_info_address;
+        /* 0x48 */ CpuAddr send_buffer_address;
+        /* 0x50 */ CpuAddr return_buffer_info_address;
+        /* 0x58 */ CpuAddr return_buffer_address;
+        /* 0x60 */ u32 mix_buffer_sample_size;
+        /* 0x64 */ u32 sample_count;
+        /* 0x68 */ u32 mix_buffer_sample_count;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "AuxInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxMixBuffers> inputs;
+        /* 0x18 */ std::array<s8, MaxMixBuffers> outputs;
+        /* 0x30 */ u32 mix_buffer_count;
+        /* 0x34 */ u32 sample_rate;
+        /* 0x38 */ u32 count_max;
+        /* 0x3C */ u32 mix_buffer_count_max;
+        /* 0x40 */ CpuAddr send_buffer_info_address;
+        /* 0x48 */ CpuAddr send_buffer_address;
+        /* 0x50 */ CpuAddr return_buffer_info_address;
+        /* 0x58 */ CpuAddr return_buffer_address;
+        /* 0x60 */ u32 mix_buffer_sample_size;
+        /* 0x64 */ u32 sample_count;
+        /* 0x68 */ u32 mix_buffer_sample_count;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "AuxInfo::ParameterVersion2 has the wrong size!");
+
+    struct AuxInfoDsp {
+        /* 0x00 */ u32 read_offset;
+        /* 0x04 */ u32 write_offset;
+        /* 0x08 */ u32 lost_sample_count;
+        /* 0x0C */ u32 total_sample_count;
+        /* 0x10 */ char unk10[0x30];
+    };
+    static_assert(sizeof(AuxInfoDsp) == 0x40, "AuxInfo::AuxInfoDsp has the wrong size!");
+
+    struct AuxBufferInfo {
+        /* 0x00 */ AuxInfoDsp cpu_info;
+        /* 0x40 */ AuxInfoDsp dsp_info;
+    };
+    static_assert(sizeof(AuxBufferInfo) == 0x80, "AuxInfo::AuxBufferInfo has the wrong size!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/biquad_filter.cpp b/src/audio_core/renderer/effect/biquad_filter.cpp
new file mode 100755
index 000000000..a1efb3231
--- /dev/null
+++ b/src/audio_core/renderer/effect/biquad_filter.cpp
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/biquad_filter.h"
+
+namespace AudioCore::AudioRenderer {
+
+void BiquadFilterInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                              const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void BiquadFilterInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                              const InParameterVersion2& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion2*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion2*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion2));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void BiquadFilterInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+    params->state = ParameterState::Updated;
+}
+
+void BiquadFilterInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void BiquadFilterInfo::UpdateResultState(EffectResultState& cpu_state,
+                                         EffectResultState& dsp_state) {}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/biquad_filter.h b/src/audio_core/renderer/effect/biquad_filter.h
new file mode 100755
index 000000000..f53fd5bab
--- /dev/null
+++ b/src/audio_core/renderer/effect/biquad_filter.h
@@ -0,0 +1,79 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+
+namespace AudioCore::AudioRenderer {
+
+class BiquadFilterInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ std::array<s16, 3> b;
+        /* 0x12 */ std::array<s16, 2> a;
+        /* 0x16 */ s8 channel_count;
+        /* 0x17 */ ParameterState state;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "BiquadFilterInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ std::array<s16, 3> b;
+        /* 0x12 */ std::array<s16, 2> a;
+        /* 0x16 */ s8 channel_count;
+        /* 0x17 */ ParameterState state;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "BiquadFilterInfo::ParameterVersion2 has the wrong size!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/buffer_mixer.cpp b/src/audio_core/renderer/effect/buffer_mixer.cpp
new file mode 100755
index 000000000..9c8877f01
--- /dev/null
+++ b/src/audio_core/renderer/effect/buffer_mixer.cpp
@@ -0,0 +1,49 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/buffer_mixer.h"
+
+namespace AudioCore::AudioRenderer {
+
+void BufferMixerInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                             const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void BufferMixerInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                             const InParameterVersion2& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion2*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion2*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion2));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void BufferMixerInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+}
+
+void BufferMixerInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void BufferMixerInfo::UpdateResultState(EffectResultState& cpu_state,
+                                        EffectResultState& dsp_state) {}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/buffer_mixer.h b/src/audio_core/renderer/effect/buffer_mixer.h
new file mode 100755
index 000000000..23eed4a8b
--- /dev/null
+++ b/src/audio_core/renderer/effect/buffer_mixer.h
@@ -0,0 +1,75 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+
+namespace AudioCore::AudioRenderer {
+
+class BufferMixerInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxMixBuffers> inputs;
+        /* 0x18 */ std::array<s8, MaxMixBuffers> outputs;
+        /* 0x30 */ std::array<f32, MaxMixBuffers> volumes;
+        /* 0x90 */ u32 mix_count;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "BufferMixerInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxMixBuffers> inputs;
+        /* 0x18 */ std::array<s8, MaxMixBuffers> outputs;
+        /* 0x30 */ std::array<f32, MaxMixBuffers> volumes;
+        /* 0x90 */ u32 mix_count;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "BufferMixerInfo::ParameterVersion2 has the wrong size!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/capture.cpp b/src/audio_core/renderer/effect/capture.cpp
new file mode 100755
index 000000000..3f038efdb
--- /dev/null
+++ b/src/audio_core/renderer/effect/capture.cpp
@@ -0,0 +1,82 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/aux_.h"
+#include "audio_core/renderer/effect/capture.h"
+
+namespace AudioCore::AudioRenderer {
+
+void CaptureInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                         const PoolMapper& pool_mapper) {
+    auto in_specific{
+        reinterpret_cast<const AuxInfo::ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<AuxInfo::ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(AuxInfo::ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+    if (buffer_unmapped || in_params.is_new) {
+        buffer_unmapped = !pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[0], in_specific->send_buffer_info_address,
+            in_specific->count_max * sizeof(s32) + sizeof(AuxInfo::AuxBufferInfo));
+
+        if (!buffer_unmapped) {
+            const auto send_address{workbuffers[0].GetReference(false)};
+            send_buffer_info = send_address + sizeof(AuxInfo::AuxInfoDsp);
+            send_buffer = send_address + sizeof(AuxInfo::AuxBufferInfo);
+            return_buffer_info = 0;
+            return_buffer = 0;
+        }
+    } else {
+        error_info.error_code = ResultSuccess;
+        error_info.address = CpuAddr(0);
+    }
+}
+
+void CaptureInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                         const PoolMapper& pool_mapper) {
+    auto in_specific{
+        reinterpret_cast<const AuxInfo::ParameterVersion2*>(in_params.specific.data())};
+    auto params{reinterpret_cast<AuxInfo::ParameterVersion2*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(AuxInfo::ParameterVersion2));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    if (buffer_unmapped || in_params.is_new) {
+        buffer_unmapped = !pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[0], params->send_buffer_info_address,
+            params->count_max * sizeof(s32) + sizeof(AuxInfo::AuxBufferInfo));
+
+        if (!buffer_unmapped) {
+            const auto send_address{workbuffers[0].GetReference(false)};
+            send_buffer_info = send_address + sizeof(AuxInfo::AuxInfoDsp);
+            send_buffer = send_address + sizeof(AuxInfo::AuxBufferInfo);
+            return_buffer_info = 0;
+            return_buffer = 0;
+        }
+    } else {
+        error_info.error_code = ResultSuccess;
+        error_info.address = CpuAddr(0);
+    }
+}
+
+void CaptureInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+}
+
+void CaptureInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void CaptureInfo::UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) {}
+
+CpuAddr CaptureInfo::GetWorkbuffer(s32 index) {
+    return workbuffers[index].GetReference(true);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/capture.h b/src/audio_core/renderer/effect/capture.h
new file mode 100755
index 000000000..6fbed8e6b
--- /dev/null
+++ b/src/audio_core/renderer/effect/capture.h
@@ -0,0 +1,65 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+
+namespace AudioCore::AudioRenderer {
+
+class CaptureInfo : public EffectInfoBase {
+public:
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/compressor.cpp b/src/audio_core/renderer/effect/compressor.cpp
new file mode 100755
index 000000000..220ae02f9
--- /dev/null
+++ b/src/audio_core/renderer/effect/compressor.cpp
@@ -0,0 +1,40 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/compressor.h"
+
+namespace AudioCore::AudioRenderer {
+
+void CompressorInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                            const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {}
+
+void CompressorInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                            const InParameterVersion2& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void CompressorInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+    params->state = ParameterState::Updated;
+}
+
+CpuAddr CompressorInfo::GetWorkbuffer(s32 index) {
+    return GetSingleBuffer(index);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/compressor.h b/src/audio_core/renderer/effect/compressor.h
new file mode 100755
index 000000000..019a5ae58
--- /dev/null
+++ b/src/audio_core/renderer/effect/compressor.h
@@ -0,0 +1,106 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+#include "common/fixed_point.h"
+
+namespace AudioCore::AudioRenderer {
+
+class CompressorInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ s16 channel_count_max;
+        /* 0x0E */ s16 channel_count;
+        /* 0x10 */ s32 sample_rate;
+        /* 0x14 */ f32 threshold;
+        /* 0x18 */ f32 compressor_ratio;
+        /* 0x1C */ s32 attack_time;
+        /* 0x20 */ s32 release_time;
+        /* 0x24 */ f32 unk_24;
+        /* 0x28 */ f32 unk_28;
+        /* 0x2C */ f32 unk_2C;
+        /* 0x30 */ f32 out_gain;
+        /* 0x34 */ ParameterState state;
+        /* 0x35 */ bool makeup_gain_enabled;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "CompressorInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ s16 channel_count_max;
+        /* 0x0E */ s16 channel_count;
+        /* 0x10 */ s32 sample_rate;
+        /* 0x14 */ f32 threshold;
+        /* 0x18 */ f32 compressor_ratio;
+        /* 0x1C */ s32 attack_time;
+        /* 0x20 */ s32 release_time;
+        /* 0x24 */ f32 unk_24;
+        /* 0x28 */ f32 unk_28;
+        /* 0x2C */ f32 unk_2C;
+        /* 0x30 */ f32 out_gain;
+        /* 0x34 */ ParameterState state;
+        /* 0x35 */ bool makeup_gain_enabled;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "CompressorInfo::ParameterVersion2 has the wrong size!");
+
+    struct State {
+        f32 unk_00;
+        f32 unk_04;
+        f32 unk_08;
+        f32 unk_0C;
+        f32 unk_10;
+        f32 unk_14;
+        f32 unk_18;
+        f32 makeup_gain;
+        f32 unk_20;
+        char unk_24[0x1C];
+    };
+    static_assert(sizeof(State) <= sizeof(EffectInfoBase::State),
+                  "CompressorInfo::State has the wrong size!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/delay.cpp b/src/audio_core/renderer/effect/delay.cpp
new file mode 100755
index 000000000..d9853efd9
--- /dev/null
+++ b/src/audio_core/renderer/effect/delay.cpp
@@ -0,0 +1,93 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/delay.h"
+
+namespace AudioCore::AudioRenderer {
+
+void DelayInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                       const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    if (IsChannelCountValid(in_specific->channel_count_max)) {
+        const auto old_state{params->state};
+        std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+        mix_id = in_params.mix_id;
+        process_order = in_params.process_order;
+        enabled = in_params.enabled;
+
+        if (!IsChannelCountValid(in_specific->channel_count)) {
+            params->channel_count = params->channel_count_max;
+        }
+
+        if (!IsChannelCountValid(in_specific->channel_count) ||
+            old_state != ParameterState::Updated) {
+            params->state = old_state;
+        }
+
+        if (buffer_unmapped || in_params.is_new) {
+            usage_state = UsageState::New;
+            params->state = ParameterState::Initialized;
+            buffer_unmapped = !pool_mapper.TryAttachBuffer(
+                error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+            return;
+        }
+    }
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void DelayInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                       const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    if (IsChannelCountValid(in_specific->channel_count_max)) {
+        const auto old_state{params->state};
+        std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+        mix_id = in_params.mix_id;
+        process_order = in_params.process_order;
+        enabled = in_params.enabled;
+
+        if (!IsChannelCountValid(in_specific->channel_count)) {
+            params->channel_count = params->channel_count_max;
+        }
+
+        if (!IsChannelCountValid(in_specific->channel_count) ||
+            old_state != ParameterState::Updated) {
+            params->state = old_state;
+        }
+
+        if (buffer_unmapped || in_params.is_new) {
+            usage_state = UsageState::New;
+            params->state = ParameterState::Initialized;
+            buffer_unmapped = !pool_mapper.TryAttachBuffer(
+                error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+            return;
+        }
+    }
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void DelayInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+    params->state = ParameterState::Updated;
+}
+
+void DelayInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void DelayInfo::UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) {}
+
+CpuAddr DelayInfo::GetWorkbuffer(s32 index) {
+    return GetSingleBuffer(index);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/delay.h b/src/audio_core/renderer/effect/delay.h
new file mode 100755
index 000000000..accc42a06
--- /dev/null
+++ b/src/audio_core/renderer/effect/delay.h
@@ -0,0 +1,135 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+#include "common/fixed_point.h"
+
+namespace AudioCore::AudioRenderer {
+
+class DelayInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x10 */ u32 delay_time_max;
+        /* 0x14 */ u32 delay_time;
+        /* 0x18 */ Common::FixedPoint<18, 14> sample_rate;
+        /* 0x1C */ Common::FixedPoint<18, 14> in_gain;
+        /* 0x20 */ Common::FixedPoint<18, 14> feedback_gain;
+        /* 0x24 */ Common::FixedPoint<18, 14> wet_gain;
+        /* 0x28 */ Common::FixedPoint<18, 14> dry_gain;
+        /* 0x2C */ Common::FixedPoint<18, 14> channel_spread;
+        /* 0x30 */ Common::FixedPoint<18, 14> lowpass_amount;
+        /* 0x34 */ ParameterState state;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "DelayInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ s16 channel_count_max;
+        /* 0x0E */ s16 channel_count;
+        /* 0x10 */ s32 delay_time_max;
+        /* 0x14 */ s32 delay_time;
+        /* 0x18 */ s32 sample_rate;
+        /* 0x1C */ s32 in_gain;
+        /* 0x20 */ s32 feedback_gain;
+        /* 0x24 */ s32 wet_gain;
+        /* 0x28 */ s32 dry_gain;
+        /* 0x2C */ s32 channel_spread;
+        /* 0x30 */ s32 lowpass_amount;
+        /* 0x34 */ ParameterState state;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "DelayInfo::ParameterVersion2 has the wrong size!");
+
+    struct DelayLine {
+        Common::FixedPoint<50, 14> Read() const {
+            return buffer[buffer_pos];
+        }
+
+        void Write(const Common::FixedPoint<50, 14> value) {
+            buffer[buffer_pos] = value;
+            buffer_pos = static_cast<u32>((buffer_pos + 1) % buffer.size());
+        }
+
+        s32 sample_count_max{};
+        s32 sample_count{};
+        std::vector<Common::FixedPoint<50, 14>> buffer{};
+        u32 buffer_pos{};
+        Common::FixedPoint<18, 14> decay_rate{};
+    };
+
+    struct State {
+        /* 0x000 */ std::array<s32, 8> unk_000;
+        /* 0x020 */ std::array<DelayLine, MaxChannels> delay_lines;
+        /* 0x0B0 */ Common::FixedPoint<18, 14> feedback_gain;
+        /* 0x0B4 */ Common::FixedPoint<18, 14> delay_feedback_gain;
+        /* 0x0B8 */ Common::FixedPoint<18, 14> delay_feedback_cross_gain;
+        /* 0x0BC */ Common::FixedPoint<18, 14> lowpass_gain;
+        /* 0x0C0 */ Common::FixedPoint<18, 14> lowpass_feedback_gain;
+        /* 0x0C4 */ std::array<Common::FixedPoint<50, 14>, MaxChannels> lowpass_z;
+    };
+    static_assert(sizeof(State) <= sizeof(EffectInfoBase::State),
+                  "DelayInfo::State has the wrong size!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/effect_info_base.h b/src/audio_core/renderer/effect/effect_info_base.h
index 0a9836e75..43d0589cc 100755
--- a/src/audio_core/renderer/effect/effect_info_base.h
+++ b/src/audio_core/renderer/effect/effect_info_base.h
@@ -29,6 +29,7 @@ public:
         BiquadFilter,
         LightLimiter,
         Capture,
+        Compressor,
     };
 
     enum class UsageState {
diff --git a/src/audio_core/renderer/effect/effect_reset.h b/src/audio_core/renderer/effect/effect_reset.h
index 9d496a03e..1ea67e334 100755
--- a/src/audio_core/renderer/effect/effect_reset.h
+++ b/src/audio_core/renderer/effect/effect_reset.h
@@ -3,14 +3,15 @@
 
 #pragma once
 
-#include "audio_core/renderer/effect/effect_aux_info.h"
-#include "audio_core/renderer/effect/effect_biquad_filter_info.h"
-#include "audio_core/renderer/effect/effect_buffer_mixer_info.h"
-#include "audio_core/renderer/effect/effect_capture_info.h"
-#include "audio_core/renderer/effect/effect_delay_info.h"
-#include "audio_core/renderer/effect/effect_i3dl2_info.h"
-#include "audio_core/renderer/effect/effect_light_limiter_info.h"
-#include "audio_core/renderer/effect/effect_reverb_info.h"
+#include "audio_core/renderer/effect/aux_.h"
+#include "audio_core/renderer/effect/biquad_filter.h"
+#include "audio_core/renderer/effect/buffer_mixer.h"
+#include "audio_core/renderer/effect/capture.h"
+#include "audio_core/renderer/effect/compressor.h"
+#include "audio_core/renderer/effect/delay.h"
+#include "audio_core/renderer/effect/i3dl2.h"
+#include "audio_core/renderer/effect/light_limiter.h"
+#include "audio_core/renderer/effect/reverb.h"
 #include "common/common_types.h"
 
 namespace AudioCore::AudioRenderer {
@@ -60,6 +61,10 @@ static void ResetEffect(EffectInfoBase* effect, const EffectInfoBase::Type type)
         std::construct_at<CaptureInfo>(reinterpret_cast<CaptureInfo*>(effect));
         effect->SetType(EffectInfoBase::Type::Capture);
         break;
+    case EffectInfoBase::Type::Compressor:
+        std::construct_at<CompressorInfo>(reinterpret_cast<CompressorInfo*>(effect));
+        effect->SetType(EffectInfoBase::Type::Compressor);
+        break;
     }
 }
 
diff --git a/src/audio_core/renderer/effect/i3dl2.cpp b/src/audio_core/renderer/effect/i3dl2.cpp
new file mode 100755
index 000000000..960b29cfc
--- /dev/null
+++ b/src/audio_core/renderer/effect/i3dl2.cpp
@@ -0,0 +1,94 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/i3dl2.h"
+
+namespace AudioCore::AudioRenderer {
+
+void I3dl2ReverbInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                             const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    if (IsChannelCountValid(in_specific->channel_count_max)) {
+        const auto old_state{params->state};
+        std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+        mix_id = in_params.mix_id;
+        process_order = in_params.process_order;
+        enabled = in_params.enabled;
+
+        if (!IsChannelCountValid(in_specific->channel_count)) {
+            params->channel_count = params->channel_count_max;
+        }
+
+        if (!IsChannelCountValid(in_specific->channel_count) ||
+            old_state != ParameterState::Updated) {
+            params->state = old_state;
+        }
+
+        if (buffer_unmapped || in_params.is_new) {
+            usage_state = UsageState::New;
+            params->state = ParameterState::Initialized;
+            buffer_unmapped = !pool_mapper.TryAttachBuffer(
+                error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+            return;
+        }
+    }
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void I3dl2ReverbInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                             const InParameterVersion2& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    if (IsChannelCountValid(in_specific->channel_count_max)) {
+        const auto old_state{params->state};
+        std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+        mix_id = in_params.mix_id;
+        process_order = in_params.process_order;
+        enabled = in_params.enabled;
+
+        if (!IsChannelCountValid(in_specific->channel_count)) {
+            params->channel_count = params->channel_count_max;
+        }
+
+        if (!IsChannelCountValid(in_specific->channel_count) ||
+            old_state != ParameterState::Updated) {
+            params->state = old_state;
+        }
+
+        if (buffer_unmapped || in_params.is_new) {
+            usage_state = UsageState::New;
+            params->state = ParameterState::Initialized;
+            buffer_unmapped = !pool_mapper.TryAttachBuffer(
+                error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+            return;
+        }
+    }
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void I3dl2ReverbInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+    params->state = ParameterState::Updated;
+}
+
+void I3dl2ReverbInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void I3dl2ReverbInfo::UpdateResultState(EffectResultState& cpu_state,
+                                        EffectResultState& dsp_state) {}
+
+CpuAddr I3dl2ReverbInfo::GetWorkbuffer(s32 index) {
+    return GetSingleBuffer(index);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/i3dl2.h b/src/audio_core/renderer/effect/i3dl2.h
new file mode 100755
index 000000000..7a088a627
--- /dev/null
+++ b/src/audio_core/renderer/effect/i3dl2.h
@@ -0,0 +1,200 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+#include "common/fixed_point.h"
+
+namespace AudioCore::AudioRenderer {
+
+class I3dl2ReverbInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x10 */ char unk10[0x4];
+        /* 0x14 */ u32 sample_rate;
+        /* 0x18 */ f32 room_HF_gain;
+        /* 0x1C */ f32 reference_HF;
+        /* 0x20 */ f32 late_reverb_decay_time;
+        /* 0x24 */ f32 late_reverb_HF_decay_ratio;
+        /* 0x28 */ f32 room_gain;
+        /* 0x2C */ f32 reflection_gain;
+        /* 0x30 */ f32 reverb_gain;
+        /* 0x34 */ f32 late_reverb_diffusion;
+        /* 0x38 */ f32 reflection_delay;
+        /* 0x3C */ f32 late_reverb_delay_time;
+        /* 0x40 */ f32 late_reverb_density;
+        /* 0x44 */ f32 dry_gain;
+        /* 0x48 */ ParameterState state;
+        /* 0x49 */ char unk49[0x3];
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "I3dl2ReverbInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x10 */ char unk10[0x4];
+        /* 0x14 */ u32 sample_rate;
+        /* 0x18 */ f32 room_HF_gain;
+        /* 0x1C */ f32 reference_HF;
+        /* 0x20 */ f32 late_reverb_decay_time;
+        /* 0x24 */ f32 late_reverb_HF_decay_ratio;
+        /* 0x28 */ f32 room_gain;
+        /* 0x2C */ f32 reflection_gain;
+        /* 0x30 */ f32 reverb_gain;
+        /* 0x34 */ f32 late_reverb_diffusion;
+        /* 0x38 */ f32 reflection_delay;
+        /* 0x3C */ f32 late_reverb_delay_time;
+        /* 0x40 */ f32 late_reverb_density;
+        /* 0x44 */ f32 dry_gain;
+        /* 0x48 */ ParameterState state;
+        /* 0x49 */ char unk49[0x3];
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "I3dl2ReverbInfo::ParameterVersion2 has the wrong size!");
+
+    static constexpr u32 MaxDelayLines = 4;
+    static constexpr u32 MaxDelayTaps = 20;
+
+    struct I3dl2DelayLine {
+        void Initialize(const s32 delay_time) {
+            max_delay = delay_time;
+            buffer.resize(delay_time + 1, 0);
+            buffer_end = &buffer[delay_time];
+            output = &buffer[0];
+            SetDelay(delay_time);
+            wet_gain = 0.0f;
+        }
+
+        void SetDelay(const s32 delay_time) {
+            if (max_delay < delay_time) {
+                return;
+            }
+            delay = delay_time;
+            input = &buffer[(output - buffer.data() + delay) % (max_delay + 1)];
+        }
+
+        Common::FixedPoint<50, 14> Tick(const Common::FixedPoint<50, 14> sample) {
+            Write(sample);
+
+            auto out_sample{Read()};
+
+            output++;
+            if (output >= buffer_end) {
+                output = buffer.data();
+            }
+
+            return out_sample;
+        }
+
+        Common::FixedPoint<50, 14> Read() {
+            return *output;
+        }
+
+        void Write(const Common::FixedPoint<50, 14> sample) {
+            *(input++) = sample;
+            if (input >= buffer_end) {
+                input = buffer.data();
+            }
+        }
+
+        Common::FixedPoint<50, 14> TapOut(const s32 index) {
+            auto out{input - (index + 1)};
+            if (out < buffer.data()) {
+                out += max_delay + 1;
+            }
+            return *out;
+        }
+
+        std::vector<Common::FixedPoint<50, 14>> buffer{};
+        Common::FixedPoint<50, 14>* buffer_end{};
+        s32 max_delay{};
+        Common::FixedPoint<50, 14>* input{};
+        Common::FixedPoint<50, 14>* output{};
+        s32 delay{};
+        f32 wet_gain{};
+    };
+
+    struct State {
+        f32 lowpass_0;
+        f32 lowpass_1;
+        f32 lowpass_2;
+        I3dl2DelayLine early_delay_line;
+        std::array<s32, MaxDelayTaps> early_tap_steps;
+        f32 early_gain;
+        f32 late_gain;
+        s32 early_to_late_taps;
+        std::array<I3dl2DelayLine, MaxDelayLines> fdn_delay_lines;
+        std::array<I3dl2DelayLine, MaxDelayLines> decay_delay_lines0;
+        std::array<I3dl2DelayLine, MaxDelayLines> decay_delay_lines1;
+        f32 last_reverb_echo;
+        I3dl2DelayLine center_delay_line;
+        std::array<std::array<f32, 3>, MaxDelayLines> lowpass_coeff;
+        std::array<f32, MaxDelayLines> shelf_filter;
+        f32 dry_gain;
+    };
+    static_assert(sizeof(State) <= sizeof(EffectInfoBase::State),
+                  "I3dl2ReverbInfo::State is too large!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/light_limiter.cpp b/src/audio_core/renderer/effect/light_limiter.cpp
new file mode 100755
index 000000000..1635a952d
--- /dev/null
+++ b/src/audio_core/renderer/effect/light_limiter.cpp
@@ -0,0 +1,81 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/light_limiter.h"
+
+namespace AudioCore::AudioRenderer {
+
+void LightLimiterInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                              const InParameterVersion1& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    if (buffer_unmapped || in_params.is_new) {
+        usage_state = UsageState::New;
+        params->state = ParameterState::Initialized;
+        buffer_unmapped = !pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+    } else {
+        error_info.error_code = ResultSuccess;
+        error_info.address = CpuAddr(0);
+    }
+}
+
+void LightLimiterInfo::Update(BehaviorInfo::ErrorInfo& error_info,
+                              const InParameterVersion2& in_params, const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+    mix_id = in_params.mix_id;
+    process_order = in_params.process_order;
+    enabled = in_params.enabled;
+
+    if (buffer_unmapped || in_params.is_new) {
+        usage_state = UsageState::New;
+        params->state = ParameterState::Initialized;
+        buffer_unmapped = !pool_mapper.TryAttachBuffer(
+            error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+    } else {
+        error_info.error_code = ResultSuccess;
+        error_info.address = CpuAddr(0);
+    }
+}
+
+void LightLimiterInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+    params->state = ParameterState::Updated;
+    params->statistics_reset_required = false;
+}
+
+void LightLimiterInfo::InitializeResultState(EffectResultState& result_state) {
+    auto result_state_{reinterpret_cast<StatisticsInternal*>(result_state.state.data())};
+
+    result_state_->channel_max_sample.fill(0);
+    result_state_->channel_compression_gain_min.fill(1.0f);
+}
+
+void LightLimiterInfo::UpdateResultState(EffectResultState& cpu_state,
+                                         EffectResultState& dsp_state) {
+    auto cpu_statistics{reinterpret_cast<StatisticsInternal*>(cpu_state.state.data())};
+    auto dsp_statistics{reinterpret_cast<StatisticsInternal*>(dsp_state.state.data())};
+
+    *cpu_statistics = *dsp_statistics;
+}
+
+CpuAddr LightLimiterInfo::GetWorkbuffer(s32 index) {
+    return GetSingleBuffer(index);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/light_limiter.h b/src/audio_core/renderer/effect/light_limiter.h
new file mode 100755
index 000000000..338d67bbc
--- /dev/null
+++ b/src/audio_core/renderer/effect/light_limiter.h
@@ -0,0 +1,138 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+#include "common/fixed_point.h"
+
+namespace AudioCore::AudioRenderer {
+
+class LightLimiterInfo : public EffectInfoBase {
+public:
+    enum class ProcessingMode {
+        Mode0,
+        Mode1,
+    };
+
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x0C */ u32 sample_rate;
+        /* 0x14 */ s32 look_ahead_time_max;
+        /* 0x18 */ s32 attack_time;
+        /* 0x1C */ s32 release_time;
+        /* 0x20 */ s32 look_ahead_time;
+        /* 0x24 */ f32 attack_coeff;
+        /* 0x28 */ f32 release_coeff;
+        /* 0x2C */ f32 threshold;
+        /* 0x30 */ f32 input_gain;
+        /* 0x34 */ f32 output_gain;
+        /* 0x38 */ s32 look_ahead_samples_min;
+        /* 0x3C */ s32 look_ahead_samples_max;
+        /* 0x40 */ ParameterState state;
+        /* 0x41 */ bool statistics_enabled;
+        /* 0x42 */ bool statistics_reset_required;
+        /* 0x43 */ ProcessingMode processing_mode;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "LightLimiterInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x0C */ u32 sample_rate;
+        /* 0x14 */ s32 look_ahead_time_max;
+        /* 0x18 */ s32 attack_time;
+        /* 0x1C */ s32 release_time;
+        /* 0x20 */ s32 look_ahead_time;
+        /* 0x24 */ f32 attack_coeff;
+        /* 0x28 */ f32 release_coeff;
+        /* 0x2C */ f32 threshold;
+        /* 0x30 */ f32 input_gain;
+        /* 0x34 */ f32 output_gain;
+        /* 0x38 */ s32 look_ahead_samples_min;
+        /* 0x3C */ s32 look_ahead_samples_max;
+        /* 0x40 */ ParameterState state;
+        /* 0x41 */ bool statistics_enabled;
+        /* 0x42 */ bool statistics_reset_required;
+        /* 0x43 */ ProcessingMode processing_mode;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "LightLimiterInfo::ParameterVersion2 has the wrong size!");
+
+    struct State {
+        std::array<Common::FixedPoint<49, 15>, MaxChannels> samples_average;
+        std::array<Common::FixedPoint<49, 15>, MaxChannels> compression_gain;
+        std::array<s32, MaxChannels> look_ahead_sample_offsets;
+        std::array<std::vector<Common::FixedPoint<49, 15>>, MaxChannels> look_ahead_sample_buffers;
+    };
+    static_assert(sizeof(State) <= sizeof(EffectInfoBase::State),
+                  "LightLimiterInfo::State has the wrong size!");
+
+    struct StatisticsInternal {
+        /* 0x00 */ std::array<f32, MaxChannels> channel_max_sample;
+        /* 0x18 */ std::array<f32, MaxChannels> channel_compression_gain_min;
+    };
+    static_assert(sizeof(StatisticsInternal) == 0x30,
+                  "LightLimiterInfo::StatisticsInternal has the wrong size!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new limiter statistics result state. Version 2 only.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side limiter statistics with the ADSP-side one. Version 2 only.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/reverb.cpp b/src/audio_core/renderer/effect/reverb.cpp
new file mode 100755
index 000000000..2d32383d0
--- /dev/null
+++ b/src/audio_core/renderer/effect/reverb.cpp
@@ -0,0 +1,93 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "audio_core/renderer/effect/reverb.h"
+
+namespace AudioCore::AudioRenderer {
+
+void ReverbInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                        const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion1*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+
+    if (IsChannelCountValid(in_specific->channel_count_max)) {
+        const auto old_state{params->state};
+        std::memcpy(params, in_specific, sizeof(ParameterVersion1));
+        mix_id = in_params.mix_id;
+        process_order = in_params.process_order;
+        enabled = in_params.enabled;
+
+        if (!IsChannelCountValid(in_specific->channel_count)) {
+            params->channel_count = params->channel_count_max;
+        }
+
+        if (!IsChannelCountValid(in_specific->channel_count) ||
+            old_state != ParameterState::Updated) {
+            params->state = old_state;
+        }
+
+        if (buffer_unmapped || in_params.is_new) {
+            usage_state = UsageState::New;
+            params->state = ParameterState::Initialized;
+            buffer_unmapped = !pool_mapper.TryAttachBuffer(
+                error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+            return;
+        }
+    }
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void ReverbInfo::Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                        const PoolMapper& pool_mapper) {
+    auto in_specific{reinterpret_cast<const ParameterVersion2*>(in_params.specific.data())};
+    auto params{reinterpret_cast<ParameterVersion2*>(parameter.data())};
+
+    if (IsChannelCountValid(in_specific->channel_count_max)) {
+        const auto old_state{params->state};
+        std::memcpy(params, in_specific, sizeof(ParameterVersion2));
+        mix_id = in_params.mix_id;
+        process_order = in_params.process_order;
+        enabled = in_params.enabled;
+
+        if (!IsChannelCountValid(in_specific->channel_count)) {
+            params->channel_count = params->channel_count_max;
+        }
+
+        if (!IsChannelCountValid(in_specific->channel_count) ||
+            old_state != ParameterState::Updated) {
+            params->state = old_state;
+        }
+
+        if (buffer_unmapped || in_params.is_new) {
+            usage_state = UsageState::New;
+            params->state = ParameterState::Initialized;
+            buffer_unmapped = !pool_mapper.TryAttachBuffer(
+                error_info, workbuffers[0], in_params.workbuffer, in_params.workbuffer_size);
+            return;
+        }
+    }
+    error_info.error_code = ResultSuccess;
+    error_info.address = CpuAddr(0);
+}
+
+void ReverbInfo::UpdateForCommandGeneration() {
+    if (enabled) {
+        usage_state = UsageState::Enabled;
+    } else {
+        usage_state = UsageState::Disabled;
+    }
+
+    auto params{reinterpret_cast<ParameterVersion1*>(parameter.data())};
+    params->state = ParameterState::Updated;
+}
+
+void ReverbInfo::InitializeResultState(EffectResultState& result_state) {}
+
+void ReverbInfo::UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) {}
+
+CpuAddr ReverbInfo::GetWorkbuffer(s32 index) {
+    return GetSingleBuffer(index);
+}
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/effect/reverb.h b/src/audio_core/renderer/effect/reverb.h
new file mode 100755
index 000000000..b4df9f6ef
--- /dev/null
+++ b/src/audio_core/renderer/effect/reverb.h
@@ -0,0 +1,190 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "audio_core/common/common.h"
+#include "audio_core/renderer/effect/effect_info_base.h"
+#include "common/common_types.h"
+#include "common/fixed_point.h"
+
+namespace AudioCore::AudioRenderer {
+
+class ReverbInfo : public EffectInfoBase {
+public:
+    struct ParameterVersion1 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x10 */ u32 sample_rate;
+        /* 0x14 */ u32 early_mode;
+        /* 0x18 */ s32 early_gain;
+        /* 0x1C */ s32 pre_delay;
+        /* 0x20 */ s32 late_mode;
+        /* 0x24 */ s32 late_gain;
+        /* 0x28 */ s32 decay_time;
+        /* 0x2C */ s32 high_freq_Decay_ratio;
+        /* 0x30 */ s32 colouration;
+        /* 0x34 */ s32 base_gain;
+        /* 0x38 */ s32 wet_gain;
+        /* 0x3C */ s32 dry_gain;
+        /* 0x40 */ ParameterState state;
+    };
+    static_assert(sizeof(ParameterVersion1) <= sizeof(EffectInfoBase::InParameterVersion1),
+                  "ReverbInfo::ParameterVersion1 has the wrong size!");
+
+    struct ParameterVersion2 {
+        /* 0x00 */ std::array<s8, MaxChannels> inputs;
+        /* 0x06 */ std::array<s8, MaxChannels> outputs;
+        /* 0x0C */ u16 channel_count_max;
+        /* 0x0E */ u16 channel_count;
+        /* 0x10 */ u32 sample_rate;
+        /* 0x14 */ u32 early_mode;
+        /* 0x18 */ s32 early_gain;
+        /* 0x1C */ s32 pre_delay;
+        /* 0x20 */ s32 late_mode;
+        /* 0x24 */ s32 late_gain;
+        /* 0x28 */ s32 decay_time;
+        /* 0x2C */ s32 high_freq_decay_ratio;
+        /* 0x30 */ s32 colouration;
+        /* 0x34 */ s32 base_gain;
+        /* 0x38 */ s32 wet_gain;
+        /* 0x3C */ s32 dry_gain;
+        /* 0x40 */ ParameterState state;
+    };
+    static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2),
+                  "ReverbInfo::ParameterVersion2 has the wrong size!");
+
+    static constexpr u32 MaxDelayLines = 4;
+    static constexpr u32 MaxDelayTaps = 10;
+    static constexpr u32 NumEarlyModes = 5;
+    static constexpr u32 NumLateModes = 5;
+
+    struct ReverbDelayLine {
+        void Initialize(const s32 delay_time, const f32 decay_rate) {
+            buffer.resize(delay_time + 1, 0);
+            buffer_end = &buffer[delay_time];
+            output = &buffer[0];
+            decay = decay_rate;
+            sample_count_max = delay_time;
+            SetDelay(delay_time);
+        }
+
+        void SetDelay(const s32 delay_time) {
+            if (sample_count_max < delay_time) {
+                return;
+            }
+            sample_count = delay_time;
+            input = &buffer[(output - buffer.data() + sample_count) % (sample_count_max + 1)];
+        }
+
+        Common::FixedPoint<50, 14> Tick(const Common::FixedPoint<50, 14> sample) {
+            Write(sample);
+
+            auto out_sample{Read()};
+
+            output++;
+            if (output >= buffer_end) {
+                output = buffer.data();
+            }
+
+            return out_sample;
+        }
+
+        Common::FixedPoint<50, 14> Read() {
+            return *output;
+        }
+
+        void Write(const Common::FixedPoint<50, 14> sample) {
+            *(input++) = sample;
+            if (input >= buffer_end) {
+                input = buffer.data();
+            }
+        }
+
+        Common::FixedPoint<50, 14> TapOut(const s32 index) {
+            auto out{input - (index + 1)};
+            if (out < buffer.data()) {
+                out += sample_count;
+            }
+            return *out;
+        }
+
+        s32 sample_count{};
+        s32 sample_count_max{};
+        std::vector<Common::FixedPoint<50, 14>> buffer{};
+        Common::FixedPoint<50, 14>* buffer_end;
+        Common::FixedPoint<50, 14>* input{};
+        Common::FixedPoint<50, 14>* output{};
+        Common::FixedPoint<50, 14> decay{};
+    };
+
+    struct State {
+        ReverbDelayLine pre_delay_line;
+        ReverbDelayLine center_delay_line;
+        std::array<s32, MaxDelayTaps> early_delay_times;
+        std::array<Common::FixedPoint<50, 14>, MaxDelayTaps> early_gains;
+        s32 pre_delay_time;
+        std::array<ReverbDelayLine, MaxDelayLines> decay_delay_lines;
+        std::array<ReverbDelayLine, MaxDelayLines> fdn_delay_lines;
+        std::array<Common::FixedPoint<50, 14>, MaxDelayLines> hf_decay_gain;
+        std::array<Common::FixedPoint<50, 14>, MaxDelayLines> hf_decay_prev_gain;
+        std::array<Common::FixedPoint<50, 14>, MaxDelayLines> prev_feedback_output;
+    };
+    static_assert(sizeof(State) <= sizeof(EffectInfoBase::State),
+                  "ReverbInfo::State is too large!");
+
+    /**
+     * Update the info with new parameters, version 1.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion1& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info with new parameters, version 2.
+     *
+     * @param error_info  - Used to write call result code.
+     * @param in_params   - New parameters to update the info with.
+     * @param pool_mapper - Pool for mapping buffers.
+     */
+    void Update(BehaviorInfo::ErrorInfo& error_info, const InParameterVersion2& in_params,
+                const PoolMapper& pool_mapper) override;
+
+    /**
+     * Update the info after command generation. Usually only changes its state.
+     */
+    void UpdateForCommandGeneration() override;
+
+    /**
+     * Initialize a new result state. Version 2 only, unused.
+     *
+     * @param result_state - Result state to initialize.
+     */
+    void InitializeResultState(EffectResultState& result_state) override;
+
+    /**
+     * Update the host-side state with the ADSP-side state. Version 2 only, unused.
+     *
+     * @param cpu_state - Host-side result state to update.
+     * @param dsp_state - AudioRenderer-side result state to update from.
+     */
+    void UpdateResultState(EffectResultState& cpu_state, EffectResultState& dsp_state) override;
+
+    /**
+     * Get a workbuffer assigned to this effect with the given index.
+     *
+     * @param index - Workbuffer index.
+     * @return Address of the buffer.
+     */
+    CpuAddr GetWorkbuffer(s32 index) override;
+};
+
+} // namespace AudioCore::AudioRenderer
diff --git a/src/audio_core/renderer/performance/performance_detail.h b/src/audio_core/renderer/performance/performance_detail.h
index d9069ff78..3a4897e60 100755
--- a/src/audio_core/renderer/performance/performance_detail.h
+++ b/src/audio_core/renderer/performance/performance_detail.h
@@ -9,19 +9,20 @@
 namespace AudioCore::AudioRenderer {
 
 enum class PerformanceDetailType : u8 {
-    /*  0 */ Invalid,
-    /*  1 */ Unk1,
-    /*  2 */ Unk2,
-    /*  3 */ Unk3,
-    /*  4 */ Unk4,
-    /*  5 */ Unk5,
-    /*  6 */ Unk6,
-    /*  7 */ Unk7,
-    /*  8 */ Unk8,
-    /*  9 */ Unk9,
-    /* 10 */ Unk10,
-    /* 11 */ Unk11,
-    /* 12 */ Unk12,
+    Invalid,
+    Unk1,
+    Unk2,
+    Unk3,
+    Unk4,
+    Unk5,
+    Unk6,
+    Unk7,
+    Unk8,
+    Unk9,
+    Unk10,
+    Unk11,
+    Unk12,
+    Unk13,
 };
 
 struct PerformanceDetailVersion1 {
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 5a4938270..7a217969e 100755
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -367,7 +367,11 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
 
     // nn::audio::dsp::FlushDataCache(transferMemory, transferMemorySize);
 
-    if (behavior.IsCommandProcessingTimeEstimatorVersion4Supported()) {
+    if (behavior.IsCommandProcessingTimeEstimatorVersion5Supported()) {
+        command_processing_time_estimator =
+            std::make_unique<CommandProcessingTimeEstimatorVersion5>(sample_count,
+                                                                     mix_buffer_count);
+    } else if (behavior.IsCommandProcessingTimeEstimatorVersion4Supported()) {
         command_processing_time_estimator =
             std::make_unique<CommandProcessingTimeEstimatorVersion4>(sample_count,
                                                                      mix_buffer_count);
@@ -595,13 +599,13 @@ void System::SendCommandToDsp() {
                 memory_pool_info.Translate(CpuAddr(command_workbuffer.data()), command_size)};
 
             auto time_limit_percent{70.0f};
-            if (behavior.IsAudioRenererProcessingTimeLimit80PercentSupported()) {
+            if (behavior.IsAudioRendererProcessingTimeLimit80PercentSupported()) {
                 time_limit_percent = 80.0f;
-            } else if (behavior.IsAudioRenererProcessingTimeLimit75PercentSupported()) {
+            } else if (behavior.IsAudioRendererProcessingTimeLimit75PercentSupported()) {
                 time_limit_percent = 75.0f;
             } else {
                 // result ignored and 70 is used anyway
-                behavior.IsAudioRenererProcessingTimeLimit70PercentSupported();
+                behavior.IsAudioRendererProcessingTimeLimit70PercentSupported();
                 time_limit_percent = 70.0f;
             }
 
@@ -698,13 +702,14 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
 
     if (drop_voice) {
         f32 time_limit_percent{70.0f};
-        if (render_context.behavior->IsAudioRenererProcessingTimeLimit80PercentSupported()) {
+        if (render_context.behavior->IsAudioRendererProcessingTimeLimit80PercentSupported()) {
             time_limit_percent = 80.0f;
-        } else if (render_context.behavior->IsAudioRenererProcessingTimeLimit75PercentSupported()) {
+        } else if (render_context.behavior
+                       ->IsAudioRendererProcessingTimeLimit75PercentSupported()) {
             time_limit_percent = 75.0f;
         } else {
             // result is ignored
-            render_context.behavior->IsAudioRenererProcessingTimeLimit70PercentSupported();
+            render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported();
             time_limit_percent = 70.0f;
         }
         const auto time_limit{static_cast<u32>(
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index aca8c0590..381a66ba5 100755
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -107,7 +107,7 @@ private:
     }
 
     void RequestUpdate(Kernel::HLERequestContext& ctx) {
-        LOG_DEBUG(Service_Audio, "called");
+        LOG_TRACE(Service_Audio, "called");
 
         std::vector<u8> input{ctx.ReadBuffer(0)};
 
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 75da659e5..4f2ed2d52 100755
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -298,7 +298,7 @@ void HwOpus::OpenHardwareOpusDecoderEx(Kernel::HLERequestContext& ctx) {
     const auto sample_rate = rp.Pop<u32>();
     const auto channel_count = rp.Pop<u32>();
 
-    LOG_CRITICAL(Audio, "called sample_rate={}, channel_count={}", sample_rate, channel_count);
+    LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}", sample_rate, channel_count);
 
     ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
                    sample_rate == 12000 || sample_rate == 8000,