| @@ -21,6 +21,8 @@ | |||||
| <Add option="-g"/> | <Add option="-g"/> | ||||
| <Add option="-D__MINGW__=1"/> | <Add option="-D__MINGW__=1"/> | ||||
| <Add option="-D__MINGW_EXTENSION="/> | <Add option="-D__MINGW_EXTENSION="/> | ||||
| <Add option="-DDEBUG=1"/> | |||||
| <Add option="-D_DEBUG=1"/> | |||||
| <Add option="-DJUCER_CODEBLOCKS_20734A5D=1"/> | <Add option="-DJUCER_CODEBLOCKS_20734A5D=1"/> | ||||
| <Add option="-DJUCE_APP_VERSION=3.1.0"/> | <Add option="-DJUCE_APP_VERSION=3.1.0"/> | ||||
| <Add option="-DJUCE_APP_VERSION_HEX=0x30100"/> | <Add option="-DJUCE_APP_VERSION_HEX=0x30100"/> | ||||
| @@ -55,6 +57,7 @@ | |||||
| <Add option="-mstackrealign"/> | <Add option="-mstackrealign"/> | ||||
| <Add option="-D__MINGW__=1"/> | <Add option="-D__MINGW__=1"/> | ||||
| <Add option="-D__MINGW_EXTENSION="/> | <Add option="-D__MINGW_EXTENSION="/> | ||||
| <Add option="-DNDEBUG=1"/> | |||||
| <Add option="-DJUCER_CODEBLOCKS_20734A5D=1"/> | <Add option="-DJUCER_CODEBLOCKS_20734A5D=1"/> | ||||
| <Add option="-DJUCE_APP_VERSION=3.1.0"/> | <Add option="-DJUCE_APP_VERSION=3.1.0"/> | ||||
| <Add option="-DJUCE_APP_VERSION_HEX=0x30100"/> | <Add option="-DJUCE_APP_VERSION_HEX=0x30100"/> | ||||
| @@ -12,9 +12,9 @@ | |||||
| #include "PluginEditor.h" | #include "PluginEditor.h" | ||||
| //============================================================================== | //============================================================================== | ||||
| JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor* ownerFilter) | |||||
| : AudioProcessorEditor (ownerFilter), | |||||
| midiKeyboard (ownerFilter->keyboardState, MidiKeyboardComponent::horizontalKeyboard), | |||||
| JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor& owner) | |||||
| : AudioProcessorEditor (owner), | |||||
| midiKeyboard (owner.keyboardState, MidiKeyboardComponent::horizontalKeyboard), | |||||
| infoLabel (String::empty), | infoLabel (String::empty), | ||||
| gainLabel ("", "Throughput level:"), | gainLabel ("", "Throughput level:"), | ||||
| delayLabel ("", "Delay:"), | delayLabel ("", "Delay:"), | ||||
| @@ -51,8 +51,8 @@ JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemo | |||||
| resizeLimits.setSizeLimits (150, 150, 800, 300); | 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 | // set our component's initial size to be the last one that was stored in the filter's settings | ||||
| setSize (ownerFilter->lastUIWidth, | |||||
| ownerFilter->lastUIHeight); | |||||
| setSize (owner.lastUIWidth, | |||||
| owner.lastUIHeight); | |||||
| startTimer (50); | startTimer (50); | ||||
| } | } | ||||
| @@ -80,23 +80,23 @@ void JuceDemoPluginAudioProcessorEditor::resized() | |||||
| resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); | resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); | ||||
| getProcessor()->lastUIWidth = getWidth(); | |||||
| getProcessor()->lastUIHeight = getHeight(); | |||||
| getProcessor().lastUIWidth = getWidth(); | |||||
| getProcessor().lastUIHeight = getHeight(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| // This timer periodically checks whether any of the filter's parameters have changed... | // This timer periodically checks whether any of the filter's parameters have changed... | ||||
| void JuceDemoPluginAudioProcessorEditor::timerCallback() | void JuceDemoPluginAudioProcessorEditor::timerCallback() | ||||
| { | { | ||||
| JuceDemoPluginAudioProcessor* ourProcessor = getProcessor(); | |||||
| JuceDemoPluginAudioProcessor& ourProcessor = getProcessor(); | |||||
| AudioPlayHead::CurrentPositionInfo newPos (ourProcessor->lastPosInfo); | |||||
| AudioPlayHead::CurrentPositionInfo newPos (ourProcessor.lastPosInfo); | |||||
| if (lastDisplayedPosition != newPos) | if (lastDisplayedPosition != newPos) | ||||
| displayPositionInfo (newPos); | displayPositionInfo (newPos); | ||||
| gainSlider.setValue (ourProcessor->gain, dontSendNotification); | |||||
| delaySlider.setValue (ourProcessor->delay, dontSendNotification); | |||||
| gainSlider.setValue (ourProcessor.gain, dontSendNotification); | |||||
| delaySlider.setValue (ourProcessor.delay, dontSendNotification); | |||||
| } | } | ||||
| // This is our Slider::Listener callback, when the user drags a slider. | // This is our Slider::Listener callback, when the user drags a slider. | ||||
| @@ -107,13 +107,13 @@ void JuceDemoPluginAudioProcessorEditor::sliderValueChanged (Slider* slider) | |||||
| // It's vital to use setParameterNotifyingHost to change any parameters that are automatable | // 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 | // by the host, rather than just modifying them directly, otherwise the host won't know | ||||
| // that they've changed. | // that they've changed. | ||||
| getProcessor()->setParameterNotifyingHost (JuceDemoPluginAudioProcessor::gainParam, | |||||
| (float) gainSlider.getValue()); | |||||
| getProcessor().setParameterNotifyingHost (JuceDemoPluginAudioProcessor::gainParam, | |||||
| (float) gainSlider.getValue()); | |||||
| } | } | ||||
| else if (slider == &delaySlider) | else if (slider == &delaySlider) | ||||
| { | { | ||||
| getProcessor()->setParameterNotifyingHost (JuceDemoPluginAudioProcessor::delayParam, | |||||
| (float) delaySlider.getValue()); | |||||
| getProcessor().setParameterNotifyingHost (JuceDemoPluginAudioProcessor::delayParam, | |||||
| (float) delaySlider.getValue()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -23,7 +23,7 @@ class JuceDemoPluginAudioProcessorEditor : public AudioProcessorEditor, | |||||
| public Timer | public Timer | ||||
| { | { | ||||
| public: | public: | ||||
| JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor* ownerFilter); | |||||
| JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor&); | |||||
| ~JuceDemoPluginAudioProcessorEditor(); | ~JuceDemoPluginAudioProcessorEditor(); | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -41,9 +41,9 @@ private: | |||||
| AudioPlayHead::CurrentPositionInfo lastDisplayedPosition; | AudioPlayHead::CurrentPositionInfo lastDisplayedPosition; | ||||
| JuceDemoPluginAudioProcessor* getProcessor() const | |||||
| JuceDemoPluginAudioProcessor& getProcessor() const | |||||
| { | { | ||||
| return static_cast <JuceDemoPluginAudioProcessor*> (getAudioProcessor()); | |||||
| return static_cast<JuceDemoPluginAudioProcessor&> (processor); | |||||
| } | } | ||||
| void displayPositionInfo (const AudioPlayHead::CurrentPositionInfo& pos); | void displayPositionInfo (const AudioPlayHead::CurrentPositionInfo& pos); | ||||
| @@ -21,8 +21,8 @@ class SineWaveSound : public SynthesiserSound | |||||
| public: | public: | ||||
| SineWaveSound() {} | SineWaveSound() {} | ||||
| bool appliesToNote (const int /*midiNoteNumber*/) { return true; } | |||||
| bool appliesToChannel (const int /*midiChannel*/) { return true; } | |||||
| bool appliesToNote (const int /*midiNoteNumber*/) override { return true; } | |||||
| bool appliesToChannel (const int /*midiChannel*/) override { return true; } | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -36,13 +36,13 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| bool canPlaySound (SynthesiserSound* sound) | |||||
| bool canPlaySound (SynthesiserSound* sound) override | |||||
| { | { | ||||
| return dynamic_cast <SineWaveSound*> (sound) != 0; | return dynamic_cast <SineWaveSound*> (sound) != 0; | ||||
| } | } | ||||
| void startNote (int midiNoteNumber, float velocity, | void startNote (int midiNoteNumber, float velocity, | ||||
| SynthesiserSound* /*sound*/, int /*currentPitchWheelPosition*/) | |||||
| SynthesiserSound* /*sound*/, int /*currentPitchWheelPosition*/) override | |||||
| { | { | ||||
| currentAngle = 0.0; | currentAngle = 0.0; | ||||
| level = velocity * 0.15; | level = velocity * 0.15; | ||||
| @@ -54,7 +54,7 @@ public: | |||||
| angleDelta = cyclesPerSample * 2.0 * double_Pi; | angleDelta = cyclesPerSample * 2.0 * double_Pi; | ||||
| } | } | ||||
| void stopNote (bool allowTailOff) | |||||
| void stopNote (bool allowTailOff) override | |||||
| { | { | ||||
| if (allowTailOff) | if (allowTailOff) | ||||
| { | { | ||||
| @@ -74,17 +74,17 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void pitchWheelMoved (int /*newValue*/) | |||||
| void pitchWheelMoved (int /*newValue*/) override | |||||
| { | { | ||||
| // can't be bothered implementing this for the demo! | // can't be bothered implementing this for the demo! | ||||
| } | } | ||||
| void controllerMoved (int /*controllerNumber*/, int /*newValue*/) | |||||
| void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override | |||||
| { | { | ||||
| // not interested in controllers in this case. | // not interested in controllers in this case. | ||||
| } | } | ||||
| void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) | |||||
| void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override | |||||
| { | { | ||||
| if (angleDelta != 0.0) | if (angleDelta != 0.0) | ||||
| { | { | ||||
| @@ -303,7 +303,7 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi | |||||
| //============================================================================== | //============================================================================== | ||||
| AudioProcessorEditor* JuceDemoPluginAudioProcessor::createEditor() | AudioProcessorEditor* JuceDemoPluginAudioProcessor::createEditor() | ||||
| { | { | ||||
| return new JuceDemoPluginAudioProcessorEditor (this); | |||||
| return new JuceDemoPluginAudioProcessorEditor (*this); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -177,6 +177,20 @@ struct AAXClasses | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| static Colour getColourFromHighlightEnum (AAX_EHighlightColor colour) noexcept | |||||
| { | |||||
| switch (colour) | |||||
| { | |||||
| case AAX_eHighlightColor_Red: return Colours::red; | |||||
| case AAX_eHighlightColor_Blue: return Colours::blue; | |||||
| case AAX_eHighlightColor_Green: return Colours::green; | |||||
| case AAX_eHighlightColor_Yellow: return Colours::yellow; | |||||
| default: jassertfalse; break; | |||||
| } | |||||
| return Colours::black; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| class JuceAAX_Processor; | class JuceAAX_Processor; | ||||
| @@ -306,27 +320,40 @@ struct AAXClasses | |||||
| return AAX_ERROR_NULL_OBJECT; | return AAX_ERROR_NULL_OBJECT; | ||||
| } | } | ||||
| AAX_Result ParameterUpdated (AAX_CParamID /*paramID*/) override | |||||
| AAX_Result ParameterUpdated (AAX_CParamID) override | |||||
| { | { | ||||
| return AAX_SUCCESS; | return AAX_SUCCESS; | ||||
| } | } | ||||
| AAX_Result SetControlHighlightInfo (AAX_CParamID /*paramID*/, AAX_CBoolean /*isHighlighted*/, AAX_EHighlightColor) override | |||||
| AAX_Result SetControlHighlightInfo (AAX_CParamID paramID, AAX_CBoolean isHighlighted, AAX_EHighlightColor colour) override | |||||
| { | { | ||||
| return AAX_SUCCESS; | |||||
| if (component != nullptr && component->pluginEditor != nullptr) | |||||
| { | |||||
| AudioProcessorEditor::ParameterControlHighlightInfo info; | |||||
| info.parameterIndex = getParamIndexFromID (paramID); | |||||
| info.isHighlighted = isHighlighted; | |||||
| info.suggestedColour = getColourFromHighlightEnum (colour); | |||||
| component->pluginEditor->setControlHighlight (info); | |||||
| return AAX_SUCCESS; | |||||
| } | |||||
| return AAX_ERROR_NULL_OBJECT; | |||||
| } | } | ||||
| private: | private: | ||||
| class ContentWrapperComponent : public juce::Component | |||||
| struct ContentWrapperComponent : public juce::Component | |||||
| { | { | ||||
| public: | |||||
| ContentWrapperComponent (JuceAAX_GUI& gui, AudioProcessor& plugin) | ContentWrapperComponent (JuceAAX_GUI& gui, AudioProcessor& plugin) | ||||
| : owner (gui) | : owner (gui) | ||||
| { | { | ||||
| setOpaque (true); | setOpaque (true); | ||||
| addAndMakeVisible (pluginEditor = plugin.createEditorIfNeeded()); | |||||
| setBounds (pluginEditor->getLocalBounds()); | |||||
| setBroughtToFrontOnMouseClick (true); | setBroughtToFrontOnMouseClick (true); | ||||
| addAndMakeVisible (pluginEditor = plugin.createEditorIfNeeded()); | |||||
| if (pluginEditor != nullptr) | |||||
| setBounds (pluginEditor->getLocalBounds()); | |||||
| } | } | ||||
| ~ContentWrapperComponent() | ~ContentWrapperComponent() | ||||
| @@ -334,7 +361,7 @@ struct AAXClasses | |||||
| if (pluginEditor != nullptr) | if (pluginEditor != nullptr) | ||||
| { | { | ||||
| PopupMenu::dismissAllActiveMenus(); | PopupMenu::dismissAllActiveMenus(); | ||||
| pluginEditor->getAudioProcessor()->editorBeingDeleted (pluginEditor); | |||||
| pluginEditor->processor.editorBeingDeleted (pluginEditor); | |||||
| } | } | ||||
| } | } | ||||
| @@ -356,7 +383,6 @@ struct AAXClasses | |||||
| } | } | ||||
| } | } | ||||
| private: | |||||
| ScopedPointer<AudioProcessorEditor> pluginEditor; | ScopedPointer<AudioProcessorEditor> pluginEditor; | ||||
| JuceAAX_GUI& owner; | JuceAAX_GUI& owner; | ||||
| @@ -458,7 +458,7 @@ private: | |||||
| if (pluginEditor != nullptr) | if (pluginEditor != nullptr) | ||||
| { | { | ||||
| PopupMenu::dismissAllActiveMenus(); | PopupMenu::dismissAllActiveMenus(); | ||||
| pluginEditor->getAudioProcessor()->editorBeingDeleted (pluginEditor); | |||||
| pluginEditor->processor.editorBeingDeleted (pluginEditor); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1446,7 +1446,7 @@ public: | |||||
| warnOnFailure (view->removed()); | warnOnFailure (view->removed()); | ||||
| warnOnFailure (view->setFrame (nullptr)); | warnOnFailure (view->setFrame (nullptr)); | ||||
| getAudioProcessor()->editorBeingDeleted (this); | |||||
| processor.editorBeingDeleted (this); | |||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| dummyComponent.setView (nullptr); | dummyComponent.setView (nullptr); | ||||
| @@ -22,16 +22,21 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* const p) | |||||
| : owner (p) | |||||
| AudioProcessorEditor::AudioProcessorEditor (AudioProcessor& p) noexcept : processor (p) | |||||
| { | |||||
| } | |||||
| AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : processor (*p) | |||||
| { | { | ||||
| // the filter must be valid.. | // the filter must be valid.. | ||||
| jassert (owner != nullptr); | |||||
| jassert (p != nullptr); | |||||
| } | } | ||||
| AudioProcessorEditor::~AudioProcessorEditor() | AudioProcessorEditor::~AudioProcessorEditor() | ||||
| { | { | ||||
| // if this fails, then the wrapper hasn't called editorBeingDeleted() on the | // if this fails, then the wrapper hasn't called editorBeingDeleted() on the | ||||
| // filter for some reason.. | // filter for some reason.. | ||||
| jassert (owner->getActiveEditor() != this); | |||||
| jassert (processor.getActiveEditor() != this); | |||||
| } | } | ||||
| void AudioProcessorEditor::setControlHighlight (ParameterControlHighlightInfo) {} | |||||
| @@ -39,9 +39,11 @@ class JUCE_API AudioProcessorEditor : public Component | |||||
| { | { | ||||
| protected: | protected: | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates an editor for the specified processor. | |||||
| */ | |||||
| AudioProcessorEditor (AudioProcessor* owner); | |||||
| /** Creates an editor for the specified processor. */ | |||||
| AudioProcessorEditor (AudioProcessor&) noexcept; | |||||
| /** Creates an editor for the specified processor. */ | |||||
| AudioProcessorEditor (AudioProcessor*) noexcept; | |||||
| public: | public: | ||||
| /** Destructor. */ | /** Destructor. */ | ||||
| @@ -49,14 +51,31 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns a pointer to the processor that this editor represents. */ | |||||
| AudioProcessor* getAudioProcessor() const noexcept { return owner; } | |||||
| /** The AudioProcessor that this editor represents. */ | |||||
| AudioProcessor& processor; | |||||
| /** Returns a pointer to the processor that this editor represents. | |||||
| This method is here to support legacy code, but it's easier to just use the | |||||
| AudioProcessorEditor::processor member variable directly to get this object. | |||||
| */ | |||||
| AudioProcessor* getAudioProcessor() const noexcept { return &processor; } | |||||
| private: | |||||
| //============================================================================== | //============================================================================== | ||||
| AudioProcessor* const owner; | |||||
| /** Used by the setParameterHighlighting() method. */ | |||||
| struct ParameterControlHighlightInfo | |||||
| { | |||||
| int parameterIndex; | |||||
| bool isHighlighted; | |||||
| Colour suggestedColour; | |||||
| }; | |||||
| /** Some types of plugin can call this to suggest that the control for a particular | |||||
| parameter should be highlighted. | |||||
| Currently only AAX plugins will call this, and implementing it is optional. | |||||
| */ | |||||
| virtual void setControlHighlight (ParameterControlHighlightInfo); | |||||
| private: | |||||
| JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) | JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) | ||||
| }; | }; | ||||