OpenShot Audio Library | OpenShotAudio  0.6.0
juce_ProcessorChain.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11  Agreement and JUCE Privacy Policy.
12 
13  End User License Agreement: www.juce.com/juce-7-licence
14  Privacy Policy: www.juce.com/juce-privacy-policy
15 
16  Or: You may also use this code under the terms of the GPL v3 (see
17  www.gnu.org/licenses).
18 
19  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21  DISCLAIMED.
22 
23  ==============================================================================
24 */
25 
26 namespace juce::dsp
27 {
28 
29 //==============================================================================
30 #ifndef DOXYGEN
34 namespace detail
35 {
36  template <typename Fn, typename Tuple, size_t... Ix>
37  constexpr void forEachInTuple (Fn&& fn, Tuple&& tuple, std::index_sequence<Ix...>)
38  {
39  (fn (std::get<Ix> (tuple), std::integral_constant<size_t, Ix>()), ...);
40  }
41 
42  template <typename T>
43  using TupleIndexSequence = std::make_index_sequence<std::tuple_size_v<std::remove_cv_t<std::remove_reference_t<T>>>>;
44 
45  template <typename Fn, typename Tuple>
46  constexpr void forEachInTuple (Fn&& fn, Tuple&& tuple)
47  {
48  forEachInTuple (std::forward<Fn> (fn), std::forward<Tuple> (tuple), TupleIndexSequence<Tuple>{});
49  }
50 
51  template <typename Context, size_t Ix>
52  inline constexpr auto useContextDirectly = ! Context::usesSeparateInputAndOutputBlocks() || Ix == 0;
53 }
54 #endif
55 
61 template <typename... Processors>
63 {
64 public:
66  template <int Index> auto& get() noexcept { return std::get<Index> (processors); }
67 
69  template <int Index> const auto& get() const noexcept { return std::get<Index> (processors); }
70 
72  template <int Index>
73  void setBypassed (bool b) noexcept { bypassed[(size_t) Index] = b; }
74 
76  template <int Index>
77  bool isBypassed() const noexcept { return bypassed[(size_t) Index]; }
78 
80  void prepare (const ProcessSpec& spec)
81  {
82  detail::forEachInTuple ([&] (auto& proc, auto) { proc.prepare (spec); }, processors);
83  }
84 
86  void reset()
87  {
88  detail::forEachInTuple ([] (auto& proc, auto) { proc.reset(); }, processors);
89  }
90 
92  template <typename ProcessContext>
93  void process (const ProcessContext& context) noexcept
94  {
95  detail::forEachInTuple ([this, &context] (auto& proc, auto index) noexcept { this->processOne (context, proc, index); },
96  processors);
97  }
98 
99 private:
100  template <typename Context, typename Proc, size_t Ix>
101  void processOne (const Context& context, Proc& proc, std::integral_constant<size_t, Ix>) noexcept
102  {
103  if constexpr (detail::useContextDirectly<Context, Ix>)
104  {
105  auto contextCopy = context;
106  contextCopy.isBypassed = (bypassed[Ix] || context.isBypassed);
107 
108  proc.process (contextCopy);
109  }
110  else
111  {
112  jassert (context.getOutputBlock().getNumChannels() == context.getInputBlock().getNumChannels());
113  ProcessContextReplacing<typename Context::SampleType> replacingContext (context.getOutputBlock());
114  replacingContext.isBypassed = (bypassed[Ix] || context.isBypassed);
115 
116  proc.process (replacingContext);
117  }
118  }
119 
120  std::tuple<Processors...> processors;
121  std::array<bool, sizeof... (Processors)> bypassed { {} };
122 };
123 
127 template <int Index, typename... Processors>
128 inline auto& get (ProcessorChain<Processors...>& chain) noexcept
129 {
130  return chain.template get<Index>();
131 }
132 
136 template <int Index, typename... Processors>
137 inline auto& get (const ProcessorChain<Processors...>& chain) noexcept
138 {
139  return chain.template get<Index>();
140 }
141 
145 template <int Index, typename... Processors>
146 inline void setBypassed (ProcessorChain<Processors...>& chain, bool bypassed) noexcept
147 {
148  chain.template setBypassed<Index> (bypassed);
149 }
150 
154 template <int Index, typename... Processors>
155 inline bool isBypassed (const ProcessorChain<Processors...>& chain) noexcept
156 {
157  return chain.template isBypassed<Index>();
158 }
159 
160 } // namespace juce::dsp
161 
162 #ifndef DOXYGEN
163 namespace std
164 {
165 
166 JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wmismatched-tags")
167 
168 
169 template <typename... Processors>
170 struct tuple_size<::juce::dsp::ProcessorChain<Processors...>> : integral_constant<size_t, sizeof... (Processors)> {};
171 
173 template <size_t I, typename... Processors>
174 struct tuple_element<I, ::juce::dsp::ProcessorChain<Processors...>> : tuple_element<I, tuple<Processors...>> {};
175 
176 JUCE_END_IGNORE_WARNINGS_GCC_LIKE
177 
178 } // namespace std
179 #endif
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