Browse Source

tags/2021-05-28
jules 18 years ago
parent
commit
47b610f0d6
17 changed files with 244 additions and 40 deletions
  1. +4
    -2
      docs/JUCE changelist.txt
  2. +1
    -1
      extras/audio plugin host/build/mac/PluginHost.xcodeproj/project.pbxproj
  3. +14
    -4
      extras/audio plugin host/src/host/FilterGraph.cpp
  4. +4
    -1
      extras/audio plugin host/src/host/FilterGraph.h
  5. +33
    -7
      extras/audio plugin host/src/plugins/juce_AudioPluginInstance.cpp
  6. +26
    -2
      extras/audio plugin host/src/plugins/juce_AudioPluginInstance.h
  7. +1
    -1
      extras/audio plugin host/src/plugins/juce_GenericAudioFilterEditor.cpp
  8. +9
    -1
      extras/audio plugin host/src/plugins/juce_PluginDescription.cpp
  9. +3
    -2
      extras/audio plugin host/src/plugins/juce_PluginDescription.h
  10. +12
    -0
      extras/audio plugin host/src/plugins/juce_PluginListComponent.cpp
  11. +45
    -14
      extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp
  12. +10
    -0
      extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp
  13. +7
    -0
      extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp
  14. +2
    -0
      extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h
  15. +10
    -0
      extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp
  16. +31
    -2
      extras/audio plugins/wrapper/juce_AudioFilterBase.cpp
  17. +32
    -3
      extras/audio plugins/wrapper/juce_AudioFilterBase.h

+ 4
- 2
docs/JUCE changelist.txt View File

@@ -6,9 +6,11 @@
==============================================================================
Changelist for version 1.45

- big new project in the "extras" folder - a basic audio plugin host! Currently it loads VSTs on PC/Mac, and lets you put them together in a filter graph, which it plays. Hosting functionality is very basic at the moment, but I'm laying down a good architecture to hopefully build out into cross-platform plugin loading.
- audio plugins: I've simplified the processBlock() call in AudioFilterBase. It now just takes a single buffer for all input and output channels, and the accumulate parameter has gone. This will mean tweaking your plugin code, but the result will probably make it much less complex and less messy.
- big new project in the "extras" folder - a basic audio plugin host! Currently it loads VSTs on PC/Mac, and lets you put them together in a filter graph, which it plays. Hosting functionality is very basic at the moment, but I'm laying down a good architecture to hopefully develop into a full cross-platform plugin host.
- audio plugins: I've simplified the processBlock() call in AudioFilterBase. It now just takes a single buffer for all input and output channels, and the accumulate parameter has gone. This will mean tweaking your plugin code, but will probably make it much less complicated.
- audio plugins: AudioFilterBase now requires a few extra methods to be implemented by your plugin: getInputChannelName, getOutputChannelName, isInputChannelStereoPair, isOutputChannelStereoPair.
- audio plugins: new method AudioFilterBase::updateHostDisplay() to tell the host that something about your plugin has changed and that it should refresh its display.
- audio plugins: new methods AudioFilterBase::beginParameterChangeGesture() and endParameterChangeGesture() let you tell the host when a parameter-change action starts and finishes.
- new class: FileSearchPathListComponent, for letting the user edit a FileSearchPath.




+ 1
- 1
extras/audio plugin host/build/mac/PluginHost.xcodeproj/project.pbxproj View File

