| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 -    Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 -    27th April 2017).
 - 
 -    End User License Agreement: www.juce.com/juce-5-licence
 -    Privacy Policy: www.juce.com/juce-5-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #include "PluginProcessor.h"
 - #include "PluginEditor.h"
 - 
 - 
 - //==============================================================================
 - DspModulePluginDemoAudioProcessor::DspModulePluginDemoAudioProcessor()
 -      : AudioProcessor (BusesProperties()
 -                        .withInput ("Input",  AudioChannelSet::stereo(), true)
 -                        .withOutput ("Output", AudioChannelSet::stereo(), true)),
 -        lowPassFilter  (dsp::IIR::Coefficients<float>::makeFirstOrderLowPass  (48000.0, 20000.f)),
 -        highPassFilter (dsp::IIR::Coefficients<float>::makeFirstOrderHighPass (48000.0, 20.0f)),
 -        waveShapers { {std::tanh}, {dsp::FastMathApproximations::tanh} },
 -        clipping { clip }
 - {
 -     // Oversampling 2 times with IIR filtering
 -     oversampling = new dsp::Oversampling<float> (2, 1, dsp::Oversampling<float>::filterHalfBandPolyphaseIIR, false);
 - 
 -     addParameter (inputVolumeParam        = new AudioParameterFloat ("INPUT",  "Input Volume",       { 0.f, 60.f, 0.f, 1.0f },     0.f,     "dB"));
 -     addParameter (highPassFilterFreqParam = new AudioParameterFloat ("HPFREQ", "Pre Highpass Freq.", { 20.f, 20000.f, 0.f, 0.5f }, 20.f,    "Hz"));
 -     addParameter (lowPassFilterFreqParam  = new AudioParameterFloat ("LPFREQ", "Post Lowpass Freq.", { 20.f, 20000.f, 0.f, 0.5f }, 20000.f, "Hz"));
 - 
 -     addParameter (stereoParam             = new AudioParameterChoice ("STEREO", "Stereo Processing", { "Always mono", "Yes" },             1));
 -     addParameter (slopeParam              = new AudioParameterChoice ("SLOPE", "Slope",      { "-6 dB / octave", "-12 dB / octave" },      0));
 -     addParameter (waveshaperParam         = new AudioParameterChoice ("WVSHP", "Waveshaper", { "std::tanh", "Fast tanh approx." },         0));
 - 
 -     addParameter (cabinetTypeParam        = new AudioParameterChoice ("CABTYPE", "Cabinet Type", { "Guitar amplifier 8'' cabinet ",
 -                                                                                                    "Cassette recorder cabinet" },          0));
 - 
 -     addParameter (cabinetSimParam         = new AudioParameterBool ("CABSIM", "Cabinet Sim", false));
 -     addParameter (oversamplingParam       = new AudioParameterBool ("OVERS", "Oversampling", false));
 - 
 -     addParameter (outputVolumeParam       = new AudioParameterFloat ("OUTPUT", "Output Volume", { -40.f, 40.f, 0.f, 1.0f }, 0.f, "dB"));
 - 
 -     cabinetType.set (0);
 - }
 - 
 - DspModulePluginDemoAudioProcessor::~DspModulePluginDemoAudioProcessor()
 - {
 - }
 - 
 - //==============================================================================
 - bool DspModulePluginDemoAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
 - {
 -     // This is the place where you check if the layout is supported.
 -     // In this template code we only support mono or stereo.
 -     if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
 -         return false;
 - 
 -     // This checks if the input layout matches the output layout
 -     if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
 -         return false;
 - 
 -     return true;
 - }
 - 
 - void DspModulePluginDemoAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
 - {
 -     auto channels = static_cast<uint32> (jmin (getMainBusNumInputChannels(), getMainBusNumOutputChannels()));
 -     dsp::ProcessSpec spec { sampleRate, static_cast<uint32> (samplesPerBlock), channels };
 - 
 -     lowPassFilter.prepare (spec);
 -     highPassFilter.prepare (spec);
 - 
 -     inputVolume.prepare (spec);
 -     outputVolume.prepare (spec);
 - 
 -     convolution.prepare (spec);
 -     cabinetType.set (-1);
 - 
 -     oversampling->initProcessing (static_cast<size_t> (samplesPerBlock));
 - 
 -     updateParameters();
 -     reset();
 - }
 - 
 - void DspModulePluginDemoAudioProcessor::reset()
 - {
 -     lowPassFilter.reset();
 -     highPassFilter.reset();
 -     convolution.reset();
 -     oversampling->reset();
 - }
 - 
 - void DspModulePluginDemoAudioProcessor::releaseResources()
 - {
 - 
 - }
 - 
 - void DspModulePluginDemoAudioProcessor::process (dsp::ProcessContextReplacing<float> context) noexcept
 - {
 -     ScopedNoDenormals noDenormals;
 - 
 -     // Input volume applied with a LinearSmoothedValue
 -     inputVolume.process (context);
 - 
 -     // Pre-highpass filtering, very useful for distortion audio effects
 -     // Note : try frequencies around 700 Hz
 -     highPassFilter.process (context);
 - 
 -     // Upsampling
 -     dsp::AudioBlock<float> oversampledBlock;
 - 
 -     setLatencySamples (audioCurrentlyOversampled ? roundFloatToInt (oversampling->getLatencyInSamples()) : 0);
 - 
 -     if (audioCurrentlyOversampled)
 -         oversampledBlock = oversampling->processSamplesUp (context.getInputBlock());
 - 
 -     dsp::ProcessContextReplacing<float> waveshaperContext = audioCurrentlyOversampled ? dsp::ProcessContextReplacing<float> (oversampledBlock) : context;
 - 
 -     // Waveshaper processing, for distortion generation, thanks to the input gain
 -     // The fast tanh can be used instead of std::tanh to reduce the CPU load
 -     auto waveshaperIndex = waveshaperParam->getIndex();
 - 
 -     if (isPositiveAndBelow (waveshaperIndex, numWaveShapers) )
 -     {
 -         waveShapers[waveshaperIndex].process (waveshaperContext);
 - 
 -         if (waveshaperIndex == 1)
 -             clipping.process (waveshaperContext);
 - 
 -         waveshaperContext.getOutputBlock() *= 0.7f;
 -     }
 - 
 -     // Downsampling
 -     if (audioCurrentlyOversampled)
 -         oversampling->processSamplesDown (context.getOutputBlock());
 - 
 -     // Post-lowpass filtering
 -     lowPassFilter.process (context);
 - 
 -     // Convolution with the impulse response of a guitar cabinet
 -     auto wasBypassed = context.isBypassed;
 -     context.isBypassed = context.isBypassed || cabinetIsBypassed;
 -     convolution.process (context);
 -     context.isBypassed = wasBypassed;
 - 
 -     // Output volume applied with a LinearSmoothedValue
 -     outputVolume.process (context);
 - }
 - 
 - void DspModulePluginDemoAudioProcessor::processBlock (AudioSampleBuffer& inoutBuffer, MidiBuffer&)
 - {
 -     auto totalNumInputChannels  = getTotalNumInputChannels();
 -     auto totalNumOutputChannels = getTotalNumOutputChannels();
 - 
 -     auto numSamples = inoutBuffer.getNumSamples();
 - 
 -     for (auto i = jmin (2, totalNumInputChannels); i < totalNumOutputChannels; ++i)
 -         inoutBuffer.clear (i, 0, numSamples);
 - 
 -     updateParameters();
 - 
 -     dsp::AudioBlock<float> block (inoutBuffer);
 - 
 -     if (stereoParam->getIndex() == 1)
 -     {
 -         // Stereo processing mode:
 -         if (block.getNumChannels() > 2)
 -             block = block.getSubsetChannelBlock (0, 2);
 - 
 -         process (dsp::ProcessContextReplacing<float> (block));
 -     }
 -     else
 -     {
 -         // Mono processing mode:
 -         auto firstChan = block.getSingleChannelBlock (0);
 - 
 -         process (dsp::ProcessContextReplacing<float> (firstChan));
 - 
 -         for (size_t chan = 1; chan < block.getNumChannels(); ++chan)
 -             block.getSingleChannelBlock (chan).copy (firstChan);
 -     }
 - }
 - 
 - //==============================================================================
 - bool DspModulePluginDemoAudioProcessor::hasEditor() const
 - {
 -     return true;
 - }
 - 
 - AudioProcessorEditor* DspModulePluginDemoAudioProcessor::createEditor()
 - {
 -     return new DspModulePluginDemoAudioProcessorEditor (*this);
 - }
 - 
 - //==============================================================================
 - bool DspModulePluginDemoAudioProcessor::acceptsMidi() const
 - {
 -    #if JucePlugin_WantsMidiInput
 -     return true;
 -    #else
 -     return false;
 -    #endif
 - }
 - 
 - bool DspModulePluginDemoAudioProcessor::producesMidi() const
 - {
 -    #if JucePlugin_ProducesMidiOutput
 -     return true;
 -    #else
 -     return false;
 -    #endif
 - }
 - 
 - //==============================================================================
 - void DspModulePluginDemoAudioProcessor::updateParameters()
 - {
 -     auto newOversampling = oversamplingParam->get();
 -     if (newOversampling != audioCurrentlyOversampled)
 -     {
 -         audioCurrentlyOversampled = newOversampling;
 -         oversampling->reset();
 -     }
 - 
 -     //==============================================================================
 -     auto inputdB  = Decibels::decibelsToGain (inputVolumeParam->get());
 -     auto outputdB = Decibels::decibelsToGain (outputVolumeParam->get());
 - 
 -     if (inputVolume.getGainLinear() != inputdB)     inputVolume.setGainLinear (inputdB);
 -     if (outputVolume.getGainLinear() != outputdB)   outputVolume.setGainLinear (outputdB);
 - 
 -     auto newSlopeType = slopeParam->getIndex();
 - 
 -     if (newSlopeType == 0)
 -     {
 -         *lowPassFilter.state  = *dsp::IIR::Coefficients<float>::makeFirstOrderLowPass  (getSampleRate(), lowPassFilterFreqParam->get());
 -         *highPassFilter.state = *dsp::IIR::Coefficients<float>::makeFirstOrderHighPass (getSampleRate(), highPassFilterFreqParam->get());
 -     }
 -     else
 -     {
 -         *lowPassFilter.state  = *dsp::IIR::Coefficients<float>::makeLowPass  (getSampleRate(), lowPassFilterFreqParam->get());
 -         *highPassFilter.state = *dsp::IIR::Coefficients<float>::makeHighPass (getSampleRate(), highPassFilterFreqParam->get());
 -     }
 - 
 -     //==============================================================================
 -     auto type = cabinetTypeParam->getIndex();
 -     auto currentType = cabinetType.get();
 - 
 -     if (type != currentType)
 -     {
 -         cabinetType.set(type);
 - 
 -         auto maxSize = static_cast<size_t> (roundDoubleToInt (8192 * getSampleRate() / 44100));
 - 
 -         if (type == 0)
 -             convolution.loadImpulseResponse (BinaryData::Impulse1_wav, BinaryData::Impulse1_wavSize, false, true, maxSize);
 -         else
 -             convolution.loadImpulseResponse (BinaryData::Impulse2_wav, BinaryData::Impulse2_wavSize, false, true, maxSize);
 -     }
 - 
 -     cabinetIsBypassed = ! cabinetSimParam->get();
 - 
 - }
 - 
 - //==============================================================================
 - // This creates new instances of the plugin..
 - AudioProcessor* JUCE_CALLTYPE createPluginFilter()
 - {
 -     return new DspModulePluginDemoAudioProcessor();
 - }
 
 
  |