| 
							- /*
 -   ==============================================================================
 - 
 -    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 "../JuceLibraryCode/JuceHeader.h"
 - #include "InternalPlugins.h"
 - #include "PluginGraph.h"
 - 
 - //==============================================================================
 - class InternalPlugin   : public AudioPluginInstance
 - {
 - protected:
 -     InternalPlugin (const PluginDescription& descr,
 -                     const AudioChannelSet& channelSetToUse = AudioChannelSet::stereo())
 -         : AudioPluginInstance (getBusProperties (descr.numInputChannels == 0, channelSetToUse)),
 -           name  (descr.fileOrIdentifier.upToFirstOccurrenceOf (":", false, false)),
 -           state (descr.fileOrIdentifier.fromFirstOccurrenceOf (":", false, false)),
 -           isGenerator (descr.numInputChannels == 0),
 -           hasMidi (descr.isInstrument),
 -           channelSet (channelSetToUse)
 -     {
 -         jassert (channelSetToUse.size() == descr.numOutputChannels);
 -     }
 - 
 - public:
 -     //==============================================================================
 -     const String getName() const override                     { return name; }
 -     double getTailLengthSeconds() const override              { return 0.0; }
 -     bool acceptsMidi() const override                         { return hasMidi; }
 -     bool producesMidi() const override                        { return hasMidi; }
 -     AudioProcessorEditor* createEditor() override             { return nullptr; }
 -     bool hasEditor() const override                           { return false; }
 -     int getNumPrograms() override                             { return 0; }
 -     int getCurrentProgram() override                          { return 0; }
 -     void setCurrentProgram (int) override                     {}
 -     const String getProgramName (int) override                { return {}; }
 -     void changeProgramName (int, const String&) override      {}
 -     void getStateInformation (juce::MemoryBlock&) override    {}
 -     void setStateInformation (const void*, int) override      {}
 - 
 -     //==============================================================================
 -     bool isBusesLayoutSupported (const BusesLayout& layout) const override
 -     {
 -         if (! isGenerator)
 -             if (layout.getMainOutputChannelSet() != channelSet)
 -                 return false;
 - 
 -         if (layout.getMainInputChannelSet() != channelSet)
 -             return false;
 - 
 -         return true;
 -     }
 - 
 -     //==============================================================================
 -     void fillInPluginDescription (PluginDescription& description) const override
 -     {
 -         description = getPluginDescription (name + ":" + state,
 -                                             isGenerator,
 -                                             hasMidi,
 -                                             channelSet);
 -     }
 - 
 -     static PluginDescription getPluginDescription (const String& identifier,
 -                                                    bool registerAsGenerator,
 -                                                    bool acceptsMidi,
 -                                                    const AudioChannelSet& channelSetToUse
 -                                                       = AudioChannelSet::stereo())
 -     {
 -         PluginDescription descr;
 -         auto pluginName  = identifier.upToFirstOccurrenceOf (":", false, false);
 -         auto pluginState = identifier.fromFirstOccurrenceOf (":", false, false);
 - 
 -         descr.name              = pluginName;
 -         descr.descriptiveName   = pluginName;
 -         descr.pluginFormatName  = "Internal";
 -         descr.category          = (registerAsGenerator ? (acceptsMidi ? "Synth" : "Generator") : "Effect");
 -         descr.manufacturerName  = "JUCE";
 -         descr.version           = ProjectInfo::versionString;
 -         descr.fileOrIdentifier  = pluginName + ":" + pluginState;
 -         descr.uid               = pluginName.hashCode();
 -         descr.isInstrument      = (acceptsMidi && registerAsGenerator);
 -         descr.numInputChannels  = (registerAsGenerator ? 0 : channelSetToUse.size());
 -         descr.numOutputChannels = channelSetToUse.size();
 - 
 -         return descr;
 -     }
 - private:
 -     static BusesProperties getBusProperties (bool registerAsGenerator,
 -                                              const AudioChannelSet& channelSetToUse)
 -     {
 -         return registerAsGenerator ? BusesProperties().withOutput ("Output", channelSetToUse)
 -                                    : BusesProperties().withInput  ("Input",  channelSetToUse)
 -                                                       .withOutput ("Output", channelSetToUse);
 -     }
 - 
 -     //==============================================================================
 -     String name, state;
 -     bool isGenerator, hasMidi;
 -     AudioChannelSet channelSet;
 - 
 -     //==============================================================================
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InternalPlugin)
 - };
 - 
 - //==============================================================================
 - class SineWaveSynth :   public InternalPlugin
 - {
 - public:
 -     SineWaveSynth (const PluginDescription& descr)  : InternalPlugin (descr)
 -     {
 -         const int numVoices = 8;
 - 
 -         // Add some voices...
 -         for (int i = numVoices; --i >= 0;)
 -             synth.addVoice (new SineWaveVoice());
 - 
 -         // ..and give the synth a sound to play
 -         synth.addSound (new SineWaveSound());
 -     }
 - 
 -     static String getIdentifier()
 -     {
 -         return "Sine Wave Synth";
 -     }
 - 
 -     static PluginDescription getPluginDescription()
 -     {
 -         return InternalPlugin::getPluginDescription (getIdentifier(), true, true);
 -     }
 - 
 -     //==============================================================================
 -     void prepareToPlay (double newSampleRate, int) override
 -     {
 -         synth.setCurrentPlaybackSampleRate (newSampleRate);
 -     }
 - 
 -     void releaseResources() override {}
 - 
 -     //==============================================================================
 -     void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override
 -     {
 -         const int numSamples = buffer.getNumSamples();
 - 
 -         buffer.clear();
 -         synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
 -         buffer.applyGain (0.8f);
 -     }
 - 
 -     using InternalPlugin::processBlock;
 - 
 - private:
 -     //==============================================================================
 -     struct SineWaveSound  : public SynthesiserSound
 -     {
 -         SineWaveSound() = default;
 - 
 -         bool appliesToNote (int /*midiNoteNumber*/) override    { return true; }
 -         bool appliesToChannel (int /*midiChannel*/) override    { return true; }
 -     };
 - 
 -     struct SineWaveVoice  : public SynthesiserVoice
 -     {
 -         SineWaveVoice() = default;
 - 
 -         bool canPlaySound (SynthesiserSound* sound) override
 -         {
 -             return dynamic_cast<SineWaveSound*> (sound) != nullptr;
 -         }
 - 
 -         void startNote (int midiNoteNumber, float velocity,
 -                         SynthesiserSound* /*sound*/,
 -                         int /*currentPitchWheelPosition*/) override
 -         {
 -             currentAngle = 0.0;
 -             level = velocity * 0.15;
 -             tailOff = 0.0;
 - 
 -             double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
 -             double cyclesPerSample = cyclesPerSecond / getSampleRate();
 - 
 -             angleDelta = cyclesPerSample * 2.0 * double_Pi;
 -         }
 - 
 -         void stopNote (float /*velocity*/, bool allowTailOff) override
 -         {
 -             if (allowTailOff)
 -             {
 -                 // start a tail-off by setting this flag. The render callback will pick up on
 -                 // this and do a fade out, calling clearCurrentNote() when it's finished.
 - 
 -                 if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the
 -                     // stopNote method could be called more than once.
 -                     tailOff = 1.0;
 -             }
 -             else
 -             {
 -                 // we're being told to stop playing immediately, so reset everything..
 - 
 -                 clearCurrentNote();
 -                 angleDelta = 0.0;
 -             }
 -         }
 - 
 -         void pitchWheelMoved (int /*newValue*/) override
 -         {
 -             // not implemented for the purposes of this demo!
 -         }
 - 
 -         void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override
 -         {
 -             // not implemented for the purposes of this demo!
 -         }
 - 
 -         void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples) override
 -         {
 -             if (angleDelta != 0.0)
 -             {
 -                 if (tailOff > 0)
 -                 {
 -                     while (--numSamples >= 0)
 -                     {
 -                         const float currentSample = (float) (sin (currentAngle) * level * tailOff);
 - 
 -                         for (int i = outputBuffer.getNumChannels(); --i >= 0;)
 -                             outputBuffer.addSample (i, startSample, currentSample);
 - 
 -                         currentAngle += angleDelta;
 -                         ++startSample;
 - 
 -                         tailOff *= 0.99;
 - 
 -                         if (tailOff <= 0.005)
 -                         {
 -                             // tells the synth that this voice has stopped
 -                             clearCurrentNote();
 - 
 -                             angleDelta = 0.0;
 -                             break;
 -                         }
 -                     }
 -                 }
 -                 else
 -                 {
 -                     while (--numSamples >= 0)
 -                     {
 -                         const float currentSample = (float) (sin (currentAngle) * level);
 - 
 -                         for (int i = outputBuffer.getNumChannels(); --i >= 0;)
 -                             outputBuffer.addSample (i, startSample, currentSample);
 - 
 -                         currentAngle += angleDelta;
 -                         ++startSample;
 -                     }
 -                 }
 -             }
 -         }
 - 
 -         using SynthesiserVoice::renderNextBlock;
 - 
 -     private:
 -         double currentAngle = 0, angleDelta = 0, level = 0, tailOff = 0;
 -     };
 - 
 -     //==============================================================================
 -     Synthesiser synth;
 - 
 -     //==============================================================================
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SineWaveSynth)
 - };
 - 
 - //==============================================================================
 - class ReverbPlugin    : public InternalPlugin
 - {
 - public:
 -     ReverbPlugin (const PluginDescription& descr) :   InternalPlugin (descr)
 -     {}
 - 
 -     static String getIdentifier()
 -     {
 -         return "Reverb";
 -     }
 - 
 -     static PluginDescription getPluginDescription()
 -     {
 -         return InternalPlugin::getPluginDescription (getIdentifier(), false, false);
 -     }
 - 
 -     void prepareToPlay (double newSampleRate, int) override
 -     {
 -         reverb.setSampleRate (newSampleRate);
 -     }
 - 
 -     void reset() override
 -     {
 -         reverb.reset();
 -     }
 - 
 -     void releaseResources() override {}
 - 
 -     void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override
 -     {
 -         auto numChannels = buffer.getNumChannels();
 - 
 -         if (numChannels == 1)
 -             reverb.processMono (buffer.getWritePointer (0), buffer.getNumSamples());
 -         else
 -             reverb.processStereo (buffer.getWritePointer (0),
 -                                   buffer.getWritePointer (1),
 -                                   buffer.getNumSamples());
 - 
 -         for (int ch = 2; ch < numChannels; ++ch)
 -             buffer.clear (ch, 0, buffer.getNumSamples());
 -     }
 - 
 -     using InternalPlugin::processBlock;
 - 
 - private:
 -     Reverb reverb;
 - };
 - 
 - //==============================================================================
 - InternalPluginFormat::InternalPluginFormat()
 - {
 -     {
 -         AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
 -         p.fillInPluginDescription (audioOutDesc);
 -     }
 - 
 -     {
 -         AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
 -         p.fillInPluginDescription (audioInDesc);
 -     }
 - 
 -     {
 -         AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
 -         p.fillInPluginDescription (midiInDesc);
 -     }
 - }
 - 
 - std::unique_ptr<AudioPluginInstance> InternalPluginFormat::createInstance (const String& name)
 - {
 -     if (name == audioOutDesc.name) return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
 -     if (name == audioInDesc.name)  return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
 -     if (name == midiInDesc.name)   return std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor> (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
 - 
 -     if (name == SineWaveSynth::getIdentifier()) return std::make_unique<SineWaveSynth> (SineWaveSynth::getPluginDescription());
 -     if (name == ReverbPlugin::getIdentifier())  return std::make_unique<ReverbPlugin>  (ReverbPlugin::getPluginDescription());
 - 
 -     return {};
 - }
 - 
 - void InternalPluginFormat::createPluginInstance (const PluginDescription& desc,
 -                                                  double /*initialSampleRate*/, int /*initialBufferSize*/,
 -                                                  PluginCreationCallback callback)
 - {
 -     if (auto p = createInstance (desc.name))
 -         callback (std::move (p), {});
 -     else
 -         callback (nullptr, NEEDS_TRANS ("Invalid internal plugin name"));
 - }
 - 
 - bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const
 - {
 -     return false;
 - }
 - 
 - void InternalPluginFormat::getAllTypes (Array<PluginDescription>& results)
 - {
 -     results.add (audioInDesc, audioOutDesc, midiInDesc,
 -                  SineWaveSynth::getPluginDescription(),
 -                  ReverbPlugin::getPluginDescription());
 - }
 
 
  |