@@ -43,7 +43,7 @@
20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
508344B209E5C41E0093A071 /* Juce Plugin Host.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Juce Plugin Host.app"; sourceTree = BUILT_PRODUCTS_DIR; };
508344B209E5C41E0093A071 /* Juce Plugin Host.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "Juce Plugin Host.app"; sourceTree = BUILT_PRODUCTS_DIR; };
84E5BB950C7203B70088E799 /* juce_GenericAudioFilterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_GenericAudioFilterEditor.cpp; sourceTree = "<group>"; };
84E5BB960C7203B70088E799 /* juce_GenericAudioFilterEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_GenericAudioFilterEditor.h; sourceTree = "<group>"; };
84FFAE920C6C8A6F009F6E72 /* FilterGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = FilterGraph.cpp; path = ../../src/host/FilterGraph.cpp; sourceTree = SOURCE_ROOT; };


+ 14
- 4
extras/audio plugin host/src/host/FilterGraph.cpp View File

@@ -233,9 +233,11 @@ XmlElement* FilterInGraph::createXml() const
return e;
}
FilterInGraph* FilterInGraph::createForDescription (FilterGraph& owner, const PluginDescription& desc)
FilterInGraph* FilterInGraph::createForDescription (FilterGraph& owner,
const PluginDescription& desc,
String& errorMessage)
{
AudioPluginInstance* instance = desc.createInstance();
AudioPluginInstance* instance = desc.createInstance (errorMessage);
if (instance != 0)
return new FilterInGraph (owner, instance);
@@ -253,7 +255,8 @@ FilterInGraph* FilterInGraph::createFromXml (FilterGraph& owner, const XmlElemen
break;
}
FilterInGraph* const c = createForDescription (owner, pd);
String errorMessage;
FilterInGraph* const c = createForDescription (owner, pd, errorMessage);
if (c == 0)
return 0;
@@ -398,13 +401,20 @@ void FilterGraph::addFilter (const PluginDescription* desc, double x, double y)
{
if (desc != 0)
{
FilterInGraph* cf = FilterInGraph::createForDescription (*this, *desc);
String errorMessage;
FilterInGraph* cf = FilterInGraph::createForDescription (*this, *desc, errorMessage);
if (cf != 0)
{
cf->setPosition (x, y);
addFilter (cf);
}
else
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Couldn't create filter"),
errorMessage);
}
}
}


+ 4
- 1
extras/audio plugin host/src/host/FilterGraph.h View File

@@ -95,7 +95,10 @@ public:
XmlElement* createXml() const;
static FilterInGraph* createForDescription (FilterGraph& owner, const PluginDescription& desc);
static FilterInGraph* createForDescription (FilterGraph& owner,
const PluginDescription& desc,
String& errorMessage);
static FilterInGraph* createFromXml (FilterGraph& owner, const XmlElement& xml);
//==============================================================================


+ 33
- 7
extras/audio plugin host/src/plugins/juce_AudioPluginInstance.cpp View File

@@ -67,6 +67,8 @@ void AudioPluginInstance::internalAsyncCallback()
changedParamLock.enter();
Array <int> changed;
changed.swapWithArray (changedParams);
Array <float> changedValues;
changedValues.swapWithArray (changedParamValues);
changedParamLock.exit();
for (int j = 0; j < changed.size(); ++j)
@@ -78,9 +80,13 @@ void AudioPluginInstance::internalAsyncCallback()
AudioPluginParameterListener* const l = (AudioPluginParameterListener*) listeners.getUnchecked(i);
if (paramIndex >= 0)
l->audioPluginParameterChanged (this, paramIndex);
else
l->audioPluginParameterChanged (this, paramIndex, changedValues.getUnchecked(j));
else if (paramIndex == -1)
l->audioPluginChanged (this);
else if ((paramIndex & 0xc0000000) == 0xc0000000)
l->audioPluginParameterChangeGestureBegin (this, paramIndex & 0x3fffffff);
else if ((paramIndex & 0xc0000000) == 0x80000000)
l->audioPluginParameterChangeGestureEnd (this, paramIndex & 0x3fffffff);
i = jmin (i, listeners.size());
}
@@ -122,20 +128,31 @@ bool JUCE_CALLTYPE AudioPluginInstance::getCurrentPositionInfo (AudioFilterBase:
return true;
}
void JUCE_CALLTYPE AudioPluginInstance::informHostOfParameterChange (int index, float /*newValue*/)
void JUCE_CALLTYPE AudioPluginInstance::informHostOfParameterChange (int index, float newValue)
{
queueChangeMessage (index);
queueChangeMessage (index, newValue);
}
void JUCE_CALLTYPE AudioPluginInstance::informHostOfParameterGestureBegin (int index)
{
queueChangeMessage (0xc0000000 | index, 0);
}
void JUCE_CALLTYPE AudioPluginInstance::informHostOfParameterGestureEnd (int index)
{
queueChangeMessage (0x80000000 | index, 0);
}
void JUCE_CALLTYPE AudioPluginInstance::informHostOfStateChange()
{
queueChangeMessage (-1);
queueChangeMessage (-1, 0);
}
void AudioPluginInstance::queueChangeMessage (const int index) throw()
void AudioPluginInstance::queueChangeMessage (const int index, const float value) throw()
{
const ScopedLock sl (changedParamLock);
changedParams.addIfNotAlreadyThere (index);
changedParams.add (index);
changedParamValues.add (value);
if (! internalAsyncUpdater->isTimerRunning())
internalAsyncUpdater->startTimer (1);
@@ -153,3 +170,12 @@ void AudioPluginInstance::InternalAsyncUpdater::timerCallback()
owner.internalAsyncCallback();
}
//==============================================================================
void AudioPluginParameterListener::audioPluginParameterChangeGestureBegin (AudioPluginInstance*, int)
{
}
void AudioPluginParameterListener::audioPluginParameterChangeGestureEnd (AudioPluginInstance*, int)
{
}

