| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- // Copyright 2020 yuzu Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #include <algorithm>
- #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,
- [] { return std::make_unique<EffectStubbed>(); });
- }
- EffectContext::~EffectContext() = default;
- std::size_t EffectContext::GetCount() const {
- return effect_count;
- }
- 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<EffectStubbed>();
- break;
- case EffectType::BufferMixer:
- effects[i] = std::make_unique<EffectBufferMixer>();
- break;
- case EffectType::Aux:
- effects[i] = std::make_unique<EffectAuxInfo>();
- break;
- case EffectType::Delay:
- effects[i] = std::make_unique<EffectDelay>();
- break;
- case EffectType::Reverb:
- effects[i] = std::make_unique<EffectReverb>();
- break;
- case EffectType::I3dl2Reverb:
- effects[i] = std::make_unique<EffectI3dl2Reverb>();
- break;
- case EffectType::BiquadFilter:
- effects[i] = std::make_unique<EffectBiquadFilter>();
- break;
- default:
- UNREACHABLE_MSG("Unimplemented effect {}", effect);
- effects[i] = std::make_unique<EffectStubbed>();
- }
- return GetInfo(i);
- }
- const EffectBase* EffectContext::GetInfo(std::size_t i) const {
- return effects.at(i).get();
- }
- EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {}
- EffectStubbed::~EffectStubbed() = default;
- void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {}
- void EffectStubbed::UpdateForCommandGeneration() {}
- EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {}
- EffectBase::~EffectBase() = default;
- 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;
- }
- std::vector<u8>& EffectBase::GetWorkBuffer() {
- return work_buffer;
- }
- const std::vector<u8>& EffectBase::GetWorkBuffer() const {
- return work_buffer;
- }
- EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {}
- EffectI3dl2Reverb::~EffectI3dl2Reverb() = default;
- void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
- auto& params = GetParams();
- const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(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 = params.status;
- mix_id = in_params.mix_id;
- processing_order = in_params.processing_order;
- params = *reverb_params;
- if (!ValidChannelCountForEffect(reverb_params->channel_count)) {
- params.channel_count = params.max_channels;
- }
- enabled = in_params.is_enabled;
- if (last_status != ParameterStatus::Updated) {
- params.status = last_status;
- }
- if (in_params.is_new || skipped) {
- usage = UsageState::Initialized;
- params.status = ParameterStatus::Initialized;
- skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
- if (!skipped) {
- auto& cur_work_buffer = GetWorkBuffer();
- // Has two buffers internally
- cur_work_buffer.resize(in_params.buffer_size * 2);
- std::fill(cur_work_buffer.begin(), cur_work_buffer.end(), 0);
- }
- }
- }
- void EffectI3dl2Reverb::UpdateForCommandGeneration() {
- if (enabled) {
- usage = UsageState::Running;
- } else {
- usage = UsageState::Stopped;
- }
- GetParams().status = ParameterStatus::Updated;
- }
- I3dl2ReverbState& EffectI3dl2Reverb::GetState() {
- return state;
- }
- const I3dl2ReverbState& EffectI3dl2Reverb::GetState() const {
- return state;
- }
- EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {}
- EffectBiquadFilter::~EffectBiquadFilter() = default;
- void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) {
- auto& params = GetParams();
- const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data());
- mix_id = in_params.mix_id;
- processing_order = in_params.processing_order;
- 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(EffectType::Aux) {}
- EffectAuxInfo::~EffectAuxInfo() = default;
- void EffectAuxInfo::Update(EffectInfo::InParams& in_params) {
- const auto* aux_params = reinterpret_cast<AuxInfo*>(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;
- }
- }
- VAddr EffectAuxInfo::GetSendInfo() const {
- return send_info;
- }
- VAddr EffectAuxInfo::GetSendBuffer() const {
- return send_buffer;
- }
- VAddr EffectAuxInfo::GetRecvInfo() const {
- return recv_info;
- }
- VAddr EffectAuxInfo::GetRecvBuffer() const {
- return recv_buffer;
- }
- EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {}
- EffectDelay::~EffectDelay() = default;
- void EffectDelay::Update(EffectInfo::InParams& in_params) {
- const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data());
- auto& params = GetParams();
- if (!ValidChannelCountForEffect(delay_params->max_channels)) {
- return;
- }
- const auto last_status = params.status;
- mix_id = in_params.mix_id;
- processing_order = in_params.processing_order;
- params = *delay_params;
- if (!ValidChannelCountForEffect(delay_params->channels)) {
- params.channels = params.max_channels;
- }
- enabled = in_params.is_enabled;
- if (last_status != ParameterStatus::Updated) {
- params.status = last_status;
- }
- if (in_params.is_new || skipped) {
- usage = UsageState::Initialized;
- 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(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<BufferMixerParams*>(in_params.raw.data());
- enabled = in_params.is_enabled;
- }
- void EffectBufferMixer::UpdateForCommandGeneration() {
- if (enabled) {
- usage = UsageState::Running;
- } else {
- usage = UsageState::Stopped;
- }
- }
- EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {}
- EffectReverb::~EffectReverb() = default;
- void EffectReverb::Update(EffectInfo::InParams& in_params) {
- const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data());
- auto& params = GetParams();
- if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
- return;
- }
- const auto last_status = params.status;
- mix_id = in_params.mix_id;
- processing_order = in_params.processing_order;
- params = *reverb_params;
- if (!ValidChannelCountForEffect(reverb_params->channels)) {
- params.channels = params.max_channels;
- }
- enabled = in_params.is_enabled;
- if (last_status != ParameterStatus::Updated) {
- params.status = last_status;
- }
- if (in_params.is_new || skipped) {
- usage = UsageState::Initialized;
- 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
|