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.

167 lines
6.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #include "../JuceLibraryCode/JuceHeader.h"
  18. #include "../../GenericEditor.h"
  19. class NoiseGate : public AudioProcessor
  20. {
  21. public:
  22. //==============================================================================
  23. NoiseGate()
  24. {
  25. addParameter (threshold = new AudioParameterFloat ("threshold", "Threshold", 0.0f, 1.0f, 0.5f));
  26. addParameter (alpha = new AudioParameterFloat ("alpha", "Alpha", 0.0f, 1.0f, 0.8f));
  27. // add single side-chain bus
  28. busArrangement.inputBuses.add (AudioProcessorBus ("Sidechain In", AudioChannelSet::mono()));
  29. // To be compatible with all VST2 DAWs, it's best to pass through the sidechain
  30. if (isVST2())
  31. busArrangement.outputBuses.add (AudioProcessorBus ("Sidechain Out", AudioChannelSet::mono()));
  32. }
  33. ~NoiseGate() {}
  34. //==============================================================================
  35. bool setPreferredBusArrangement (bool isInputBus, int busIndex, const AudioChannelSet& preferred) override
  36. {
  37. const bool isMainBus = (busIndex == 0);
  38. const bool isSideChain = (busIndex == 1);
  39. const int numChannels = preferred.size();
  40. // do not allow disabling channels on main bus
  41. if (numChannels == 0 && isMainBus) return false;
  42. // VST2 does not natively support sidechains/aux buses.
  43. // But many DAWs treat the third input of a plug-in
  44. // as a sidechain. So limit the main bus to stereo!
  45. if (isVST2())
  46. {
  47. if (isMainBus && numChannels != 2) return false;
  48. // we only allow mono sidechains in VST-2
  49. if (isSideChain && numChannels != 1)
  50. return false;
  51. }
  52. // always have the same channel layout on both input and output on the main bus
  53. if (isMainBus && ! AudioProcessor::setPreferredBusArrangement (! isInputBus, busIndex, preferred))
  54. return false;
  55. return AudioProcessor::setPreferredBusArrangement (isInputBus, busIndex, preferred);
  56. }
  57. //==============================================================================
  58. void prepareToPlay (double /*sampleRate*/, int /*maxBlockSize*/) override { lowPassCoeff = 0.0f; sampleCountDown = 0; }
  59. void releaseResources() override {}
  60. void processBlock (AudioSampleBuffer& buffer, MidiBuffer&) override
  61. {
  62. AudioSampleBuffer mainInputOutput = busArrangement.getBusBuffer (buffer, true, 0);
  63. AudioSampleBuffer sideChainInput = busArrangement.getBusBuffer (buffer, true, 1);
  64. float alphaCopy = *alpha;
  65. float thresholdCopy = *threshold;
  66. for (int j = 0; j < buffer.getNumSamples(); ++j)
  67. {
  68. float mixedSamples = 0.0f;
  69. for (int i = 0; i < sideChainInput.getNumChannels(); ++i)
  70. mixedSamples += sideChainInput.getReadPointer (i) [j];
  71. mixedSamples /= static_cast<float> (sideChainInput.getNumChannels());
  72. lowPassCoeff = (alphaCopy * lowPassCoeff) + ((1.0f - alphaCopy) * mixedSamples);
  73. if (lowPassCoeff >= thresholdCopy)
  74. sampleCountDown = (int) getSampleRate();
  75. // very in-effective way of doing this
  76. for (int i = 0; i < mainInputOutput.getNumChannels(); ++i)
  77. *mainInputOutput.getWritePointer (i, j) = sampleCountDown > 0 ? *mainInputOutput.getReadPointer (i, j) : 0.0f;
  78. if (sampleCountDown > 0)
  79. --sampleCountDown;
  80. }
  81. // VST-2 passes this through so clear the audio in this channel
  82. sideChainInput.clear();
  83. }
  84. //==============================================================================
  85. AudioProcessorEditor* createEditor() override { return new GenericEditor (*this); }
  86. bool hasEditor() const override { return true; }
  87. const String getName() const override { return "NoiseGate"; }
  88. bool acceptsMidi() const override { return false; }
  89. bool producesMidi() const override { return false; }
  90. double getTailLengthSeconds() const override { return 0.0; }
  91. int getNumPrograms() override { return 1; }
  92. int getCurrentProgram() override { return 0; }
  93. void setCurrentProgram (int) override {}
  94. const String getProgramName (int) override { return ""; }
  95. void changeProgramName (int, const String&) override {}
  96. bool isVST2() const noexcept { return (wrapperType == wrapperType_VST); }
  97. //==============================================================================
  98. void getStateInformation (MemoryBlock& destData) override
  99. {
  100. MemoryOutputStream stream (destData, true);
  101. stream.writeFloat (*threshold);
  102. stream.writeFloat (*alpha);
  103. }
  104. void setStateInformation (const void* data, int sizeInBytes) override
  105. {
  106. MemoryInputStream stream (data, static_cast<size_t> (sizeInBytes), false);
  107. threshold->setValueNotifyingHost (stream.readFloat());
  108. alpha->setValueNotifyingHost (stream.readFloat());
  109. }
  110. enum
  111. {
  112. kVST2MaxChannels = 8
  113. };
  114. private:
  115. //==============================================================================
  116. AudioParameterFloat* threshold;
  117. AudioParameterFloat* alpha;
  118. int sampleCountDown;
  119. float lowPassCoeff;
  120. //==============================================================================
  121. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NoiseGate)
  122. };
  123. //==============================================================================
  124. // This creates new instances of the plugin..
  125. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  126. {
  127. return new NoiseGate();
  128. }