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.

180 lines
6.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  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 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. namespace dsp
  21. {
  22. //==============================================================================
  23. template <typename SampleType>
  24. DryWetMixer<SampleType>::DryWetMixer()
  25. : DryWetMixer (0)
  26. {
  27. }
  28. template <typename SampleType>
  29. DryWetMixer<SampleType>::DryWetMixer (int maximumWetLatencyInSamples)
  30. : dryDelayLine (maximumWetLatencyInSamples)
  31. {
  32. dryDelayLine.setDelay (0);
  33. update();
  34. reset();
  35. }
  36. //==============================================================================
  37. template <typename SampleType>
  38. void DryWetMixer<SampleType>::setMixingRule (MixingRule newRule)
  39. {
  40. currentMixingRule = newRule;
  41. update();
  42. }
  43. template <typename SampleType>
  44. void DryWetMixer<SampleType>::setWetMixProportion (SampleType newWetMixProportion)
  45. {
  46. jassert (isPositiveAndNotGreaterThan (newWetMixProportion, 1.0));
  47. mix = jlimit (static_cast<SampleType> (0.0), static_cast<SampleType> (1.0), newWetMixProportion);
  48. update();
  49. }
  50. template <typename SampleType>
  51. void DryWetMixer<SampleType>::setWetLatency (SampleType wetLatencySamples)
  52. {
  53. dryDelayLine.setDelay (wetLatencySamples);
  54. }
  55. //==============================================================================
  56. template <typename SampleType>
  57. void DryWetMixer<SampleType>::prepare (const ProcessSpec& spec)
  58. {
  59. jassert (spec.sampleRate > 0);
  60. jassert (spec.numChannels > 0);
  61. sampleRate = spec.sampleRate;
  62. dryDelayLine.prepare (spec);
  63. bufferDry.setSize ((int) spec.numChannels, (int) spec.maximumBlockSize, false, false, true);
  64. update();
  65. reset();
  66. }
  67. template <typename SampleType>
  68. void DryWetMixer<SampleType>::reset()
  69. {
  70. dryVolume.reset (sampleRate, 0.05);
  71. wetVolume.reset (sampleRate, 0.05);
  72. dryDelayLine.reset();
  73. }
  74. //==============================================================================
  75. template <typename SampleType>
  76. void DryWetMixer<SampleType>::pushDrySamples (const AudioBlock<const SampleType> drySamples)
  77. {
  78. jassert (drySamples.getNumChannels() <= (size_t) bufferDry.getNumChannels());
  79. auto dryBlock = AudioBlock<SampleType> (bufferDry);
  80. dryBlock = dryBlock.getSubsetChannelBlock (0, drySamples.getNumChannels()).getSubBlock (0, drySamples.getNumSamples());
  81. auto context = ProcessContextNonReplacing<SampleType>(drySamples, dryBlock);
  82. dryDelayLine.process (context);
  83. }
  84. template <typename SampleType>
  85. void DryWetMixer<SampleType>::mixWetSamples (AudioBlock<SampleType> inOutBlock)
  86. {
  87. auto dryBlock = AudioBlock<SampleType> (bufferDry);
  88. dryBlock = dryBlock.getSubsetChannelBlock (0, inOutBlock.getNumChannels()).getSubBlock (0, inOutBlock.getNumSamples());
  89. dryBlock.multiplyBy (dryVolume);
  90. inOutBlock.multiplyBy (wetVolume);
  91. inOutBlock.add (dryBlock);
  92. }
  93. //==============================================================================
  94. template <typename SampleType>
  95. void DryWetMixer<SampleType>::update()
  96. {
  97. SampleType dryValue, wetValue;
  98. switch (currentMixingRule)
  99. {
  100. case MixingRule::balanced:
  101. dryValue = static_cast<SampleType> (2.0) * jmin (static_cast<SampleType> (0.5), static_cast<SampleType> (1.0) - mix);
  102. wetValue = static_cast<SampleType> (2.0) * jmin (static_cast<SampleType> (0.5), mix);
  103. break;
  104. case MixingRule::linear:
  105. dryValue = static_cast<SampleType> (1.0) - mix;
  106. wetValue = mix;
  107. break;
  108. case MixingRule::sin3dB:
  109. dryValue = static_cast<SampleType> (std::sin (0.5 * MathConstants<double>::pi * (1.0 - mix)));
  110. wetValue = static_cast<SampleType> (std::sin (0.5 * MathConstants<double>::pi * mix));
  111. break;
  112. case MixingRule::sin4p5dB:
  113. dryValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * (1.0 - mix)), 1.5));
  114. wetValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * mix), 1.5));
  115. break;
  116. case MixingRule::sin6dB:
  117. dryValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * (1.0 - mix)), 2.0));
  118. wetValue = static_cast<SampleType> (std::pow (std::sin (0.5 * MathConstants<double>::pi * mix), 2.0));
  119. break;
  120. case MixingRule::squareRoot3dB:
  121. dryValue = std::sqrt (static_cast<SampleType> (1.0) - mix);
  122. wetValue = std::sqrt (mix);
  123. break;
  124. case MixingRule::squareRoot4p5dB:
  125. dryValue = static_cast<SampleType> (std::pow (std::sqrt (1.0 - mix), 1.5));
  126. wetValue = static_cast<SampleType> (std::pow (std::sqrt (mix), 1.5));
  127. break;
  128. default:
  129. dryValue = jmin (static_cast<SampleType> (0.5), static_cast<SampleType> (1.0) - mix);
  130. wetValue = jmin (static_cast<SampleType> (0.5), mix);
  131. break;
  132. }
  133. dryVolume.setTargetValue (dryValue);
  134. wetVolume.setTargetValue (wetValue);
  135. }
  136. //==============================================================================
  137. template class DryWetMixer<float>;
  138. template class DryWetMixer<double>;
  139. } // namespace dsp
  140. } // namespace juce