From 380658c21d39cf05ac765a9284da246388cca2a4 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Jul 2020 21:59:14 +1000 Subject: audio_core: Apollo Part 1, AudioRenderer refactor --- src/audio_core/effect_context.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/audio_core/effect_context.cpp (limited to 'src/audio_core/effect_context.cpp') diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp new file mode 100644 index 000000000..c42e71c1c --- /dev/null +++ b/src/audio_core/effect_context.cpp @@ -0,0 +1,39 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "audio_core/effect_context.h" + +namespace AudioCore { +EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) { + for (std::size_t i = 0; i < effect_count; i++) { + effects.push_back(std::make_unique()); + } +} +EffectContext::~EffectContext() = default; + +std::size_t EffectContext::GetCount() const { + return effect_count; +} + +EffectBase* EffectContext::GetInfo(std::size_t i) { + return effects.at(i).get(); +} + +EffectStubbed::EffectStubbed() : EffectBase::EffectBase() {} +EffectStubbed::~EffectStubbed() = default; + +void EffectStubbed::Update(EffectInfo::InParams& in_params) { + if (in_params.is_new) { + usage = UsageStatus::New; + } +} + +EffectBase::EffectBase() = default; +EffectBase::~EffectBase() = default; + +UsageStatus EffectBase::GetUsage() const { + return usage; +} + +} // namespace AudioCore -- cgit v1.2.3 From b924c71822225b6de396b687debb93c1af59e2d6 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 25 Jul 2020 12:32:05 +1000 Subject: Address issues --- src/audio_core/effect_context.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/audio_core/effect_context.cpp') diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index c42e71c1c..2497d2f32 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp @@ -2,13 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "audio_core/effect_context.h" namespace AudioCore { EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) { - for (std::size_t i = 0; i < effect_count; i++) { - effects.push_back(std::make_unique()); - } + effects.reserve(effect_count); + std::generate_n(std::back_inserter(effects), effect_count, + [] { return std::make_unique(); }); } EffectContext::~EffectContext() = default; @@ -20,6 +21,10 @@ EffectBase* EffectContext::GetInfo(std::size_t i) { return effects.at(i).get(); } +const EffectBase* EffectContext::GetInfo(std::size_t i) const { + return effects.at(i).get(); +} + EffectStubbed::EffectStubbed() : EffectBase::EffectBase() {} EffectStubbed::~EffectStubbed() = default; -- cgit v1.2.3 From 80ac1331b545d993aa7c205dc24f8b20a4d6d44e Mon Sep 17 00:00:00 2001 From: David Marcec Date: Mon, 17 Aug 2020 01:23:55 +1000 Subject: Preliminary effects --- src/audio_core/effect_context.cpp | 271 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 263 insertions(+), 8 deletions(-) (limited to 'src/audio_core/effect_context.cpp') diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index 2497d2f32..adfec3df5 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp @@ -6,6 +6,12 @@ #include "audio_core/effect_context.h" namespace AudioCore { +namespace { +bool ValidChannelCountForEffect(s32 channel_count) { + return channel_count == 1 || channel_count == 2 || channel_count == 4 || channel_count == 6; +} +} // namespace + EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) { effects.reserve(effect_count); std::generate_n(std::back_inserter(effects), effect_count, @@ -21,24 +27,273 @@ EffectBase* EffectContext::GetInfo(std::size_t i) { return effects.at(i).get(); } +EffectBase* EffectContext::RetargetEffect(std::size_t i, EffectType effect) { + switch (effect) { + case EffectType::Invalid: + effects[i] = std::make_unique(); + break; + case EffectType::BufferMixer: + effects[i] = std::make_unique(); + break; + case EffectType::Aux: + effects[i] = std::make_unique(); + break; + case EffectType::Delay: + effects[i] = std::make_unique(); + break; + case EffectType::Reverb: + effects[i] = std::make_unique(); + break; + case EffectType::I3dl2Reverb: + effects[i] = std::make_unique(); + break; + case EffectType::BiquadFilter: + effects[i] = std::make_unique(); + break; + default: + UNREACHABLE_MSG("Unimplemented effect {}", effect); + effects[i] = std::make_unique(); + } + return GetInfo(i); +} + const EffectBase* EffectContext::GetInfo(std::size_t i) const { return effects.at(i).get(); } -EffectStubbed::EffectStubbed() : EffectBase::EffectBase() {} +EffectStubbed::EffectStubbed() : EffectBase::EffectBase(EffectType::Invalid) {} EffectStubbed::~EffectStubbed() = default; -void EffectStubbed::Update(EffectInfo::InParams& in_params) { - if (in_params.is_new) { - usage = UsageStatus::New; - } -} +void EffectStubbed::Update(EffectInfo::InParams& in_params) {} +void EffectStubbed::UpdateForCommandGeneration() {} -EffectBase::EffectBase() = default; +EffectBase::EffectBase(EffectType effect_type) : effect_type(effect_type) {} EffectBase::~EffectBase() = default; -UsageStatus EffectBase::GetUsage() const { +UsageState EffectBase::GetUsage() const { return usage; } +EffectType EffectBase::GetType() const { + return effect_type; +} + +bool EffectBase::IsEnabled() const { + return enabled; +} + +s32 EffectBase::GetMixID() const { + return mix_id; +} + +s32 EffectBase::GetProcessingOrder() const { + return processing_order; +} + +EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric::EffectGeneric(EffectType::I3dl2Reverb) {} +EffectI3dl2Reverb::~EffectI3dl2Reverb() = default; + +void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) { + auto& internal_params = GetParams(); + const auto* reverb_params = reinterpret_cast(in_params.raw.data()); + if (!ValidChannelCountForEffect(reverb_params->max_channels)) { + UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels); + return; + } + + const auto last_status = internal_params.status; + mix_id = in_params.mix_id; + processing_order = in_params.processing_order; + internal_params = *reverb_params; + if (!ValidChannelCountForEffect(reverb_params->channel_count)) { + internal_params.channel_count = internal_params.max_channels; + } + enabled = in_params.is_enabled; + if (last_status != ParameterStatus::Updated) { + internal_params.status = last_status; + } + + if (in_params.is_new || skipped) { + usage = UsageState::Initialized; + internal_params.status = ParameterStatus::Initialized; + skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; + } +} + +void EffectI3dl2Reverb::UpdateForCommandGeneration() { + if (enabled) { + usage = UsageState::Running; + } else { + usage = UsageState::Stopped; + } + GetParams().status = ParameterStatus::Updated; +} + +EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric::EffectGeneric(EffectType::BiquadFilter) {} +EffectBiquadFilter::~EffectBiquadFilter() = default; + +void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) { + auto& internal_params = GetParams(); + const auto* biquad_params = reinterpret_cast(in_params.raw.data()); + mix_id = in_params.mix_id; + processing_order = in_params.processing_order; + internal_params = *biquad_params; + enabled = in_params.is_enabled; +} + +void EffectBiquadFilter::UpdateForCommandGeneration() { + if (enabled) { + usage = UsageState::Running; + } else { + usage = UsageState::Stopped; + } + GetParams().status = ParameterStatus::Updated; +} + +EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {} +EffectAuxInfo::~EffectAuxInfo() = default; + +void EffectAuxInfo::Update(EffectInfo::InParams& in_params) { + const auto* aux_params = reinterpret_cast(in_params.raw.data()); + mix_id = in_params.mix_id; + processing_order = in_params.processing_order; + GetParams() = *aux_params; + enabled = in_params.is_enabled; + + if (in_params.is_new || skipped) { + skipped = aux_params->send_buffer_info == 0 || aux_params->return_buffer_info == 0; + if (skipped) { + return; + } + + // There's two AuxInfos which are an identical size, the first one is managed by the cpu, + // the second is managed by the dsp. All we care about is managing the DSP one + send_info = aux_params->send_buffer_info + sizeof(AuxInfoDSP); + send_buffer = aux_params->send_buffer_info + (sizeof(AuxInfoDSP) * 2); + + recv_info = aux_params->return_buffer_info + sizeof(AuxInfoDSP); + recv_buffer = aux_params->return_buffer_info + (sizeof(AuxInfoDSP) * 2); + } +} + +void EffectAuxInfo::UpdateForCommandGeneration() { + if (enabled) { + usage = UsageState::Running; + } else { + usage = UsageState::Stopped; + } +} + +const VAddr EffectAuxInfo::GetSendInfo() const { + return send_info; +} + +const VAddr EffectAuxInfo::GetSendBuffer() const { + return send_buffer; +} + +const VAddr EffectAuxInfo::GetRecvInfo() const { + return recv_info; +} + +const VAddr EffectAuxInfo::GetRecvBuffer() const { + return recv_buffer; +} + +EffectDelay::EffectDelay() : EffectGeneric::EffectGeneric(EffectType::Delay) {} +EffectDelay::~EffectDelay() = default; + +void EffectDelay::Update(EffectInfo::InParams& in_params) { + const auto* delay_params = reinterpret_cast(in_params.raw.data()); + auto& internal_params = GetParams(); + if (!ValidChannelCountForEffect(delay_params->max_channels)) { + return; + } + + const auto last_status = internal_params.status; + mix_id = in_params.mix_id; + processing_order = in_params.processing_order; + internal_params = *delay_params; + if (!ValidChannelCountForEffect(delay_params->channels)) { + internal_params.channels = internal_params.max_channels; + } + enabled = in_params.is_enabled; + + if (last_status != ParameterStatus::Updated) { + internal_params.status = last_status; + } + + if (in_params.is_new || skipped) { + usage = UsageState::Initialized; + internal_params.status = ParameterStatus::Initialized; + skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; + } +} + +void EffectDelay::UpdateForCommandGeneration() { + if (enabled) { + usage = UsageState::Running; + } else { + usage = UsageState::Stopped; + } + GetParams().status = ParameterStatus::Updated; +} + +EffectBufferMixer::EffectBufferMixer() : EffectGeneric::EffectGeneric(EffectType::BufferMixer) {} +EffectBufferMixer::~EffectBufferMixer() = default; + +void EffectBufferMixer::Update(EffectInfo::InParams& in_params) { + mix_id = in_params.mix_id; + processing_order = in_params.processing_order; + GetParams() = *reinterpret_cast(in_params.raw.data()); + enabled = in_params.is_enabled; +} + +void EffectBufferMixer::UpdateForCommandGeneration() { + if (enabled) { + usage = UsageState::Running; + } else { + usage = UsageState::Stopped; + } +} + +EffectReverb::EffectReverb() : EffectGeneric::EffectGeneric(EffectType::Reverb) {} +EffectReverb::~EffectReverb() = default; + +void EffectReverb::Update(EffectInfo::InParams& in_params) { + const auto* reverb_params = reinterpret_cast(in_params.raw.data()); + auto& internal_params = GetParams(); + if (!ValidChannelCountForEffect(reverb_params->max_channels)) { + return; + } + + const auto last_status = internal_params.status; + mix_id = in_params.mix_id; + processing_order = in_params.processing_order; + internal_params = *reverb_params; + if (!ValidChannelCountForEffect(reverb_params->channels)) { + internal_params.channels = internal_params.max_channels; + } + enabled = in_params.is_enabled; + + if (last_status != ParameterStatus::Updated) { + internal_params.status = last_status; + } + + if (in_params.is_new || skipped) { + usage = UsageState::Initialized; + internal_params.status = ParameterStatus::Initialized; + skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; + } +} + +void EffectReverb::UpdateForCommandGeneration() { + if (enabled) { + usage = UsageState::Running; + } else { + usage = UsageState::Stopped; + } + GetParams().status = ParameterStatus::Updated; +} + } // namespace AudioCore -- cgit v1.2.3