- clean working copy for leaving SVN
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated by the Jucer!
|
||||
|
||||
It contains the basic startup code for a Juce application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "PluginProcessor.h"
|
||||
#include "PluginEditor.h"
|
||||
|
||||
//==============================================================================
|
||||
JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor& owner)
|
||||
: AudioProcessorEditor (owner),
|
||||
midiKeyboard (owner.keyboardState, MidiKeyboardComponent::horizontalKeyboard),
|
||||
infoLabel (String::empty),
|
||||
gainLabel ("", "Throughput level:"),
|
||||
delayLabel ("", "Delay:"),
|
||||
gainSlider ("gain"),
|
||||
delaySlider ("delay")
|
||||
{
|
||||
// add some sliders..
|
||||
addAndMakeVisible (gainSlider);
|
||||
gainSlider.setSliderStyle (Slider::Rotary);
|
||||
gainSlider.addListener (this);
|
||||
gainSlider.setRange (0.0, 1.0, 0.01);
|
||||
|
||||
addAndMakeVisible (delaySlider);
|
||||
delaySlider.setSliderStyle (Slider::Rotary);
|
||||
delaySlider.addListener (this);
|
||||
delaySlider.setRange (0.0, 1.0, 0.01);
|
||||
|
||||
// add some labels for the sliders..
|
||||
gainLabel.attachToComponent (&gainSlider, false);
|
||||
gainLabel.setFont (Font (11.0f));
|
||||
|
||||
delayLabel.attachToComponent (&delaySlider, false);
|
||||
delayLabel.setFont (Font (11.0f));
|
||||
|
||||
// add the midi keyboard component..
|
||||
addAndMakeVisible (midiKeyboard);
|
||||
|
||||
// add a label that will display the current timecode and status..
|
||||
addAndMakeVisible (infoLabel);
|
||||
infoLabel.setColour (Label::textColourId, Colours::blue);
|
||||
|
||||
// add the triangular resizer component for the bottom-right of the UI
|
||||
addAndMakeVisible (resizer = new ResizableCornerComponent (this, &resizeLimits));
|
||||
resizeLimits.setSizeLimits (150, 150, 800, 300);
|
||||
|
||||
// set our component's initial size to be the last one that was stored in the filter's settings
|
||||
setSize (owner.lastUIWidth,
|
||||
owner.lastUIHeight);
|
||||
|
||||
startTimer (50);
|
||||
}
|
||||
|
||||
JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void JuceDemoPluginAudioProcessorEditor::paint (Graphics& g)
|
||||
{
|
||||
g.setGradientFill (ColourGradient (Colours::white, 0, 0,
|
||||
Colours::grey, 0, (float) getHeight(), false));
|
||||
g.fillAll();
|
||||
}
|
||||
|
||||
void JuceDemoPluginAudioProcessorEditor::resized()
|
||||
{
|
||||
infoLabel.setBounds (10, 4, 400, 25);
|
||||
gainSlider.setBounds (20, 60, 150, 40);
|
||||
delaySlider.setBounds (200, 60, 150, 40);
|
||||
|
||||
const int keyboardHeight = 70;
|
||||
midiKeyboard.setBounds (4, getHeight() - keyboardHeight - 4, getWidth() - 8, keyboardHeight);
|
||||
|
||||
resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16);
|
||||
|
||||
getProcessor().lastUIWidth = getWidth();
|
||||
getProcessor().lastUIHeight = getHeight();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// This timer periodically checks whether any of the filter's parameters have changed...
|
||||
void JuceDemoPluginAudioProcessorEditor::timerCallback()
|
||||
{
|
||||
JuceDemoPluginAudioProcessor& ourProcessor = getProcessor();
|
||||
|
||||
AudioPlayHead::CurrentPositionInfo newPos (ourProcessor.lastPosInfo);
|
||||
|
||||
if (lastDisplayedPosition != newPos)
|
||||
displayPositionInfo (newPos);
|
||||
|
||||
gainSlider.setValue (ourProcessor.gain, dontSendNotification);
|
||||
delaySlider.setValue (ourProcessor.delay, dontSendNotification);
|
||||
}
|
||||
|
||||
// This is our Slider::Listener callback, when the user drags a slider.
|
||||
void JuceDemoPluginAudioProcessorEditor::sliderValueChanged (Slider* slider)
|
||||
{
|
||||
if (slider == &gainSlider)
|
||||
{
|
||||
// It's vital to use setParameterNotifyingHost to change any parameters that are automatable
|
||||
// by the host, rather than just modifying them directly, otherwise the host won't know
|
||||
// that they've changed.
|
||||
getProcessor().setParameterNotifyingHost (JuceDemoPluginAudioProcessor::gainParam,
|
||||
(float) gainSlider.getValue());
|
||||
}
|
||||
else if (slider == &delaySlider)
|
||||
{
|
||||
getProcessor().setParameterNotifyingHost (JuceDemoPluginAudioProcessor::delayParam,
|
||||
(float) delaySlider.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// quick-and-dirty function to format a timecode string
|
||||
static String timeToTimecodeString (const double seconds)
|
||||
{
|
||||
const double absSecs = std::abs (seconds);
|
||||
|
||||
const int hours = (int) (absSecs / (60.0 * 60.0));
|
||||
const int mins = ((int) (absSecs / 60.0)) % 60;
|
||||
const int secs = ((int) absSecs) % 60;
|
||||
|
||||
String s (seconds < 0 ? "-" : "");
|
||||
|
||||
s << String (hours).paddedLeft ('0', 2) << ":"
|
||||
<< String (mins) .paddedLeft ('0', 2) << ":"
|
||||
<< String (secs) .paddedLeft ('0', 2) << ":"
|
||||
<< String (roundToInt (absSecs * 1000) % 1000).paddedLeft ('0', 3);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// quick-and-dirty function to format a bars/beats string
|
||||
static String ppqToBarsBeatsString (double ppq, double /*lastBarPPQ*/, int numerator, int denominator)
|
||||
{
|
||||
if (numerator == 0 || denominator == 0)
|
||||
return "1|1|0";
|
||||
|
||||
const int ppqPerBar = (numerator * 4 / denominator);
|
||||
const double beats = (fmod (ppq, ppqPerBar) / ppqPerBar) * numerator;
|
||||
|
||||
const int bar = ((int) ppq) / ppqPerBar + 1;
|
||||
const int beat = ((int) beats) + 1;
|
||||
const int ticks = ((int) (fmod (beats, 1.0) * 960.0 + 0.5));
|
||||
|
||||
String s;
|
||||
s << bar << '|' << beat << '|' << ticks;
|
||||
return s;
|
||||
}
|
||||
|
||||
// Updates the text in our position label.
|
||||
void JuceDemoPluginAudioProcessorEditor::displayPositionInfo (const AudioPlayHead::CurrentPositionInfo& pos)
|
||||
{
|
||||
lastDisplayedPosition = pos;
|
||||
String displayText;
|
||||
displayText.preallocateBytes (128);
|
||||
|
||||
displayText << String (pos.bpm, 2) << " bpm, "
|
||||
<< pos.timeSigNumerator << '/' << pos.timeSigDenominator
|
||||
<< " - " << timeToTimecodeString (pos.timeInSeconds)
|
||||
<< " - " << ppqToBarsBeatsString (pos.ppqPosition, pos.ppqPositionOfLastBarStart,
|
||||
pos.timeSigNumerator, pos.timeSigDenominator);
|
||||
|
||||
if (pos.isRecording)
|
||||
displayText << " (recording)";
|
||||
else if (pos.isPlaying)
|
||||
displayText << " (playing)";
|
||||
|
||||
infoLabel.setText ("[" + SystemStats::getJUCEVersion() + "] " + displayText, dontSendNotification);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated by the Jucer!
|
||||
|
||||
It contains the basic startup code for a Juce application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __PLUGINEDITOR_H_4ACCBAA__
|
||||
#define __PLUGINEDITOR_H_4ACCBAA__
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "PluginProcessor.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** This is the editor component that our filter will display.
|
||||
*/
|
||||
class JuceDemoPluginAudioProcessorEditor : public AudioProcessorEditor,
|
||||
public SliderListener,
|
||||
public Timer
|
||||
{
|
||||
public:
|
||||
JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor&);
|
||||
~JuceDemoPluginAudioProcessorEditor();
|
||||
|
||||
//==============================================================================
|
||||
void timerCallback() override;
|
||||
void paint (Graphics&) override;
|
||||
void resized() override;
|
||||
void sliderValueChanged (Slider*) override;
|
||||
|
||||
private:
|
||||
MidiKeyboardComponent midiKeyboard;
|
||||
Label infoLabel, gainLabel, delayLabel;
|
||||
Slider gainSlider, delaySlider;
|
||||
ScopedPointer<ResizableCornerComponent> resizer;
|
||||
ComponentBoundsConstrainer resizeLimits;
|
||||
|
||||
AudioPlayHead::CurrentPositionInfo lastDisplayedPosition;
|
||||
|
||||
JuceDemoPluginAudioProcessor& getProcessor() const
|
||||
{
|
||||
return static_cast<JuceDemoPluginAudioProcessor&> (processor);
|
||||
}
|
||||
|
||||
void displayPositionInfo (const AudioPlayHead::CurrentPositionInfo& pos);
|
||||
};
|
||||
|
||||
|
||||
#endif // __PLUGINEDITOR_H_4ACCBAA__
|
||||
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated by the Jucer!
|
||||
|
||||
It contains the basic startup code for a Juce application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "PluginProcessor.h"
|
||||
#include "PluginEditor.h"
|
||||
|
||||
AudioProcessor* JUCE_CALLTYPE createPluginFilter();
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A demo synth sound that's just a basic sine wave.. */
|
||||
class SineWaveSound : public SynthesiserSound
|
||||
{
|
||||
public:
|
||||
SineWaveSound() {}
|
||||
|
||||
bool appliesToNote (int /*midiNoteNumber*/) override { return true; }
|
||||
bool appliesToChannel (int /*midiChannel*/) override { return true; }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** A simple demo synth voice that just plays a sine wave.. */
|
||||
class SineWaveVoice : public SynthesiserVoice
|
||||
{
|
||||
public:
|
||||
SineWaveVoice()
|
||||
: angleDelta (0.0),
|
||||
tailOff (0.0)
|
||||
{
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
// can't be bothered implementing this for the demo!
|
||||
}
|
||||
|
||||
void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override
|
||||
{
|
||||
// not interested in controllers in this case.
|
||||
}
|
||||
|
||||
void renderNextBlock (AudioSampleBuffer& 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
double currentAngle, angleDelta, level, tailOff;
|
||||
};
|
||||
|
||||
const float defaultGain = 1.0f;
|
||||
const float defaultDelay = 0.5f;
|
||||
|
||||
//==============================================================================
|
||||
JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor()
|
||||
: delayBuffer (2, 12000)
|
||||
{
|
||||
// Set up some default values..
|
||||
gain = defaultGain;
|
||||
delay = defaultDelay;
|
||||
|
||||
lastUIWidth = 400;
|
||||
lastUIHeight = 200;
|
||||
|
||||
lastPosInfo.resetToDefault();
|
||||
delayPosition = 0;
|
||||
|
||||
// Initialise the synth...
|
||||
for (int i = 4; --i >= 0;)
|
||||
synth.addVoice (new SineWaveVoice()); // These voices will play our custom sine-wave sounds..
|
||||
|
||||
synth.addSound (new SineWaveSound());
|
||||
}
|
||||
|
||||
JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int JuceDemoPluginAudioProcessor::getNumParameters()
|
||||
{
|
||||
return totalNumParams;
|
||||
}
|
||||
|
||||
float JuceDemoPluginAudioProcessor::getParameter (int index)
|
||||
{
|
||||
// This method will be called by the host, probably on the audio thread, so
|
||||
// it's absolutely time-critical. Don't use critical sections or anything
|
||||
// UI-related, or anything at all that may block in any way!
|
||||
switch (index)
|
||||
{
|
||||
case gainParam: return gain;
|
||||
case delayParam: return delay;
|
||||
default: return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void JuceDemoPluginAudioProcessor::setParameter (int index, float newValue)
|
||||
{
|
||||
// This method will be called by the host, probably on the audio thread, so
|
||||
// it's absolutely time-critical. Don't use critical sections or anything
|
||||
// UI-related, or anything at all that may block in any way!
|
||||
switch (index)
|
||||
{
|
||||
case gainParam: gain = newValue; break;
|
||||
case delayParam: delay = newValue; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
float JuceDemoPluginAudioProcessor::getParameterDefaultValue (int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case gainParam: return defaultGain;
|
||||
case delayParam: return defaultDelay;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const String JuceDemoPluginAudioProcessor::getParameterName (int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case gainParam: return "gain";
|
||||
case delayParam: return "delay";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
const String JuceDemoPluginAudioProcessor::getParameterText (int index)
|
||||
{
|
||||
return String (getParameter (index), 2);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void JuceDemoPluginAudioProcessor::prepareToPlay (double sampleRate, int /*samplesPerBlock*/)
|
||||
{
|
||||
// Use this method as the place to do any pre-playback
|
||||
// initialisation that you need..
|
||||
synth.setCurrentPlaybackSampleRate (sampleRate);
|
||||
keyboardState.reset();
|
||||
delayBuffer.clear();
|
||||
}
|
||||
|
||||
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.
|
||||
delayBuffer.clear();
|
||||
}
|
||||
|
||||
void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
|
||||
{
|
||||
const int numSamples = buffer.getNumSamples();
|
||||
int channel, dp = 0;
|
||||
|
||||
// Go through the incoming data, and apply our gain to it...
|
||||
for (channel = 0; channel < getNumInputChannels(); ++channel)
|
||||
buffer.applyGain (channel, 0, buffer.getNumSamples(), gain);
|
||||
|
||||
// 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 the synth to process these midi events and generate its output.
|
||||
synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
|
||||
|
||||
// Apply our delay effect to the new output..
|
||||
for (channel = 0; channel < getNumInputChannels(); ++channel)
|
||||
{
|
||||
float* channelData = buffer.getWritePointer (channel);
|
||||
float* delayData = delayBuffer.getWritePointer (jmin (channel, delayBuffer.getNumChannels() - 1));
|
||||
dp = delayPosition;
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
const float in = channelData[i];
|
||||
channelData[i] += delayData[dp];
|
||||
delayData[dp] = (delayData[dp] + in) * delay;
|
||||
if (++dp >= delayBuffer.getNumSamples())
|
||||
dp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delayPosition = dp;
|
||||
|
||||
// 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 = getNumInputChannels(); i < getNumOutputChannels(); ++i)
|
||||
buffer.clear (i, 0, buffer.getNumSamples());
|
||||
|
||||
// ask the host for the current time so we can display it...
|
||||
AudioPlayHead::CurrentPositionInfo newTime;
|
||||
|
||||
if (getPlayHead() != nullptr && getPlayHead()->getCurrentPosition (newTime))
|
||||
{
|
||||
// Successfully got the current time from the host..
|
||||
lastPosInfo = newTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the host fails to fill-in the current time, we'll just clear it 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);
|
||||
xml.setAttribute ("gain", gain);
|
||||
xml.setAttribute ("delay", delay);
|
||||
|
||||
// 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 parameters..
|
||||
lastUIWidth = xmlState->getIntAttribute ("uiWidth", lastUIWidth);
|
||||
lastUIHeight = xmlState->getIntAttribute ("uiHeight", lastUIHeight);
|
||||
|
||||
gain = (float) xmlState->getDoubleAttribute ("gain", gain);
|
||||
delay = (float) xmlState->getDoubleAttribute ("delay", delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const String JuceDemoPluginAudioProcessor::getInputChannelName (const int channelIndex) const
|
||||
{
|
||||
return String (channelIndex + 1);
|
||||
}
|
||||
|
||||
const String JuceDemoPluginAudioProcessor::getOutputChannelName (const int channelIndex) const
|
||||
{
|
||||
return String (channelIndex + 1);
|
||||
}
|
||||
|
||||
bool JuceDemoPluginAudioProcessor::isInputChannelStereoPair (int /*index*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JuceDemoPluginAudioProcessor::isOutputChannelStereoPair (int /*index*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JuceDemoPluginAudioProcessor::acceptsMidi() const
|
||||
{
|
||||
#if JucePlugin_WantsMidiInput
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool JuceDemoPluginAudioProcessor::producesMidi() const
|
||||
{
|
||||
#if JucePlugin_ProducesMidiOutput
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool JuceDemoPluginAudioProcessor::silenceInProducesSilenceOut() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double JuceDemoPluginAudioProcessor::getTailLengthSeconds() const
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// This creates new instances of the plugin..
|
||||
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
||||
{
|
||||
return new JuceDemoPluginAudioProcessor();
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated by the Jucer!
|
||||
|
||||
It contains the basic startup code for a Juce application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __PLUGINPROCESSOR_H_526ED7A9__
|
||||
#define __PLUGINPROCESSOR_H_526ED7A9__
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
As the name suggest, this class does the actual audio processing.
|
||||
*/
|
||||
class JuceDemoPluginAudioProcessor : public AudioProcessor
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
JuceDemoPluginAudioProcessor();
|
||||
~JuceDemoPluginAudioProcessor();
|
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (double sampleRate, int samplesPerBlock) override;
|
||||
void releaseResources() override;
|
||||
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override;
|
||||
void reset() override;
|
||||
|
||||
//==============================================================================
|
||||
bool hasEditor() const override { return true; }
|
||||
AudioProcessorEditor* createEditor() override;
|
||||
|
||||
//==============================================================================
|
||||
const String getName() const override { return JucePlugin_Name; }
|
||||
|
||||
int getNumParameters() override;
|
||||
float getParameter (int index) override;
|
||||
float getParameterDefaultValue (int index) override;
|
||||
void setParameter (int index, float newValue) override;
|
||||
const String getParameterName (int index) override;
|
||||
const String getParameterText (int index) override;
|
||||
|
||||
const String getInputChannelName (int channelIndex) const override;
|
||||
const String getOutputChannelName (int channelIndex) const override;
|
||||
bool isInputChannelStereoPair (int index) const override;
|
||||
bool isOutputChannelStereoPair (int index) const override;
|
||||
|
||||
bool acceptsMidi() const override;
|
||||
bool producesMidi() const override;
|
||||
bool silenceInProducesSilenceOut() const override;
|
||||
double getTailLengthSeconds() const override;
|
||||
|
||||
//==============================================================================
|
||||
int getNumPrograms() override { return 1; }
|
||||
int getCurrentProgram() override { return 0; }
|
||||
void setCurrentProgram (int /*index*/) override {}
|
||||
const String getProgramName (int /*index*/) override { return "Default"; }
|
||||
void changeProgramName (int /*index*/, const String& /*newName*/) override {}
|
||||
|
||||
//==============================================================================
|
||||
void getStateInformation (MemoryBlock& destData) override;
|
||||
void setStateInformation (const void* data, int sizeInBytes) override;
|
||||
|
||||
//==============================================================================
|
||||
// These properties are public so that our editor component can access them
|
||||
// A bit of a hacky way to do it, but it's only a demo! Obviously in your own
|
||||
// code you'll do this much more neatly..
|
||||
|
||||
// this is kept up to date with the midi messages that arrive, and the UI component
|
||||
// registers with it so it can represent the incoming messages
|
||||
MidiKeyboardState keyboardState;
|
||||
|
||||
// this keeps a copy of the last set of time info that was acquired during an audio
|
||||
// callback - the UI component will read this and display it.
|
||||
AudioPlayHead::CurrentPositionInfo lastPosInfo;
|
||||
|
||||
// these are used to persist the UI's size - the values are stored along with the
|
||||
// filter's other parameters, and the UI component will update them when it gets
|
||||
// resized.
|
||||
int lastUIWidth, lastUIHeight;
|
||||
|
||||
//==============================================================================
|
||||
enum Parameters
|
||||
{
|
||||
gainParam = 0,
|
||||
delayParam,
|
||||
|
||||
totalNumParams
|
||||
};
|
||||
|
||||
float gain, delay;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioSampleBuffer delayBuffer;
|
||||
int delayPosition;
|
||||
|
||||
// the synth!
|
||||
Synthesiser synth;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceDemoPluginAudioProcessor)
|
||||
};
|
||||
|
||||
#endif // __PLUGINPROCESSOR_H_526ED7A9__
|
||||
Reference in New Issue
Block a user