37 namespace ProcessorHelpers
42 template <
typename ProcessorType>
43 static auto& get (ProcessorType& a) noexcept {
return AccessHelper<arg - 1>::get (a.processors); }
45 template <
typename ProcessorType>
46 static const auto& get (
const ProcessorType& a) noexcept {
return AccessHelper<arg - 1>::get (a.processors); }
48 template <
typename ProcessorType>
49 static void setBypassed (ProcessorType& a,
bool bypassed) { AccessHelper<arg - 1>::setBypassed (a.processors, bypassed); }
53 struct AccessHelper<0>
55 template <
typename ProcessorType>
56 static auto& get (ProcessorType& a) noexcept {
return a.getProcessor(); }
58 template <
typename ProcessorType>
59 static const auto& get (
const ProcessorType& a) noexcept {
return a.getProcessor(); }
61 template <
typename ProcessorType>
62 static void setBypassed (ProcessorType& a,
bool bypassed) { a.isBypassed = bypassed; }
66 template <
bool isFirst,
typename Processor,
typename Sub
class>
69 void prepare (
const ProcessSpec& spec)
71 processor.prepare (spec);
74 template <
typename ProcessContext>
75 void process (
const ProcessContext& context) noexcept
77 if (context.usesSeparateInputAndOutputBlocks() && ! isFirst)
79 jassert (context.getOutputBlock().getNumChannels() == context.getInputBlock().getNumChannels());
80 ProcessContextReplacing<typename ProcessContext::SampleType> replacingContext (context.getOutputBlock());
81 replacingContext.isBypassed = (isBypassed || context.isBypassed);
83 processor.process (replacingContext);
87 ProcessContext contextCopy (context);
88 contextCopy.isBypassed = (isBypassed || context.isBypassed);
90 processor.process (contextCopy);
99 bool isBypassed =
false;
102 Processor& getProcessor() noexcept {
return processor; }
103 const Processor& getProcessor() const noexcept {
return processor; }
104 Subclass& getThis() noexcept {
return *
static_cast<Subclass*
> (
this); }
105 const Subclass& getThis() const noexcept {
return *
static_cast<const Subclass*
> (
this); }
107 template <
int arg>
auto& get() noexcept {
return AccessHelper<arg>::get (getThis()); }
108 template <
int arg>
const auto& get() const noexcept {
return AccessHelper<arg>::get (getThis()); }
109 template <
int arg>
void setBypassed (
bool bypassed) noexcept { AccessHelper<arg>::setBypassed (getThis(), bypassed); }
113 template <
bool isFirst,
typename FirstProcessor,
typename... SubsequentProcessors>
114 struct ChainBase :
public ChainElement<isFirst, FirstProcessor, ChainBase<isFirst, FirstProcessor, SubsequentProcessors...>>
116 using Base = ChainElement<isFirst, FirstProcessor, ChainBase<isFirst, FirstProcessor, SubsequentProcessors...>>;
118 template <
typename ProcessContext>
119 void process (
const ProcessContext& context) noexcept { Base::process (context); processors.process (context); }
120 void prepare (
const ProcessSpec& spec) { Base::prepare (spec); processors.prepare (spec); }
121 void reset() { Base::reset(); processors.reset(); }
123 ChainBase<
false, SubsequentProcessors...> processors;
126 template <
bool isFirst,
typename ProcessorType>
127 struct ChainBase<isFirst, ProcessorType> :
public ChainElement<isFirst, ProcessorType, ChainBase<isFirst, ProcessorType>> {};
137 template <
typename... Processors>
138 using ProcessorChain = ProcessorHelpers::ChainBase<
true, Processors...>;