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.

139 lines
5.9KB

  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. //==============================================================================
  24. NoiseGate()
  25. : AudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo())
  26. .withOutput ("Output", AudioChannelSet::stereo())
  27. .withInput ("Sidechain", AudioChannelSet::mono()))
  28. {
  29. addParameter (threshold = new AudioParameterFloat ("threshold", "Threshold", 0.0f, 1.0f, 0.5f));
  30. addParameter (alpha = new AudioParameterFloat ("alpha", "Alpha", 0.0f, 1.0f, 0.8f));
  31. }
  32. ~NoiseGate() {}
  33. //==============================================================================
  34. bool isBusesLayoutSupported (const BusesLayout& layouts) const override
  35. {
  36. // the sidechain can take any layout, the main bus needs to be the same on the input and output
  37. return (layouts.getMainInputChannelSet() == layouts.getMainOutputChannelSet() &&
  38. (! layouts.getMainInputChannelSet().isDisabled()));
  39. }
  40. //==============================================================================
  41. void prepareToPlay (double /*sampleRate*/, int /*maxBlockSize*/) override { lowPassCoeff = 0.0f; sampleCountDown = 0; }
  42. void releaseResources() override {}
  43. void processBlock (AudioSampleBuffer& buffer, MidiBuffer&) override
  44. {
  45. AudioSampleBuffer mainInputOutput = getBusBuffer(buffer, true, 0);
  46. AudioSampleBuffer sideChainInput = getBusBuffer(buffer, true, 1);
  47. float alphaCopy = *alpha;
  48. float thresholdCopy = *threshold;
  49. for (int j = 0; j < buffer.getNumSamples(); ++j)
  50. {
  51. float mixedSamples = 0.0f;
  52. for (int i = 0; i < sideChainInput.getNumChannels(); ++i)
  53. mixedSamples += sideChainInput.getReadPointer (i) [j];
  54. mixedSamples /= static_cast<float> (sideChainInput.getNumChannels());
  55. lowPassCoeff = (alphaCopy * lowPassCoeff) + ((1.0f - alphaCopy) * mixedSamples);
  56. if (lowPassCoeff >= thresholdCopy)
  57. sampleCountDown = (int) getSampleRate();
  58. // very in-effective way of doing this
  59. for (int i = 0; i < mainInputOutput.getNumChannels(); ++i)
  60. *mainInputOutput.getWritePointer (i, j) = sampleCountDown > 0 ? *mainInputOutput.getReadPointer (i, j) : 0.0f;
  61. if (sampleCountDown > 0)
  62. --sampleCountDown;
  63. }
  64. }
  65. //==============================================================================
  66. AudioProcessorEditor* createEditor() override { return new GenericEditor (*this); }
  67. bool hasEditor() const override { return true; }
  68. const String getName() const override { return "NoiseGate"; }
  69. bool acceptsMidi() const override { return false; }
  70. bool producesMidi() const override { return false; }
  71. double getTailLengthSeconds() const override { return 0.0; }
  72. int getNumPrograms() override { return 1; }
  73. int getCurrentProgram() override { return 0; }
  74. void setCurrentProgram (int) override {}
  75. const String getProgramName (int) override { return ""; }
  76. void changeProgramName (int, const String&) override {}
  77. bool isVST2() const noexcept { return (wrapperType == wrapperType_VST); }
  78. //==============================================================================
  79. void getStateInformation (MemoryBlock& destData) override
  80. {
  81. MemoryOutputStream stream (destData, true);
  82. stream.writeFloat (*threshold);
  83. stream.writeFloat (*alpha);
  84. }
  85. void setStateInformation (const void* data, int sizeInBytes) override
  86. {
  87. MemoryInputStream stream (data, static_cast<size_t> (sizeInBytes), false);
  88. threshold->setValueNotifyingHost (stream.readFloat());
  89. alpha->setValueNotifyingHost (stream.readFloat());
  90. }
  91. enum
  92. {
  93. kVST2MaxChannels = 8
  94. };
  95. private:
  96. //==============================================================================
  97. AudioParameterFloat* threshold;
  98. AudioParameterFloat* alpha;
  99. int sampleCountDown;
  100. float lowPassCoeff;
  101. //==============================================================================
  102. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NoiseGate)
  103. };
  104. //==============================================================================
  105. // This creates new instances of the plugin..
  106. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  107. {
  108. return new NoiseGate();
  109. }