1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - 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 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-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 27 { 28 namespace dsp 29 { 30 31 /** 32 A simple limiter with standard threshold and release time controls, featuring 33 two compressors and a hard clipper at 0 dB. 34 35 @tags{DSP} 36 */ 37 template <typename SampleType> 38 class Limiter 39 { 40 public: 41 //============================================================================== 42 /** Constructor. */ 43 Limiter() = default; 44 45 //============================================================================== 46 /** Sets the threshold in dB of the limiter.*/ 47 void setThreshold (SampleType newThreshold); 48 49 /** Sets the release time in milliseconds of the limiter.*/ 50 void setRelease (SampleType newRelease); 51 52 //============================================================================== 53 /** Initialises the processor. */ 54 void prepare (const ProcessSpec& spec); 55 56 /** Resets the internal state variables of the processor. */ 57 void reset(); 58 59 //============================================================================== 60 /** Processes the input and output samples supplied in the processing context. */ 61 template <typename ProcessContext> process(const ProcessContext & context)62 void process (const ProcessContext& context) noexcept 63 { 64 const auto& inputBlock = context.getInputBlock(); 65 auto& outputBlock = context.getOutputBlock(); 66 const auto numChannels = outputBlock.getNumChannels(); 67 const auto numSamples = outputBlock.getNumSamples(); 68 69 jassert (inputBlock.getNumChannels() == numChannels); 70 jassert (inputBlock.getNumSamples() == numSamples); 71 72 if (context.isBypassed) 73 { 74 outputBlock.copyFrom (inputBlock); 75 return; 76 } 77 78 firstStageCompressor.process (context); 79 80 auto secondContext = ProcessContextReplacing<SampleType> (outputBlock); 81 secondStageCompressor.process (secondContext); 82 83 outputBlock.multiplyBy (outputVolume); 84 85 for (size_t channel = 0; channel < numChannels; ++channel) 86 { 87 FloatVectorOperations::clip (outputBlock.getChannelPointer (channel), outputBlock.getChannelPointer (channel), 88 (SampleType) -1.0, (SampleType) 1.0, (int) numSamples); 89 } 90 } 91 92 private: 93 //============================================================================== 94 void update(); 95 96 //============================================================================== 97 Compressor<SampleType> firstStageCompressor, secondStageCompressor; 98 SmoothedValue<SampleType, ValueSmoothingTypes::Linear> outputVolume; 99 100 double sampleRate = 44100.0; 101 SampleType thresholddB = -10.0, releaseTime = 100.0; 102 }; 103 104 } // namespace dsp 105 } // namespace juce 106