+ 26
- 2
extras/audio plugin host/src/plugins/juce_AudioPluginInstance.h View File

@@ -47,12 +47,33 @@ public:
//==============================================================================
/** Receives a callback when a parameter is changed. */
virtual void audioPluginParameterChanged (AudioPluginInstance* plugin,
int parameterIndex) = 0;
int parameterIndex,
float newValue) = 0;
/** Called to indicate that something else in the plugin has changed, like its
program, number of parameters, etc.
*/
virtual void audioPluginChanged (AudioPluginInstance* plugin) = 0;
/** Indicates that a parameter change gesture has started.
E.g. if the user is dragging a slider, this would be called when they first
press the mouse button, and audioPluginParameterChangeGestureEnd would be
called when they release it.
@see audioPluginParameterChangeGestureEnd
*/
virtual void audioPluginParameterChangeGestureBegin (AudioPluginInstance* plugin,
int parameterIndex);
/** Indicates that a parameter change gesture has finished.
E.g. if the user is dragging a slider, this would be called when they release
the mouse button.
@see audioPluginParameterChangeGestureStart
*/
virtual void audioPluginParameterChangeGestureEnd (AudioPluginInstance* plugin,
int parameterIndex);
};
@@ -145,6 +166,7 @@ protected:
VoidArray listeners;
CriticalSection changedParamLock;
Array <int> changedParams;
Array <float> changedParamValues;
class InternalAsyncUpdater : public Timer
{
@@ -162,12 +184,14 @@ protected:
InternalAsyncUpdater* internalAsyncUpdater;
void internalAsyncCallback();
void queueChangeMessage (const int index) throw();
void queueChangeMessage (const int index, const float value) throw();
AudioPluginInstance();
bool JUCE_CALLTYPE getCurrentPositionInfo (AudioFilterBase::CurrentPositionInfo& info);
void JUCE_CALLTYPE informHostOfParameterChange (int index, float newValue);
void JUCE_CALLTYPE informHostOfParameterGestureBegin (int index);
void JUCE_CALLTYPE informHostOfParameterGestureEnd (int index);
void JUCE_CALLTYPE informHostOfStateChange();
};


+ 1
- 1
extras/audio plugin host/src/plugins/juce_GenericAudioFilterEditor.cpp View File

@@ -64,7 +64,7 @@ public:
{
}
void audioPluginParameterChanged (AudioPluginInstance*, int parameterIndex)
void audioPluginParameterChanged (AudioPluginInstance*, int parameterIndex, float)
{
if (parameterIndex == index)
refresh();


+ 9
- 1
extras/audio plugin host/src/plugins/juce_PluginDescription.cpp View File

@@ -100,7 +100,7 @@ void PluginDescription::fillInFromInstance (AudioPluginInstance& instance) throw
isInstrument = instance.isInstrument();
}
AudioPluginInstance* PluginDescription::createInstance() const
AudioPluginInstance* PluginDescription::createInstance (String& errorMessage) const
{
AudioPluginInstance* result = 0;
@@ -114,6 +114,14 @@ AudioPluginInstance* PluginDescription::createInstance() const
break;
}
if (result == 0)
{
if (file != File::nonexistent && ! file.exists())
errorMessage = TRANS ("This plug-in file no longer exists");
else
errorMessage = TRANS ("This plug-in failed to load correctly");
}
return result;
}


