The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
4.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. namespace juce
  20. {
  21. namespace dsp
  22. {
  23. #ifndef DOXYGEN
  24. namespace ProcessorHelpers // Internal helper classes used in building the ProcessorChain
  25. {
  26. template <int arg>
  27. struct GetterHelper
  28. {
  29. template <typename ProcessorType>
  30. static auto& get (ProcessorType& a) noexcept { return GetterHelper<arg - 1>::get (a.processors); }
  31. };
  32. template <>
  33. struct GetterHelper<0>
  34. {
  35. template <typename ProcessorType>
  36. static auto& get (ProcessorType& a) noexcept { return a.getProcessor(); }
  37. };
  38. template <typename Processor, typename Subclass>
  39. struct ChainBase
  40. {
  41. Processor processor;
  42. Processor& getProcessor() noexcept { return processor; }
  43. Subclass& getThis() noexcept { return *static_cast<Subclass*> (this); }
  44. template <int arg> auto& get() noexcept { return GetterHelper<arg>::get (getThis()); }
  45. };
  46. template <typename FirstProcessor, typename... SubsequentProcessors>
  47. struct Chain : public ChainBase<FirstProcessor, Chain<FirstProcessor, SubsequentProcessors...>>
  48. {
  49. using Base = ChainBase<FirstProcessor, Chain<FirstProcessor, SubsequentProcessors...>>;
  50. void prepare (const ProcessSpec& spec)
  51. {
  52. Base::processor.prepare (spec);
  53. processors.prepare (spec);
  54. }
  55. template <typename ProcessContext>
  56. void process (ProcessContext& context) noexcept
  57. {
  58. Base::processor.process (context);
  59. if (context.usesSeparateInputAndOutputBlocks())
  60. {
  61. jassert (context.getOutputBlock().getNumChannels() == context.getInputBlock().getNumChannels());
  62. ProcessContextReplacing<typename ProcessContext::SampleType> replacingContext (context.getOutputBlock());
  63. processors.process (replacingContext);
  64. }
  65. else
  66. {
  67. processors.process (context);
  68. }
  69. }
  70. void reset()
  71. {
  72. Base::processor.reset();
  73. processors.reset();
  74. }
  75. Chain<SubsequentProcessors...> processors;
  76. };
  77. template <typename ProcessorType>
  78. struct Chain<ProcessorType> : public ChainBase<ProcessorType, Chain<ProcessorType>>
  79. {
  80. using Base = ChainBase<ProcessorType, Chain<ProcessorType>>;
  81. template <typename ProcessContext>
  82. void process (ProcessContext& context) noexcept
  83. {
  84. Base::processor.process (context);
  85. }
  86. void prepare (const ProcessSpec& spec)
  87. {
  88. Base::processor.prepare (spec);
  89. }
  90. void reset()
  91. {
  92. Base::processor.reset();
  93. }
  94. };
  95. }
  96. #endif
  97. //==============================================================================
  98. /**
  99. This variadically-templated class lets you join together any number of processor
  100. classes into a single processor which will call process() on them all in sequence.
  101. */
  102. template <typename... Processors>
  103. using ProcessorChain = ProcessorHelpers::Chain<Processors...>;
  104. } // namespace dsp
  105. } // namespace juce