diff --git a/framework/audio/engine/internal/audiofactory.cpp b/framework/audio/engine/internal/audiofactory.cpp index f354fcf478..8589632f3a 100644 --- a/framework/audio/engine/internal/audiofactory.cpp +++ b/framework/audio/engine/internal/audiofactory.cpp @@ -84,10 +84,8 @@ FxChainPtr AudioFactory::makeMasterFxChain(const AudioFxChain& fxChain) const std::vector fxlist = fxResolver()->resolveMasterFxList(fxChain, audioEngine()->outputSpec()); FxChainPtr chain = std::make_shared(); - for (const auto& fx : fxlist) { - chain->add(std::make_shared(fx)); - } - + chain->setName("FxChain [master]"); + chain->setFxList(fxlist); chain->setFxChainSpec(fxChain); return chain; @@ -96,11 +94,14 @@ FxChainPtr AudioFactory::makeMasterFxChain(const AudioFxChain& fxChain) const FxChainPtr AudioFactory::makeTrackFxChain(const TrackId trackId, const AudioFxChain& fxChain) const { std::vector fxlist = fxResolver()->resolveFxList(trackId, fxChain, audioEngine()->outputSpec()); + FxChainPtr chain = std::make_shared(); - for (const auto& fx : fxlist) { - chain->add(std::make_shared(fx)); + if (trackId == MASTER_TRACK_ID) { + chain->setName("FxChain [master]"); + } else { + chain->setName("FxChain [track " + std::to_string(trackId) + "]"); } - + chain->setFxList(fxlist); chain->setFxChainSpec(fxChain); return chain; diff --git a/framework/audio/engine/internal/nodes/eventaudionode.cpp b/framework/audio/engine/internal/nodes/eventaudionode.cpp index 219df328a1..78ee47e151 100644 --- a/framework/audio/engine/internal/nodes/eventaudionode.cpp +++ b/framework/audio/engine/internal/nodes/eventaudionode.cpp @@ -159,7 +159,7 @@ void EventAudioNode::applyInputParams(const AudioInputParams& requiredParams) m_synth->setMode(ProcessMode::Idle); } - setName(std::string("Source[") + m_synth->name() + "] "); + setName(std::string("Source[") + m_synth->name() + "]"); m_params = m_synth->params(); m_paramsChanges.send(m_params); diff --git a/framework/audio/engine/internal/nodes/fxchain.cpp b/framework/audio/engine/internal/nodes/fxchain.cpp index bf97033138..7d6a123cb3 100644 --- a/framework/audio/engine/internal/nodes/fxchain.cpp +++ b/framework/audio/engine/internal/nodes/fxchain.cpp @@ -21,6 +21,7 @@ */ #include "fxchain.h" +#include "fxnode.h" #include "log.h" @@ -28,32 +29,27 @@ using namespace muse; using namespace muse::audio; using namespace muse::audio::engine; -void FxChain::add(FxNodePtr fx) +void FxChain::setFxList(const std::vector& fxList) { - IF_ASSERT_FAILED(fx) { - return; - } + clear(); - ChainNode::add(fx); + for (auto it = fxList.rbegin(); it != fxList.rend(); ++it) { + FxNodePtr node = std::make_shared(*it); + doAdd(node); - fx->paramsChanged().onReceive(this, [this](const AudioFxParams& fxParams) { - m_fxChainSpec.insert_or_assign(fxParams.chainOrder, fxParams); - m_fxChainSpecChanged.send(m_fxChainSpec); - updateShouldProcessDuringSilence(); - }, async::Asyncable::Mode::SetReplace); + node->paramsChanged().onReceive(this, [this](const AudioFxParams& fxParams) { + m_fxChainSpec.insert_or_assign(fxParams.chainOrder, fxParams); + m_fxChainSpecChanged.send(m_fxChainSpec); + updateShouldProcessDuringSilence(); + }, async::Asyncable::Mode::SetReplace); + } + rebuild(); updateShouldProcessDuringSilence(); -} -void FxChain::remove(FxNodePtr fx) -{ - IF_ASSERT_FAILED(fx) { - return; + if (!name().empty() && !m_nodes.empty()) { + LOGD() << name() << ": " << m_nodes.front()->dump(); } - - ChainNode::remove(fx); - - fx->paramsChanged().disconnect(this); } void FxChain::setFxChainSpec(const AudioFxChain& fxChainSpec) @@ -117,6 +113,23 @@ void FxChain::setPlayheadPosition(PlayheadPositionPtr playheadPosition) } } +void FxChain::rebuild() +{ + for (size_t i = 1; i < m_nodes.size(); ++i) { + IAudioNodePtr& prev = m_nodes.at(i - 1); + IAudioNodePtr& curr = m_nodes.at(i); + curr->disconnectAll(); + curr->connect(prev); // prev->input = curr + } +} + +void FxChain::doSelfProcess(float* buffer, samples_t samplesPerChannel) +{ + if (!m_nodes.empty()) { + m_nodes.front()->process(buffer, samplesPerChannel); + } +} + void FxChain::updateShouldProcessDuringSilence() { bool shouldProcessDuringSilence = false; diff --git a/framework/audio/engine/internal/nodes/fxchain.h b/framework/audio/engine/internal/nodes/fxchain.h index 1d524970a7..b4d491a4c3 100644 --- a/framework/audio/engine/internal/nodes/fxchain.h +++ b/framework/audio/engine/internal/nodes/fxchain.h @@ -23,7 +23,9 @@ #pragma once #include "chainnode.h" -#include "fxnode.h" +#include "audio/engine/ifxprocessor.h" +#include "audio/engine/iplayhead.h" + #include "async/asyncable.h" #include "async/channel.h" @@ -38,11 +40,9 @@ namespace muse::audio::engine { class FxChain : public ChainNode, public async::Asyncable { public: + void setFxList(const std::vector& fxList); - void add(FxNodePtr fx); - void remove(FxNodePtr fx); - - //! NOTE Must be setted after adding all nodes to the chain + //! NOTE Must be set after adding all nodes to the chain void setFxChainSpec(const AudioFxChain& fxChainSpec); const AudioFxChain& fxChainSpec() const; async::Channel fxChainSpecChanged() const; @@ -53,6 +53,8 @@ class FxChain : public ChainNode, public async::Asyncable async::Channel shouldProcessDuringSilenceChanged() const; private: + void rebuild() override; + void doSelfProcess(float* buffer, samples_t samplesPerChannel) override; void updateShouldProcessDuringSilence(); diff --git a/framework/audio/engine/internal/nodes/fxnode.cpp b/framework/audio/engine/internal/nodes/fxnode.cpp index ea7ad6ece9..984b3706e7 100644 --- a/framework/audio/engine/internal/nodes/fxnode.cpp +++ b/framework/audio/engine/internal/nodes/fxnode.cpp @@ -31,7 +31,7 @@ FxNode::FxNode(IFxProcessorPtr fxProcessor, PlayheadPositionPtr playheadPosition { assert(m_fxProcessor && "FxNode requires a non-null IFxProcessor"); - setName(std::string("Fx[") + m_fxProcessor->name() + "] "); + setName(std::string("Fx[") + m_fxProcessor->name() + "]"); } void FxNode::setPlayheadPosition(PlayheadPositionPtr playheadPosition)