1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

AudioPluginInstance: Add new API to query properties of hosted plugins

This commit is contained in:
reuk 2021-05-13 13:13:45 +01:00
parent d5175b6e23
commit 442369bd6b
No known key found for this signature in database
GPG key ID: 9ADCD339CFC98A11
8 changed files with 180 additions and 7 deletions

View file

@ -878,6 +878,20 @@ public:
desc.isInstrument = (componentDesc.componentType == kAudioUnitType_MusicDevice);
}
void getExtensions (ExtensionsVisitor& visitor) const override
{
struct Extensions : public ExtensionsVisitor::AudioUnitClient
{
explicit Extensions (const AudioUnitPluginInstance* instanceIn) : instance (instanceIn) {}
void* getAudioUnitHandle() const noexcept override { return instance->audioUnit; }
const AudioUnitPluginInstance* instance = nullptr;
};
visitor.visitAudioUnitClient (Extensions { this });
}
void* getPlatformSpecificData() override { return audioUnit; }
const String getName() const override { return pluginName; }

View file

@ -2256,6 +2256,27 @@ public:
return true;
}
void getExtensions (ExtensionsVisitor& visitor) const override
{
struct Extensions : public ExtensionsVisitor::VST3Client
{
explicit Extensions (const VST3PluginInstance* instanceIn) : instance (instanceIn) {}
void* getIComponentPtr() const noexcept override { return instance->holder->component; }
MemoryBlock getPreset() const override { return instance->getStateForPresetFile(); }
bool setPreset (const MemoryBlock& rawData) const override
{
return instance->setStateFromPresetFile (rawData);
}
const VST3PluginInstance* instance = nullptr;
};
visitor.visitVST3Client (Extensions { this });
}
void* getPlatformSpecificData() override { return holder->component; }
void updateMidiMappings()
@ -2857,7 +2878,25 @@ public:
}
}
bool setStateFromPresetFile (const MemoryBlock& rawData)
MemoryBlock getStateForPresetFile() const
{
VSTComSmartPtr<Steinberg::MemoryStream> memoryStream = new Steinberg::MemoryStream();
if (memoryStream == nullptr || holder->component == nullptr)
return {};
const auto saved = Steinberg::Vst::PresetFile::savePreset (memoryStream,
holder->cidOfComponent,
holder->component,
editController);
if (saved)
return { memoryStream->getData(), static_cast<size_t> (memoryStream->getSize()) };
return {};
}
bool setStateFromPresetFile (const MemoryBlock& rawData) const
{
MemoryBlock rawDataCopy (rawData);
VSTComSmartPtr<Steinberg::MemoryStream> memoryStream = new Steinberg::MemoryStream (rawDataCopy.getData(), (int) rawDataCopy.getSize());
@ -3539,8 +3578,8 @@ tresult VST3HostContext::notifyProgramListChange (Vst::ProgramListID, Steinberg:
//==============================================================================
//==============================================================================
VST3PluginFormat::VST3PluginFormat() {}
VST3PluginFormat::~VST3PluginFormat() {}
VST3PluginFormat::VST3PluginFormat() = default;
VST3PluginFormat::~VST3PluginFormat() = default;
bool VST3PluginFormat::setStateFromVSTPresetFile (AudioPluginInstance* api, const MemoryBlock& rawData)
{

View file

@ -43,11 +43,16 @@ public:
~VST3PluginFormat() override;
//==============================================================================
/** Attempts to reload a VST3 plugin's state from some preset file data.
/** Instead of using this function, use AudioPluginInstance::getExtensions()
to visit the ExtensionsVisitor::VST3 struct for the instance, if it exists.
Then, call ExtensionsVisitor::VST3::setPreset() to set the state using the
contents of a vstpreset file.
Attempts to reload a VST3 plugin's state from some preset file data.
@see VSTPluginFormat::loadFromFXBFile
*/
static bool setStateFromVSTPresetFile (AudioPluginInstance*, const MemoryBlock&);
JUCE_DEPRECATED (static bool setStateFromVSTPresetFile (AudioPluginInstance*, const MemoryBlock&));
//==============================================================================
static String getFormatName() { return "VST3"; }

View file

@ -1250,6 +1250,20 @@ struct VSTPluginInstance : public AudioPluginInstance,
setLatencySamples (vstEffect->initialDelay);
}
void getExtensions (ExtensionsVisitor& visitor) const override
{
struct Extensions : public ExtensionsVisitor::VSTClient
{
explicit Extensions (const VSTPluginInstance* instanceIn) : instance (instanceIn) {}
void* getAEffectPtr() const noexcept override { return instance->vstEffect; }
const VSTPluginInstance* instance = nullptr;
};
visitor.visitVSTClient (Extensions { this });
}
void* getPlatformSpecificData() override { return vstEffect; }
const String getName() const override

View file

@ -115,6 +115,7 @@
#endif
//==============================================================================
#include "utilities/juce_ExtensionsVisitor.h"
#include "processors/juce_AudioProcessorEditor.h"
#include "processors/juce_AudioProcessorListener.h"
#include "processors/juce_AudioProcessorParameter.h"

View file

@ -35,6 +35,8 @@ PluginDescription AudioPluginInstance::getPluginDescription() const
void* AudioPluginInstance::getPlatformSpecificData() { return nullptr; }
void AudioPluginInstance::getExtensions (ExtensionsVisitor& visitor) const { visitor.visitUnknown ({}); }
String AudioPluginInstance::getParameterID (int parameterIndex)
{
assertOnceOnDeprecatedMethodUse();

View file

@ -65,11 +65,24 @@ public:
*/
PluginDescription getPluginDescription() const;
/** Returns a pointer to some kind of platform-specific data about the plugin.
/** Allows retrieval of information related to the inner workings of a particular plugin format,
such as the AEffect* of a VST, or the handle of an AudioUnit.
To use this, create a new class derived from ExtensionsVisitor, and override
each of the visit member functions. If this AudioPluginInstance wraps a VST3 plugin
the visitVST3() member will be called, while if the AudioPluginInstance wraps an
unknown format the visitUnknown() member will be called. The argument of the visit function
can be queried to extract information related to the AudioPluginInstance's implementation.
*/
virtual void getExtensions (ExtensionsVisitor&) const;
/** Use the new typesafe visitor-based interface rather than this function.
Returns a pointer to some kind of platform-specific data about the plugin.
E.g. For a VST, this value can be cast to an AEffect*. For an AudioUnit, it can be
cast to an AudioUnit handle.
*/
virtual void* getPlatformSpecificData();
JUCE_DEPRECATED (virtual void* getPlatformSpecificData());
// Rather than using these methods you should call the corresponding methods
// on the AudioProcessorParameter objects returned from getParameters().

View file

@ -0,0 +1,85 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
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 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-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.
==============================================================================
*/
namespace juce
{
//==============================================================================
/** Create a derived implementation of this class and pass it to
AudioPluginInstance::getExtensions() to retrieve format-specific
information about a plugin instance.
Note that the references passed to the visit member functions are only
guaranteed to live for the duration of the function call, so don't
store pointers to these objects! If you need to store and reuse
format-specific information, it is recommended to copy the result
of the function calls that you care about. For example, you should
store the result of VST::getAEffectPtr() rather than storing a pointer
to the VST instance.
*/
struct ExtensionsVisitor
{
struct Unknown {};
/** Can be used to retrieve information about a VST3 that is wrapped by an AudioProcessor. */
struct VST3Client
{
virtual ~VST3Client() = default;
virtual void* getIComponentPtr() const noexcept = 0;
virtual MemoryBlock getPreset() const = 0;
virtual bool setPreset (const MemoryBlock&) const = 0;
};
/** Can be used to retrieve information about an AudioUnit that is wrapped by an AudioProcessor. */
struct AudioUnitClient
{
virtual ~AudioUnitClient() = default;
virtual void* getAudioUnitHandle() const noexcept = 0;
};
/** Can be used to retrieve information about a VST that is wrapped by an AudioProcessor. */
struct VSTClient
{
virtual ~VSTClient() = default;
virtual void* getAEffectPtr() const noexcept = 0;
};
virtual ~ExtensionsVisitor() = default;
/** Will be called if there is no platform specific information available. */
virtual void visitUnknown (const Unknown&) {}
/** Called with VST3-specific information. */
virtual void visitVST3Client (const VST3Client&) {}
/** Called with VST-specific information. */
virtual void visitVSTClient (const VSTClient&) {}
/** Called with AU-specific information. */
virtual void visitAudioUnitClient (const AudioUnitClient&) {}
};
} // namespace juce