+ 3
- 2
extras/audio plugin host/src/plugins/juce_PluginDescription.h View File

@@ -117,9 +117,10 @@ public:
The caller is responsible for deleting the object that is returned.
Returns 0 if it can't load the plugin for some reason.
If it can't load the plugin, it returns 0 and leaves a message in the
errorMessage string.
*/
AudioPluginInstance* createInstance() const;
AudioPluginInstance* createInstance (String& errorMessage) const;
//==============================================================================
/** Creates an XML object containing these details.


+ 12
- 0
extras/audio plugin host/src/plugins/juce_PluginListComponent.cpp View File

@@ -135,6 +135,7 @@ void PluginListComponent::buttonClicked (Button* b)
menu.addItem (1, TRANS("Clear list"));
menu.addItem (5, TRANS("Remove selected plugin from list"), listBox->getNumSelectedRows() > 0);
menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox->getNumSelectedRows() > 0);
menu.addItem (7, TRANS("Remove any plugins whose files no longer exist"));
menu.addSeparator();
menu.addItem (2, TRANS("Sort alphabetically"));
menu.addItem (3, TRANS("Sort by category"));
@@ -182,6 +183,17 @@ void PluginListComponent::buttonClicked (Button* b)
if (desc != 0)
desc->file.getParentDirectory().startAsProcess();
}
else if (r == 7)
{
for (int i = list.getNumTypes(); --i >= 0;)
{
if (list.getType (i)->file != File::nonexistent
&& ! list.getType (i)->file.exists())
{
list.removeType (i);
}
}
}
else if (r != 0)
{
scanFor (AudioPluginFormatManager::getInstance()->getFormat (r - 10));


+ 45
- 14
extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp View File

@@ -81,6 +81,11 @@ public:
Globals()->UseIndexedParameters (juceFilter->getNumParameters());
activePlugins.add (this);
zerostruct (auEvent);
auEvent.mArgument.mParameter.mAudioUnit = GetComponentInstance();
auEvent.mArgument.mParameter.mScope = kAudioUnitScope_Global;
auEvent.mArgument.mParameter.mElement = 0;
}
~JuceAU()
@@ -219,14 +224,27 @@ public:
AudioUnitParameterID inParameterID,
AudioUnitParameterInfo& outParameterInfo)
{
if (inScope == kAudioUnitScope_Global && juceFilter != 0)
const int index = (int) inParameterID;
if (inScope == kAudioUnitScope_Global
&& juceFilter != 0
&& index < juceFilter->getNumParameters())
{
outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable
| kAudioUnitParameterFlag_IsReadable
| kAudioUnitParameterFlag_HasCFNameString;
outParameterInfo.name[0] = 0;
outParameterInfo.cfNameString = PlatformUtilities::juceStringToCFString (juceFilter->getParameterName ((int) inParameterID));
const String name (juceFilter->getParameterName (index));
CharacterFunctions::copy ((char*) outParameterInfo.name,
(const char*) name.toUTF8(),
sizeof (outParameterInfo.name) - 1);
// set whether the param is automatable (unnamed parameters aren't allowed to be automated)
if (name.isEmpty() || ! juceFilter->isParameterAutomatable (index))
outParameterInfo.flags |= kAudioUnitParameterFlag_NonRealTime;
outParameterInfo.cfNameString = PlatformUtilities::juceStringToCFString (name);
outParameterInfo.minValue = 0.0f;
outParameterInfo.maxValue = 1.0f;
outParameterInfo.defaultValue = 0.0f;
@@ -377,25 +395,37 @@ public:
return true;
}
void sendAUEvent (const AudioUnitEventType type, const int index) throw()
{
if (AUEventListenerNotify != 0)
{
auEvent.mEventType = type;
auEvent.mArgument.mParameter.mParameterID = (AudioUnitParameterID) index;
AUEventListenerNotify (0, 0, &auEvent);
}
}
void informHostOfParameterChange (int index, float newValue)
{
if (juceFilter != 0)
{
juceFilter->setParameter (index, newValue);
if (AUEventListenerNotify != 0)
{
AudioUnitEvent e;
e.mEventType = kAudioUnitEvent_ParameterValueChange;
e.mArgument.mParameter.mAudioUnit = GetComponentInstance();
e.mArgument.mParameter.mParameterID = (AudioUnitParameterID) index;
e.mArgument.mParameter.mScope = kAudioUnitScope_Global;
e.mArgument.mParameter.mElement = 0;
AUEventListenerNotify (0, 0, &e);
}
sendAUEvent (kAudioUnitEvent_ParameterValueChange, index);
}
}
void informHostOfParameterGestureBegin (int index)
{
if (juceFilter != 0)
sendAUEvent (kAudioUnitEvent_BeginParameterChangeGesture, index);
}
void informHostOfParameterGestureEnd (int index)
{
if (juceFilter != 0)
sendAUEvent (kAudioUnitEvent_EndParameterChangeGesture, index);
}
void informHostOfStateChange()
{
// xxx is there an AU equivalent?
@@ -645,6 +675,7 @@ private:
bool prepared;
SMPTETime lastSMPTETime;
AUChannelInfo channelInfo [numChannelConfigs];
AudioUnitEvent auEvent;
};


+ 10
- 0
extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp View File

@@ -848,6 +848,16 @@ protected:
SetControlValue (index + 2, floatToLong (newValue));
}
void JUCE_CALLTYPE informHostOfParameterGestureBegin (int index)
{
TouchControl (index + 2);
}
void JUCE_CALLTYPE informHostOfParameterGestureEnd (int index)
{
ReleaseControl (index + 2);
}
void JUCE_CALLTYPE informHostOfStateChange()
{
// xxx is there an RTAS equivalent?


+ 7
- 0
extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp View File

@@ -142,6 +142,13 @@ void AudioFilterStreamer::informHostOfParameterChange (int index, float newValue
filter.setParameter (index, newValue);
}
void JUCE_CALLTYPE AudioFilterStreamer::informHostOfParameterGestureBegin (int index)
{
}
void JUCE_CALLTYPE AudioFilterStreamer::informHostOfParameterGestureEnd (int index)
{
}
void JUCE_CALLTYPE AudioFilterStreamer::informHostOfStateChange()
{


+ 2
- 0
extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h View File

@@ -73,6 +73,8 @@ public:
bool JUCE_CALLTYPE getCurrentPositionInfo (AudioFilterBase::CurrentPositionInfo& info);
void JUCE_CALLTYPE informHostOfParameterChange (int index, float newValue);
void JUCE_CALLTYPE informHostOfParameterGestureBegin (int index);
void JUCE_CALLTYPE informHostOfParameterGestureEnd (int index);
void JUCE_CALLTYPE informHostOfStateChange();
juce_UseDebuggingNewOperator


+ 10
- 0
extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp View File

@@ -814,6 +814,16 @@ public:
setParameterAutomated (index, newValue);
}
void JUCE_CALLTYPE informHostOfParameterGestureBegin (int index)
{
beginEdit (index);
}
void JUCE_CALLTYPE informHostOfParameterGestureEnd (int index)
{
endEdit (index);
}
void JUCE_CALLTYPE informHostOfStateChange()
{
updateDisplay();


+ 31
- 2
extras/audio plugins/wrapper/juce_AudioFilterBase.cpp View File

@@ -49,9 +49,13 @@ AudioFilterBase::~AudioFilterBase()
// ooh, nasty - the editor should have been deleted before the filter
// that it refers to is deleted..
jassert (activeEditor == 0);
// This will fail if you've called beginParameterChangeGesture() for one
// or more parameters without having made a corresponding call to endParameterChangeGesture...
jassert (changingParams.countNumberOfSetBits() == 0);
}
void AudioFilterBase::setHostCallbacks (HostCallbacks* const callbacks_)
void AudioFilterBase::setHostCallbacks (HostCallbacks* const callbacks_) throw()
{
callbacks = callbacks_;
}
@@ -78,6 +82,31 @@ void AudioFilterBase::setParameterNotifyingHost (const int parameterIndex,
setParameter (parameterIndex, newValue);
}
void AudioFilterBase::beginParameterChangeGesture (int parameterIndex)
{
jassert (parameterIndex >= 0 && parameterIndex < getNumParameters());
// This means you've called beginParameterChangeGesture twice in succession without a matching
// call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it.
jassert (! changingParams [parameterIndex]);
if (callbacks != 0)
callbacks->informHostOfParameterGestureBegin (parameterIndex);
}
void AudioFilterBase::endParameterChangeGesture (int parameterIndex)
{
jassert (parameterIndex >= 0 && parameterIndex < getNumParameters());
// This means you've called endParameterChangeGesture without having previously called
// endParameterChangeGesture. That might be fine in most hosts, but better to keep the
// calls matched correctly.
jassert (changingParams [parameterIndex]);
if (callbacks != 0)
callbacks->informHostOfParameterGestureEnd (parameterIndex);
}
void JUCE_CALLTYPE AudioFilterBase::updateHostDisplay()
{
if (callbacks != 0)
@@ -103,7 +132,7 @@ bool AudioFilterBase::getCurrentPositionInfo (CurrentPositionInfo& info)
}
//==============================================================================
void AudioFilterBase::editorBeingDeleted (AudioFilterEditor* const editor)
void AudioFilterBase::editorBeingDeleted (AudioFilterEditor* const editor) throw()
{
const ScopedLock sl (callbackLock);


+ 32
- 3
extras/audio plugins/wrapper/juce_AudioFilterBase.h View File

@@ -403,6 +403,10 @@ public:
This could happen when the editor or some other internal operation changes
a parameter. This method will call the setParameter() method to change the
value, and will then send a message to the host telling it about the change.
Note that to make sure the host correctly handles automation, you should call
the beginParameterChangeGesture() and endParameterChangeGesture() methods to
tell the host when the user has started and stopped changing the parameter.
*/
void JUCE_CALLTYPE setParameterNotifyingHost (int parameterIndex,
float newValue);
@@ -411,7 +415,26 @@ public:
By default, this returns true for all parameters.
*/
virtual bool isParameterAutomatable (int index) const;
virtual bool isParameterAutomatable (int parameterIndex) const;
/** Sends a signal to the host to tell it that the user is about to start changing this
parameter.
This allows the host to know when a parameter is actively being held by the user, and
it may use this information to help it record automation.
If you call this, it must be matched by a later call to endParameterChangeGesture().
*/
void beginParameterChangeGesture (int parameterIndex);
/** Tells the host that the user has finished changing this parameter.
This allows the host to know when a parameter is actively being held by the user, and
it may use this information to help it record automation.
A call to this method must follow a call to beginParameterChangeGesture().
*/
void endParameterChangeGesture (int parameterIndex);
/** The filter can call this when something (apart from a parameter value) has changed.
@@ -506,6 +529,8 @@ public:
virtual bool JUCE_CALLTYPE getCurrentPositionInfo (CurrentPositionInfo& info) = 0;
virtual void JUCE_CALLTYPE informHostOfParameterChange (int index, float newValue) = 0;
virtual void JUCE_CALLTYPE informHostOfParameterGestureBegin (int index) = 0;
virtual void JUCE_CALLTYPE informHostOfParameterGestureEnd (int index) = 0;
/** Callback to indicate that something (other than a parameter) has changed in the
filter, such as its current program, parameter list, etc. */
@@ -517,12 +542,12 @@ public:
/** Not for public use - this is called by the wrapper code before deleting an
editor component.
*/
void JUCE_CALLTYPE editorBeingDeleted (AudioFilterEditor* const editor);
void JUCE_CALLTYPE editorBeingDeleted (AudioFilterEditor* const editor) throw();
/** Not for public use - this is called by the wrapper code to initialise the
filter.
*/
void JUCE_CALLTYPE setHostCallbacks (HostCallbacks* const);
void JUCE_CALLTYPE setHostCallbacks (HostCallbacks* const) throw();
/** Not for public use - this is called by the wrapper code to initialise the
filter.
@@ -564,6 +589,10 @@ private:
int blockSize, numInputChannels, numOutputChannels;
bool suspended;
CriticalSection callbackLock;
#ifdef JUCE_DEBUG
BitArray changingParams;
#endif
};
//==============================================================================


Loading…
Cancel
Save