36 template <
typename Fn,
typename Tuple,
size_t... Ix>
37 constexpr void forEachInTuple (Fn&& fn, Tuple&& tuple, std::index_sequence<Ix...>)
39 (fn (std::get<Ix> (tuple), std::integral_constant<size_t, Ix>()), ...);
43 using TupleIndexSequence = std::make_index_sequence<std::tuple_size_v<std::remove_cv_t<std::remove_reference_t<T>>>>;
45 template <
typename Fn,
typename Tuple>
46 constexpr void forEachInTuple (Fn&& fn, Tuple&& tuple)
48 forEachInTuple (std::forward<Fn> (fn), std::forward<Tuple> (tuple), TupleIndexSequence<Tuple>{});
51 template <
typename Context,
size_t Ix>
52 inline constexpr auto useContextDirectly = ! Context::usesSeparateInputAndOutputBlocks() || Ix == 0;
61template <
typename... Processors>
66 template <
int Index>
auto&
get() noexcept {
return std::get<Index> (processors); }
69 template <
int Index>
const auto&
get() const noexcept {
return std::get<Index> (processors); }
73 void setBypassed (
bool b)
noexcept { bypassed[(size_t) Index] = b; }
77 bool isBypassed() const noexcept {
return bypassed[(size_t) Index]; }
82 detail::forEachInTuple ([&] (
auto& proc,
auto) { proc.prepare (spec); }, processors);
88 detail::forEachInTuple ([] (
auto& proc,
auto) { proc.reset(); }, processors);
92 template <
typename ProcessContext>
93 void process (
const ProcessContext& context)
noexcept
95 detail::forEachInTuple ([
this, &context] (
auto& proc,
auto index)
noexcept { this->processOne (context, proc, index); },
100 template <
typename Context,
typename Proc,
size_t Ix>
101 void processOne (
const Context& context, Proc& proc, std::integral_constant<size_t, Ix>)
noexcept
103 if constexpr (detail::useContextDirectly<Context, Ix>)
105 auto contextCopy = context;
106 contextCopy.isBypassed = (bypassed[Ix] || context.isBypassed);
108 proc.process (contextCopy);
112 jassert (context.getOutputBlock().getNumChannels() == context.getInputBlock().getNumChannels());
113 ProcessContextReplacing<typename Context::SampleType> replacingContext (context.getOutputBlock());
114 replacingContext.isBypassed = (bypassed[Ix] || context.isBypassed);
116 proc.process (replacingContext);
120 std::tuple<Processors...> processors;
121 std::array<bool,
sizeof... (Processors)> bypassed { {} };
127template <
int Index,
typename... Processors>
128inline auto& get (ProcessorChain<Processors...>& chain)
noexcept
130 return chain.template get<Index>();
136template <
int Index,
typename... Processors>
137inline auto& get (
const ProcessorChain<Processors...>& chain)
noexcept
139 return chain.template get<Index>();
145template <
int Index,
typename... Processors>
146inline void setBypassed (ProcessorChain<Processors...>& chain,
bool bypassed)
noexcept
148 chain.template setBypassed<Index> (bypassed);
154template <
int Index,
typename... Processors>
155inline bool isBypassed (
const ProcessorChain<Processors...>& chain)
noexcept
157 return chain.template isBypassed<Index>();
166JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE (
"-Wmismatched-tags")
169template <typename... Processors>
170struct tuple_size<::juce::dsp::ProcessorChain<Processors...>> : integral_constant<
size_t, sizeof... (Processors)> {};
173template <
size_t I,
typename... Processors>
176JUCE_END_IGNORE_WARNINGS_GCC_LIKE
bool isBypassed() const noexcept
void setBypassed(bool b) noexcept
void prepare(const ProcessSpec &spec)
const auto & get() const noexcept
void process(const ProcessContext &context) noexcept