| 
							- /*
 -   ==============================================================================
 - 
 -    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"
 - #include "SinewaveSynth.h"
 - 
 - AudioProcessor* JUCE_CALLTYPE createPluginFilter();
 - 
 - 
 - //==============================================================================
 - JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor()
 -     : AudioProcessor (getBusesProperties())
 - {
 -     lastPosInfo.resetToDefault();
 - 
 -     // This creates our parameters. We'll keep some raw pointers to them in this class,
 -     // so that we can easily access them later, but the base class will take care of
 -     // deleting them for us.
 -     addParameter (gainParam  = new AudioParameterFloat ("gain",  "Gain",           0.0f, 1.0f, 0.9f));
 -     addParameter (delayParam = new AudioParameterFloat ("delay", "Delay Feedback", 0.0f, 1.0f, 0.5f));
 - 
 -     initialiseSynth();
 - }
 - 
 - JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor()
 - {
 - }
 - 
 - void JuceDemoPluginAudioProcessor::initialiseSynth()
 - {
 -     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());
 - }
 - 
 - //==============================================================================
 - bool JuceDemoPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
 - {
 -     // Only mono/stereo and input/output must have same layout
 -     const AudioChannelSet& mainOutput = layouts.getMainOutputChannelSet();
 -     const AudioChannelSet& mainInput  = layouts.getMainInputChannelSet();
 - 
 -     // input and output layout must either be the same or the input must be disabled altogether
 -     if (! mainInput.isDisabled() && mainInput != mainOutput)
 -         return false;
 - 
 -     // do not allow disabling the main buses
 -     if (mainOutput.isDisabled())
 -         return false;
 - 
 -     // only allow stereo and mono
 -     if (mainOutput.size() > 2)
 -         return false;
 - 
 -     return true;
 - }
 - 
 - AudioProcessor::BusesProperties JuceDemoPluginAudioProcessor::getBusesProperties()
 - {
 -     return BusesProperties().withInput  ("Input",  AudioChannelSet::stereo(), true)
 -                             .withOutput ("Output", AudioChannelSet::stereo(), true);
 - }
 - 
 - //==============================================================================
 - void JuceDemoPluginAudioProcessor::prepareToPlay (double newSampleRate, int /*samplesPerBlock*/)
 - {
 -     // Use this method as the place to do any pre-playback
 -     // initialisation that you need..
 -     synth.setCurrentPlaybackSampleRate (newSampleRate);
 -     keyboardState.reset();
 - 
 -     if (isUsingDoublePrecision())
 -     {
 -         delayBufferDouble.setSize (2, 12000);
 -         delayBufferFloat.setSize (1, 1);
 -     }
 -     else
 -     {
 -         delayBufferFloat.setSize (2, 12000);
 -         delayBufferDouble.setSize (1, 1);
 -     }
 - 
 -     reset();
 - }
 - 
 - void JuceDemoPluginAudioProcessor::releaseResources()
 - {
 -     // When playback stops, you can use this as an opportunity to free up any
 -     // spare memory, etc.
 -     keyboardState.reset();
 - }
 - 
 - void JuceDemoPluginAudioProcessor::reset()
 - {
 -     // Use this method as the place to clear any delay lines, buffers, etc, as it
 -     // means there's been a break in the audio's continuity.
 -     delayBufferFloat.clear();
 -     delayBufferDouble.clear();
 - }
 - 
 - template <typename FloatType>
 - void JuceDemoPluginAudioProcessor::process (AudioBuffer<FloatType>& buffer,
 -                                             MidiBuffer& midiMessages,
 -                                             AudioBuffer<FloatType>& delayBuffer)
 - {
 -     const int numSamples = buffer.getNumSamples();
 - 
 -     // In case we have more outputs than inputs, we'll clear any output
 -     // channels that didn't contain input data, (because these aren't
 -     // guaranteed to be empty - they may contain garbage).
 -     for (int i = getTotalNumInputChannels(); i < getTotalNumOutputChannels(); ++i)
 -         buffer.clear (i, 0, numSamples);
 - 
 -     // Now pass any incoming midi messages to our keyboard state object, and let it
 -     // add messages to the buffer if the user is clicking on the on-screen keys
 -     keyboardState.processNextMidiBuffer (midiMessages, 0, numSamples, true);
 - 
 -     // and now get our synth to process these midi events and generate its output.
 -     synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
 - 
 -     // Apply our delay effect to the new output..
 -     applyDelay (buffer, delayBuffer);
 - 
 -     applyGain (buffer, delayBuffer); // apply our gain-change to the outgoing data..
 - 
 -     // Now ask the host for the current time so we can store it to be displayed later...
 -     updateCurrentTimeInfoFromHost();
 - }
 - 
 - template <typename FloatType>
 - void JuceDemoPluginAudioProcessor::applyGain (AudioBuffer<FloatType>& buffer, AudioBuffer<FloatType>& delayBuffer)
 - {
 -     ignoreUnused (delayBuffer);
 -     const float gainLevel = *gainParam;
 - 
 -     for (int channel = 0; channel < getTotalNumOutputChannels(); ++channel)
 -         buffer.applyGain (channel, 0, buffer.getNumSamples(), gainLevel);
 - }
 - 
 - template <typename FloatType>
 - void JuceDemoPluginAudioProcessor::applyDelay (AudioBuffer<FloatType>& buffer, AudioBuffer<FloatType>& delayBuffer)
 - {
 -     const int numSamples = buffer.getNumSamples();
 -     const float delayLevel = *delayParam;
 - 
 -     int delayPos = 0;
 - 
 -     for (int channel = 0; channel < getTotalNumOutputChannels(); ++channel)
 -     {
 -         auto channelData = buffer.getWritePointer (channel);
 -         auto delayData = delayBuffer.getWritePointer (jmin (channel, delayBuffer.getNumChannels() - 1));
 -         delayPos = delayPosition;
 - 
 -         for (int i = 0; i < numSamples; ++i)
 -         {
 -             auto in = channelData[i];
 -             channelData[i] += delayData[delayPos];
 -             delayData[delayPos] = (delayData[delayPos] + in) * delayLevel;
 - 
 -             if (++delayPos >= delayBuffer.getNumSamples())
 -                 delayPos = 0;
 -         }
 -     }
 - 
 -     delayPosition = delayPos;
 - }
 - 
 - void JuceDemoPluginAudioProcessor::updateCurrentTimeInfoFromHost()
 - {
 -     if (AudioPlayHead* ph = getPlayHead())
 -     {
 -         AudioPlayHead::CurrentPositionInfo newTime;
 - 
 -         if (ph->getCurrentPosition (newTime))
 -         {
 -             lastPosInfo = newTime;  // Successfully got the current time from the host..
 -             return;
 -         }
 -     }
 - 
 -     // If the host fails to provide the current time, we'll just reset our copy to a default..
 -     lastPosInfo.resetToDefault();
 - }
 - 
 - //==============================================================================
 - AudioProcessorEditor* JuceDemoPluginAudioProcessor::createEditor()
 - {
 -     return new JuceDemoPluginAudioProcessorEditor (*this);
 - }
 - 
 - //==============================================================================
 - void JuceDemoPluginAudioProcessor::getStateInformation (MemoryBlock& destData)
 - {
 -     // You should use this method to store your parameters in the memory block.
 -     // Here's an example of how you can use XML to make it easy and more robust:
 - 
 -     // Create an outer XML element..
 -     XmlElement xml ("MYPLUGINSETTINGS");
 - 
 -     // add some attributes to it..
 -     xml.setAttribute ("uiWidth", lastUIWidth);
 -     xml.setAttribute ("uiHeight", lastUIHeight);
 - 
 -     // Store the values of all our parameters, using their param ID as the XML attribute
 -     for (auto* param : getParameters())
 -         if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (param))
 -             xml.setAttribute (p->paramID, p->getValue());
 - 
 -     // then use this helper function to stuff it into the binary blob and return it..
 -     copyXmlToBinary (xml, destData);
 - }
 - 
 - void JuceDemoPluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
 - {
 -     // You should use this method to restore your parameters from this memory block,
 -     // whose contents will have been created by the getStateInformation() call.
 - 
 -     // This getXmlFromBinary() helper function retrieves our XML from the binary blob..
 -     ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
 - 
 -     if (xmlState != nullptr)
 -     {
 -         // make sure that it's actually our type of XML object..
 -         if (xmlState->hasTagName ("MYPLUGINSETTINGS"))
 -         {
 -             // ok, now pull out our last window size..
 -             lastUIWidth  = jmax (xmlState->getIntAttribute ("uiWidth", lastUIWidth), 400);
 -             lastUIHeight = jmax (xmlState->getIntAttribute ("uiHeight", lastUIHeight), 200);
 - 
 -             // Now reload our parameters..
 -             for (auto* param : getParameters())
 -                 if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (param))
 -                     p->setValue ((float) xmlState->getDoubleAttribute (p->paramID, p->getValue()));
 -         }
 -     }
 - }
 - 
 - void JuceDemoPluginAudioProcessor::updateTrackProperties (const TrackProperties& properties)
 - {
 -     trackProperties = properties;
 - 
 -     if (auto* editor = dynamic_cast<JuceDemoPluginAudioProcessorEditor*> (getActiveEditor()))
 -         editor->updateTrackProperties ();
 - }
 - 
 - //==============================================================================
 - // This creates new instances of the plugin..
 - AudioProcessor* JUCE_CALLTYPE createPluginFilter()
 - {
 -     return new JuceDemoPluginAudioProcessor();
 - }
 
 
  |