33namespace ProcessorHelpers
38 template <
typename ProcessorType>
39 static auto& get (ProcessorType& a)
noexcept {
return AccessHelper<arg - 1>::get (a.processors); }
41 template <
typename ProcessorType>
42 static const auto& get (
const ProcessorType& a)
noexcept {
return AccessHelper<arg - 1>::get (a.processors); }
44 template <
typename ProcessorType>
45 static void setBypassed (ProcessorType& a,
bool bypassed) { AccessHelper<arg - 1>::setBypassed (a.processors, bypassed); }
49 struct AccessHelper<0>
51 template <
typename ProcessorType>
52 static auto& get (ProcessorType& a)
noexcept {
return a.getProcessor(); }
54 template <
typename ProcessorType>
55 static const auto& get (
const ProcessorType& a)
noexcept {
return a.getProcessor(); }
57 template <
typename ProcessorType>
58 static void setBypassed (ProcessorType& a,
bool bypassed) { a.isBypassed = bypassed; }
62 template <
bool isFirst,
typename Processor,
typename Sub
class>
65 void prepare (
const ProcessSpec& spec)
67 processor.prepare (spec);
70 template <
typename ProcessContext>
71 void process (
const ProcessContext& context)
noexcept
73 if (context.usesSeparateInputAndOutputBlocks() && ! isFirst)
75 jassert (context.getOutputBlock().getNumChannels() == context.getInputBlock().getNumChannels());
76 ProcessContextReplacing<typename ProcessContext::SampleType> replacingContext (context.getOutputBlock());
77 replacingContext.isBypassed = (isBypassed || context.isBypassed);
79 processor.process (replacingContext);
83 ProcessContext contextCopy (context);
84 contextCopy.isBypassed = (isBypassed || context.isBypassed);
86 processor.process (contextCopy);
95 bool isBypassed =
false;
98 Processor& getProcessor() noexcept {
return processor; }
99 const Processor& getProcessor() const noexcept {
return processor; }
100 Subclass& getThis() noexcept {
return *
static_cast<Subclass*
> (
this); }
101 const Subclass& getThis() const noexcept {
return *
static_cast<const Subclass*
> (
this); }
103 template <
int arg>
auto& get() noexcept {
return AccessHelper<arg>::get (getThis()); }
104 template <
int arg>
const auto& get() const noexcept {
return AccessHelper<arg>::get (getThis()); }
105 template <
int arg>
void setBypassed (
bool bypassed)
noexcept { AccessHelper<arg>::setBypassed (getThis(), bypassed); }
109 template <
bool isFirst,
typename FirstProcessor,
typename... SubsequentProcessors>
110 struct ChainBase :
public ChainElement<isFirst, FirstProcessor, ChainBase<isFirst, FirstProcessor, SubsequentProcessors...>>
112 using Base = ChainElement<isFirst, FirstProcessor, ChainBase<isFirst, FirstProcessor, SubsequentProcessors...>>;
114 template <
typename ProcessContext>
115 void process (
const ProcessContext& context)
noexcept { Base::process (context); processors.process (context); }
116 void prepare (
const ProcessSpec& spec) { Base::prepare (spec); processors.prepare (spec); }
117 void reset() { Base::reset(); processors.reset(); }
119 ChainBase<
false, SubsequentProcessors...> processors;
122 template <
bool isFirst,
typename ProcessorType>
123 struct ChainBase<isFirst, ProcessorType> :
public ChainElement<isFirst, ProcessorType, ChainBase<isFirst, ProcessorType>> {};
133template <
typename... Processors>
134using ProcessorChain = ProcessorHelpers::ChainBase<
true, Processors...>;