mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
Move files without UI dependencies to juce_audio_processors_headless
This commit is contained in:
parent
1f5d09d3fc
commit
407cc5b004
73 changed files with 115 additions and 80 deletions
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioPluginFormat::AudioPluginFormat() {}
|
||||
AudioPluginFormat::~AudioPluginFormat() {}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize)
|
||||
{
|
||||
String errorMessage;
|
||||
return createInstanceFromDescription (desc, initialSampleRate, initialBufferSize, errorMessage);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
String& errorMessage)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread()
|
||||
&& requiresUnblockedMessageThreadDuringCreation (desc))
|
||||
{
|
||||
errorMessage = NEEDS_TRANS ("This plug-in cannot be instantiated synchronously");
|
||||
return {};
|
||||
}
|
||||
|
||||
WaitableEvent finishedSignal;
|
||||
std::unique_ptr<AudioPluginInstance> instance;
|
||||
|
||||
auto callback = [&] (std::unique_ptr<AudioPluginInstance> p, const String& error)
|
||||
{
|
||||
errorMessage = error;
|
||||
instance = std::move (p);
|
||||
finishedSignal.signal();
|
||||
};
|
||||
|
||||
if (! MessageManager::getInstance()->isThisTheMessageThread())
|
||||
createPluginInstanceAsync (desc, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
else
|
||||
createPluginInstance (desc, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
|
||||
finishedSignal.wait();
|
||||
return instance;
|
||||
}
|
||||
|
||||
struct AudioPluginFormat::AsyncCreateMessage final : public Message
|
||||
{
|
||||
AsyncCreateMessage (const PluginDescription& d, double sr, int size, PluginCreationCallback call)
|
||||
: desc (d), sampleRate (sr), bufferSize (size), callbackToUse (std::move (call))
|
||||
{
|
||||
}
|
||||
|
||||
PluginDescription desc;
|
||||
double sampleRate;
|
||||
int bufferSize;
|
||||
PluginCreationCallback callbackToUse;
|
||||
};
|
||||
|
||||
void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
PluginCreationCallback callback)
|
||||
{
|
||||
jassert (callback != nullptr);
|
||||
postMessage (new AsyncCreateMessage (description, initialSampleRate, initialBufferSize, std::move (callback)));
|
||||
}
|
||||
|
||||
void AudioPluginFormat::handleMessage (const Message& message)
|
||||
{
|
||||
if (auto m = dynamic_cast<const AsyncCreateMessage*> (&message))
|
||||
createPluginInstance (m->desc, m->sampleRate, m->bufferSize, std::move (m->callbackToUse));
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.
|
||||
|
||||
@see AudioPluginFormatManager
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioPluginFormat : private MessageListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
~AudioPluginFormat() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the format name.
|
||||
E.g. "VST", "AudioUnit", etc.
|
||||
*/
|
||||
virtual String getName() const = 0;
|
||||
|
||||
/** This tries to create descriptions for all the plugin types available in
|
||||
a binary module file.
|
||||
|
||||
The file will be some kind of DLL or bundle.
|
||||
|
||||
Normally there will only be one type returned, but some plugins
|
||||
(e.g. VST shells) can use a single DLL to create a set of different plugin
|
||||
subtypes, so in that case, each subtype is returned as a separate object.
|
||||
*/
|
||||
virtual void findAllTypesForFile (OwnedArray<PluginDescription>& results,
|
||||
const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Tries to recreate a type from a previously generated PluginDescription.
|
||||
@see AudioPluginFormatManager::createInstance
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize);
|
||||
|
||||
/** Same as above but with the possibility of returning an error message.
|
||||
@see AudioPluginFormatManager::createInstance
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
String& errorMessage);
|
||||
|
||||
/** A callback lambda that is passed to createPluginInstanceAsync() */
|
||||
using PluginCreationCallback = std::function<void (std::unique_ptr<AudioPluginInstance>, const String&)>;
|
||||
|
||||
/** Tries to recreate a type from a previously generated PluginDescription.
|
||||
When the plugin has been created, it will be passed to the caller via an
|
||||
asynchronous call to the PluginCreationCallback lambda that was provided.
|
||||
@see AudioPluginFormatManager::createPluginInstanceAsync
|
||||
*/
|
||||
void createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
PluginCreationCallback);
|
||||
|
||||
/** Should do a quick check to see if this file or directory might be a plugin of
|
||||
this format.
|
||||
|
||||
This is for searching for potential files, so it shouldn't actually try to
|
||||
load the plugin or do anything time-consuming.
|
||||
*/
|
||||
virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Returns a readable version of the name of the plugin that this identifier refers to. */
|
||||
virtual String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Returns true if this plugin's version or date has changed and it should be re-checked. */
|
||||
virtual bool pluginNeedsRescanning (const PluginDescription&) = 0;
|
||||
|
||||
/** Checks whether this plugin could possibly be loaded.
|
||||
It doesn't actually need to load it, just to check whether the file or component
|
||||
still exists.
|
||||
*/
|
||||
virtual bool doesPluginStillExist (const PluginDescription&) = 0;
|
||||
|
||||
/** Returns true if this format needs to run a scan to find its list of plugins. */
|
||||
virtual bool canScanForPlugins() const = 0;
|
||||
|
||||
/** Should return true if this format is both safe and quick to scan - i.e. if a file
|
||||
can be scanned within a few milliseconds on a background thread, without actually
|
||||
needing to load an executable.
|
||||
*/
|
||||
virtual bool isTrivialToScan() const = 0;
|
||||
|
||||
/** Searches a suggested set of directories for any plugins in this format.
|
||||
The path might be ignored, e.g. by AUs, which are found by the OS rather
|
||||
than manually.
|
||||
|
||||
@param directoriesToSearch This specifies which directories shall be
|
||||
searched for plug-ins.
|
||||
@param recursive Should the search recursively traverse folders.
|
||||
@param allowPluginsWhichRequireAsynchronousInstantiation
|
||||
If this is false then plug-ins which require
|
||||
asynchronous creation will be excluded.
|
||||
*/
|
||||
virtual StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
|
||||
bool recursive,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false) = 0;
|
||||
|
||||
/** Returns the typical places to look for this kind of plugin.
|
||||
|
||||
Note that if this returns no paths, it means that the format doesn't search in
|
||||
files or folders, e.g. AudioUnits.
|
||||
*/
|
||||
virtual FileSearchPath getDefaultLocationsToSearch() = 0;
|
||||
|
||||
/** Returns true if instantiation of this plugin type must be done from a non-message thread. */
|
||||
virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0;
|
||||
|
||||
/** A callback lambda that is passed to getARAFactory() */
|
||||
using ARAFactoryCreationCallback = std::function<void (ARAFactoryResult)>;
|
||||
|
||||
/** Tries to create an ::ARAFactoryWrapper for this description.
|
||||
|
||||
The result of the operation will be wrapped into an ARAFactoryResult,
|
||||
which will be passed to a callback object supplied by the caller.
|
||||
|
||||
@see AudioPluginFormatManager::createARAFactoryAsync
|
||||
*/
|
||||
virtual void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) { callback ({}); }
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
friend class AudioPluginFormatManager;
|
||||
|
||||
AudioPluginFormat();
|
||||
|
||||
/** Implementors must override this function. This is guaranteed to be called on
|
||||
the message thread. You may call the callback on any thread.
|
||||
*/
|
||||
virtual void createPluginInstance (const PluginDescription&, double initialSampleRate,
|
||||
int initialBufferSize, PluginCreationCallback) = 0;
|
||||
|
||||
private:
|
||||
struct AsyncCreateMessage;
|
||||
void handleMessage (const Message&) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU) && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX))
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
static void dummyARAInterfaceAssert (ARA::ARAAssertCategory, const void*, const char*)
|
||||
{}
|
||||
|
||||
static ARA::ARAInterfaceConfiguration createInterfaceConfig (const ARA::ARAFactory* araFactory)
|
||||
{
|
||||
static auto* assertFunction = &dummyARAInterfaceAssert;
|
||||
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
assertFunction = &::ARA::ARAInterfaceAssert;
|
||||
static std::once_flag flag;
|
||||
std::call_once (flag, [] { ARA::ARASetExternalAssertReference (&assertFunction); });
|
||||
#endif
|
||||
|
||||
return makeARASizedStruct (&ARA::ARAInterfaceConfiguration::assertFunctionAddress,
|
||||
jmin (araFactory->highestSupportedApiGeneration, (ARA::ARAAPIGeneration) ARA::kARAAPIGeneration_2_X_Draft),
|
||||
&assertFunction);
|
||||
}
|
||||
|
||||
/* If the provided ARAFactory is not yet in use it constructs a new shared_ptr that will call the
|
||||
provided onDelete function inside the custom deleter of this new shared_ptr instance.
|
||||
|
||||
The onDelete function is responsible for releasing the resources that guarantee the validity of
|
||||
the wrapped ARAFactory*.
|
||||
|
||||
If however the ARAFactory is already in use the function will just return a copy of the already
|
||||
existing shared_ptr and call the onDelete function immediately. This is to ensure that the
|
||||
ARAFactory is only uninitialised when no plugin instance can be using it.
|
||||
|
||||
On both platforms the onDelete function is used to release resources that ensure that the module
|
||||
providing the ARAFactory* remains loaded.
|
||||
*/
|
||||
static std::shared_ptr<const ARA::ARAFactory> getOrCreateARAFactory (const ARA::ARAFactory* ptr,
|
||||
std::function<void()> onDelete)
|
||||
{
|
||||
JUCE_ASSERT_MESSAGE_THREAD
|
||||
|
||||
static std::unordered_map<const ARA::ARAFactory*, std::weak_ptr<const ARA::ARAFactory>> cache;
|
||||
|
||||
auto& cachePtr = cache[ptr];
|
||||
|
||||
if (const auto obj = cachePtr.lock())
|
||||
{
|
||||
onDelete();
|
||||
return obj;
|
||||
}
|
||||
|
||||
const auto interfaceConfig = createInterfaceConfig (ptr);
|
||||
ptr->initializeARAWithConfiguration (&interfaceConfig);
|
||||
const auto obj = std::shared_ptr<const ARA::ARAFactory> (ptr, [deleter = std::move (onDelete)] (const ARA::ARAFactory* factory)
|
||||
{
|
||||
factory->uninitializeARA();
|
||||
deleter();
|
||||
});
|
||||
cachePtr = obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARA
|
||||
{
|
||||
struct ARAFactory;
|
||||
}
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Encapsulates an ARAFactory pointer and makes sure that it remains in a valid state
|
||||
for the lifetime of the ARAFactoryWrapper object.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class ARAFactoryWrapper
|
||||
{
|
||||
public:
|
||||
ARAFactoryWrapper() = default;
|
||||
|
||||
/** @internal
|
||||
|
||||
Used by the framework to encapsulate ARAFactory pointers loaded from plugins.
|
||||
*/
|
||||
explicit ARAFactoryWrapper (std::shared_ptr<const ARA::ARAFactory> factoryIn) : factory (std::move (factoryIn)) {}
|
||||
|
||||
/** Returns the contained ARAFactory pointer, which can be a nullptr.
|
||||
|
||||
The validity of the returned pointer is only guaranteed for the lifetime of this wrapper.
|
||||
*/
|
||||
const ARA::ARAFactory* get() const noexcept { return factory.get(); }
|
||||
|
||||
private:
|
||||
std::shared_ptr<const ARA::ARAFactory> factory;
|
||||
};
|
||||
|
||||
/** Represents the result of AudioPluginFormatManager::createARAFactoryAsync().
|
||||
|
||||
If the operation fails then #araFactory will contain `nullptr`, and #errorMessage may
|
||||
contain a reason for the failure.
|
||||
|
||||
The araFactory member ensures that the module necessary for the correct functioning
|
||||
of the factory will remain loaded.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
struct ARAFactoryResult
|
||||
{
|
||||
ARAFactoryWrapper araFactory;
|
||||
String errorMessage;
|
||||
};
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wmissing-field-initializers")
|
||||
|
||||
template <typename Obj, typename Member, typename... Ts>
|
||||
constexpr Obj makeARASizedStruct (Member Obj::* member, Ts&&... ts)
|
||||
{
|
||||
return { reinterpret_cast<uintptr_t> (&(static_cast<const Obj*> (nullptr)->*member)) + sizeof (Member),
|
||||
std::forward<Ts> (ts)... };
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -34,8 +34,6 @@
|
|||
|
||||
#if (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU) && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX))
|
||||
|
||||
#include "juce_ARAHosting.h"
|
||||
|
||||
#include <ARA_Library/Dispatch/ARAHostDispatch.cpp>
|
||||
|
||||
namespace juce
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@
|
|||
|
||||
#include <juce_audio_basics/native/juce_CoreAudioTimeConversions_mac.h>
|
||||
#include <juce_audio_basics/native/juce_CoreAudioLayouts_mac.h>
|
||||
#include "juce_AU_Shared.h"
|
||||
#include <juce_audio_processors/format_types/juce_AU_Shared.h>
|
||||
#include <juce_audio_processors_headless/format_types/juce_ARACommonInternal.h>
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
JUCE_BEGIN_IGNORE_DEPRECATION_WARNINGS
|
||||
|
||||
class LegacyAudioParameter final : public HostedAudioProcessorParameter
|
||||
{
|
||||
public:
|
||||
LegacyAudioParameter (AudioProcessorParameter::Listener& listener,
|
||||
AudioProcessor& audioProcessorToUse,
|
||||
int audioParameterIndex)
|
||||
: processor (&audioProcessorToUse)
|
||||
{
|
||||
setOwner (&listener);
|
||||
setParameterIndex (audioParameterIndex);
|
||||
jassert (getParameterIndex() < processor->getNumParameters());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
float getValue() const override { return processor->getParameter (getParameterIndex()); }
|
||||
void setValue (float newValue) override { processor->setParameter (getParameterIndex(), newValue); }
|
||||
float getDefaultValue() const override { return processor->getParameterDefaultValue (getParameterIndex()); }
|
||||
String getName (int maxLen) const override { return processor->getParameterName (getParameterIndex(), maxLen); }
|
||||
String getLabel() const override { return processor->getParameterLabel (getParameterIndex()); }
|
||||
int getNumSteps() const override { return processor->getParameterNumSteps (getParameterIndex()); }
|
||||
bool isDiscrete() const override { return processor->isParameterDiscrete (getParameterIndex()); }
|
||||
bool isBoolean() const override { return false; }
|
||||
bool isOrientationInverted() const override { return processor->isParameterOrientationInverted (getParameterIndex()); }
|
||||
bool isAutomatable() const override { return processor->isParameterAutomatable (getParameterIndex()); }
|
||||
bool isMetaParameter() const override { return processor->isMetaParameter (getParameterIndex()); }
|
||||
Category getCategory() const override { return processor->getParameterCategory (getParameterIndex()); }
|
||||
String getCurrentValueAsText() const override { return processor->getParameterText (getParameterIndex()); }
|
||||
String getParameterID() const override { return processor->getParameterID (getParameterIndex()); }
|
||||
|
||||
//==============================================================================
|
||||
float getValueForText (const String&) const override
|
||||
{
|
||||
// legacy parameters do not support this method
|
||||
jassertfalse;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
String getText (float, int) const override
|
||||
{
|
||||
// legacy parameters do not support this method
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool isLegacy (AudioProcessorParameter* param) noexcept
|
||||
{
|
||||
return (dynamic_cast<LegacyAudioParameter*> (param) != nullptr);
|
||||
}
|
||||
|
||||
static int getParamIndex (AudioProcessor& proc, AudioProcessorParameter* param) noexcept
|
||||
{
|
||||
if (auto* legacy = dynamic_cast<LegacyAudioParameter*> (param))
|
||||
return legacy->getParameterIndex();
|
||||
|
||||
auto n = proc.getNumParameters();
|
||||
jassert (n == proc.getParameters().size());
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (proc.getParameters()[i] == param)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static String getParamID (const AudioProcessorParameter* param, bool forceLegacyParamIDs) noexcept
|
||||
{
|
||||
if (auto* legacy = dynamic_cast<const LegacyAudioParameter*> (param))
|
||||
return forceLegacyParamIDs ? String (legacy->getParameterIndex()) : legacy->getParameterID();
|
||||
|
||||
if (auto* paramWithID = dynamic_cast<const HostedAudioProcessorParameter*> (param))
|
||||
{
|
||||
if (! forceLegacyParamIDs)
|
||||
return paramWithID->getParameterID();
|
||||
}
|
||||
|
||||
if (param != nullptr)
|
||||
return String (param->getParameterIndex());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
AudioProcessor* processor = nullptr;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class LegacyAudioParametersWrapper
|
||||
{
|
||||
public:
|
||||
LegacyAudioParametersWrapper() = default;
|
||||
|
||||
LegacyAudioParametersWrapper (AudioProcessor& audioProcessor, bool forceLegacyParamIDs)
|
||||
{
|
||||
update (audioProcessor, forceLegacyParamIDs);
|
||||
}
|
||||
|
||||
void update (AudioProcessor& audioProcessor, bool forceLegacyParamIDs)
|
||||
{
|
||||
clear();
|
||||
|
||||
forwarder = AudioProcessor::ParameterChangeForwarder { &audioProcessor };
|
||||
legacyParamIDs = forceLegacyParamIDs;
|
||||
|
||||
auto numParameters = audioProcessor.getNumParameters();
|
||||
usingManagedParameters = audioProcessor.getParameters().size() == numParameters;
|
||||
|
||||
for (int i = 0; i < numParameters; ++i)
|
||||
{
|
||||
auto* param = [&]() -> AudioProcessorParameter*
|
||||
{
|
||||
if (usingManagedParameters)
|
||||
return audioProcessor.getParameters()[i];
|
||||
|
||||
auto newParam = std::make_unique<LegacyAudioParameter> (forwarder, audioProcessor, i);
|
||||
auto* result = newParam.get();
|
||||
ownedGroup.addChild (std::move (newParam));
|
||||
|
||||
return result;
|
||||
}();
|
||||
|
||||
params.add (param);
|
||||
}
|
||||
|
||||
processorGroup = usingManagedParameters ? &audioProcessor.getParameterTree()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
forwarder = AudioProcessor::ParameterChangeForwarder { nullptr };
|
||||
ownedGroup = AudioProcessorParameterGroup();
|
||||
params.clear();
|
||||
}
|
||||
|
||||
AudioProcessorParameter* getParamForIndex (int index) const
|
||||
{
|
||||
if (isPositiveAndBelow (index, params.size()))
|
||||
return params[index];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
String getParamID (AudioProcessor& processor, int idx) const noexcept
|
||||
{
|
||||
if (usingManagedParameters && ! legacyParamIDs)
|
||||
return processor.getParameterID (idx);
|
||||
|
||||
return String (idx);
|
||||
}
|
||||
|
||||
const AudioProcessorParameterGroup& getGroup() const
|
||||
{
|
||||
return processorGroup != nullptr ? *processorGroup
|
||||
: ownedGroup;
|
||||
}
|
||||
|
||||
void addNonOwning (AudioProcessorParameter* param)
|
||||
{
|
||||
params.add (param);
|
||||
}
|
||||
|
||||
size_t size() const noexcept { return (size_t) params.size(); }
|
||||
|
||||
bool isUsingManagedParameters() const noexcept { return usingManagedParameters; }
|
||||
int getNumParameters() const noexcept { return params.size(); }
|
||||
|
||||
AudioProcessorParameter* const* begin() const { return params.begin(); }
|
||||
AudioProcessorParameter* const* end() const { return params.end(); }
|
||||
|
||||
bool contains (AudioProcessorParameter* param) const
|
||||
{
|
||||
return params.contains (param);
|
||||
}
|
||||
|
||||
private:
|
||||
const AudioProcessorParameterGroup* processorGroup = nullptr;
|
||||
AudioProcessorParameterGroup ownedGroup;
|
||||
Array<AudioProcessorParameter*> params;
|
||||
AudioProcessor::ParameterChangeForwarder forwarder { nullptr };
|
||||
bool legacyParamIDs = false, usingManagedParameters = false;
|
||||
};
|
||||
|
||||
JUCE_END_IGNORE_DEPRECATION_WARNINGS
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <juce_audio_processors_headless/utilities/juce_FlagCache.h>
|
||||
|
||||
/** @cond */
|
||||
namespace juce
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "juce_VST3Headers.h"
|
||||
#include "juce_VST3Utilities.h"
|
||||
#include "juce_VST3Common.h"
|
||||
#include "juce_ARACommon.h"
|
||||
#include <juce_audio_processors_headless/format_types/juce_ARACommon.h>
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
|
|
|||
|
|
@ -180,19 +180,9 @@ private:
|
|||
|
||||
} // namespace juce
|
||||
|
||||
#include "utilities/juce_FlagCache.h"
|
||||
#include "format/juce_AudioPluginFormat.cpp"
|
||||
#include "format/juce_AudioPluginFormatManager.cpp"
|
||||
#include "format_types/juce_LegacyAudioParameter.cpp"
|
||||
#include "processors/juce_AudioProcessorParameter.cpp"
|
||||
#include "processors/juce_AudioProcessor.cpp"
|
||||
#include "processors/juce_AudioProcessorListener.cpp"
|
||||
#include "processors/juce_AudioPluginInstance.cpp"
|
||||
#include "processors/juce_AudioProcessorEditor.cpp"
|
||||
#include "processors/juce_AudioProcessorGraph.cpp"
|
||||
#include "processors/juce_GenericAudioProcessorEditor.cpp"
|
||||
#include "processors/juce_PluginDescription.cpp"
|
||||
#include "format_types/juce_ARACommon.cpp"
|
||||
#include "format_types/juce_LADSPAPluginFormat.cpp"
|
||||
#include "format_types/juce_VSTPluginFormat.cpp"
|
||||
#include "format_types/juce_VST3PluginFormat.cpp"
|
||||
|
|
@ -201,20 +191,9 @@ private:
|
|||
#include "scanning/juce_KnownPluginList.cpp"
|
||||
#include "scanning/juce_PluginDirectoryScanner.cpp"
|
||||
#include "scanning/juce_PluginListComponent.cpp"
|
||||
#include "processors/juce_AudioProcessorParameterGroup.cpp"
|
||||
#include "utilities/juce_AudioProcessorParameterWithID.cpp"
|
||||
#include "utilities/juce_RangedAudioParameter.cpp"
|
||||
#include "utilities/juce_AudioParameterFloat.cpp"
|
||||
#include "utilities/juce_AudioParameterInt.cpp"
|
||||
#include "utilities/juce_AudioParameterBool.cpp"
|
||||
#include "utilities/juce_AudioParameterChoice.cpp"
|
||||
#include "utilities/juce_ParameterAttachments.cpp"
|
||||
#include "utilities/juce_AudioProcessorValueTreeState.cpp"
|
||||
#include "utilities/juce_PluginHostType.cpp"
|
||||
#include "utilities/juce_AAXClientExtensions.cpp"
|
||||
#include "utilities/juce_VST2ClientExtensions.cpp"
|
||||
#include "utilities/juce_VST3ClientExtensions.cpp"
|
||||
#include "utilities/ARA/juce_ARA_utils.cpp"
|
||||
|
||||
#include "format_types/juce_LV2PluginFormat.cpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -137,24 +137,9 @@
|
|||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#include "utilities/juce_AAXClientExtensions.h"
|
||||
#include "utilities/juce_VST2ClientExtensions.h"
|
||||
#include "utilities/juce_VST3Interface.h"
|
||||
#include "utilities/juce_VST3ClientExtensions.h"
|
||||
#include "format_types/juce_ARACommon.h"
|
||||
#include "utilities/juce_ExtensionsVisitor.h"
|
||||
#include "processors/juce_AudioProcessorParameter.h"
|
||||
#include "processors/juce_HostedAudioProcessorParameter.h"
|
||||
#include "processors/juce_AudioProcessorEditorHostContext.h"
|
||||
#include "processors/juce_AudioProcessorEditor.h"
|
||||
#include "processors/juce_AudioProcessorListener.h"
|
||||
#include "processors/juce_AudioProcessorParameterGroup.h"
|
||||
#include "processors/juce_AudioProcessor.h"
|
||||
#include "processors/juce_PluginDescription.h"
|
||||
#include "processors/juce_AudioPluginInstance.h"
|
||||
#include "processors/juce_AudioProcessorGraph.h"
|
||||
#include "processors/juce_GenericAudioProcessorEditor.h"
|
||||
#include "format/juce_AudioPluginFormat.h"
|
||||
#include "format/juce_AudioPluginFormatManager.h"
|
||||
#include "scanning/juce_KnownPluginList.h"
|
||||
#include "format_types/juce_AudioUnitPluginFormat.h"
|
||||
|
|
@ -166,17 +151,9 @@
|
|||
#include "format_types/juce_ARAHosting.h"
|
||||
#include "scanning/juce_PluginDirectoryScanner.h"
|
||||
#include "scanning/juce_PluginListComponent.h"
|
||||
#include "utilities/juce_AudioProcessorParameterWithID.h"
|
||||
#include "utilities/juce_RangedAudioParameter.h"
|
||||
#include "utilities/juce_AudioParameterFloat.h"
|
||||
#include "utilities/juce_AudioParameterInt.h"
|
||||
#include "utilities/juce_AudioParameterBool.h"
|
||||
#include "utilities/juce_AudioParameterChoice.h"
|
||||
#include "utilities/juce_ParameterAttachments.h"
|
||||
#include "utilities/juce_AudioProcessorValueTreeState.h"
|
||||
#include "utilities/juce_PluginHostType.h"
|
||||
#include "utilities/ARA/juce_ARADebug.h"
|
||||
#include "utilities/ARA/juce_ARA_utils.h"
|
||||
|
||||
//==============================================================================
|
||||
// These declarations are here to avoid missing-prototype warnings in user code.
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_CompilerWarnings.h>
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
|
||||
#include "utilities/ARA/juce_ARADebug.h"
|
||||
|
||||
/* Having WIN32_LEAN_AND_MEAN defined at the point of including ARADebug.c will produce warnings.
|
||||
|
||||
To prevent such problems it's easiest to have it in its own translation unit.
|
||||
*/
|
||||
|
||||
#if (JucePlugin_Enable_ARA || (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU))) && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments", "-Wmissing-prototypes")
|
||||
#include <ARA_Library/Debug/ARADebug.c>
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,294 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
PluginDescription AudioPluginInstance::getPluginDescription() const
|
||||
{
|
||||
PluginDescription desc;
|
||||
fillInPluginDescription (desc);
|
||||
return desc;
|
||||
}
|
||||
|
||||
void* AudioPluginInstance::getPlatformSpecificData() { return nullptr; }
|
||||
|
||||
void AudioPluginInstance::getExtensions (ExtensionsVisitor& visitor) const { visitor.visitUnknown ({}); }
|
||||
|
||||
String AudioPluginInstance::getParameterID (int parameterIndex)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
// Currently there is no corresponding method available in the
|
||||
// AudioProcessorParameter class, and the previous behaviour of JUCE's
|
||||
// plug-in hosting code simply returns a string version of the index; to
|
||||
// maintain backwards compatibility you should perform the operation below
|
||||
// this comment. However the caveat is that for plug-ins which change their
|
||||
// number of parameters dynamically at runtime you cannot rely upon the
|
||||
// returned parameter ID mapping to the correct parameter. A comprehensive
|
||||
// solution to this problem requires some additional work in JUCE's hosting
|
||||
// code.
|
||||
return String (parameterIndex);
|
||||
}
|
||||
|
||||
float AudioPluginInstance::getParameter (int parameterIndex)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getValue();
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void AudioPluginInstance::setParameter (int parameterIndex, float newValue)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
param->setValue (newValue);
|
||||
}
|
||||
|
||||
const String AudioPluginInstance::getParameterName (int parameterIndex)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getName (1024);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
String AudioPluginInstance::getParameterName (int parameterIndex, int maximumStringLength)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getName (maximumStringLength);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
const String AudioPluginInstance::getParameterText (int parameterIndex)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getCurrentValueAsText();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
String AudioPluginInstance::getParameterText (int parameterIndex, int maximumStringLength)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getCurrentValueAsText().substring (0, maximumStringLength);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
float AudioPluginInstance::getParameterDefaultValue (int parameterIndex)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getDefaultValue();
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
int AudioPluginInstance::getParameterNumSteps (int parameterIndex)
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getNumSteps();
|
||||
|
||||
return AudioProcessor::getDefaultNumParameterSteps();
|
||||
}
|
||||
|
||||
bool AudioPluginInstance::isParameterDiscrete (int parameterIndex) const
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->isDiscrete();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioPluginInstance::isParameterAutomatable (int parameterIndex) const
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->isAutomatable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String AudioPluginInstance::getParameterLabel (int parameterIndex) const
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getLabel();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool AudioPluginInstance::isParameterOrientationInverted (int parameterIndex) const
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->isOrientationInverted();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioPluginInstance::isMetaParameter (int parameterIndex) const
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->isMetaParameter();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AudioProcessorParameter::Category AudioPluginInstance::getParameterCategory (int parameterIndex) const
|
||||
{
|
||||
assertOnceOnDeprecatedMethodUse();
|
||||
|
||||
if (auto* param = getParameters()[parameterIndex])
|
||||
return param->getCategory();
|
||||
|
||||
return AudioProcessorParameter::genericParameter;
|
||||
}
|
||||
|
||||
void AudioPluginInstance::assertOnceOnDeprecatedMethodUse() const noexcept
|
||||
{
|
||||
if (! deprecationAssertiontriggered)
|
||||
{
|
||||
// If you hit this assertion then you are using at least one of the
|
||||
// methods marked as deprecated in this class. For now you can simply
|
||||
// continue past this point and subsequent uses of deprecated methods
|
||||
// will not trigger additional assertions. However, we will shortly be
|
||||
// removing these methods so you are strongly advised to look at the
|
||||
// implementation of the corresponding method in this class and use
|
||||
// that approach instead.
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
deprecationAssertiontriggered = true;
|
||||
}
|
||||
|
||||
bool AudioPluginInstance::deprecationAssertiontriggered = false;
|
||||
|
||||
AudioPluginInstance::Parameter::Parameter()
|
||||
: onStrings { TRANS ("on"), TRANS ("yes"), TRANS ("true") },
|
||||
offStrings { TRANS ("off"), TRANS ("no"), TRANS ("false") }
|
||||
{
|
||||
}
|
||||
|
||||
String AudioPluginInstance::Parameter::getText (float value, int maximumStringLength) const
|
||||
{
|
||||
if (isBoolean())
|
||||
return value < 0.5f ? TRANS ("Off") : TRANS ("On");
|
||||
|
||||
return String (value).substring (0, maximumStringLength);
|
||||
}
|
||||
|
||||
float AudioPluginInstance::Parameter::getValueForText (const String& text) const
|
||||
{
|
||||
auto floatValue = text.retainCharacters ("-0123456789.").getFloatValue();
|
||||
|
||||
if (isBoolean())
|
||||
{
|
||||
if (onStrings.contains (text, true))
|
||||
return 1.0f;
|
||||
|
||||
if (offStrings.contains (text, true))
|
||||
return 0.0f;
|
||||
|
||||
return floatValue < 0.5f ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
void AudioPluginInstance::addHostedParameter (std::unique_ptr<HostedParameter> param)
|
||||
{
|
||||
addParameter (param.release());
|
||||
}
|
||||
|
||||
void AudioPluginInstance::addHostedParameterGroup (std::unique_ptr<AudioProcessorParameterGroup> group)
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
// All parameters *must* be HostedParameters, otherwise getHostedParameter will return
|
||||
// garbage and your host will crash and burn
|
||||
for (auto* param : group->getParameters (true))
|
||||
{
|
||||
jassertquiet (dynamic_cast<HostedParameter*> (param) != nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
addParameterGroup (std::move (group));
|
||||
}
|
||||
|
||||
void AudioPluginInstance::setHostedParameterTree (AudioProcessorParameterGroup group)
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
// All parameters *must* be HostedParameters, otherwise getHostedParameter will return
|
||||
// garbage and your host will crash and burn
|
||||
for (auto* param : group.getParameters (true))
|
||||
{
|
||||
jassertquiet (dynamic_cast<HostedParameter*> (param) != nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
setParameterTree (std::move (group));
|
||||
}
|
||||
|
||||
AudioPluginInstance::HostedParameter* AudioPluginInstance::getHostedParameter (int index) const
|
||||
{
|
||||
// It's important that all AudioPluginInstance implementations
|
||||
// only ever own HostedParameters!
|
||||
return static_cast<HostedParameter*> (getParameters()[index]);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
// MSVC does not like it if you override a deprecated method even if you
|
||||
// keep the deprecation attribute. Other compilers are more forgiving.
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Base class for an active instance of a plugin.
|
||||
|
||||
This derives from the AudioProcessor class, and adds some extra functionality
|
||||
that helps when wrapping dynamically loaded plugins.
|
||||
|
||||
This class is not needed when writing plugins, and you should never need to derive
|
||||
your own sub-classes from it. The plugin hosting classes use it internally and will
|
||||
return AudioPluginInstance objects which wrap external plugins.
|
||||
|
||||
@see AudioProcessor, AudioPluginFormat
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioPluginInstance : public AudioProcessor
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Destructor.
|
||||
|
||||
Make sure that you delete any UI components that belong to this plugin before
|
||||
deleting the plugin.
|
||||
*/
|
||||
~AudioPluginInstance() override = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Fills-in the appropriate parts of this plugin description object. */
|
||||
virtual void fillInPluginDescription (PluginDescription&) const = 0;
|
||||
|
||||
/** Returns a PluginDescription for this plugin.
|
||||
This is just a convenience method to avoid calling fillInPluginDescription.
|
||||
*/
|
||||
PluginDescription getPluginDescription() const;
|
||||
|
||||
/** 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;
|
||||
|
||||
using HostedParameter = HostedAudioProcessorParameter;
|
||||
|
||||
/** Adds a parameter to this instance.
|
||||
|
||||
@see AudioProcessor::addParameter()
|
||||
*/
|
||||
void addHostedParameter (std::unique_ptr<HostedParameter>);
|
||||
|
||||
/** Adds multiple parameters to this instance.
|
||||
|
||||
In debug mode, this will also check that all added parameters derive from
|
||||
HostedParameter.
|
||||
|
||||
@see AudioProcessor::addParameterGroup()
|
||||
*/
|
||||
void addHostedParameterGroup (std::unique_ptr<AudioProcessorParameterGroup>);
|
||||
|
||||
/** Adds multiple parameters to this instance.
|
||||
|
||||
In debug mode, this will also check that all added parameters derive from
|
||||
HostedParameter.
|
||||
|
||||
@see AudioProcessor::setParameterTree()
|
||||
*/
|
||||
void setHostedParameterTree (AudioProcessorParameterGroup);
|
||||
|
||||
/** Gets the parameter at a particular index.
|
||||
|
||||
If you want to find lots of parameters by their IDs, you should probably build and
|
||||
use a map<String, HostedParameter*> by looping through all parameters.
|
||||
*/
|
||||
HostedParameter* getHostedParameter (int index) const;
|
||||
|
||||
/** @cond */
|
||||
/** 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.
|
||||
*/
|
||||
[[deprecated ("Use the new typesafe visitor-based interface rather than this function.")]]
|
||||
virtual void* getPlatformSpecificData();
|
||||
|
||||
// Rather than using these methods you should call the corresponding methods
|
||||
// on the AudioProcessorParameter objects returned from getParameters().
|
||||
// See the implementations of the methods below for some examples of how to
|
||||
// do this.
|
||||
//
|
||||
// In addition to being marked as deprecated these methods will assert on
|
||||
// the first call.
|
||||
[[deprecated]] String getParameterID (int index) override;
|
||||
[[deprecated]] float getParameter (int parameterIndex) override;
|
||||
[[deprecated]] void setParameter (int parameterIndex, float newValue) override;
|
||||
[[deprecated]] const String getParameterName (int parameterIndex) override;
|
||||
[[deprecated]] String getParameterName (int parameterIndex, int maximumStringLength) override;
|
||||
[[deprecated]] const String getParameterText (int parameterIndex) override;
|
||||
[[deprecated]] String getParameterText (int parameterIndex, int maximumStringLength) override;
|
||||
[[deprecated]] int getParameterNumSteps (int parameterIndex) override;
|
||||
[[deprecated]] bool isParameterDiscrete (int parameterIndex) const override;
|
||||
[[deprecated]] bool isParameterAutomatable (int parameterIndex) const override;
|
||||
[[deprecated]] float getParameterDefaultValue (int parameterIndex) override;
|
||||
[[deprecated]] String getParameterLabel (int parameterIndex) const override;
|
||||
[[deprecated]] bool isParameterOrientationInverted (int parameterIndex) const override;
|
||||
[[deprecated]] bool isMetaParameter (int parameterIndex) const override;
|
||||
[[deprecated]] AudioProcessorParameter::Category getParameterCategory (int parameterIndex) const override;
|
||||
/** @endcond */
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Structure used to describe plugin parameters */
|
||||
struct Parameter : public HostedParameter
|
||||
{
|
||||
public:
|
||||
Parameter();
|
||||
|
||||
String getText (float value, int maximumStringLength) const override;
|
||||
float getValueForText (const String& text) const override;
|
||||
|
||||
private:
|
||||
const StringArray onStrings, offStrings;
|
||||
};
|
||||
|
||||
AudioPluginInstance() = default;
|
||||
AudioPluginInstance (const BusesProperties& ioLayouts) : AudioProcessor (ioLayouts) {}
|
||||
template <size_t numLayouts>
|
||||
AudioPluginInstance (const short channelLayoutList[numLayouts][2]) : AudioProcessor (channelLayoutList) {}
|
||||
|
||||
private:
|
||||
// It's not safe to add a plain AudioProcessorParameter to an AudioPluginInstance.
|
||||
// Instead, all parameters must be HostedParameters.
|
||||
using AudioProcessor::addParameter;
|
||||
using AudioProcessor::addParameterGroup;
|
||||
using AudioProcessor::setParameterTree;
|
||||
|
||||
void assertOnceOnDeprecatedMethodUse() const noexcept;
|
||||
|
||||
static bool deprecationAssertiontriggered;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance)
|
||||
};
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
} // namespace juce
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,472 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A type of AudioProcessor which plays back a graph of other AudioProcessors.
|
||||
|
||||
Use one of these objects if you want to wire-up a set of AudioProcessors
|
||||
and play back the result.
|
||||
|
||||
Processors can be added to the graph as "nodes" using addNode(), and once
|
||||
added, you can connect any of their input or output channels to other
|
||||
nodes using addConnection().
|
||||
|
||||
To play back a graph through an audio device, you might want to use an
|
||||
AudioProcessorPlayer object.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioProcessorGraph : public AudioProcessor,
|
||||
public ChangeBroadcaster
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty graph. */
|
||||
AudioProcessorGraph();
|
||||
|
||||
/** Destructor.
|
||||
Any processor objects that have been added to the graph will also be deleted.
|
||||
*/
|
||||
~AudioProcessorGraph() override;
|
||||
|
||||
/** Each node in the graph has a UID of this type. */
|
||||
struct NodeID
|
||||
{
|
||||
constexpr NodeID() = default;
|
||||
explicit constexpr NodeID (uint32 i) : uid (i) {}
|
||||
|
||||
uint32 uid = 0;
|
||||
|
||||
constexpr bool operator== (const NodeID& other) const noexcept { return uid == other.uid; }
|
||||
constexpr bool operator!= (const NodeID& other) const noexcept { return uid != other.uid; }
|
||||
constexpr bool operator< (const NodeID& other) const noexcept { return uid < other.uid; }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** A special index that represents the midi channel of a node.
|
||||
|
||||
This is used as a channel index value if you want to refer to the midi input
|
||||
or output instead of an audio channel.
|
||||
*/
|
||||
enum { midiChannelIndex = 0x1000 };
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents an input or output channel of a node in an AudioProcessorGraph.
|
||||
*/
|
||||
class NodeAndChannel
|
||||
{
|
||||
constexpr auto tie() const { return std::tie (nodeID, channelIndex); }
|
||||
|
||||
public:
|
||||
NodeID nodeID;
|
||||
int channelIndex;
|
||||
|
||||
constexpr bool isMIDI() const noexcept { return channelIndex == midiChannelIndex; }
|
||||
|
||||
constexpr bool operator== (const NodeAndChannel& other) const noexcept { return tie() == other.tie(); }
|
||||
constexpr bool operator!= (const NodeAndChannel& other) const noexcept { return tie() != other.tie(); }
|
||||
constexpr bool operator< (const NodeAndChannel& other) const noexcept { return tie() < other.tie(); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Represents one of the nodes, or processors, in an AudioProcessorGraph.
|
||||
|
||||
To create a node, call AudioProcessorGraph::addNode().
|
||||
*/
|
||||
class JUCE_API Node : public ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** The ID number assigned to this node.
|
||||
This is assigned by the graph that owns it, and can't be changed.
|
||||
*/
|
||||
const NodeID nodeID;
|
||||
|
||||
/** The actual processor object that this node represents. */
|
||||
AudioProcessor* getProcessor() const noexcept { return processor.get(); }
|
||||
|
||||
/** A set of user-definable properties that are associated with this node.
|
||||
|
||||
This can be used to attach values to the node for whatever purpose seems
|
||||
useful. For example, you might store an x and y position if your application
|
||||
is displaying the nodes on-screen.
|
||||
*/
|
||||
NamedValueSet properties;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns if the node is bypassed or not. */
|
||||
bool isBypassed() const noexcept
|
||||
{
|
||||
if (processor != nullptr)
|
||||
{
|
||||
if (auto* bypassParam = processor->getBypassParameter())
|
||||
return ! approximatelyEqual (bypassParam->getValue(), 0.0f);
|
||||
}
|
||||
|
||||
return bypassed;
|
||||
}
|
||||
|
||||
/** Tell this node to bypass processing. */
|
||||
void setBypassed (bool shouldBeBypassed) noexcept
|
||||
{
|
||||
if (processor != nullptr)
|
||||
{
|
||||
if (auto* bypassParam = processor->getBypassParameter())
|
||||
bypassParam->setValueNotifyingHost (shouldBeBypassed ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
bypassed = shouldBeBypassed;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** A convenient typedef for referring to a pointer to a node object. */
|
||||
using Ptr = ReferenceCountedObjectPtr<Node>;
|
||||
|
||||
/** @internal
|
||||
|
||||
Returns true if setBypassed (true) was called on this node.
|
||||
This behaviour is different from isBypassed(), which may additionally return true if
|
||||
the node has a bypass parameter that is not set to 0.
|
||||
*/
|
||||
bool userRequestedBypass() const { return bypassed; }
|
||||
|
||||
/** @internal
|
||||
|
||||
To create a new node, use AudioProcessorGraph::addNode.
|
||||
*/
|
||||
Node (NodeID n, std::unique_ptr<AudioProcessor> p) noexcept
|
||||
: nodeID (n), processor (std::move (p))
|
||||
{
|
||||
jassert (processor != nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::unique_ptr<AudioProcessor> processor;
|
||||
std::atomic<bool> bypassed { false };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Node)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Represents a connection between two channels of two nodes in an AudioProcessorGraph.
|
||||
|
||||
To create a connection, use AudioProcessorGraph::addConnection().
|
||||
*/
|
||||
struct JUCE_API Connection
|
||||
{
|
||||
//==============================================================================
|
||||
constexpr Connection() = default;
|
||||
constexpr Connection (NodeAndChannel sourceIn, NodeAndChannel destinationIn) noexcept
|
||||
: source (sourceIn), destination (destinationIn) {}
|
||||
|
||||
constexpr Connection (const Connection&) = default;
|
||||
constexpr Connection& operator= (const Connection&) = default;
|
||||
|
||||
constexpr bool operator== (const Connection& other) const noexcept
|
||||
{
|
||||
return source == other.source && destination == other.destination;
|
||||
}
|
||||
|
||||
constexpr bool operator!= (const Connection& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
constexpr bool operator< (const Connection& other) const noexcept
|
||||
{
|
||||
const auto tie = [] (auto& x)
|
||||
{
|
||||
return std::tie (x.source.nodeID,
|
||||
x.destination.nodeID,
|
||||
x.source.channelIndex,
|
||||
x.destination.channelIndex);
|
||||
};
|
||||
return tie (*this) < tie (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** The channel and node which is the input source for this connection. */
|
||||
NodeAndChannel source { {}, 0 };
|
||||
|
||||
/** The channel and node which is the input source for this connection. */
|
||||
NodeAndChannel destination { {}, 0 };
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Indicates how the graph should be updated after a change.
|
||||
|
||||
If you need to make lots of changes to a graph (e.g. lots of separate calls
|
||||
to addNode, addConnection etc.) you can avoid rebuilding the graph on each
|
||||
change by using the async update kind.
|
||||
*/
|
||||
enum class UpdateKind
|
||||
{
|
||||
sync, ///< Graph should be rebuilt immediately after modification.
|
||||
async, ///< Graph rebuild should be delayed. If you make several changes to the graph
|
||||
///< inside the same call stack, these changes will be applied in one go.
|
||||
none ///< Graph should not be rebuilt automatically. Use rebuild() to trigger a graph
|
||||
///< rebuild.
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Deletes all nodes and connections from this graph.
|
||||
Any processor objects in the graph will be deleted.
|
||||
*/
|
||||
void clear (UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Returns the array of nodes in the graph. */
|
||||
const ReferenceCountedArray<Node>& getNodes() const noexcept;
|
||||
|
||||
/** Returns the number of nodes in the graph. */
|
||||
int getNumNodes() const noexcept { return getNodes().size(); }
|
||||
|
||||
/** Returns a pointer to one of the nodes in the graph.
|
||||
This will return nullptr if the index is out of range.
|
||||
@see getNodeForId
|
||||
*/
|
||||
Node::Ptr getNode (int index) const noexcept { return getNodes()[index]; }
|
||||
|
||||
/** Searches the graph for a node with the given ID number and returns it.
|
||||
If no such node was found, this returns nullptr.
|
||||
@see getNode
|
||||
*/
|
||||
Node* getNodeForId (NodeID) const;
|
||||
|
||||
/** Adds a node to the graph.
|
||||
|
||||
This creates a new node in the graph, for the specified processor. Once you have
|
||||
added a processor to the graph, the graph owns it and will delete it later when
|
||||
it is no longer needed.
|
||||
|
||||
The optional nodeId parameter lets you specify a unique ID to use for the node.
|
||||
If the value is already in use, this method will fail and return an empty node.
|
||||
|
||||
If this succeeds, it returns a pointer to the newly-created node.
|
||||
*/
|
||||
Node::Ptr addNode (std::unique_ptr<AudioProcessor> newProcessor, std::optional<NodeID> nodeId = std::nullopt, UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Deletes a node within the graph which has the specified ID.
|
||||
This will also delete any connections that are attached to this node.
|
||||
*/
|
||||
Node::Ptr removeNode (NodeID, UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Deletes a node within the graph.
|
||||
This will also delete any connections that are attached to this node.
|
||||
*/
|
||||
Node::Ptr removeNode (Node*, UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Returns the list of connections in the graph. */
|
||||
std::vector<Connection> getConnections() const;
|
||||
|
||||
/** Returns true if the given connection exists. */
|
||||
bool isConnected (const Connection&) const noexcept;
|
||||
|
||||
/** Returns true if there is a direct connection between any of the channels of
|
||||
two specified nodes.
|
||||
*/
|
||||
bool isConnected (NodeID possibleSourceNodeID, NodeID possibleDestNodeID) const noexcept;
|
||||
|
||||
/** Does a recursive check to see if there's a direct or indirect series of connections
|
||||
between these two nodes.
|
||||
*/
|
||||
bool isAnInputTo (const Node& source, const Node& destination) const noexcept;
|
||||
|
||||
/** Does a recursive check to see if there's a direct or indirect series of connections
|
||||
between these two nodes.
|
||||
*/
|
||||
bool isAnInputTo (NodeID source, NodeID destination) const noexcept;
|
||||
|
||||
/** Returns true if it would be legal to connect the specified points. */
|
||||
bool canConnect (const Connection&) const;
|
||||
|
||||
/** Attempts to connect two specified channels of two nodes.
|
||||
|
||||
If this isn't allowed (e.g. because you're trying to connect a midi channel
|
||||
to an audio one or other such nonsense), then it'll return false.
|
||||
*/
|
||||
bool addConnection (const Connection&, UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Deletes the given connection. */
|
||||
bool removeConnection (const Connection&, UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Removes all connections from the specified node. */
|
||||
bool disconnectNode (NodeID, UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Returns true if the given connection's channel numbers map on to valid
|
||||
channels at each end.
|
||||
Even if a connection is valid when created, its status could change if
|
||||
a node changes its channel config.
|
||||
*/
|
||||
bool isConnectionLegal (const Connection&) const;
|
||||
|
||||
/** Performs a sanity checks of all the connections.
|
||||
|
||||
This might be useful if some of the processors are doing things like changing
|
||||
their channel counts, which could render some connections obsolete.
|
||||
*/
|
||||
bool removeIllegalConnections (UpdateKind = UpdateKind::sync);
|
||||
|
||||
/** Rebuilds the graph if necessary.
|
||||
|
||||
This function will only ever rebuild the graph on the main thread. If this function is
|
||||
called from another thread, the rebuild request will be dispatched asynchronously to the
|
||||
main thread.
|
||||
*/
|
||||
void rebuild();
|
||||
|
||||
//==============================================================================
|
||||
/** A special type of AudioProcessor that can live inside an AudioProcessorGraph
|
||||
in order to use the audio that comes into and out of the graph itself.
|
||||
|
||||
If you create an AudioGraphIOProcessor in "input" mode, it will act as a
|
||||
node in the graph which delivers the audio that is coming into the parent
|
||||
graph. This allows you to stream the data to other nodes and process the
|
||||
incoming audio.
|
||||
|
||||
Likewise, one of these in "output" mode can be sent data which it will add to
|
||||
the sum of data being sent to the graph's output.
|
||||
|
||||
@see AudioProcessorGraph
|
||||
*/
|
||||
class JUCE_API AudioGraphIOProcessor : public AudioPluginInstance
|
||||
{
|
||||
public:
|
||||
/** Specifies the mode in which this processor will operate.
|
||||
*/
|
||||
enum IODeviceType
|
||||
{
|
||||
audioInputNode, /**< In this mode, the processor has output channels
|
||||
representing all the audio input channels that are
|
||||
coming into its parent audio graph. */
|
||||
audioOutputNode, /**< In this mode, the processor has input channels
|
||||
representing all the audio output channels that are
|
||||
going out of its parent audio graph. */
|
||||
midiInputNode, /**< In this mode, the processor has a midi output which
|
||||
delivers the same midi data that is arriving at its
|
||||
parent graph. */
|
||||
midiOutputNode /**< In this mode, the processor has a midi input and
|
||||
any data sent to it will be passed out of the parent
|
||||
graph. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the mode of this processor. */
|
||||
IODeviceType getType() const noexcept { return type; }
|
||||
|
||||
/** Returns the parent graph to which this processor belongs, or nullptr if it
|
||||
hasn't yet been added to one. */
|
||||
AudioProcessorGraph* getParentGraph() const noexcept { return graph; }
|
||||
|
||||
/** True if this is an audio or midi input. */
|
||||
bool isInput() const noexcept;
|
||||
/** True if this is an audio or midi output. */
|
||||
bool isOutput() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
AudioGraphIOProcessor (IODeviceType);
|
||||
~AudioGraphIOProcessor() override;
|
||||
|
||||
const String getName() const override;
|
||||
void fillInPluginDescription (PluginDescription&) const override;
|
||||
void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) override;
|
||||
void releaseResources() override;
|
||||
void processBlock (AudioBuffer<float>& , MidiBuffer&) override;
|
||||
void processBlock (AudioBuffer<double>&, MidiBuffer&) override;
|
||||
bool supportsDoublePrecisionProcessing() const override;
|
||||
|
||||
double getTailLengthSeconds() const override;
|
||||
bool acceptsMidi() const override;
|
||||
bool producesMidi() const override;
|
||||
|
||||
bool hasEditor() const override;
|
||||
AudioProcessorEditor* createEditor() override;
|
||||
|
||||
int getNumPrograms() override;
|
||||
int getCurrentProgram() override;
|
||||
void setCurrentProgram (int) override;
|
||||
const String getProgramName (int) override;
|
||||
void changeProgramName (int, const String&) override;
|
||||
|
||||
void getStateInformation (juce::MemoryBlock& destData) override;
|
||||
void setStateInformation (const void* data, int sizeInBytes) override;
|
||||
|
||||
/** @internal */
|
||||
void setParentGraph (AudioProcessorGraph*);
|
||||
|
||||
private:
|
||||
const IODeviceType type;
|
||||
AudioProcessorGraph* graph = nullptr;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioGraphIOProcessor)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
const String getName() const override;
|
||||
void prepareToPlay (double, int) override;
|
||||
void releaseResources() override;
|
||||
void processBlock (AudioBuffer<float>&, MidiBuffer&) override;
|
||||
void processBlock (AudioBuffer<double>&, MidiBuffer&) override;
|
||||
bool supportsDoublePrecisionProcessing() const override;
|
||||
|
||||
void reset() override;
|
||||
void setNonRealtime (bool) noexcept override;
|
||||
|
||||
double getTailLengthSeconds() const override;
|
||||
bool acceptsMidi() const override;
|
||||
bool producesMidi() const override;
|
||||
|
||||
bool hasEditor() const override { return false; }
|
||||
AudioProcessorEditor* createEditor() override { return nullptr; }
|
||||
int getNumPrograms() override { return 0; }
|
||||
int getCurrentProgram() override { return 0; }
|
||||
void setCurrentProgram (int) override { }
|
||||
const String getProgramName (int) override { return {}; }
|
||||
void changeProgramName (int, const String&) override { }
|
||||
void getStateInformation (juce::MemoryBlock&) override;
|
||||
void setStateInformation (const void* data, int sizeInBytes) override;
|
||||
|
||||
private:
|
||||
class Pimpl;
|
||||
std::unique_ptr<Pimpl> pimpl;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorGraph)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {}
|
||||
void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Base class for listeners that want to know about changes to an AudioProcessor.
|
||||
|
||||
Use AudioProcessor::addListener() to register your listener with an AudioProcessor.
|
||||
|
||||
@see AudioProcessor
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioProcessorListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Destructor. */
|
||||
virtual ~AudioProcessorListener() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Receives a callback when a parameter is changed.
|
||||
|
||||
IMPORTANT NOTE: This will be called synchronously when a parameter changes, and
|
||||
many audio processors will change their parameter during their audio callback.
|
||||
This means that not only has your handler code got to be completely thread-safe,
|
||||
but it's also got to be VERY fast, and avoid blocking. If you need to handle
|
||||
this event on your message thread, use this callback to trigger an AsyncUpdater
|
||||
or ChangeBroadcaster which you can respond to on the message thread.
|
||||
*/
|
||||
virtual void audioProcessorParameterChanged (AudioProcessor* processor,
|
||||
int parameterIndex,
|
||||
float newValue) = 0;
|
||||
|
||||
/** Provides details about aspects of an AudioProcessor which have changed.
|
||||
*/
|
||||
struct JUCE_API ChangeDetails
|
||||
{
|
||||
/** @see withLatencyChanged */
|
||||
bool latencyChanged = false;
|
||||
/** @see withParameterInfoChanged */
|
||||
bool parameterInfoChanged = false;
|
||||
/** @see withProgramChanged */
|
||||
bool programChanged = false;
|
||||
/** @see withNonParameterStateChanged */
|
||||
bool nonParameterStateChanged = false;
|
||||
|
||||
/** Indicates that the AudioProcessor's latency has changed.
|
||||
|
||||
Most of the time, you won't need to use this function directly.
|
||||
AudioProcessor::setLatencySamples() will automatically call
|
||||
AudioProcessor::updateHostDisplay(), indicating that the latency has changed.
|
||||
|
||||
@see latencyChanged
|
||||
*/
|
||||
[[nodiscard]] ChangeDetails withLatencyChanged (bool b) const noexcept { return with (&ChangeDetails::latencyChanged, b); }
|
||||
|
||||
/** Indicates that some attributes of the AudioProcessor's parameters have changed.
|
||||
|
||||
When this flag is set, the host should rescan the AudioProcessor's parameters, and
|
||||
update its controls to match. This is often used to update the names of a plugin's
|
||||
parameters in the host.
|
||||
|
||||
@see parameterInfoChanged
|
||||
*/
|
||||
[[nodiscard]] ChangeDetails withParameterInfoChanged (bool b) const noexcept { return with (&ChangeDetails::parameterInfoChanged, b); }
|
||||
|
||||
/** Indicates that the loaded program has changed.
|
||||
|
||||
When this flag is set, the host should call AudioProcessor::getCurrentProgram() and
|
||||
update any preset list views to display the program that is currently in use.
|
||||
|
||||
@see programChanged
|
||||
*/
|
||||
[[nodiscard]] ChangeDetails withProgramChanged (bool b) const noexcept { return with (&ChangeDetails::programChanged, b); }
|
||||
|
||||
/** Indicates that the plugin state has changed (but not its parameters!).
|
||||
|
||||
An AudioProcessor can call updateHostDisplay with this flag set to notify the host that
|
||||
its state has changed in a way that requires re-saving.
|
||||
|
||||
If a host receives a call to audioProcessorChanged with this flag set, it should offer
|
||||
to save the plugin state before taking any actions that might irrevocably destroy the
|
||||
current plugin state, such as closing the project.
|
||||
|
||||
@see nonParameterStateChanged
|
||||
*/
|
||||
[[nodiscard]] ChangeDetails withNonParameterStateChanged (bool b) const noexcept { return with (&ChangeDetails::nonParameterStateChanged, b); }
|
||||
|
||||
/** Returns the default set of flags that will be used when
|
||||
AudioProcessor::updateHostDisplay() is called with no arguments.
|
||||
*/
|
||||
static ChangeDetails getDefaultFlags()
|
||||
{
|
||||
return ChangeDetails{}.withLatencyChanged (true)
|
||||
.withParameterInfoChanged (true)
|
||||
.withProgramChanged (true);
|
||||
}
|
||||
|
||||
[[deprecated ("The naming of this function is misleading. Use getDefaultFlags instead.")]]
|
||||
static ChangeDetails getAllChanged()
|
||||
{
|
||||
return getDefaultFlags();
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Member, typename Value>
|
||||
ChangeDetails with (Member&& member, Value&& value) const noexcept
|
||||
{
|
||||
auto copy = *this;
|
||||
copy.*member = std::forward<Value> (value);
|
||||
return copy;
|
||||
}
|
||||
};
|
||||
|
||||
/** Called to indicate that something else in the plugin has changed, like its
|
||||
program, number of parameters, etc.
|
||||
|
||||
IMPORTANT NOTE: This will be called synchronously, and many audio processors will
|
||||
call it during their audio callback. This means that not only has your handler code
|
||||
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
||||
blocking. If you need to handle this event on your message thread, use this callback
|
||||
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
||||
message thread.
|
||||
*/
|
||||
virtual void audioProcessorChanged (AudioProcessor* processor, const ChangeDetails& details) = 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 audioProcessorParameterChangeGestureEnd would be
|
||||
called when they release it.
|
||||
|
||||
IMPORTANT NOTE: This will be called synchronously, and many audio processors will
|
||||
call it during their audio callback. This means that not only has your handler code
|
||||
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
||||
blocking. If you need to handle this event on your message thread, use this callback
|
||||
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
||||
message thread.
|
||||
|
||||
@see audioProcessorParameterChangeGestureEnd
|
||||
*/
|
||||
virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor,
|
||||
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.
|
||||
|
||||
IMPORTANT NOTE: This will be called synchronously, and many audio processors will
|
||||
call it during their audio callback. This means that not only has your handler code
|
||||
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
||||
blocking. If you need to handle this event on your message thread, use this callback
|
||||
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
||||
message thread.
|
||||
|
||||
@see audioProcessorParameterChangeGestureBegin
|
||||
*/
|
||||
virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor,
|
||||
int parameterIndex);
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioProcessorParameter::~AudioProcessorParameter()
|
||||
{
|
||||
#if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING
|
||||
// This will fail if you've called beginChangeGesture() without having made
|
||||
// a corresponding call to endChangeGesture...
|
||||
jassert (! isPerformingGesture);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::setParameterIndex (int index) noexcept
|
||||
{
|
||||
jassert (parameterIndex < 0 && 0 <= index);
|
||||
parameterIndex = index;
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::setOwner (Listener* listenerIn) noexcept
|
||||
{
|
||||
jassert (finalListener == nullptr);
|
||||
finalListener = listenerIn;
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::setValueNotifyingHost (float newValue)
|
||||
{
|
||||
setValue (newValue);
|
||||
sendValueChangedMessageToListeners (newValue);
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::beginChangeGesture()
|
||||
{
|
||||
// This method can't be used until the parameter has been attached to a processor!
|
||||
jassert (parameterIndex >= 0);
|
||||
|
||||
#if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING
|
||||
// This means you've called beginChangeGesture twice in succession without
|
||||
// a matching call to endChangeGesture. That might be fine in most hosts,
|
||||
// but it would be better to avoid doing it.
|
||||
jassert (! isPerformingGesture);
|
||||
isPerformingGesture = true;
|
||||
#endif
|
||||
|
||||
ScopedLock lock (listenerLock);
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
if (auto* l = listeners[i])
|
||||
l->parameterGestureChanged (getParameterIndex(), true);
|
||||
|
||||
if (finalListener != nullptr)
|
||||
finalListener->parameterGestureChanged (getParameterIndex(), true);
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::endChangeGesture()
|
||||
{
|
||||
// This method can't be used until the parameter has been attached to a processor!
|
||||
jassert (parameterIndex >= 0);
|
||||
|
||||
#if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING
|
||||
// This means you've called endChangeGesture without having previously
|
||||
// called beginChangeGesture. That might be fine in most hosts, but it
|
||||
// would be better to keep the calls matched correctly.
|
||||
jassert (isPerformingGesture);
|
||||
isPerformingGesture = false;
|
||||
#endif
|
||||
|
||||
ScopedLock lock (listenerLock);
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
if (auto* l = listeners[i])
|
||||
l->parameterGestureChanged (getParameterIndex(), false);
|
||||
|
||||
if (finalListener != nullptr)
|
||||
finalListener->parameterGestureChanged (getParameterIndex(), false);
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue)
|
||||
{
|
||||
ScopedLock lock (listenerLock);
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
if (auto* l = listeners [i])
|
||||
l->parameterValueChanged (getParameterIndex(), newValue);
|
||||
|
||||
if (finalListener != nullptr)
|
||||
finalListener->parameterValueChanged (getParameterIndex(), newValue);
|
||||
}
|
||||
|
||||
bool AudioProcessorParameter::isOrientationInverted() const { return false; }
|
||||
bool AudioProcessorParameter::isAutomatable() const { return true; }
|
||||
bool AudioProcessorParameter::isMetaParameter() const { return false; }
|
||||
AudioProcessorParameter::Category AudioProcessorParameter::getCategory() const { return genericParameter; }
|
||||
int AudioProcessorParameter::getNumSteps() const { return getDefaultNumParameterSteps(); }
|
||||
bool AudioProcessorParameter::isDiscrete() const { return false; }
|
||||
bool AudioProcessorParameter::isBoolean() const { return false; }
|
||||
|
||||
String AudioProcessorParameter::getText (float value, int /*maximumStringLength*/) const
|
||||
{
|
||||
return String (value, 2);
|
||||
}
|
||||
|
||||
String AudioProcessorParameter::getCurrentValueAsText() const
|
||||
{
|
||||
return getText (getValue(), 1024);
|
||||
}
|
||||
|
||||
StringArray AudioProcessorParameter::getAllValueStrings() const
|
||||
{
|
||||
if (isDiscrete() && valueStrings.isEmpty())
|
||||
{
|
||||
auto maxIndex = getNumSteps() - 1;
|
||||
|
||||
for (int i = 0; i < getNumSteps(); ++i)
|
||||
valueStrings.add (getText ((float) i / (float) maxIndex, 1024));
|
||||
}
|
||||
|
||||
return valueStrings;
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::addListener (AudioProcessorParameter::Listener* newListener)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
listeners.addIfNotAlreadyThere (newListener);
|
||||
}
|
||||
|
||||
void AudioProcessorParameter::removeListener (AudioProcessorParameter::Listener* listenerToRemove)
|
||||
{
|
||||
const ScopedLock sl (listenerLock);
|
||||
listeners.removeFirstMatchingValue (listenerToRemove);
|
||||
}
|
||||
|
||||
int AudioProcessorParameter::getDefaultNumParameterSteps() noexcept
|
||||
{
|
||||
return 0x7fffffff;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,387 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** An abstract base class for parameter objects that can be added to an
|
||||
AudioProcessor.
|
||||
|
||||
@see AudioProcessor::addParameter
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioProcessorParameter
|
||||
{
|
||||
public:
|
||||
AudioProcessorParameter() noexcept = default;
|
||||
|
||||
/** The version hint supplied to this constructor is used in Audio Unit plugins to aid ordering
|
||||
parameter identifiers when JUCE_FORCE_USE_LEGACY_PARAM_IDS is not enabled.
|
||||
|
||||
When adding a parameter that is not present in a previous version of the Audio Unit, you
|
||||
must ensure that the version hint supplied is a number higher than that of any parameter in
|
||||
any previous plugin version.
|
||||
|
||||
For example, in the first release of a plugin, every parameter was created with "1" as a
|
||||
version hint. If you add some parameters in the second release of the plugin, all of the
|
||||
new parameters should have "2" as a version hint. Additional parameters added in subsequent
|
||||
plugin versions should have "3", "4", and so forth, increasing monotonically.
|
||||
|
||||
Note that adding or removing parameters with a version hint that is lower than the maximum
|
||||
version hint of all parameters will break saved automation in some hosts, so be careful!
|
||||
|
||||
A version hint of "0" will be treated as though the version hint has not been set
|
||||
explicitly. When targeting the AU format, the version hint may be checked at runtime in
|
||||
debug builds to ensure that it has been set.
|
||||
|
||||
Rationale:
|
||||
|
||||
According to <a href="https://developer.apple.com/documentation/audiotoolbox/audiounitparameter?language=objc">Apple's Documentation</a>:
|
||||
> An audio unit parameter is uniquely identified by the combination of its scope, element, and ID.
|
||||
|
||||
However, Logic Pro and GarageBand have a known limitation that causes them to use parameter
|
||||
indices instead of IDs to identify parameters. The effect of this is that adding parameters
|
||||
to a later version of a plugin can break automation saved with an earlier version of the
|
||||
plugin if the indices of existing parameters are changed. It is *always* unsafe to remove
|
||||
parameters from an Audio Unit plugin that will be used in one of these hosts, because
|
||||
removing a parameter will always modify the indices of following parameters.
|
||||
|
||||
In order to work around this limitation, parameters in AUv2 plugins are sorted first by
|
||||
their version hint, and then by the hash of their string identifier. As long as the
|
||||
parameters from later versions of the plugin always have a version hint that is higher than
|
||||
the parameters from earlier versions of the plugin, recall of automation data will work as
|
||||
expected in Logic and GarageBand.
|
||||
|
||||
Note that we can't just use the JUCE parameter index directly in order to preserve ordering.
|
||||
This would require all new parameters to be added at the end of the parameter list, which
|
||||
would make it impossible to add parameters to existing parameter groups. It would also make
|
||||
it awkward to structure code sensibly, undoing all of the benefits of string-based parameter
|
||||
identifiers.
|
||||
|
||||
At time of writing, AUv3 plugins seem to be affected by the same issue, but there does not
|
||||
appear to be any API to control parameter indices in this format. Therefore, when building
|
||||
AUv3 plugins you must not add or remove parameters in subsequent plugin versions if you
|
||||
wish to support Logic and GarageBand.
|
||||
*/
|
||||
explicit AudioProcessorParameter (int versionHint)
|
||||
: version (versionHint) {}
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~AudioProcessorParameter();
|
||||
|
||||
/** Called by the host to find out the value of this parameter.
|
||||
|
||||
Hosts will expect the value returned to be between 0 and 1.0.
|
||||
|
||||
This could be called quite frequently, so try to make your code efficient.
|
||||
It's also likely to be called by non-UI threads, so the code in here should
|
||||
be thread-aware.
|
||||
*/
|
||||
virtual float getValue() const = 0;
|
||||
|
||||
/** The host will call this method to change the value of a parameter.
|
||||
|
||||
The host may call this at any time, including during the audio processing
|
||||
callback, so your implementation has to process this very efficiently and
|
||||
avoid any kind of locking.
|
||||
|
||||
If you want to set the value of a parameter internally, e.g. from your
|
||||
editor component, then don't call this directly - instead, use the
|
||||
setValueNotifyingHost() method, which will also send a message to
|
||||
the host telling it about the change. If the message isn't sent, the host
|
||||
won't be able to automate your parameters properly.
|
||||
|
||||
The value passed will be between 0 and 1.0.
|
||||
*/
|
||||
virtual void setValue (float newValue) = 0;
|
||||
|
||||
/** A processor should call this when it needs to change one of its parameters.
|
||||
|
||||
This could happen when the editor or some other internal operation changes
|
||||
a parameter. This method will call the setValue() 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 beginChangeGesture() and endChangeGesture() methods to tell the host when
|
||||
the user has started and stopped changing the parameter.
|
||||
*/
|
||||
void setValueNotifyingHost (float newValue);
|
||||
|
||||
/** 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 endChangeGesture().
|
||||
*/
|
||||
void beginChangeGesture();
|
||||
|
||||
/** 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 beginChangeGesture().
|
||||
*/
|
||||
void endChangeGesture();
|
||||
|
||||
/** This should return the default value for this parameter. */
|
||||
virtual float getDefaultValue() const = 0;
|
||||
|
||||
/** Returns the name to display for this parameter, which should be made
|
||||
to fit within the given string length.
|
||||
*/
|
||||
virtual String getName (int maximumStringLength) const = 0;
|
||||
|
||||
/** Some parameters may be able to return a label string for
|
||||
their units. For example "Hz" or "%".
|
||||
*/
|
||||
virtual String getLabel() const = 0;
|
||||
|
||||
/** Returns the number of steps that this parameter's range should be quantised into.
|
||||
|
||||
If you want a continuous range of values, don't override this method, and allow
|
||||
the default implementation to return getDefaultNumParameterSteps().
|
||||
|
||||
If your parameter is boolean, then you may want to make this return 2.
|
||||
|
||||
The value that is returned may or may not be used, depending on the host. If you
|
||||
want the host to display stepped automation values, rather than a continuous
|
||||
interpolation between successive values, you should override isDiscrete to return true.
|
||||
|
||||
@see isDiscrete
|
||||
*/
|
||||
virtual int getNumSteps() const;
|
||||
|
||||
/** Returns whether the parameter uses discrete values, based on the result of
|
||||
getNumSteps, or allows the host to select values continuously.
|
||||
|
||||
This information may or may not be used, depending on the host. If you
|
||||
want the host to display stepped automation values, rather than a continuous
|
||||
interpolation between successive values, override this method to return true.
|
||||
|
||||
@see getNumSteps
|
||||
*/
|
||||
virtual bool isDiscrete() const;
|
||||
|
||||
/** Returns whether the parameter represents a boolean switch, typically with
|
||||
"On" and "Off" states.
|
||||
|
||||
This information may or may not be used, depending on the host. If you
|
||||
want the host to display a switch, rather than a two item dropdown menu,
|
||||
override this method to return true. You also need to override
|
||||
isDiscrete() to return `true` and getNumSteps() to return `2`.
|
||||
|
||||
@see isDiscrete getNumSteps
|
||||
*/
|
||||
virtual bool isBoolean() const;
|
||||
|
||||
/** Returns a textual version of the supplied normalised parameter value.
|
||||
The default implementation just returns the floating point value
|
||||
as a string, but this could do anything you need for a custom type
|
||||
of value.
|
||||
*/
|
||||
virtual String getText (float normalisedValue, int /*maximumStringLength*/) const;
|
||||
|
||||
/** Should parse a string and return the appropriate value for it. */
|
||||
virtual float getValueForText (const String& text) const = 0;
|
||||
|
||||
/** This can be overridden to tell the host that this parameter operates in the
|
||||
reverse direction.
|
||||
(Not all plugin formats or hosts will actually use this information).
|
||||
*/
|
||||
virtual bool isOrientationInverted() const;
|
||||
|
||||
/** Returns true if the host can automate this parameter.
|
||||
By default, this returns true.
|
||||
*/
|
||||
virtual bool isAutomatable() const;
|
||||
|
||||
/** Should return true if this parameter is a "meta" parameter.
|
||||
A meta-parameter is a parameter that changes other params. It is used
|
||||
by some hosts (e.g. AudioUnit hosts).
|
||||
By default this returns false.
|
||||
*/
|
||||
virtual bool isMetaParameter() const;
|
||||
|
||||
enum Category
|
||||
{
|
||||
genericParameter = (0 << 16) | 0, /**< If your parameter is not a meter then you should use this category */
|
||||
|
||||
inputGain = (1 << 16) | 0, /**< Currently not used */
|
||||
outputGain = (1 << 16) | 1,
|
||||
|
||||
/** The following categories tell the host that this parameter is a meter level value
|
||||
and therefore read-only. Most hosts will display these type of parameters as
|
||||
a meter in the generic view of your plug-in. Pro-Tools will also show the meter
|
||||
in the mixer view.
|
||||
*/
|
||||
inputMeter = (2 << 16) | 0,
|
||||
outputMeter = (2 << 16) | 1,
|
||||
compressorLimiterGainReductionMeter = (2 << 16) | 2,
|
||||
expanderGateGainReductionMeter = (2 << 16) | 3,
|
||||
analysisMeter = (2 << 16) | 4,
|
||||
otherMeter = (2 << 16) | 5
|
||||
};
|
||||
|
||||
/** Returns the parameter's category. */
|
||||
virtual Category getCategory() const;
|
||||
|
||||
/** Returns the index of this parameter in its parent processor's parameter list. */
|
||||
int getParameterIndex() const noexcept { return parameterIndex; }
|
||||
|
||||
/** @internal
|
||||
This should only be called by the owner of the parameter after it has been added to
|
||||
a processor. Do not call this function; changing the parameter index *will* break things!
|
||||
*/
|
||||
void setParameterIndex (int) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the current value of the parameter as a String.
|
||||
|
||||
This function can be called when you are hosting plug-ins to get a
|
||||
more specialised textual representation of the current value from the
|
||||
plug-in, for example "On" rather than "1.0".
|
||||
|
||||
If you are implementing a plug-in then you should ignore this function
|
||||
and instead override getText.
|
||||
*/
|
||||
virtual String getCurrentValueAsText() const;
|
||||
|
||||
/** Returns the set of strings which represent the possible states a parameter
|
||||
can be in.
|
||||
|
||||
If you are hosting a plug-in you can use the result of this function to
|
||||
populate a ComboBox listing the allowed values.
|
||||
|
||||
If you are implementing a plug-in then you do not need to override this.
|
||||
*/
|
||||
virtual StringArray getAllValueStrings() const;
|
||||
|
||||
//==============================================================================
|
||||
/** @see AudioProcessorParameter (int) */
|
||||
int getVersionHint() const { return version; }
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A base class for listeners that want to know about changes to an
|
||||
AudioProcessorParameter.
|
||||
|
||||
Use AudioProcessorParameter::addListener() to register your listener with
|
||||
an AudioProcessorParameter.
|
||||
|
||||
This Listener replaces most of the functionality in the
|
||||
AudioProcessorListener class, which will be deprecated and removed.
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Receives a callback when a parameter has been changed.
|
||||
|
||||
IMPORTANT NOTE: This will be called synchronously when a parameter changes, and
|
||||
many audio processors will change their parameter during their audio callback.
|
||||
This means that not only has your handler code got to be completely thread-safe,
|
||||
but it's also got to be VERY fast, and avoid blocking. If you need to handle
|
||||
this event on your message thread, use this callback to trigger an AsyncUpdater
|
||||
or ChangeBroadcaster which you can respond to on the message thread.
|
||||
*/
|
||||
virtual void parameterValueChanged (int parameterIndex, float newValue) = 0;
|
||||
|
||||
/** Indicates that a parameter change gesture has started.
|
||||
|
||||
E.g. if the user is dragging a slider, this would be called with gestureIsStarting
|
||||
being true when they first press the mouse button, and it will be called again with
|
||||
gestureIsStarting being false when they release it.
|
||||
|
||||
IMPORTANT NOTE: This will be called synchronously, and many audio processors will
|
||||
call it during their audio callback. This means that not only has your handler code
|
||||
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
||||
blocking. If you need to handle this event on your message thread, use this callback
|
||||
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
||||
message thread.
|
||||
*/
|
||||
virtual void parameterGestureChanged (int parameterIndex, bool gestureIsStarting) = 0;
|
||||
};
|
||||
|
||||
/** @internal
|
||||
This should only be called by the owner of the parameter after it has been added to
|
||||
a processor. Do not call this function; changing the owner *will* break things!
|
||||
*/
|
||||
void setOwner (Listener* listener) noexcept;
|
||||
|
||||
/** Registers a listener to receive events when the parameter's state changes.
|
||||
If the listener is already registered, this will not register it again.
|
||||
|
||||
@see removeListener
|
||||
*/
|
||||
void addListener (Listener* newListener);
|
||||
|
||||
/** Removes a previously registered parameter listener
|
||||
|
||||
@see addListener
|
||||
*/
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void sendValueChangedMessageToListeners (float newValue);
|
||||
|
||||
/** Returns the default number of steps for a parameter.
|
||||
|
||||
NOTE! This method is deprecated! It's recommended that you use
|
||||
AudioProcessorParameter::getNumSteps() instead.
|
||||
|
||||
@see getParameterNumSteps
|
||||
*/
|
||||
static int getDefaultNumParameterSteps() noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int parameterIndex = -1;
|
||||
int version = 0;
|
||||
CriticalSection listenerLock;
|
||||
Array<Listener*> listeners;
|
||||
Listener* finalListener = nullptr;
|
||||
mutable StringArray valueStrings;
|
||||
|
||||
#if JUCE_DEBUG
|
||||
bool isPerformingGesture = false;
|
||||
#endif
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameter)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,330 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterNode::~AudioProcessorParameterNode() = default;
|
||||
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterNode::AudioProcessorParameterNode (AudioProcessorParameterNode&& other)
|
||||
: group (std::move (other.group)), parameter (std::move (other.parameter))
|
||||
{
|
||||
if (group != nullptr)
|
||||
group->parent = parent;
|
||||
}
|
||||
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterNode::AudioProcessorParameterNode (std::unique_ptr<AudioProcessorParameter> param,
|
||||
AudioProcessorParameterGroup* parentGroup)
|
||||
: parameter (std::move (param)), parent (parentGroup)
|
||||
{}
|
||||
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterNode::AudioProcessorParameterNode (std::unique_ptr<AudioProcessorParameterGroup> grp,
|
||||
AudioProcessorParameterGroup* parentGroup)
|
||||
: group (std::move (grp)), parent (parentGroup)
|
||||
{
|
||||
group->parent = parent;
|
||||
}
|
||||
|
||||
AudioProcessorParameterGroup* AudioProcessorParameterGroup::AudioProcessorParameterNode::getParent() const { return parent; }
|
||||
AudioProcessorParameter* AudioProcessorParameterGroup::AudioProcessorParameterNode::getParameter() const { return parameter.get(); }
|
||||
AudioProcessorParameterGroup* AudioProcessorParameterGroup::AudioProcessorParameterNode::getGroup() const { return group.get(); }
|
||||
|
||||
//==============================================================================
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterGroup() = default;
|
||||
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterGroup (String groupID, String groupName, String subgroupSeparator)
|
||||
: identifier (std::move (groupID)), name (std::move (groupName)), separator (std::move (subgroupSeparator))
|
||||
{
|
||||
}
|
||||
|
||||
AudioProcessorParameterGroup::~AudioProcessorParameterGroup() = default;
|
||||
|
||||
AudioProcessorParameterGroup::AudioProcessorParameterGroup (AudioProcessorParameterGroup&& other)
|
||||
: identifier (std::move (other.identifier)),
|
||||
name (std::move (other.name)),
|
||||
separator (std::move (other.separator)),
|
||||
children (std::move (other.children))
|
||||
{
|
||||
updateChildParentage();
|
||||
}
|
||||
|
||||
AudioProcessorParameterGroup& AudioProcessorParameterGroup::operator= (AudioProcessorParameterGroup&& other)
|
||||
{
|
||||
identifier = std::move (other.identifier);
|
||||
name = std::move (other.name);
|
||||
separator = std::move (other.separator);
|
||||
children = std::move (other.children);
|
||||
updateChildParentage();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AudioProcessorParameterGroup::updateChildParentage()
|
||||
{
|
||||
for (auto* child : children)
|
||||
{
|
||||
child->parent = this;
|
||||
|
||||
if (auto* group = child->getGroup())
|
||||
group->parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
String AudioProcessorParameterGroup::getID() const { return identifier; }
|
||||
String AudioProcessorParameterGroup::getName() const { return name; }
|
||||
String AudioProcessorParameterGroup::getSeparator() const { return separator; }
|
||||
const AudioProcessorParameterGroup* AudioProcessorParameterGroup::getParent() const noexcept { return parent; }
|
||||
|
||||
void AudioProcessorParameterGroup::setName (String newName) { name = std::move (newName); }
|
||||
|
||||
const AudioProcessorParameterGroup::AudioProcessorParameterNode* const* AudioProcessorParameterGroup::begin() const noexcept { return const_cast<const AudioProcessorParameterNode**> (children.begin()); }
|
||||
const AudioProcessorParameterGroup::AudioProcessorParameterNode* const* AudioProcessorParameterGroup::end() const noexcept { return const_cast<const AudioProcessorParameterNode**> (children.end()); }
|
||||
|
||||
void AudioProcessorParameterGroup::append (std::unique_ptr<AudioProcessorParameter> newParameter)
|
||||
{
|
||||
children.add (new AudioProcessorParameterNode (std::move (newParameter), this));
|
||||
}
|
||||
|
||||
void AudioProcessorParameterGroup::append (std::unique_ptr<AudioProcessorParameterGroup> newSubGroup)
|
||||
{
|
||||
children.add (new AudioProcessorParameterNode (std::move (newSubGroup), this));
|
||||
}
|
||||
|
||||
Array<const AudioProcessorParameterGroup*> AudioProcessorParameterGroup::getSubgroups (bool recursive) const
|
||||
{
|
||||
Array<const AudioProcessorParameterGroup*> groups;
|
||||
getSubgroups (groups, recursive);
|
||||
return groups;
|
||||
}
|
||||
|
||||
Array<AudioProcessorParameter*> AudioProcessorParameterGroup::getParameters (bool recursive) const
|
||||
{
|
||||
Array<AudioProcessorParameter*> parameters;
|
||||
getParameters (parameters, recursive);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
Array<const AudioProcessorParameterGroup*> AudioProcessorParameterGroup::getGroupsForParameter (AudioProcessorParameter* parameter) const
|
||||
{
|
||||
Array<const AudioProcessorParameterGroup*> groups;
|
||||
|
||||
if (auto* group = getGroupForParameter (parameter))
|
||||
{
|
||||
while (group != nullptr && group != this)
|
||||
{
|
||||
groups.insert (0, group);
|
||||
group = group->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
void AudioProcessorParameterGroup::getSubgroups (Array<const AudioProcessorParameterGroup*>& previousGroups, bool recursive) const
|
||||
{
|
||||
for (auto* child : children)
|
||||
{
|
||||
if (auto* group = child->getGroup())
|
||||
{
|
||||
previousGroups.add (group);
|
||||
|
||||
if (recursive)
|
||||
group->getSubgroups (previousGroups, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioProcessorParameterGroup::getParameters (Array<AudioProcessorParameter*>& previousParameters, bool recursive) const
|
||||
{
|
||||
for (auto* child : children)
|
||||
{
|
||||
if (auto* parameter = child->getParameter())
|
||||
previousParameters.add (parameter);
|
||||
else if (recursive)
|
||||
child->getGroup()->getParameters (previousParameters, true);
|
||||
}
|
||||
}
|
||||
|
||||
const AudioProcessorParameterGroup* AudioProcessorParameterGroup::getGroupForParameter (AudioProcessorParameter* parameter) const
|
||||
{
|
||||
for (auto* child : children)
|
||||
{
|
||||
if (child->getParameter() == parameter)
|
||||
return this;
|
||||
|
||||
if (auto* group = child->getGroup())
|
||||
if (auto* foundGroup = group->getGroupForParameter (parameter))
|
||||
return foundGroup;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
class ParameterGroupTests final : public UnitTest
|
||||
{
|
||||
public:
|
||||
ParameterGroupTests()
|
||||
: UnitTest ("ParameterGroups", UnitTestCategories::audioProcessorParameters)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("ParameterGroups");
|
||||
|
||||
auto g1 = std::make_unique<AudioProcessorParameterGroup> ("g1", "g1", " - ");
|
||||
|
||||
auto* p1 = new AudioParameterFloat ("p1", "p1", { 0.0f, 2.0f }, 0.5f);
|
||||
auto* p2 = new AudioParameterFloat ("p2", "p2", { 0.0f, 2.0f }, 0.5f);
|
||||
auto* p3 = new AudioParameterFloat ("p3", "p3", { 0.0f, 2.0f }, 0.5f);
|
||||
|
||||
g1->addChild (std::unique_ptr<AudioParameterFloat> (p1));
|
||||
g1->addChild (std::unique_ptr<AudioParameterFloat> (p2),
|
||||
std::unique_ptr<AudioParameterFloat> (p3));
|
||||
|
||||
auto p4 = std::make_unique<AudioParameterFloat> ("p4", "p4", NormalisableRange<float> (0.0f, 2.0f), 0.5f);
|
||||
auto p5 = std::make_unique<AudioParameterFloat> ("p5", "p5", NormalisableRange<float> (0.0f, 2.0f), 0.5f);
|
||||
auto p6 = std::make_unique<AudioParameterFloat> ("p6", "p6", NormalisableRange<float> (0.0f, 2.0f), 0.5f);
|
||||
|
||||
g1->addChild (std::move (p4));
|
||||
g1->addChild (std::move (p5),
|
||||
std::move (p6));
|
||||
|
||||
{
|
||||
auto topLevelParams = g1->getParameters (false);
|
||||
auto params = g1->getParameters (true);
|
||||
expect (topLevelParams == params);
|
||||
expectEquals (params.size(), 6);
|
||||
|
||||
expect (params[0] == (AudioProcessorParameter*) p1);
|
||||
expect (params[1] == (AudioProcessorParameter*) p2);
|
||||
expect (params[2] == (AudioProcessorParameter*) p3);
|
||||
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[3])->name == "p4");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[4])->name == "p5");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[5])->name == "p6");
|
||||
}
|
||||
|
||||
auto* p7 = new AudioParameterFloat ("p7", "p7", { 0.0f, 2.0f }, 0.5f);
|
||||
auto* p8 = new AudioParameterFloat ("p8", "p8", { 0.0f, 2.0f }, 0.5f);
|
||||
auto* p9 = new AudioParameterFloat ("p9", "p9", { 0.0f, 2.0f }, 0.5f);
|
||||
|
||||
auto p10 = std::make_unique<AudioParameterFloat> ("p10", "p10", NormalisableRange<float> (0.0f, 2.0f), 0.5f);
|
||||
auto p11 = std::make_unique<AudioParameterFloat> ("p11", "p11", NormalisableRange<float> (0.0f, 2.0f), 0.5f);
|
||||
auto p12 = std::make_unique<AudioParameterFloat> ("p12", "p12", NormalisableRange<float> (0.0f, 2.0f), 0.5f);
|
||||
|
||||
auto g2 = std::make_unique<AudioProcessorParameterGroup> ("g2", "g2", " | ", std::unique_ptr<AudioParameterFloat> (p7));
|
||||
auto g3 = std::make_unique<AudioProcessorParameterGroup> ("g3", "g3", " | ", std::unique_ptr<AudioParameterFloat> (p8), std::unique_ptr<AudioParameterFloat> (p9));
|
||||
auto g4 = std::make_unique<AudioProcessorParameterGroup> ("g4", "g4", " | ", std::move (p10));
|
||||
auto g5 = std::make_unique<AudioProcessorParameterGroup> ("g5", "g5", " | ", std::move (p11), std::move (p12));
|
||||
|
||||
g1->addChild (std::move (g2));
|
||||
g4->addChild (std::move (g5));
|
||||
g1->addChild (std::move (g3), std::move (g4));
|
||||
|
||||
{
|
||||
auto topLevelParams = g1->getParameters (false);
|
||||
auto params = g1->getParameters (true);
|
||||
expectEquals (topLevelParams.size(), 6);
|
||||
expectEquals (params.size(), 12);
|
||||
|
||||
expect (params[0] == (AudioProcessorParameter*) p1);
|
||||
expect (params[1] == (AudioProcessorParameter*) p2);
|
||||
expect (params[2] == (AudioProcessorParameter*) p3);
|
||||
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[3])->name == "p4");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[4])->name == "p5");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[5])->name == "p6");
|
||||
|
||||
expect (params[6] == (AudioProcessorParameter*) p7);
|
||||
expect (params[7] == (AudioProcessorParameter*) p8);
|
||||
expect (params[8] == (AudioProcessorParameter*) p9);
|
||||
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[9]) ->name == "p10");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[10])->name == "p11");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (params[11])->name == "p12");
|
||||
}
|
||||
|
||||
g1->addChild (std::make_unique<AudioProcessorParameterGroup> ("g6", "g6", " | ",
|
||||
std::make_unique<AudioParameterFloat> ("p13", "p13", NormalisableRange<float> (0.0f, 2.0f), 0.5f),
|
||||
std::make_unique<AudioProcessorParameterGroup> ("g7", "g7", " | ",
|
||||
std::make_unique<AudioParameterFloat> ("p14", "p14", NormalisableRange<float> (0.0f, 2.0f), 0.5f)),
|
||||
std::make_unique<AudioParameterFloat> ("p15", "p15", NormalisableRange<float> (0.0f, 2.0f), 0.5f)));
|
||||
|
||||
TestAudioProcessor processor;
|
||||
|
||||
processor.addParameter (new AudioParameterFloat ("pstart", "pstart", NormalisableRange<float> (0.0f, 2.0f), 0.5f));
|
||||
auto groupParams = g1->getParameters (true);
|
||||
processor.addParameterGroup (std::move (g1));
|
||||
processor.addParameter (new AudioParameterFloat ("pend", "pend", NormalisableRange<float> (0.0f, 2.0f), 0.5f));
|
||||
|
||||
auto& processorParams = processor.getParameters();
|
||||
expect (dynamic_cast<AudioParameterFloat*> (processorParams.getFirst())->name == "pstart");
|
||||
expect (dynamic_cast<AudioParameterFloat*> (processorParams.getLast()) ->name == "pend");
|
||||
|
||||
auto numParams = processorParams.size();
|
||||
|
||||
for (int i = 1; i < numParams - 1; ++i)
|
||||
expect (processorParams[i] == groupParams[i - 1]);
|
||||
|
||||
}
|
||||
private:
|
||||
struct TestAudioProcessor final : public AudioProcessor
|
||||
{
|
||||
const String getName() const override { return "ap"; }
|
||||
void prepareToPlay (double, int) override {}
|
||||
void releaseResources() override {}
|
||||
void processBlock (AudioBuffer<float>&, MidiBuffer&) override {}
|
||||
using AudioProcessor::processBlock;
|
||||
double getTailLengthSeconds() const override { return 0.0; }
|
||||
bool acceptsMidi() const override { return false; }
|
||||
bool producesMidi() const override { return false; }
|
||||
AudioProcessorEditor* createEditor() override { return nullptr; }
|
||||
bool hasEditor() const override { return false; }
|
||||
int getNumPrograms() override { return 0; }
|
||||
int getCurrentProgram() override { return 0; }
|
||||
void setCurrentProgram (int) override {}
|
||||
const String getProgramName (int) override { return {}; }
|
||||
void changeProgramName (int, const String&) override {}
|
||||
void getStateInformation (MemoryBlock&) override {}
|
||||
void setStateInformation (const void*, int) override {}
|
||||
};
|
||||
};
|
||||
|
||||
static ParameterGroupTests parameterGroupTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** A class encapsulating a group of AudioProcessorParameters and nested
|
||||
AudioProcessorParameterGroups.
|
||||
|
||||
This class is predominantly write-only; there are methods for adding group
|
||||
members but none for removing them. Ultimately you will probably want to
|
||||
add a fully constructed group to an AudioProcessor.
|
||||
|
||||
@see AudioProcessor::addParameterGroup
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioProcessorParameterGroup
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** A child of an AudioProcessorParameterGroup.
|
||||
|
||||
This can contain either an AudioProcessorParameter or an
|
||||
AudioProcessorParameterGroup. You can query which using the
|
||||
getParameter and getGroup methods.
|
||||
|
||||
@code
|
||||
for (auto* child : group)
|
||||
if (auto* parameter = node.getParameter())
|
||||
parameter->setValueNotifyingHost (0.5f);
|
||||
else
|
||||
node.getGroup()->AddChild (new Parameter());
|
||||
@endcode
|
||||
*/
|
||||
class AudioProcessorParameterNode
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
AudioProcessorParameterNode (AudioProcessorParameterNode&&);
|
||||
~AudioProcessorParameterNode();
|
||||
|
||||
/** Returns the parent group or nullptr if this is a top-level group. */
|
||||
AudioProcessorParameterGroup* getParent() const;
|
||||
|
||||
/** Returns a pointer to a parameter if this node contains a parameter, nullptr otherwise. */
|
||||
AudioProcessorParameter* getParameter() const;
|
||||
|
||||
/** Returns a pointer to a group if this node contains a group, nullptr otherwise. */
|
||||
AudioProcessorParameterGroup* getGroup() const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioProcessorParameterNode (std::unique_ptr<AudioProcessorParameter>, AudioProcessorParameterGroup*);
|
||||
AudioProcessorParameterNode (std::unique_ptr<AudioProcessorParameterGroup>, AudioProcessorParameterGroup*);
|
||||
|
||||
std::unique_ptr<AudioProcessorParameterGroup> group;
|
||||
std::unique_ptr<AudioProcessorParameter> parameter;
|
||||
AudioProcessorParameterGroup* parent = nullptr;
|
||||
|
||||
friend class AudioProcessorParameterGroup;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterNode)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Creates an empty AudioProcessorParameterGroup with no name or ID. */
|
||||
AudioProcessorParameterGroup();
|
||||
|
||||
/** Creates an empty AudioProcessorParameterGroup.
|
||||
|
||||
@param groupID A unique identifier for the group. Keep it basic; don't use any special
|
||||
characters like "." and avoid pure integer strings which could collide with
|
||||
legacy parameter IDs.
|
||||
@param groupName The group's name, which will be displayed in the host.
|
||||
@param subgroupSeparator A separator string to use between the name of this group and the name of any
|
||||
subgroups if this group is flattened. AUv3 and VST3 plug-ins can have multiple
|
||||
layers of nested subgroups, but AU plug-ins cannot have any subgroups.
|
||||
|
||||
*/
|
||||
AudioProcessorParameterGroup (String groupID, String groupName, String subgroupSeparator);
|
||||
|
||||
/** Creates an AudioProcessorParameterGroup with a single child.
|
||||
|
||||
@param groupID A unique identifier for the group. Keep it basic; don't use any special
|
||||
characters like "." and avoid pure integer strings which could collide with
|
||||
legacy parameter IDs.
|
||||
@param groupName The group's name, which will be displayed in the host.
|
||||
@param subgroupSeparator A separator string to use between the name of this group and the name of any
|
||||
subgroups if this group is flattened. AUv3 and VST3 plug-ins can have multiple
|
||||
layers of nested subgroups, but AU plug-ins cannot have any subgroups.
|
||||
@param child An AudioProcessorParameter or an AudioProcessorParameterGroup to add to the group.
|
||||
*/
|
||||
template <typename ParameterOrGroup>
|
||||
AudioProcessorParameterGroup (String groupID, String groupName, String subgroupSeparator,
|
||||
std::unique_ptr<ParameterOrGroup> child)
|
||||
: AudioProcessorParameterGroup (groupID, groupName, subgroupSeparator)
|
||||
{
|
||||
addChild (std::move (child));
|
||||
}
|
||||
|
||||
/** Creates an AudioProcessorParameterGroup with multiple children.
|
||||
|
||||
@param groupID A unique identifier for the group. Keep it basic; don't use any special
|
||||
characters like "." and avoid pure integer strings which could collide with
|
||||
legacy parameter IDs.
|
||||
@param groupName The group's name, which will be displayed in the host.
|
||||
@param subgroupSeparator A separator string to use between the name of this group and the name of any
|
||||
subgroups if this group is flattened. AUv3 and VST3 plug-ins can have multiple
|
||||
layers of nested subgroups, but AU plug-ins cannot have any subgroups.
|
||||
@param firstChild An AudioProcessorParameter or an AudioProcessorParameterGroup to add to the group.
|
||||
@param remainingChildren A list of more AudioProcessorParameters or AudioProcessorParameterGroups to add to the group.
|
||||
*/
|
||||
template <typename ParameterOrGroup, typename... Args>
|
||||
AudioProcessorParameterGroup (String groupID, String groupName, String subgroupSeparator,
|
||||
std::unique_ptr<ParameterOrGroup> firstChild, Args&&... remainingChildren)
|
||||
: AudioProcessorParameterGroup (groupID, groupName, subgroupSeparator, std::move (firstChild))
|
||||
{
|
||||
addChild (std::forward<Args> (remainingChildren)...);
|
||||
}
|
||||
|
||||
/** Once a group has been added to an AudioProcessor don't try to mutate it by
|
||||
moving or swapping it - this will crash most hosts.
|
||||
*/
|
||||
AudioProcessorParameterGroup (AudioProcessorParameterGroup&&);
|
||||
|
||||
/** Once a group has been added to an AudioProcessor don't try to mutate it by
|
||||
moving or swapping it - this will crash most hosts.
|
||||
*/
|
||||
AudioProcessorParameterGroup& operator= (AudioProcessorParameterGroup&&);
|
||||
|
||||
/** Destructor. */
|
||||
~AudioProcessorParameterGroup();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the group's ID. */
|
||||
String getID() const;
|
||||
|
||||
/** Returns the group's name. */
|
||||
String getName() const;
|
||||
|
||||
/** Returns the group's separator string. */
|
||||
String getSeparator() const;
|
||||
|
||||
/** Returns the parent of the group, or nullptr if this is a top-level group. */
|
||||
const AudioProcessorParameterGroup* getParent() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the name of the group. If you do this after the group has been added
|
||||
to an AudioProcessor, call updateHostDisplay() to inform the host of the
|
||||
change. Not all hosts support dynamic group name changes.
|
||||
*/
|
||||
void setName (String newName);
|
||||
|
||||
//==============================================================================
|
||||
const AudioProcessorParameterNode* const* begin() const noexcept;
|
||||
const AudioProcessorParameterNode* const* end() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns all subgroups of this group.
|
||||
|
||||
@param recursive If this is true then this method will fetch all nested
|
||||
subgroups using a depth first search.
|
||||
*/
|
||||
Array<const AudioProcessorParameterGroup*> getSubgroups (bool recursive) const;
|
||||
|
||||
/** Returns all the parameters in this group.
|
||||
|
||||
@param recursive If this is true then this method will fetch all nested
|
||||
parameters using a depth first search.
|
||||
*/
|
||||
Array<AudioProcessorParameter*> getParameters (bool recursive) const;
|
||||
|
||||
/** Searches this group recursively for a parameter and returns a depth ordered
|
||||
list of the groups it belongs to.
|
||||
*/
|
||||
Array<const AudioProcessorParameterGroup*> getGroupsForParameter (AudioProcessorParameter*) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a child to the group.
|
||||
|
||||
Do not add children to a group which has itself already been added to the
|
||||
AudioProcessor - the new elements will be ignored.
|
||||
*/
|
||||
template <typename ParameterOrGroup>
|
||||
void addChild (std::unique_ptr<ParameterOrGroup> child)
|
||||
{
|
||||
// If you hit a compiler error here then you are attempting to add a
|
||||
// child that is neither a pointer to an AudioProcessorParameterGroup
|
||||
// nor a pointer to an AudioProcessorParameter.
|
||||
append (std::move (child));
|
||||
}
|
||||
|
||||
/** Adds multiple parameters or sub-groups to this group.
|
||||
|
||||
Do not add children to a group which has itself already been added to the
|
||||
AudioProcessor - the new elements will be ignored.
|
||||
*/
|
||||
template <typename ParameterOrGroup, typename... Args>
|
||||
void addChild (std::unique_ptr<ParameterOrGroup> firstChild, Args&&... remainingChildren)
|
||||
{
|
||||
addChild (std::move (firstChild));
|
||||
addChild (std::forward<Args> (remainingChildren)...);
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
[[deprecated ("This class now has a move operator, so if you're trying to move them around, you "
|
||||
"should use that, or if you really need to swap two groups, just call std::swap. "
|
||||
"However, remember that swapping a group that's already owned by an AudioProcessor "
|
||||
"will most likely crash the host, so don't do that.")]]
|
||||
void swapWith (AudioProcessorParameterGroup& other) { std::swap (*this, other); }
|
||||
/** @endcond */
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void getSubgroups (Array<const AudioProcessorParameterGroup*>&, bool recursive) const;
|
||||
void getParameters (Array<AudioProcessorParameter*>&, bool recursive) const;
|
||||
const AudioProcessorParameterGroup* getGroupForParameter (AudioProcessorParameter*) const;
|
||||
void updateChildParentage();
|
||||
void append (std::unique_ptr<AudioProcessorParameter>);
|
||||
void append (std::unique_ptr<AudioProcessorParameterGroup>);
|
||||
|
||||
//==============================================================================
|
||||
String identifier, name, separator;
|
||||
OwnedArray<AudioProcessorParameterNode> children;
|
||||
AudioProcessorParameterGroup* parent = nullptr;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterGroup)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -32,6 +32,8 @@
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_audio_processors_headless/format_types/juce_LegacyAudioParameter.h>
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A parameter with functions that are useful for plugin hosts.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct JUCE_API HostedAudioProcessorParameter : public AudioProcessorParameter
|
||||
{
|
||||
using AudioProcessorParameter::AudioProcessorParameter;
|
||||
|
||||
/** Returns an ID that is unique to this parameter.
|
||||
|
||||
Parameter indices are unstable across plugin versions, which means that the
|
||||
parameter found at a particular index in one version of a plugin might move
|
||||
to a different index in the subsequent version.
|
||||
|
||||
Unlike the parameter index, the ID returned by this function should be
|
||||
somewhat stable (depending on the format of the plugin), so it is more
|
||||
suitable for storing/recalling automation data.
|
||||
*/
|
||||
virtual String getParameterID() const = 0;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept
|
||||
{
|
||||
const auto tie = [] (const PluginDescription& d)
|
||||
{
|
||||
return std::tie (d.fileOrIdentifier, d.deprecatedUid, d.uniqueId);
|
||||
};
|
||||
|
||||
return tie (*this) == tie (other);
|
||||
}
|
||||
|
||||
static String getPluginDescSuffix (const PluginDescription& d, int uid)
|
||||
{
|
||||
return "-" + String::toHexString (d.fileOrIdentifier.hashCode())
|
||||
+ "-" + String::toHexString (uid);
|
||||
}
|
||||
|
||||
bool PluginDescription::matchesIdentifierString (const String& identifierString) const
|
||||
{
|
||||
const auto matches = [&] (int uid)
|
||||
{
|
||||
return identifierString.endsWithIgnoreCase (getPluginDescSuffix (*this, uid));
|
||||
};
|
||||
|
||||
return matches (uniqueId) || matches (deprecatedUid);
|
||||
}
|
||||
|
||||
String PluginDescription::createIdentifierString() const
|
||||
{
|
||||
const auto idToUse = uniqueId != 0 ? uniqueId : deprecatedUid;
|
||||
return pluginFormatName + "-" + name + getPluginDescSuffix (*this, idToUse);
|
||||
}
|
||||
|
||||
std::unique_ptr<XmlElement> PluginDescription::createXml() const
|
||||
{
|
||||
auto e = std::make_unique<XmlElement> ("PLUGIN");
|
||||
|
||||
e->setAttribute ("name", name);
|
||||
|
||||
if (descriptiveName != name)
|
||||
e->setAttribute ("descriptiveName", descriptiveName);
|
||||
|
||||
e->setAttribute ("format", pluginFormatName);
|
||||
e->setAttribute ("category", category);
|
||||
e->setAttribute ("manufacturer", manufacturerName);
|
||||
e->setAttribute ("version", version);
|
||||
e->setAttribute ("file", fileOrIdentifier);
|
||||
e->setAttribute ("uniqueId", String::toHexString (uniqueId));
|
||||
e->setAttribute ("isInstrument", isInstrument);
|
||||
e->setAttribute ("fileTime", String::toHexString (lastFileModTime.toMilliseconds()));
|
||||
e->setAttribute ("infoUpdateTime", String::toHexString (lastInfoUpdateTime.toMilliseconds()));
|
||||
e->setAttribute ("numInputs", numInputChannels);
|
||||
e->setAttribute ("numOutputs", numOutputChannels);
|
||||
e->setAttribute ("isShell", hasSharedContainer);
|
||||
e->setAttribute ("hasARAExtension", hasARAExtension);
|
||||
|
||||
e->setAttribute ("uid", String::toHexString (deprecatedUid));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool PluginDescription::loadFromXml (const XmlElement& xml)
|
||||
{
|
||||
if (xml.hasTagName ("PLUGIN"))
|
||||
{
|
||||
name = xml.getStringAttribute ("name");
|
||||
descriptiveName = xml.getStringAttribute ("descriptiveName", name);
|
||||
pluginFormatName = xml.getStringAttribute ("format");
|
||||
category = xml.getStringAttribute ("category");
|
||||
manufacturerName = xml.getStringAttribute ("manufacturer");
|
||||
version = xml.getStringAttribute ("version");
|
||||
fileOrIdentifier = xml.getStringAttribute ("file");
|
||||
isInstrument = xml.getBoolAttribute ("isInstrument", false);
|
||||
lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64());
|
||||
lastInfoUpdateTime = Time (xml.getStringAttribute ("infoUpdateTime").getHexValue64());
|
||||
numInputChannels = xml.getIntAttribute ("numInputs");
|
||||
numOutputChannels = xml.getIntAttribute ("numOutputs");
|
||||
hasSharedContainer = xml.getBoolAttribute ("isShell", false);
|
||||
hasARAExtension = xml.getBoolAttribute ("hasARAExtension", false);
|
||||
|
||||
deprecatedUid = xml.getStringAttribute ("uid").getHexValue32();
|
||||
uniqueId = xml.getStringAttribute ("uniqueId", "0").getHexValue32();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A small class to represent some facts about a particular type of plug-in.
|
||||
|
||||
This class is for storing and managing the details about a plug-in without
|
||||
actually having to load an instance of it.
|
||||
|
||||
A KnownPluginList contains a list of PluginDescription objects.
|
||||
|
||||
@see KnownPluginList
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API PluginDescription
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
PluginDescription() = default;
|
||||
|
||||
PluginDescription (const PluginDescription&) = default;
|
||||
PluginDescription (PluginDescription&&) = default;
|
||||
|
||||
PluginDescription& operator= (const PluginDescription&) = default;
|
||||
PluginDescription& operator= (PluginDescription&&) = default;
|
||||
|
||||
//==============================================================================
|
||||
/** The name of the plug-in. */
|
||||
String name;
|
||||
|
||||
/** A more descriptive name for the plug-in.
|
||||
This may be the same as the 'name' field, but some plug-ins may provide an
|
||||
alternative name.
|
||||
*/
|
||||
String descriptiveName;
|
||||
|
||||
/** The plug-in format, e.g. "VST", "AudioUnit", etc. */
|
||||
String pluginFormatName;
|
||||
|
||||
/** A category, such as "Dynamics", "Reverbs", etc. */
|
||||
String category;
|
||||
|
||||
/** The manufacturer. */
|
||||
String manufacturerName;
|
||||
|
||||
/** The version. This string doesn't have any particular format. */
|
||||
String version;
|
||||
|
||||
/** Either the file containing the plug-in module, or some other unique way
|
||||
of identifying it.
|
||||
|
||||
E.g. for an AU, this would be an ID string that the component manager
|
||||
could use to retrieve the plug-in. For a VST, it's the file path.
|
||||
*/
|
||||
String fileOrIdentifier;
|
||||
|
||||
/** The last time the plug-in file was changed.
|
||||
This is handy when scanning for new or changed plug-ins.
|
||||
*/
|
||||
Time lastFileModTime;
|
||||
|
||||
/** The last time that this information was updated. This would typically have
|
||||
been during a scan when this plugin was first tested or found to have changed.
|
||||
*/
|
||||
Time lastInfoUpdateTime;
|
||||
|
||||
/** Deprecated: New projects should use uniqueId instead.
|
||||
|
||||
A unique ID for the plug-in.
|
||||
|
||||
Note that this might not be unique between formats, e.g. a VST and some
|
||||
other format might actually have the same id.
|
||||
|
||||
@see createIdentifierString
|
||||
*/
|
||||
int deprecatedUid = 0;
|
||||
|
||||
/** A unique ID for the plug-in.
|
||||
|
||||
Note that this might not be unique between formats, e.g. a VST and some
|
||||
other format might actually have the same id.
|
||||
|
||||
The uniqueId field replaces the deprecatedUid field, and fixes an issue
|
||||
where VST3 plugins with matching FUIDs would generate different uid
|
||||
values depending on the platform. The deprecatedUid field is kept for
|
||||
backwards compatibility, allowing existing hosts to migrate from the
|
||||
old uid to the new uniqueId.
|
||||
|
||||
@see createIdentifierString
|
||||
*/
|
||||
int uniqueId = 0;
|
||||
|
||||
/** True if the plug-in identifies itself as a synthesiser. */
|
||||
bool isInstrument = false;
|
||||
|
||||
/** The number of inputs. */
|
||||
int numInputChannels = 0;
|
||||
|
||||
/** The number of outputs. */
|
||||
int numOutputChannels = 0;
|
||||
|
||||
/** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */
|
||||
bool hasSharedContainer = false;
|
||||
|
||||
/** True if the plug-in is ARA enabled and can supply a valid ARAFactoryWrapper. */
|
||||
bool hasARAExtension = false;
|
||||
|
||||
/** Returns true if the two descriptions refer to the same plug-in.
|
||||
|
||||
This isn't quite as simple as them just having the same file (because of
|
||||
shell plug-ins).
|
||||
*/
|
||||
bool isDuplicateOf (const PluginDescription& other) const noexcept;
|
||||
|
||||
/** Return true if this description is equivalent to another one which created the
|
||||
given identifier string.
|
||||
|
||||
Note that this isn't quite as simple as them just calling createIdentifierString()
|
||||
and comparing the strings, because the identifiers can differ (thanks to shell plug-ins).
|
||||
*/
|
||||
bool matchesIdentifierString (const String& identifierString) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string that can be saved and used to uniquely identify the
|
||||
plugin again.
|
||||
|
||||
This contains less info than the XML encoding, and is independent of the
|
||||
plug-in's file location, so can be used to store a plug-in ID for use
|
||||
across different machines.
|
||||
*/
|
||||
String createIdentifierString() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates an XML object containing these details.
|
||||
|
||||
@see loadFromXml
|
||||
*/
|
||||
std::unique_ptr<XmlElement> createXml() const;
|
||||
|
||||
/** Reloads the info in this structure from an XML record that was previously
|
||||
saved with createXML().
|
||||
|
||||
Returns true if the XML was a valid plug-in description.
|
||||
*/
|
||||
bool loadFromXml (const XmlElement& xml);
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
JUCE_LEAK_DETECTOR (PluginDescription)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_core/system/juce_PlatformDefs.h>
|
||||
|
||||
/** @cond */
|
||||
#ifndef JUCE_API
|
||||
#define JUCE_API
|
||||
#endif
|
||||
/** @endcond */
|
||||
|
||||
#if (JucePlugin_Enable_ARA || (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU))) && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
#if (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS) || JUCE_LOG_ASSERTIONS
|
||||
#define ARA_ENABLE_INTERNAL_ASSERTS 1
|
||||
#else
|
||||
#define ARA_ENABLE_INTERNAL_ASSERTS 0
|
||||
#endif // (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS) || JUCE_LOG_ASSERTIONS
|
||||
|
||||
//==============================================================================
|
||||
#if ARA_ENABLE_INTERNAL_ASSERTS
|
||||
|
||||
JUCE_API void JUCE_CALLTYPE handleARAAssertion (const char* file, const int line, const char* diagnosis) noexcept;
|
||||
|
||||
#if !defined(ARA_HANDLE_ASSERT)
|
||||
#define ARA_HANDLE_ASSERT(file, line, diagnosis) juce::handleARAAssertion (file, line, diagnosis)
|
||||
#endif
|
||||
|
||||
#if JUCE_LOG_ASSERTIONS
|
||||
#define ARA_ENABLE_DEBUG_OUTPUT 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments", "-Wmissing-prototypes")
|
||||
#include <ARA_Library/Debug/ARADebug.h>
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,986 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ARADocumentControllerSpecialisation::ARADocumentControllerImpl : public ARADocumentController
|
||||
{
|
||||
public:
|
||||
ARADocumentControllerImpl (const ARA::PlugIn::PlugInEntry* entry,
|
||||
const ARA::ARADocumentControllerHostInstance* instance,
|
||||
ARADocumentControllerSpecialisation* spec)
|
||||
: ARADocumentController (entry, instance), specialisation (spec)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename PlaybackRenderer_t = ARAPlaybackRenderer>
|
||||
std::vector<PlaybackRenderer_t*> const& getPlaybackRenderers() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::DocumentController::getPlaybackRenderers<PlaybackRenderer_t>();
|
||||
}
|
||||
|
||||
template <typename EditorRenderer_t = ARAEditorRenderer>
|
||||
std::vector<EditorRenderer_t*> const& getEditorRenderers() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::DocumentController::getEditorRenderers<EditorRenderer_t>();
|
||||
}
|
||||
|
||||
template <typename EditorView_t = ARAEditorView>
|
||||
std::vector<EditorView_t*> const& getEditorViews() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::DocumentController::getEditorViews<EditorView_t>();
|
||||
}
|
||||
|
||||
auto getSpecialisation() { return specialisation; }
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
bool doRestoreObjectsFromStream (ARAInputStream& input, const ARARestoreObjectsFilter* filter) noexcept
|
||||
{
|
||||
return specialisation->doRestoreObjectsFromStream (input, filter);
|
||||
}
|
||||
|
||||
bool doStoreObjectsToStream (ARAOutputStream& output, const ARAStoreObjectsFilter* filter) noexcept
|
||||
{
|
||||
return specialisation->doStoreObjectsToStream (output, filter);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Model object creation
|
||||
ARA::PlugIn::Document* doCreateDocument () noexcept override;
|
||||
ARA::PlugIn::MusicalContext* doCreateMusicalContext (ARA::PlugIn::Document* document, ARA::ARAMusicalContextHostRef hostRef) noexcept override;
|
||||
ARA::PlugIn::RegionSequence* doCreateRegionSequence (ARA::PlugIn::Document* document, ARA::ARARegionSequenceHostRef hostRef) noexcept override;
|
||||
ARA::PlugIn::AudioSource* doCreateAudioSource (ARA::PlugIn::Document* document, ARA::ARAAudioSourceHostRef hostRef) noexcept override;
|
||||
ARA::PlugIn::AudioModification* doCreateAudioModification (ARA::PlugIn::AudioSource* audioSource, ARA::ARAAudioModificationHostRef hostRef, const ARA::PlugIn::AudioModification* optionalModificationToClone) noexcept override;
|
||||
ARA::PlugIn::PlaybackRegion* doCreatePlaybackRegion (ARA::PlugIn::AudioModification* modification, ARA::ARAPlaybackRegionHostRef hostRef) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// Plugin role implementation
|
||||
friend class ARAPlaybackRegionReader;
|
||||
ARA::PlugIn::PlaybackRenderer* doCreatePlaybackRenderer() noexcept override;
|
||||
ARA::PlugIn::EditorRenderer* doCreateEditorRenderer() noexcept override;
|
||||
ARA::PlugIn::EditorView* doCreateEditorView() noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// ARAAudioSource content access
|
||||
bool doIsAudioSourceContentAvailable (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
ARA::ARAContentGrade doGetAudioSourceContentGrade (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
ARA::PlugIn::ContentReader* doCreateAudioSourceContentReader (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// ARAAudioModification content access
|
||||
bool doIsAudioModificationContentAvailable (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
ARA::ARAContentGrade doGetAudioModificationContentGrade (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
ARA::PlugIn::ContentReader* doCreateAudioModificationContentReader (ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// ARAPlaybackRegion content access
|
||||
bool doIsPlaybackRegionContentAvailable (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
ARA::ARAContentGrade doGetPlaybackRegionContentGrade (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
ARA::PlugIn::ContentReader* doCreatePlaybackRegionContentReader (ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range) noexcept override;
|
||||
void doGetPlaybackRegionHeadAndTailTime (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARATimeDuration* headTime,
|
||||
ARA::ARATimeDuration* tailTime) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// ARAAudioSource analysis
|
||||
bool doIsAudioSourceContentAnalysisIncomplete (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type) noexcept override;
|
||||
void doRequestAudioSourceContentAnalysis (ARA::PlugIn::AudioSource* audioSource,
|
||||
std::vector<ARA::ARAContentType> const& contentTypes) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// Analysis Algorithm selection
|
||||
ARA::ARAInt32 doGetProcessingAlgorithmsCount() noexcept override;
|
||||
const ARA::ARAProcessingAlgorithmProperties* doGetProcessingAlgorithmProperties (ARA::ARAInt32 algorithmIndex) noexcept override;
|
||||
ARA::ARAInt32 doGetProcessingAlgorithmForAudioSource (const ARA::PlugIn::AudioSource* audioSource) noexcept override;
|
||||
void doRequestProcessingAlgorithmForAudioSource (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAInt32 algorithmIndex) noexcept override;
|
||||
|
||||
/** @cond */
|
||||
//==============================================================================
|
||||
bool doRestoreObjectsFromArchive (ARA::PlugIn::HostArchiveReader* archiveReader, const ARA::PlugIn::RestoreObjectsFilter* filter) noexcept override;
|
||||
bool doStoreObjectsToArchive (ARA::PlugIn::HostArchiveWriter* archiveWriter, const ARA::PlugIn::StoreObjectsFilter* filter) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// Document notifications
|
||||
void willBeginEditing() noexcept override;
|
||||
void didEndEditing() noexcept override;
|
||||
void willNotifyModelUpdates() noexcept override;
|
||||
void didNotifyModelUpdates() noexcept override;
|
||||
void willUpdateDocumentProperties (ARA::PlugIn::Document* document, ARADocument::PropertiesPtr newProperties) noexcept override;
|
||||
void didUpdateDocumentProperties (ARA::PlugIn::Document* document) noexcept override;
|
||||
void didAddMusicalContextToDocument (ARA::PlugIn::Document* document, ARA::PlugIn::MusicalContext* musicalContext) noexcept override;
|
||||
void willRemoveMusicalContextFromDocument (ARA::PlugIn::Document* document, ARA::PlugIn::MusicalContext* musicalContext) noexcept override;
|
||||
void didReorderMusicalContextsInDocument (ARA::PlugIn::Document* document) noexcept override;
|
||||
void didAddRegionSequenceToDocument (ARA::PlugIn::Document* document, ARA::PlugIn::RegionSequence* regionSequence) noexcept override;
|
||||
void willRemoveRegionSequenceFromDocument (ARA::PlugIn::Document* document, ARA::PlugIn::RegionSequence* regionSequence) noexcept override;
|
||||
void didReorderRegionSequencesInDocument (ARA::PlugIn::Document* document) noexcept override;
|
||||
void didAddAudioSourceToDocument (ARA::PlugIn::Document* document, ARA::PlugIn::AudioSource* audioSource) noexcept override;
|
||||
void willRemoveAudioSourceFromDocument (ARA::PlugIn::Document* document, ARA::PlugIn::AudioSource* audioSource) noexcept override;
|
||||
void willDestroyDocument (ARA::PlugIn::Document* document) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// MusicalContext notifications
|
||||
void willUpdateMusicalContextProperties (ARA::PlugIn::MusicalContext* musicalContext, ARAMusicalContext::PropertiesPtr newProperties) noexcept override;
|
||||
void didUpdateMusicalContextProperties (ARA::PlugIn::MusicalContext* musicalContext) noexcept override;
|
||||
void doUpdateMusicalContextContent (ARA::PlugIn::MusicalContext* musicalContext, const ARA::ARAContentTimeRange* range, ARA::ContentUpdateScopes flags) noexcept override;
|
||||
void didAddRegionSequenceToMusicalContext (ARA::PlugIn::MusicalContext* musicalContext, ARA::PlugIn::RegionSequence* regionSequence) noexcept override;
|
||||
void willRemoveRegionSequenceFromMusicalContext (ARA::PlugIn::MusicalContext* musicalContext, ARA::PlugIn::RegionSequence* regionSequence) noexcept override;
|
||||
void didReorderRegionSequencesInMusicalContext (ARA::PlugIn::MusicalContext* musicalContext) noexcept override;
|
||||
void willDestroyMusicalContext (ARA::PlugIn::MusicalContext* musicalContext) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// RegionSequence notifications, typically not overridden further
|
||||
void willUpdateRegionSequenceProperties (ARA::PlugIn::RegionSequence* regionSequence, ARARegionSequence::PropertiesPtr newProperties) noexcept override;
|
||||
void didUpdateRegionSequenceProperties (ARA::PlugIn::RegionSequence* regionSequence) noexcept override;
|
||||
void didAddPlaybackRegionToRegionSequence (ARA::PlugIn::RegionSequence* regionSequence, ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override;
|
||||
void willRemovePlaybackRegionFromRegionSequence (ARA::PlugIn::RegionSequence* regionSequence, ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override;
|
||||
void willDestroyRegionSequence (ARA::PlugIn::RegionSequence* regionSequence) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// AudioSource notifications
|
||||
void willUpdateAudioSourceProperties (ARA::PlugIn::AudioSource* audioSource, ARAAudioSource::PropertiesPtr newProperties) noexcept override;
|
||||
void didUpdateAudioSourceProperties (ARA::PlugIn::AudioSource* audioSource) noexcept override;
|
||||
void doUpdateAudioSourceContent (ARA::PlugIn::AudioSource* audioSource, const ARA::ARAContentTimeRange* range, ARA::ContentUpdateScopes flags) noexcept override;
|
||||
void willEnableAudioSourceSamplesAccess (ARA::PlugIn::AudioSource* audioSource, bool enable) noexcept override;
|
||||
void didEnableAudioSourceSamplesAccess (ARA::PlugIn::AudioSource* audioSource, bool enable) noexcept override;
|
||||
void didAddAudioModificationToAudioSource (ARA::PlugIn::AudioSource* audioSource, ARA::PlugIn::AudioModification* audioModification) noexcept override;
|
||||
void willRemoveAudioModificationFromAudioSource (ARA::PlugIn::AudioSource* audioSource, ARA::PlugIn::AudioModification* audioModification) noexcept override;
|
||||
void willDeactivateAudioSourceForUndoHistory (ARA::PlugIn::AudioSource* audioSource, bool deactivate) noexcept override;
|
||||
void didDeactivateAudioSourceForUndoHistory (ARA::PlugIn::AudioSource* audioSource, bool deactivate) noexcept override;
|
||||
void willDestroyAudioSource (ARA::PlugIn::AudioSource* audioSource) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// AudioModification notifications
|
||||
void willUpdateAudioModificationProperties (ARA::PlugIn::AudioModification* audioModification, ARAAudioModification::PropertiesPtr newProperties) noexcept override;
|
||||
void didUpdateAudioModificationProperties (ARA::PlugIn::AudioModification* audioModification) noexcept override;
|
||||
void didAddPlaybackRegionToAudioModification (ARA::PlugIn::AudioModification* audioModification, ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override;
|
||||
void willRemovePlaybackRegionFromAudioModification (ARA::PlugIn::AudioModification* audioModification, ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override;
|
||||
void willDeactivateAudioModificationForUndoHistory (ARA::PlugIn::AudioModification* audioModification, bool deactivate) noexcept override;
|
||||
void didDeactivateAudioModificationForUndoHistory (ARA::PlugIn::AudioModification* audioModification, bool deactivate) noexcept override;
|
||||
void willDestroyAudioModification (ARA::PlugIn::AudioModification* audioModification) noexcept override;
|
||||
|
||||
//==============================================================================
|
||||
// PlaybackRegion notifications
|
||||
void willUpdatePlaybackRegionProperties (ARA::PlugIn::PlaybackRegion* playbackRegion, ARAPlaybackRegion::PropertiesPtr newProperties) noexcept override;
|
||||
void didUpdatePlaybackRegionProperties (ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override;
|
||||
void willDestroyPlaybackRegion (ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override;
|
||||
/** @endcond */
|
||||
|
||||
public:
|
||||
/** @cond */
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void internalNotifyAudioSourceAnalysisProgressStarted (ARAAudioSource* audioSource) override;
|
||||
|
||||
/** @internal */
|
||||
void internalNotifyAudioSourceAnalysisProgressUpdated (ARAAudioSource* audioSource, float progress) override;
|
||||
|
||||
/** @internal */
|
||||
void internalNotifyAudioSourceAnalysisProgressCompleted (ARAAudioSource* audioSource) override;
|
||||
|
||||
/** @internal */
|
||||
void internalDidUpdateAudioSourceAnalysisProgress (ARAAudioSource* audioSource,
|
||||
ARAAudioSource::ARAAnalysisProgressState state,
|
||||
float progress) override;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void internalNotifyAudioSourceContentChanged (ARAAudioSource* audioSource,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost) override;
|
||||
|
||||
/** @internal */
|
||||
void internalNotifyAudioModificationContentChanged (ARAAudioModification* audioModification,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost) override;
|
||||
|
||||
/** @internal */
|
||||
void internalNotifyPlaybackRegionContentChanged (ARAPlaybackRegion* playbackRegion,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost) override;
|
||||
|
||||
/** @endcond */
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ARADocumentControllerSpecialisation* specialisation;
|
||||
std::atomic<bool> internalAnalysisProgressIsSynced { true };
|
||||
ScopedJuceInitialiser_GUI libraryInitialiser;
|
||||
int activeAudioSourcesCount = 0;
|
||||
std::optional<TimedCallback> analysisTimer;
|
||||
|
||||
void analysisTimerCallback();
|
||||
|
||||
//==============================================================================
|
||||
template <typename ModelObject, typename Function, typename... Ts>
|
||||
void notifyListeners (Function ModelObject::Listener::* function, ModelObject* modelObject, Ts... ts)
|
||||
{
|
||||
(specialisation->*function) (modelObject, ts...);
|
||||
modelObject->notifyListeners ([&] (auto& l)
|
||||
{
|
||||
try
|
||||
{
|
||||
(l.*function) (modelObject, ts...);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARADocumentControllerImpl)
|
||||
};
|
||||
|
||||
ARA::PlugIn::DocumentController* ARADocumentControllerSpecialisation::getDocumentController() noexcept
|
||||
{
|
||||
return documentController.get();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalNotifyAudioSourceAnalysisProgressStarted (ARAAudioSource* audioSource)
|
||||
{
|
||||
if (audioSource->internalAnalysisProgressTracker.updateProgress (ARA::kARAAnalysisProgressStarted, 0.0f))
|
||||
internalAnalysisProgressIsSynced.store (false, std::memory_order_release);
|
||||
|
||||
DocumentController::notifyAudioSourceAnalysisProgressStarted (audioSource);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalNotifyAudioSourceAnalysisProgressUpdated (ARAAudioSource* audioSource,
|
||||
float progress)
|
||||
{
|
||||
if (audioSource->internalAnalysisProgressTracker.updateProgress (ARA::kARAAnalysisProgressUpdated, progress))
|
||||
internalAnalysisProgressIsSynced.store (false, std::memory_order_release);
|
||||
|
||||
DocumentController::notifyAudioSourceAnalysisProgressUpdated (audioSource, progress);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalNotifyAudioSourceAnalysisProgressCompleted (ARAAudioSource* audioSource)
|
||||
{
|
||||
if (audioSource->internalAnalysisProgressTracker.updateProgress (ARA::kARAAnalysisProgressCompleted, 1.0f))
|
||||
internalAnalysisProgressIsSynced.store (false, std::memory_order_release);
|
||||
|
||||
DocumentController::notifyAudioSourceAnalysisProgressCompleted (audioSource);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalDidUpdateAudioSourceAnalysisProgress (ARAAudioSource* audioSource,
|
||||
ARAAudioSource::ARAAnalysisProgressState state,
|
||||
float progress)
|
||||
{
|
||||
specialisation->didUpdateAudioSourceAnalysisProgress (audioSource, state, progress);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ARADocumentControllerSpecialisation* ARADocumentControllerSpecialisation::getSpecialisedDocumentControllerImpl (ARA::PlugIn::DocumentController* dc)
|
||||
{
|
||||
return static_cast<ARADocumentControllerImpl*> (dc)->getSpecialisation();
|
||||
}
|
||||
|
||||
ARADocument* ARADocumentControllerSpecialisation::getDocumentImpl()
|
||||
{
|
||||
return documentController->getDocument();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// some helper macros to ease repeated declaration & implementation of notification functions below:
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments")
|
||||
|
||||
// no notification arguments
|
||||
#define OVERRIDE_TO_NOTIFY_1(function, ModelObjectType, modelObject) \
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::function (ARA::PlugIn::ModelObjectType* modelObject) noexcept \
|
||||
{ \
|
||||
notifyListeners (&ARA##ModelObjectType::Listener::function, static_cast<ARA##ModelObjectType*> (modelObject)); \
|
||||
}
|
||||
|
||||
// single notification argument, model object version
|
||||
#define OVERRIDE_TO_NOTIFY_2(function, ModelObjectType, modelObject, ArgumentType, argument) \
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::function (ARA::PlugIn::ModelObjectType* modelObject, ARA::PlugIn::ArgumentType argument) noexcept \
|
||||
{ \
|
||||
notifyListeners (&ARA##ModelObjectType::Listener::function, static_cast<ARA##ModelObjectType*> (modelObject), static_cast<ARA##ArgumentType> (argument)); \
|
||||
}
|
||||
|
||||
// single notification argument, non-model object version
|
||||
#define OVERRIDE_TO_NOTIFY_3(function, ModelObjectType, modelObject, ArgumentType, argument) \
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::function (ARA::PlugIn::ModelObjectType* modelObject, ArgumentType argument) noexcept \
|
||||
{ \
|
||||
notifyListeners (&ARA##ModelObjectType::Listener::function, static_cast<ARA##ModelObjectType*> (modelObject), argument); \
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ARA::PlugIn::Document* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateDocument() noexcept
|
||||
{
|
||||
auto* document = specialisation->doCreateDocument();
|
||||
|
||||
// Your Document subclass must inherit from juce::ARADocument
|
||||
jassert (dynamic_cast<ARADocument*> (document));
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::willBeginEditing() noexcept
|
||||
{
|
||||
notifyListeners (&ARADocument::Listener::willBeginEditing, static_cast<ARADocument*> (getDocument()));
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::didEndEditing() noexcept
|
||||
{
|
||||
notifyListeners (&ARADocument::Listener::didEndEditing, static_cast<ARADocument*> (getDocument()));
|
||||
|
||||
if (activeAudioSourcesCount == 0)
|
||||
{
|
||||
analysisTimer.reset();
|
||||
}
|
||||
else if (! analysisTimer.has_value() && (activeAudioSourcesCount > 0))
|
||||
{
|
||||
analysisTimer.emplace ([this] { analysisTimerCallback(); });
|
||||
analysisTimer->startTimerHz (20);
|
||||
}
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::willNotifyModelUpdates() noexcept
|
||||
{
|
||||
notifyListeners (&ARADocument::Listener::willNotifyModelUpdates, static_cast<ARADocument*> (getDocument()));
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::didNotifyModelUpdates() noexcept
|
||||
{
|
||||
notifyListeners (&ARADocument::Listener::didNotifyModelUpdates, static_cast<ARADocument*> (getDocument()));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doRestoreObjectsFromArchive (ARA::PlugIn::HostArchiveReader* archiveReader,
|
||||
const ARA::PlugIn::RestoreObjectsFilter* filter) noexcept
|
||||
{
|
||||
ARAInputStream reader (archiveReader);
|
||||
return doRestoreObjectsFromStream (reader, filter);
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doStoreObjectsToArchive (ARA::PlugIn::HostArchiveWriter* archiveWriter,
|
||||
const ARA::PlugIn::StoreObjectsFilter* filter) noexcept
|
||||
{
|
||||
ARAOutputStream writer (archiveWriter);
|
||||
return doStoreObjectsToStream (writer, filter);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
OVERRIDE_TO_NOTIFY_3 (willUpdateDocumentProperties, Document, document, ARADocument::PropertiesPtr, newProperties)
|
||||
OVERRIDE_TO_NOTIFY_1 (didUpdateDocumentProperties, Document, document)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddMusicalContextToDocument, Document, document, MusicalContext*, musicalContext)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemoveMusicalContextFromDocument, Document, document, MusicalContext*, musicalContext)
|
||||
OVERRIDE_TO_NOTIFY_1 (didReorderMusicalContextsInDocument, Document, document)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddRegionSequenceToDocument, Document, document, RegionSequence*, regionSequence)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemoveRegionSequenceFromDocument, Document, document, RegionSequence*, regionSequence)
|
||||
OVERRIDE_TO_NOTIFY_1 (didReorderRegionSequencesInDocument, Document, document)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddAudioSourceToDocument, Document, document, AudioSource*, audioSource)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemoveAudioSourceFromDocument, Document, document, AudioSource*, audioSource)
|
||||
OVERRIDE_TO_NOTIFY_1 (willDestroyDocument, Document, document)
|
||||
|
||||
//==============================================================================
|
||||
ARA::PlugIn::MusicalContext* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateMusicalContext (ARA::PlugIn::Document* document,
|
||||
ARA::ARAMusicalContextHostRef hostRef) noexcept
|
||||
{
|
||||
return specialisation->doCreateMusicalContext (static_cast<ARADocument*> (document), hostRef);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doUpdateMusicalContextContent (ARA::PlugIn::MusicalContext* musicalContext,
|
||||
const ARA::ARAContentTimeRange*,
|
||||
ARA::ContentUpdateScopes flags) noexcept
|
||||
{
|
||||
notifyListeners (&ARAMusicalContext::Listener::doUpdateMusicalContextContent,
|
||||
static_cast<ARAMusicalContext*> (musicalContext),
|
||||
flags);
|
||||
}
|
||||
|
||||
OVERRIDE_TO_NOTIFY_3 (willUpdateMusicalContextProperties, MusicalContext, musicalContext, ARAMusicalContext::PropertiesPtr, newProperties)
|
||||
OVERRIDE_TO_NOTIFY_1 (didUpdateMusicalContextProperties, MusicalContext, musicalContext)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddRegionSequenceToMusicalContext, MusicalContext, musicalContext, RegionSequence*, regionSequence)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemoveRegionSequenceFromMusicalContext, MusicalContext, musicalContext, RegionSequence*, regionSequence)
|
||||
OVERRIDE_TO_NOTIFY_1 (didReorderRegionSequencesInMusicalContext, MusicalContext, musicalContext)
|
||||
OVERRIDE_TO_NOTIFY_1 (willDestroyMusicalContext, MusicalContext, musicalContext)
|
||||
|
||||
//==============================================================================
|
||||
ARA::PlugIn::RegionSequence* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateRegionSequence (ARA::PlugIn::Document* document, ARA::ARARegionSequenceHostRef hostRef) noexcept
|
||||
{
|
||||
return specialisation->doCreateRegionSequence (static_cast<ARADocument*> (document), hostRef);
|
||||
}
|
||||
|
||||
OVERRIDE_TO_NOTIFY_3 (willUpdateRegionSequenceProperties, RegionSequence, regionSequence, ARARegionSequence::PropertiesPtr, newProperties)
|
||||
OVERRIDE_TO_NOTIFY_1 (didUpdateRegionSequenceProperties, RegionSequence, regionSequence)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddPlaybackRegionToRegionSequence, RegionSequence, regionSequence, PlaybackRegion*, playbackRegion)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemovePlaybackRegionFromRegionSequence, RegionSequence, regionSequence, PlaybackRegion*, playbackRegion)
|
||||
OVERRIDE_TO_NOTIFY_1 (willDestroyRegionSequence, RegionSequence, regionSequence)
|
||||
|
||||
//==============================================================================
|
||||
ARA::PlugIn::AudioSource* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateAudioSource (ARA::PlugIn::Document* document, ARA::ARAAudioSourceHostRef hostRef) noexcept
|
||||
{
|
||||
++activeAudioSourcesCount;
|
||||
return specialisation->doCreateAudioSource (static_cast<ARADocument*> (document), hostRef);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doUpdateAudioSourceContent (ARA::PlugIn::AudioSource* audioSource,
|
||||
const ARA::ARAContentTimeRange*,
|
||||
ARA::ContentUpdateScopes flags) noexcept
|
||||
{
|
||||
notifyListeners (&ARAAudioSource::Listener::doUpdateAudioSourceContent, static_cast<ARAAudioSource*> (audioSource), flags);
|
||||
}
|
||||
|
||||
OVERRIDE_TO_NOTIFY_3 (willUpdateAudioSourceProperties, AudioSource, audioSource, ARAAudioSource::PropertiesPtr, newProperties)
|
||||
OVERRIDE_TO_NOTIFY_1 (didUpdateAudioSourceProperties, AudioSource, audioSource)
|
||||
OVERRIDE_TO_NOTIFY_3 (willEnableAudioSourceSamplesAccess, AudioSource, audioSource, bool, enable)
|
||||
OVERRIDE_TO_NOTIFY_3 (didEnableAudioSourceSamplesAccess, AudioSource, audioSource, bool, enable)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddAudioModificationToAudioSource, AudioSource, audioSource, AudioModification*, audioModification)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemoveAudioModificationFromAudioSource, AudioSource, audioSource, AudioModification*, audioModification)
|
||||
OVERRIDE_TO_NOTIFY_3 (willDeactivateAudioSourceForUndoHistory, AudioSource, audioSource, bool, deactivate)
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::didDeactivateAudioSourceForUndoHistory (ARA::PlugIn::AudioSource* audioSource,
|
||||
bool deactivate) noexcept
|
||||
{
|
||||
activeAudioSourcesCount += (deactivate ? -1 : 1);
|
||||
notifyListeners (&ARAAudioSource::Listener::didDeactivateAudioSourceForUndoHistory,
|
||||
static_cast<ARAAudioSource*> (audioSource),
|
||||
deactivate);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::willDestroyAudioSource (ARA::PlugIn::AudioSource* audioSource) noexcept
|
||||
{
|
||||
if (! audioSource->isDeactivatedForUndoHistory())
|
||||
--activeAudioSourcesCount;
|
||||
|
||||
notifyListeners (&ARAAudioSource::Listener::willDestroyAudioSource, static_cast<ARAAudioSource*> (audioSource));
|
||||
}
|
||||
//==============================================================================
|
||||
ARA::PlugIn::AudioModification* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateAudioModification (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAAudioModificationHostRef hostRef,
|
||||
const ARA::PlugIn::AudioModification* optionalModificationToClone) noexcept
|
||||
{
|
||||
return specialisation->doCreateAudioModification (static_cast<ARAAudioSource*> (audioSource),
|
||||
hostRef,
|
||||
static_cast<const ARAAudioModification*> (optionalModificationToClone));
|
||||
}
|
||||
|
||||
OVERRIDE_TO_NOTIFY_3 (willUpdateAudioModificationProperties, AudioModification, audioModification, ARAAudioModification::PropertiesPtr, newProperties)
|
||||
OVERRIDE_TO_NOTIFY_1 (didUpdateAudioModificationProperties, AudioModification, audioModification)
|
||||
OVERRIDE_TO_NOTIFY_2 (didAddPlaybackRegionToAudioModification, AudioModification, audioModification, PlaybackRegion*, playbackRegion)
|
||||
OVERRIDE_TO_NOTIFY_2 (willRemovePlaybackRegionFromAudioModification, AudioModification, audioModification, PlaybackRegion*, playbackRegion)
|
||||
OVERRIDE_TO_NOTIFY_3 (willDeactivateAudioModificationForUndoHistory, AudioModification, audioModification, bool, deactivate)
|
||||
OVERRIDE_TO_NOTIFY_3 (didDeactivateAudioModificationForUndoHistory, AudioModification, audioModification, bool, deactivate)
|
||||
OVERRIDE_TO_NOTIFY_1 (willDestroyAudioModification, AudioModification, audioModification)
|
||||
|
||||
//==============================================================================
|
||||
ARA::PlugIn::PlaybackRegion* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreatePlaybackRegion (ARA::PlugIn::AudioModification* modification,
|
||||
ARA::ARAPlaybackRegionHostRef hostRef) noexcept
|
||||
{
|
||||
return specialisation->doCreatePlaybackRegion (static_cast<ARAAudioModification*> (modification), hostRef);
|
||||
}
|
||||
|
||||
OVERRIDE_TO_NOTIFY_3 (willUpdatePlaybackRegionProperties, PlaybackRegion, playbackRegion, ARAPlaybackRegion::PropertiesPtr, newProperties)
|
||||
OVERRIDE_TO_NOTIFY_1 (didUpdatePlaybackRegionProperties, PlaybackRegion, playbackRegion)
|
||||
OVERRIDE_TO_NOTIFY_1 (willDestroyPlaybackRegion, PlaybackRegion, playbackRegion)
|
||||
|
||||
//==============================================================================
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalNotifyAudioSourceContentChanged (ARAAudioSource* audioSource,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost)
|
||||
{
|
||||
if (notifyARAHost)
|
||||
DocumentController::notifyAudioSourceContentChanged (audioSource, scopeFlags);
|
||||
|
||||
notifyListeners (&ARAAudioSource::Listener::doUpdateAudioSourceContent, audioSource, scopeFlags);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalNotifyAudioModificationContentChanged (ARAAudioModification* audioModification,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost)
|
||||
{
|
||||
if (notifyARAHost)
|
||||
DocumentController::notifyAudioModificationContentChanged (audioModification, scopeFlags);
|
||||
|
||||
notifyListeners (&ARAAudioModification::Listener::didUpdateAudioModificationContent, audioModification, scopeFlags);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::internalNotifyPlaybackRegionContentChanged (ARAPlaybackRegion* playbackRegion,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost)
|
||||
{
|
||||
if (notifyARAHost)
|
||||
DocumentController::notifyPlaybackRegionContentChanged (playbackRegion, scopeFlags);
|
||||
|
||||
notifyListeners (&ARAPlaybackRegion::Listener::didUpdatePlaybackRegionContent, playbackRegion, scopeFlags);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#undef OVERRIDE_TO_NOTIFY_1
|
||||
#undef OVERRIDE_TO_NOTIFY_2
|
||||
#undef OVERRIDE_TO_NOTIFY_3
|
||||
|
||||
//==============================================================================
|
||||
ARADocument* ARADocumentControllerSpecialisation::doCreateDocument()
|
||||
{
|
||||
return new ARADocument (static_cast<ARADocumentControllerImpl*> (getDocumentController()));
|
||||
}
|
||||
|
||||
ARAMusicalContext* ARADocumentControllerSpecialisation::doCreateMusicalContext (ARADocument* document,
|
||||
ARA::ARAMusicalContextHostRef hostRef)
|
||||
{
|
||||
return new ARAMusicalContext (static_cast<ARADocument*> (document), hostRef);
|
||||
}
|
||||
|
||||
ARARegionSequence* ARADocumentControllerSpecialisation::doCreateRegionSequence (ARADocument* document,
|
||||
ARA::ARARegionSequenceHostRef hostRef)
|
||||
{
|
||||
return new ARARegionSequence (static_cast<ARADocument*> (document), hostRef);
|
||||
}
|
||||
|
||||
ARAAudioSource* ARADocumentControllerSpecialisation::doCreateAudioSource (ARADocument* document,
|
||||
ARA::ARAAudioSourceHostRef hostRef)
|
||||
{
|
||||
return new ARAAudioSource (static_cast<ARADocument*> (document), hostRef);
|
||||
}
|
||||
|
||||
ARAAudioModification* ARADocumentControllerSpecialisation::doCreateAudioModification (
|
||||
ARAAudioSource* audioSource,
|
||||
ARA::ARAAudioModificationHostRef hostRef,
|
||||
const ARAAudioModification* optionalModificationToClone)
|
||||
{
|
||||
return new ARAAudioModification (static_cast<ARAAudioSource*> (audioSource),
|
||||
hostRef,
|
||||
static_cast<const ARAAudioModification*> (optionalModificationToClone));
|
||||
}
|
||||
|
||||
ARAPlaybackRegion*
|
||||
ARADocumentControllerSpecialisation::doCreatePlaybackRegion (ARAAudioModification* modification,
|
||||
ARA::ARAPlaybackRegionHostRef hostRef)
|
||||
{
|
||||
return new ARAPlaybackRegion (static_cast<ARAAudioModification*> (modification), hostRef);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ARA::PlugIn::PlaybackRenderer* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreatePlaybackRenderer() noexcept
|
||||
{
|
||||
return specialisation->doCreatePlaybackRenderer();
|
||||
}
|
||||
|
||||
ARA::PlugIn::EditorRenderer* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateEditorRenderer() noexcept
|
||||
{
|
||||
return specialisation->doCreateEditorRenderer();
|
||||
}
|
||||
|
||||
ARA::PlugIn::EditorView* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateEditorView() noexcept
|
||||
{
|
||||
return specialisation->doCreateEditorView();
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doIsAudioSourceContentAvailable (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doIsAudioSourceContentAvailable (audioSource, type);
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetAudioSourceContentGrade (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doGetAudioSourceContentGrade (audioSource, type);
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateAudioSourceContentReader (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range) noexcept
|
||||
{
|
||||
return specialisation->doCreateAudioSourceContentReader (audioSource, type, range);
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doIsAudioModificationContentAvailable (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doIsAudioModificationContentAvailable (audioModification, type);
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetAudioModificationContentGrade (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doGetAudioModificationContentGrade (audioModification, type);
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreateAudioModificationContentReader (ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range) noexcept
|
||||
{
|
||||
return specialisation->doCreateAudioModificationContentReader (audioModification, type, range);
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doIsPlaybackRegionContentAvailable (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doIsPlaybackRegionContentAvailable (playbackRegion, type);
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade
|
||||
ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetPlaybackRegionContentGrade (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doGetPlaybackRegionContentGrade (playbackRegion, type);
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doCreatePlaybackRegionContentReader (ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range) noexcept
|
||||
{
|
||||
return specialisation->doCreatePlaybackRegionContentReader (playbackRegion, type, range);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetPlaybackRegionHeadAndTailTime (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARATimeDuration* headTime,
|
||||
ARA::ARATimeDuration* tailTime) noexcept
|
||||
{
|
||||
specialisation->doGetPlaybackRegionHeadAndTailTime (playbackRegion, headTime, tailTime);
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doIsAudioSourceContentAnalysisIncomplete (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type) noexcept
|
||||
{
|
||||
return specialisation->doIsAudioSourceContentAnalysisIncomplete (audioSource, type);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doRequestAudioSourceContentAnalysis (ARA::PlugIn::AudioSource* audioSource,
|
||||
std::vector<ARA::ARAContentType> const& contentTypes) noexcept
|
||||
{
|
||||
specialisation->doRequestAudioSourceContentAnalysis (audioSource, contentTypes);
|
||||
}
|
||||
|
||||
ARA::ARAInt32 ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetProcessingAlgorithmsCount() noexcept
|
||||
{
|
||||
return specialisation->doGetProcessingAlgorithmsCount();
|
||||
}
|
||||
|
||||
const ARA::ARAProcessingAlgorithmProperties* ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetProcessingAlgorithmProperties (ARA::ARAInt32 algorithmIndex) noexcept
|
||||
{
|
||||
return specialisation->doGetProcessingAlgorithmProperties (algorithmIndex);
|
||||
}
|
||||
|
||||
ARA::ARAInt32 ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doGetProcessingAlgorithmForAudioSource (const ARA::PlugIn::AudioSource* audioSource) noexcept
|
||||
{
|
||||
return specialisation->doGetProcessingAlgorithmForAudioSource (audioSource);
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::doRequestProcessingAlgorithmForAudioSource (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAInt32 algorithmIndex) noexcept
|
||||
{
|
||||
return specialisation->doRequestProcessingAlgorithmForAudioSource (audioSource, algorithmIndex);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Helper code for ARADocumentControllerSpecialisation::ARADocumentControllerImpl::timerCallback() to
|
||||
// rewire the host-related ARA SDK's progress tracker to our internal update mechanism.
|
||||
namespace ModelUpdateControllerProgressAdapter
|
||||
{
|
||||
using namespace ARA;
|
||||
|
||||
static void ARA_CALL notifyAudioSourceAnalysisProgress (ARAModelUpdateControllerHostRef /*controllerHostRef*/,
|
||||
ARAAudioSourceHostRef audioSourceHostRef, ARAAnalysisProgressState state, float value) noexcept
|
||||
{
|
||||
auto audioSource = reinterpret_cast<ARAAudioSource*> (audioSourceHostRef);
|
||||
audioSource->getDocumentController<ARADocumentController>()->internalDidUpdateAudioSourceAnalysisProgress (audioSource, state, value);
|
||||
audioSource->notifyListeners ([&] (ARAAudioSource::Listener& l) { l.didUpdateAudioSourceAnalysisProgress (audioSource, state, value); });
|
||||
}
|
||||
|
||||
static void ARA_CALL notifyAudioSourceContentChanged (ARAModelUpdateControllerHostRef, ARAAudioSourceHostRef,
|
||||
const ARAContentTimeRange*, ARAContentUpdateFlags) noexcept
|
||||
{
|
||||
jassertfalse; // not to be called - this adapter only forwards analysis progress
|
||||
}
|
||||
|
||||
static void ARA_CALL notifyAudioModificationContentChanged (ARAModelUpdateControllerHostRef, ARAAudioModificationHostRef,
|
||||
const ARAContentTimeRange*, ARAContentUpdateFlags) noexcept
|
||||
{
|
||||
jassertfalse; // not to be called - this adapter only forwards analysis progress
|
||||
}
|
||||
|
||||
static void ARA_CALL notifyPlaybackRegionContentChanged (ARAModelUpdateControllerHostRef, ARAPlaybackRegionHostRef,
|
||||
const ARAContentTimeRange*, ARAContentUpdateFlags) noexcept
|
||||
{
|
||||
jassertfalse; // not to be called - this adapter only forwards analysis progress
|
||||
}
|
||||
|
||||
static ARA::PlugIn::HostModelUpdateController* get()
|
||||
{
|
||||
static const auto modelUpdateControllerInterface = makeARASizedStruct (&ARA::ARAModelUpdateControllerInterface::notifyPlaybackRegionContentChanged,
|
||||
ModelUpdateControllerProgressAdapter::notifyAudioSourceAnalysisProgress,
|
||||
ModelUpdateControllerProgressAdapter::notifyAudioSourceContentChanged,
|
||||
ModelUpdateControllerProgressAdapter::notifyAudioModificationContentChanged,
|
||||
ModelUpdateControllerProgressAdapter::notifyPlaybackRegionContentChanged);
|
||||
|
||||
static const auto instance = makeARASizedStruct (&ARA::ARADocumentControllerHostInstance::playbackControllerInterface,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&modelUpdateControllerInterface,
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
static auto progressAdapter = ARA::PlugIn::HostModelUpdateController { &instance };
|
||||
return &progressAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::analysisTimerCallback()
|
||||
{
|
||||
if (! internalAnalysisProgressIsSynced.exchange (true, std::memory_order_release))
|
||||
for (auto& audioSource : getDocument()->getAudioSources())
|
||||
audioSource->internalAnalysisProgressTracker.notifyProgress (ModelUpdateControllerProgressAdapter::get(),
|
||||
reinterpret_cast<ARA::ARAAudioSourceHostRef> (audioSource));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ARAInputStream::ARAInputStream (ARA::PlugIn::HostArchiveReader* reader)
|
||||
: archiveReader (reader),
|
||||
size ((int64) reader->getArchiveSize())
|
||||
{}
|
||||
|
||||
int ARAInputStream::read (void* destBuffer, int maxBytesToRead)
|
||||
{
|
||||
const auto bytesToRead = std::min ((int64) maxBytesToRead, size - position);
|
||||
|
||||
if (bytesToRead > 0 && ! archiveReader->readBytesFromArchive ((ARA::ARASize) position, (ARA::ARASize) bytesToRead,
|
||||
static_cast<ARA::ARAByte*> (destBuffer)))
|
||||
{
|
||||
failure = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
position += bytesToRead;
|
||||
return (int) bytesToRead;
|
||||
}
|
||||
|
||||
bool ARAInputStream::setPosition (int64 newPosition)
|
||||
{
|
||||
position = jlimit ((int64) 0, size, newPosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ARAInputStream::isExhausted()
|
||||
{
|
||||
return position >= size;
|
||||
}
|
||||
|
||||
ARAOutputStream::ARAOutputStream (ARA::PlugIn::HostArchiveWriter* writer)
|
||||
: archiveWriter (writer)
|
||||
{}
|
||||
|
||||
bool ARAOutputStream::write (const void* dataToWrite, size_t numberOfBytes)
|
||||
{
|
||||
if (! archiveWriter->writeBytesToArchive ((ARA::ARASize) position, numberOfBytes, (const ARA::ARAByte*) dataToWrite))
|
||||
return false;
|
||||
|
||||
position += (int64) numberOfBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ARAOutputStream::setPosition (int64 newPosition)
|
||||
{
|
||||
position = newPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ARADocumentControllerSpecialisation::ARADocumentControllerSpecialisation (
|
||||
const ARA::PlugIn::PlugInEntry* entry,
|
||||
const ARA::ARADocumentControllerHostInstance* instance)
|
||||
: documentController (std::make_unique<ARADocumentControllerImpl> (entry, instance, this))
|
||||
{
|
||||
}
|
||||
|
||||
ARADocumentControllerSpecialisation::~ARADocumentControllerSpecialisation() = default;
|
||||
|
||||
ARAPlaybackRenderer* ARADocumentControllerSpecialisation::doCreatePlaybackRenderer()
|
||||
{
|
||||
return new ARAPlaybackRenderer (getDocumentController());
|
||||
}
|
||||
|
||||
ARAEditorRenderer* ARADocumentControllerSpecialisation::doCreateEditorRenderer()
|
||||
{
|
||||
return new ARAEditorRenderer (getDocumentController());
|
||||
}
|
||||
|
||||
ARAEditorView* ARADocumentControllerSpecialisation::doCreateEditorView()
|
||||
{
|
||||
return new ARAEditorView (getDocumentController());
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsAudioSourceContentAvailable ([[maybe_unused]] const ARA::PlugIn::AudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::doGetAudioSourceContentGrade ([[maybe_unused]] const ARA::PlugIn::AudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
// Overriding doIsAudioSourceContentAvailable() requires overriding
|
||||
// doGetAudioSourceContentGrade() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
return ARA::kARAContentGradeInitial;
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::doCreateAudioSourceContentReader ([[maybe_unused]] ARA::PlugIn::AudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::ARAContentType type,
|
||||
[[maybe_unused]] const ARA::ARAContentTimeRange* range)
|
||||
{
|
||||
// Overriding doIsAudioSourceContentAvailable() requires overriding
|
||||
// doCreateAudioSourceContentReader() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsAudioModificationContentAvailable ([[maybe_unused]] const ARA::PlugIn::AudioModification* audioModification,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::doGetAudioModificationContentGrade ([[maybe_unused]] const ARA::PlugIn::AudioModification* audioModification,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
// Overriding doIsAudioModificationContentAvailable() requires overriding
|
||||
// doGetAudioModificationContentGrade() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
return ARA::kARAContentGradeInitial;
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::doCreateAudioModificationContentReader ([[maybe_unused]] ARA::PlugIn::AudioModification* audioModification,
|
||||
[[maybe_unused]] ARA::ARAContentType type,
|
||||
[[maybe_unused]] const ARA::ARAContentTimeRange* range)
|
||||
{
|
||||
// Overriding doIsAudioModificationContentAvailable() requires overriding
|
||||
// doCreateAudioModificationContentReader() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsPlaybackRegionContentAvailable ([[maybe_unused]] const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::doGetPlaybackRegionContentGrade ([[maybe_unused]] const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
// Overriding doIsPlaybackRegionContentAvailable() requires overriding
|
||||
// doGetPlaybackRegionContentGrade() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
return ARA::kARAContentGradeInitial;
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::doCreatePlaybackRegionContentReader ([[maybe_unused]] ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
[[maybe_unused]] ARA::ARAContentType type,
|
||||
[[maybe_unused]] const ARA::ARAContentTimeRange* range)
|
||||
{
|
||||
// Overriding doIsPlaybackRegionContentAvailable() requires overriding
|
||||
// doCreatePlaybackRegionContentReader() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::doGetPlaybackRegionHeadAndTailTime ([[maybe_unused]] const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARATimeDuration* headTime,
|
||||
ARA::ARATimeDuration* tailTime)
|
||||
{
|
||||
*headTime = 0.0;
|
||||
*tailTime = 0.0;
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsAudioSourceContentAnalysisIncomplete ([[maybe_unused]] const ARA::PlugIn::AudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::ARAContentType type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::doRequestAudioSourceContentAnalysis ([[maybe_unused]] ARA::PlugIn::AudioSource* audioSource,
|
||||
[[maybe_unused]] std::vector<ARA::ARAContentType> const& contentTypes)
|
||||
{
|
||||
}
|
||||
|
||||
ARA::ARAInt32 ARADocumentControllerSpecialisation::doGetProcessingAlgorithmsCount() { return 0; }
|
||||
|
||||
const ARA::ARAProcessingAlgorithmProperties*
|
||||
ARADocumentControllerSpecialisation::doGetProcessingAlgorithmProperties ([[maybe_unused]] ARA::ARAInt32 algorithmIndex)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ARA::ARAInt32 ARADocumentControllerSpecialisation::doGetProcessingAlgorithmForAudioSource ([[maybe_unused]] const ARA::PlugIn::AudioSource* audioSource)
|
||||
{
|
||||
// doGetProcessingAlgorithmForAudioSource() must be implemented if the supported
|
||||
// algorithm count is greater than zero.
|
||||
if (getDocumentController()->getProcessingAlgorithmsCount() > 0)
|
||||
jassertfalse;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::doRequestProcessingAlgorithmForAudioSource ([[maybe_unused]] ARA::PlugIn::AudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::ARAInt32 algorithmIndex)
|
||||
{
|
||||
// doRequestProcessingAlgorithmForAudioSource() must be implemented if the supported
|
||||
// algorithm count is greater than zero.
|
||||
jassert (getDocumentController()->getProcessingAlgorithmsCount() <= 0);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,538 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ARAPlaybackRenderer;
|
||||
class ARAEditorRenderer;
|
||||
class ARAEditorView;
|
||||
class ARAInputStream;
|
||||
class ARAOutputStream;
|
||||
|
||||
/** This class contains the customisation points for the JUCE provided ARA document controller
|
||||
implementation.
|
||||
|
||||
Every ARA enabled plugin must provide its own document controller implementation. To do this,
|
||||
inherit from this class, and override its protected methods as needed. Then you need to
|
||||
implement a global function somewhere in your module called createARAFactory(). This function
|
||||
must return an ARAFactory* that will instantiate document controller objects using your
|
||||
specialisation. There are helper functions inside ARADocumentControllerSpecialisation, so the
|
||||
implementation of createARAFactory() can always be a simple one-liner. For example
|
||||
|
||||
@code
|
||||
class MyDocumentController : public ARADocumentControllerSpecialisation
|
||||
{
|
||||
//...
|
||||
};
|
||||
|
||||
const ARA::ARAFactory* JUCE_CALLTYPE createARAFactory()
|
||||
{
|
||||
return juce::ARADocumentControllerSpecialisation::createARAFactory<MyDocumentController>();
|
||||
}
|
||||
@endcode
|
||||
|
||||
Most member functions have a default implementation so you can build up your required feature
|
||||
set gradually. The protected functions of this class fall in three distinct groups:
|
||||
- interactive editing and playback,
|
||||
- analysis features provided by the plugin and utilised by the host, and
|
||||
- maintaining the ARA model graph.
|
||||
|
||||
On top of the pure virtual functions, you will probably want to override
|
||||
doCreatePlaybackRenderer() at the very least if you want your plugin to play any sound. This
|
||||
function belongs to the first group.
|
||||
|
||||
If your plugin has analysis capabilities and wants to allow the host to access these, functions
|
||||
in the second group should be overridden.
|
||||
|
||||
The default implementation of the ARA model object classes - i.e. ARADocument, ARAMusicalContext,
|
||||
ARARegionSequence, ARAAudioSource, ARAAudioModification, ARAPlaybackRegion - should be sufficient
|
||||
for maintaining a representation of the ARA model graph, hence overriding the model object
|
||||
creation functions e.g. doCreateMusicalContext() is considered an advanced use case. Hence you
|
||||
should be able to get a lot done without overriding functions in the third group.
|
||||
|
||||
In order to react to the various ARA state changes you can override any of the ARA model object
|
||||
Listener functions that ARADocumentControllerSpecialisation inherits from. Such listener
|
||||
functions can be attached to one particular model objects instance, but the listener functions
|
||||
inside ARADocumentControllerSpecialisation will respond to the events of all instances of the
|
||||
model objects.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class ARADocumentControllerSpecialisation : public ARADocument::Listener,
|
||||
public ARAMusicalContext::Listener,
|
||||
public ARARegionSequence::Listener,
|
||||
public ARAAudioSource::Listener,
|
||||
public ARAAudioModification::Listener,
|
||||
public ARAPlaybackRegion::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructor. Used internally by the ARAFactory implementation.
|
||||
*/
|
||||
ARADocumentControllerSpecialisation (const ARA::PlugIn::PlugInEntry* entry,
|
||||
const ARA::ARADocumentControllerHostInstance* instance);
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~ARADocumentControllerSpecialisation();
|
||||
|
||||
/** Returns the underlying DocumentController object that references this specialisation.
|
||||
*/
|
||||
ARA::PlugIn::DocumentController* getDocumentController() noexcept;
|
||||
|
||||
/** Helper function for implementing the global createARAFactory() function.
|
||||
|
||||
For example
|
||||
|
||||
@code
|
||||
class MyDocumentController : public ARADocumentControllerSpecialisation
|
||||
{
|
||||
//...
|
||||
};
|
||||
|
||||
const ARA::ARAFactory* JUCE_CALLTYPE createARAFactory()
|
||||
{
|
||||
return juce::ARADocumentControllerSpecialisation::createARAFactory<MyDocumentController>();
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
template <typename SpecialisationType>
|
||||
static const ARA::ARAFactory* createARAFactory()
|
||||
{
|
||||
static_assert (std::is_base_of_v<ARADocumentControllerSpecialisation, SpecialisationType>,
|
||||
"DocumentController specialization types must inherit from ARADocumentControllerSpecialisation");
|
||||
return ARA::PlugIn::PlugInEntry::getPlugInEntry<FactoryConfig<SpecialisationType>>()->getFactory();
|
||||
}
|
||||
|
||||
/** Returns a pointer to the ARADocumentControllerSpecialisation instance that is referenced
|
||||
by the provided DocumentController. You can use this function to access your specialisation
|
||||
from anywhere where you have access to ARA::PlugIn::DocumentController*.
|
||||
*/
|
||||
template <typename Specialisation = ARADocumentControllerSpecialisation>
|
||||
static Specialisation* getSpecialisedDocumentController (ARA::PlugIn::DocumentController* dc)
|
||||
{
|
||||
return static_cast<Specialisation*> (getSpecialisedDocumentControllerImpl (dc));
|
||||
}
|
||||
|
||||
/** Returns a pointer to the ARA document root maintained by this document controller. */
|
||||
template <typename DocumentType = ARADocument>
|
||||
DocumentType* getDocument()
|
||||
{
|
||||
return static_cast<DocumentType*> (getDocumentImpl());
|
||||
}
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Read an ARADocument archive from a juce::InputStream.
|
||||
|
||||
@param input Data stream containing previously persisted data to be used when restoring the ARADocument
|
||||
@param filter A filter to be applied to the stream
|
||||
|
||||
Return true if the operation is successful.
|
||||
|
||||
@see ARADocumentControllerInterface::restoreObjectsFromArchive
|
||||
*/
|
||||
virtual bool doRestoreObjectsFromStream (ARAInputStream& input, const ARARestoreObjectsFilter* filter) = 0;
|
||||
|
||||
/** Write an ARADocument archive to a juce::OutputStream.
|
||||
|
||||
@param output Data stream that should be used to write the persistent ARADocument data
|
||||
@param filter A filter to be applied to the stream
|
||||
|
||||
Returns true if the operation is successful.
|
||||
|
||||
@see ARADocumentControllerInterface::storeObjectsToArchive
|
||||
*/
|
||||
virtual bool doStoreObjectsToStream (ARAOutputStream& output, const ARAStoreObjectsFilter* filter) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Override to return a custom subclass instance of ARAPlaybackRenderer. */
|
||||
virtual ARAPlaybackRenderer* doCreatePlaybackRenderer();
|
||||
|
||||
/** Override to return a custom subclass instance of ARAEditorRenderer. */
|
||||
virtual ARAEditorRenderer* doCreateEditorRenderer();
|
||||
|
||||
/** Override to return a custom subclass instance of ARAEditorView. */
|
||||
virtual ARAEditorView* doCreateEditorView();
|
||||
|
||||
//==============================================================================
|
||||
// ARAAudioSource content access
|
||||
|
||||
/** Override to implement isAudioSourceContentAvailable() for all your supported content types -
|
||||
the default implementation always returns false, preventing any calls to doGetAudioSourceContentGrade()
|
||||
and doCreateAudioSourceContentReader().
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doIsAudioSourceContentAvailable.
|
||||
*/
|
||||
virtual bool doIsAudioSourceContentAvailable (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement getAudioSourceContentGrade() for all your supported content types.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetAudioSourceContentGrade.
|
||||
*/
|
||||
virtual ARA::ARAContentGrade doGetAudioSourceContentGrade (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement createAudioSourceContentReader() for all your supported content types,
|
||||
returning a custom subclass instance of ContentReader providing data of the requested type.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doCreateAudioSourceContentReader.
|
||||
*/
|
||||
virtual ARA::PlugIn::ContentReader* doCreateAudioSourceContentReader (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range);
|
||||
|
||||
//==============================================================================
|
||||
// ARAAudioModification content access
|
||||
|
||||
/** Override to implement isAudioModificationContentAvailable() for all your supported content types -
|
||||
the default implementation always returns false.
|
||||
For read-only data directly inherited from the underlying audio source you can just delegate the
|
||||
call to the audio source, but user-editable modification data must be specifically handled here.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doIsAudioModificationContentAvailable.
|
||||
*/
|
||||
virtual bool doIsAudioModificationContentAvailable (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement getAudioModificationContentGrade() for all your supported content types.
|
||||
For read-only data directly inherited from the underlying audio source you can just delegate the
|
||||
call to the audio source, but user-editable modification data must be specifically handled here.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetAudioModificationContentGrade.
|
||||
*/
|
||||
virtual ARA::ARAContentGrade doGetAudioModificationContentGrade (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement createAudioModificationContentReader() for all your supported content types,
|
||||
returning a custom subclass instance of ContentReader providing data of the requested \p type.
|
||||
For read-only data directly inherited from the underlying audio source you can just delegate the
|
||||
call to the audio source, but user-editable modification data must be specifically handled here.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doCreateAudioModificationContentReader.
|
||||
*/
|
||||
virtual ARA::PlugIn::ContentReader* doCreateAudioModificationContentReader (ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range);
|
||||
|
||||
//==============================================================================
|
||||
// ARAPlaybackRegion content access
|
||||
|
||||
/** Override to implement isPlaybackRegionContentAvailable() for all your supported content types -
|
||||
the default implementation always returns false.
|
||||
Typically, this call can directly delegate to the underlying audio modification, since most
|
||||
plug-ins will apply their modification data to the playback region with a transformation that
|
||||
does not affect content availability.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doIsPlaybackRegionContentAvailable.
|
||||
*/
|
||||
virtual bool doIsPlaybackRegionContentAvailable (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement getPlaybackRegionContentGrade() for all your supported content types.
|
||||
Typically, this call can directly delegate to the underlying audio modification, since most
|
||||
plug-ins will apply their modification data to the playback region with a transformation that
|
||||
does not affect content grade.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetPlaybackRegionContentGrade.
|
||||
*/
|
||||
virtual ARA::ARAContentGrade doGetPlaybackRegionContentGrade (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement createPlaybackRegionContentReader() for all your supported content types,
|
||||
returning a custom subclass instance of ContentReader providing data of the requested type.
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doCreatePlaybackRegionContentReader.
|
||||
*/
|
||||
virtual ARA::PlugIn::ContentReader* doCreatePlaybackRegionContentReader (ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range);
|
||||
|
||||
/** Override to implement getPlaybackRegionHeadAndTailTime().
|
||||
|
||||
This function is called within
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetPlaybackRegionHeadAndTailTime.
|
||||
*/
|
||||
virtual void doGetPlaybackRegionHeadAndTailTime (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARATimeDuration* headTime,
|
||||
ARA::ARATimeDuration* tailTime);
|
||||
|
||||
//==============================================================================
|
||||
// ARAAudioSource analysis
|
||||
|
||||
/** Override to implement isAudioSourceContentAnalysisIncomplete().
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doIsAudioSourceContentAnalysisIncomplete.
|
||||
*/
|
||||
virtual bool doIsAudioSourceContentAnalysisIncomplete (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type);
|
||||
|
||||
/** Override to implement requestAudioSourceContentAnalysis().
|
||||
|
||||
This function's called from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doRequestAudioSourceContentAnalysis.
|
||||
*/
|
||||
virtual void doRequestAudioSourceContentAnalysis (ARA::PlugIn::AudioSource* audioSource,
|
||||
std::vector<ARA::ARAContentType> const& contentTypes);
|
||||
|
||||
//==============================================================================
|
||||
// Analysis Algorithm selection
|
||||
|
||||
/** Override to implement getProcessingAlgorithmsCount().
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetProcessingAlgorithmsCount.
|
||||
*/
|
||||
virtual ARA::ARAInt32 doGetProcessingAlgorithmsCount ();
|
||||
|
||||
/** Override to implement getProcessingAlgorithmProperties().
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetProcessingAlgorithmProperties.
|
||||
*/
|
||||
virtual const ARA::ARAProcessingAlgorithmProperties*
|
||||
doGetProcessingAlgorithmProperties (ARA::ARAInt32 algorithmIndex);
|
||||
|
||||
/** Override to implement getProcessingAlgorithmForAudioSource().
|
||||
|
||||
This function's result is returned from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doGetProcessingAlgorithmForAudioSource.
|
||||
*/
|
||||
virtual ARA::ARAInt32 doGetProcessingAlgorithmForAudioSource (const ARA::PlugIn::AudioSource* audioSource);
|
||||
|
||||
/** Override to implement requestProcessingAlgorithmForAudioSource().
|
||||
|
||||
This function's called from
|
||||
ARA::PlugIn::DocumentControllerDelegate::doRequestProcessingAlgorithmForAudioSource.
|
||||
*/
|
||||
virtual void doRequestProcessingAlgorithmForAudioSource (ARA::PlugIn::AudioSource* audioSource, ARA::ARAInt32 algorithmIndex);
|
||||
|
||||
//==============================================================================
|
||||
/** Override to return a custom subclass instance of ARADocument. */
|
||||
virtual ARADocument* doCreateDocument();
|
||||
|
||||
/** Override to return a custom subclass instance of ARAMusicalContext. */
|
||||
virtual ARAMusicalContext* doCreateMusicalContext (ARADocument* document,
|
||||
ARA::ARAMusicalContextHostRef hostRef);
|
||||
|
||||
/** Override to return a custom subclass instance of ARARegionSequence. */
|
||||
virtual ARARegionSequence* doCreateRegionSequence (ARADocument* document,
|
||||
ARA::ARARegionSequenceHostRef hostRef);
|
||||
|
||||
/** Override to return a custom subclass instance of ARAAudioSource. */
|
||||
virtual ARAAudioSource* doCreateAudioSource (ARADocument* document,
|
||||
ARA::ARAAudioSourceHostRef hostRef);
|
||||
|
||||
/** Override to return a custom subclass instance of ARAAudioModification. */
|
||||
virtual ARAAudioModification* doCreateAudioModification (ARAAudioSource* audioSource,
|
||||
ARA::ARAAudioModificationHostRef hostRef,
|
||||
const ARAAudioModification* optionalModificationToClone);
|
||||
|
||||
/** Override to return a custom subclass instance of ARAPlaybackRegion. */
|
||||
virtual ARAPlaybackRegion* doCreatePlaybackRegion (ARAAudioModification* modification,
|
||||
ARA::ARAPlaybackRegionHostRef hostRef);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
template <typename SpecialisationType>
|
||||
class FactoryConfig : public ARA::PlugIn::FactoryConfig
|
||||
{
|
||||
public:
|
||||
FactoryConfig() noexcept
|
||||
{
|
||||
const juce::String compatibleDocumentArchiveIDString = JucePlugin_ARACompatibleArchiveIDs;
|
||||
|
||||
if (compatibleDocumentArchiveIDString.isNotEmpty())
|
||||
{
|
||||
compatibleDocumentArchiveIDStrings = juce::StringArray::fromLines (compatibleDocumentArchiveIDString);
|
||||
for (const auto& compatibleID : compatibleDocumentArchiveIDStrings)
|
||||
compatibleDocumentArchiveIDs.push_back (compatibleID.toRawUTF8());
|
||||
}
|
||||
|
||||
// Update analyzeable content types
|
||||
static constexpr std::array<ARA::ARAContentType, 6> contentTypes {
|
||||
ARA::kARAContentTypeNotes,
|
||||
ARA::kARAContentTypeTempoEntries,
|
||||
ARA::kARAContentTypeBarSignatures,
|
||||
ARA::kARAContentTypeStaticTuning,
|
||||
ARA::kARAContentTypeKeySignatures,
|
||||
ARA::kARAContentTypeSheetChords
|
||||
};
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6313)
|
||||
|
||||
for (size_t i = 0; i < contentTypes.size(); ++i)
|
||||
if (JucePlugin_ARAContentTypes & (1 << i))
|
||||
analyzeableContentTypes.push_back (contentTypes[i]);
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
// Update playback transformation flags
|
||||
static constexpr std::array<ARA::ARAPlaybackTransformationFlags, 4> playbackTransformationFlags {
|
||||
ARA::kARAPlaybackTransformationTimestretch,
|
||||
ARA::kARAPlaybackTransformationTimestretchReflectingTempo,
|
||||
ARA::kARAPlaybackTransformationContentBasedFadeAtTail,
|
||||
ARA::kARAPlaybackTransformationContentBasedFadeAtHead
|
||||
};
|
||||
|
||||
supportedPlaybackTransformationFlags = 0;
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6313)
|
||||
|
||||
for (size_t i = 0; i < playbackTransformationFlags.size(); ++i)
|
||||
if (JucePlugin_ARATransformationFlags & (1 << i))
|
||||
supportedPlaybackTransformationFlags |= playbackTransformationFlags[i];
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
}
|
||||
|
||||
const char* getFactoryID() const noexcept override { return JucePlugin_ARAFactoryID; }
|
||||
const char* getPlugInName() const noexcept override { return JucePlugin_Name; }
|
||||
const char* getManufacturerName() const noexcept override { return JucePlugin_Manufacturer; }
|
||||
const char* getInformationURL() const noexcept override { return JucePlugin_ManufacturerWebsite; }
|
||||
const char* getVersion() const noexcept override { return JucePlugin_VersionString; }
|
||||
const char* getDocumentArchiveID() const noexcept override { return JucePlugin_ARADocumentArchiveID; }
|
||||
|
||||
ARA::ARASize getCompatibleDocumentArchiveIDsCount() const noexcept override
|
||||
{
|
||||
return compatibleDocumentArchiveIDs.size();
|
||||
}
|
||||
|
||||
const ARA::ARAPersistentID* getCompatibleDocumentArchiveIDs() const noexcept override
|
||||
{
|
||||
return compatibleDocumentArchiveIDs.empty() ? nullptr : compatibleDocumentArchiveIDs.data();
|
||||
}
|
||||
|
||||
ARA::ARASize getAnalyzeableContentTypesCount() const noexcept override
|
||||
{
|
||||
return analyzeableContentTypes.size();
|
||||
}
|
||||
|
||||
const ARA::ARAContentType* getAnalyzeableContentTypes() const noexcept override
|
||||
{
|
||||
return analyzeableContentTypes.empty() ? nullptr : analyzeableContentTypes.data();
|
||||
}
|
||||
|
||||
ARA::ARAPlaybackTransformationFlags getSupportedPlaybackTransformationFlags() const noexcept override
|
||||
{
|
||||
return supportedPlaybackTransformationFlags;
|
||||
}
|
||||
|
||||
ARA::PlugIn::DocumentController* createDocumentController (const ARA::PlugIn::PlugInEntry* entry,
|
||||
const ARA::ARADocumentControllerHostInstance* instance) const noexcept override
|
||||
{
|
||||
auto* spec = new SpecialisationType (entry, instance);
|
||||
return spec->getDocumentController();
|
||||
}
|
||||
|
||||
void destroyDocumentController (ARA::PlugIn::DocumentController* controller) const noexcept override
|
||||
{
|
||||
delete getSpecialisedDocumentController (controller);
|
||||
}
|
||||
|
||||
private:
|
||||
juce::StringArray compatibleDocumentArchiveIDStrings;
|
||||
std::vector<ARA::ARAPersistentID> compatibleDocumentArchiveIDs;
|
||||
std::vector<ARA::ARAContentType> analyzeableContentTypes;
|
||||
ARA::ARAPlaybackTransformationFlags supportedPlaybackTransformationFlags;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
static ARADocumentControllerSpecialisation* getSpecialisedDocumentControllerImpl (ARA::PlugIn::DocumentController*);
|
||||
|
||||
ARADocument* getDocumentImpl();
|
||||
|
||||
//==============================================================================
|
||||
class ARADocumentControllerImpl;
|
||||
std::unique_ptr<ARADocumentControllerImpl> documentController;
|
||||
};
|
||||
|
||||
/** Used to read persisted ARA archives - see doRestoreObjectsFromStream() for details.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class ARAInputStream : public InputStream
|
||||
{
|
||||
public:
|
||||
explicit ARAInputStream (ARA::PlugIn::HostArchiveReader*);
|
||||
|
||||
int64 getPosition() override { return position; }
|
||||
int64 getTotalLength() override { return size; }
|
||||
|
||||
int read (void*, int) override;
|
||||
bool setPosition (int64) override;
|
||||
bool isExhausted() override;
|
||||
|
||||
bool failed() const { return failure; }
|
||||
|
||||
private:
|
||||
ARA::PlugIn::HostArchiveReader* archiveReader;
|
||||
int64 position = 0;
|
||||
int64 size;
|
||||
bool failure = false;
|
||||
};
|
||||
|
||||
/** Used to write persistent ARA archives - see doStoreObjectsToStream() for details.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class ARAOutputStream : public OutputStream
|
||||
{
|
||||
public:
|
||||
explicit ARAOutputStream (ARA::PlugIn::HostArchiveWriter*);
|
||||
|
||||
int64 getPosition() override { return position; }
|
||||
void flush() override {}
|
||||
|
||||
bool write (const void*, size_t) override;
|
||||
bool setPosition (int64) override;
|
||||
|
||||
private:
|
||||
ARA::PlugIn::HostArchiveWriter* archiveWriter;
|
||||
int64 position = 0;
|
||||
};
|
||||
} // namespace juce
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ARADocumentController : public ARA::PlugIn::DocumentController
|
||||
{
|
||||
public:
|
||||
using ARA::PlugIn::DocumentController::DocumentController;
|
||||
|
||||
template <typename Document_t = ARADocument>
|
||||
Document_t* getDocument() const noexcept { return ARA::PlugIn::DocumentController::getDocument<Document_t>(); }
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
virtual void internalNotifyAudioSourceAnalysisProgressStarted (ARAAudioSource* audioSource) = 0;
|
||||
|
||||
/** @internal */
|
||||
virtual void internalNotifyAudioSourceAnalysisProgressUpdated (ARAAudioSource* audioSource, float progress) = 0;
|
||||
|
||||
/** @internal */
|
||||
virtual void internalNotifyAudioSourceAnalysisProgressCompleted (ARAAudioSource* audioSource) = 0;
|
||||
|
||||
/** @internal */
|
||||
virtual void internalDidUpdateAudioSourceAnalysisProgress (ARAAudioSource* audioSource,
|
||||
ARAAudioSource::ARAAnalysisProgressState state,
|
||||
float progress) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
virtual void internalNotifyAudioSourceContentChanged (ARAAudioSource* audioSource,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost) = 0;
|
||||
|
||||
/** @internal */
|
||||
virtual void internalNotifyAudioModificationContentChanged (ARAAudioModification* audioModification,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost) = 0;
|
||||
|
||||
/** @internal */
|
||||
virtual void internalNotifyPlaybackRegionContentChanged (ARAPlaybackRegion* playbackRegion,
|
||||
ARAContentUpdateScopes scopeFlags,
|
||||
bool notifyARAHost) = 0;
|
||||
|
||||
friend class ARAPlaybackRegionReader;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
size_t ARADocument::getNumChildren() const noexcept
|
||||
{
|
||||
return getMusicalContexts().size() + getRegionSequences().size() + getAudioSources().size();
|
||||
}
|
||||
|
||||
ARAObject* ARADocument::getChild (size_t index)
|
||||
{
|
||||
auto& musicalContexts = getMusicalContexts();
|
||||
|
||||
if (index < musicalContexts.size())
|
||||
return musicalContexts[index];
|
||||
|
||||
const auto numMusicalContexts = musicalContexts.size();
|
||||
auto& regionSequences = getRegionSequences();
|
||||
|
||||
if (index < numMusicalContexts + regionSequences.size())
|
||||
return regionSequences[index - numMusicalContexts];
|
||||
|
||||
const auto numMusicalContextsAndRegionSequences = numMusicalContexts + regionSequences.size();
|
||||
auto& audioSources = getAudioSources();
|
||||
|
||||
if (index < numMusicalContextsAndRegionSequences + audioSources.size())
|
||||
return getAudioSources()[index - numMusicalContextsAndRegionSequences];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
size_t ARARegionSequence::getNumChildren() const noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARAObject* ARARegionSequence::getChild (size_t)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Range<double> ARARegionSequence::getTimeRange (ARAPlaybackRegion::IncludeHeadAndTail includeHeadAndTail) const
|
||||
{
|
||||
if (getPlaybackRegions().empty())
|
||||
return {};
|
||||
|
||||
auto startTime = std::numeric_limits<double>::max();
|
||||
auto endTime = std::numeric_limits<double>::lowest();
|
||||
for (const auto& playbackRegion : getPlaybackRegions())
|
||||
{
|
||||
const auto regionTimeRange = playbackRegion->getTimeRange (includeHeadAndTail);
|
||||
startTime = jmin (startTime, regionTimeRange.getStart());
|
||||
endTime = jmax (endTime, regionTimeRange.getEnd());
|
||||
}
|
||||
return { startTime, endTime };
|
||||
}
|
||||
|
||||
double ARARegionSequence::getCommonSampleRate() const
|
||||
{
|
||||
const auto getSampleRate = [] (auto* playbackRegion)
|
||||
{
|
||||
return playbackRegion->getAudioModification()->getAudioSource()->getSampleRate();
|
||||
};
|
||||
|
||||
const auto range = getPlaybackRegions();
|
||||
const auto sampleRate = range.size() > 0 ? getSampleRate (range.front()) : 0.0;
|
||||
|
||||
if (std::any_of (range.begin(), range.end(), [&] (auto& x) { return ! exactlyEqual (getSampleRate (x), sampleRate); }))
|
||||
return 0.0;
|
||||
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
size_t ARAAudioSource::getNumChildren() const noexcept
|
||||
{
|
||||
return getAudioModifications().size();
|
||||
}
|
||||
|
||||
ARAObject* ARAAudioSource::getChild (size_t index)
|
||||
{
|
||||
return getAudioModifications()[index];
|
||||
}
|
||||
|
||||
void ARAAudioSource::notifyAnalysisProgressStarted()
|
||||
{
|
||||
getDocumentController<ARADocumentController>()->internalNotifyAudioSourceAnalysisProgressStarted (this);
|
||||
}
|
||||
|
||||
void ARAAudioSource::notifyAnalysisProgressUpdated (float progress)
|
||||
{
|
||||
getDocumentController<ARADocumentController>()->internalNotifyAudioSourceAnalysisProgressUpdated (this, progress);
|
||||
}
|
||||
|
||||
void ARAAudioSource::notifyAnalysisProgressCompleted()
|
||||
{
|
||||
getDocumentController<ARADocumentController>()->internalNotifyAudioSourceAnalysisProgressCompleted (this);
|
||||
}
|
||||
|
||||
void ARAAudioSource::notifyContentChanged (ARAContentUpdateScopes scopeFlags, bool notifyARAHost)
|
||||
{
|
||||
getDocumentController<ARADocumentController>()->internalNotifyAudioSourceContentChanged (this,
|
||||
scopeFlags,
|
||||
notifyARAHost);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
size_t ARAAudioModification::getNumChildren() const noexcept
|
||||
{
|
||||
return getPlaybackRegions().size();
|
||||
}
|
||||
|
||||
ARAObject* ARAAudioModification::getChild (size_t index)
|
||||
{
|
||||
return getPlaybackRegions()[index];
|
||||
}
|
||||
|
||||
void ARAAudioModification::notifyContentChanged (ARAContentUpdateScopes scopeFlags, bool notifyARAHost)
|
||||
{
|
||||
getDocumentController<ARADocumentController>()->internalNotifyAudioModificationContentChanged (this,
|
||||
scopeFlags,
|
||||
notifyARAHost);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ARAObject* ARAPlaybackRegion::getParent() { return getAudioModification(); }
|
||||
|
||||
Range<double> ARAPlaybackRegion::getTimeRange (IncludeHeadAndTail includeHeadAndTail) const
|
||||
{
|
||||
auto startTime = getStartInPlaybackTime();
|
||||
auto endTime = getEndInPlaybackTime();
|
||||
|
||||
if (includeHeadAndTail == IncludeHeadAndTail::yes)
|
||||
{
|
||||
ARA::ARATimeDuration headTime {}, tailTime {};
|
||||
getDocumentController()->getPlaybackRegionHeadAndTailTime (toRef (this), &headTime, &tailTime);
|
||||
startTime -= headTime;
|
||||
endTime += tailTime;
|
||||
}
|
||||
|
||||
return { startTime, endTime };
|
||||
}
|
||||
|
||||
Range<int64> ARAPlaybackRegion::getSampleRange (double sampleRate, IncludeHeadAndTail includeHeadAndTail) const
|
||||
{
|
||||
const auto timeRange = getTimeRange (includeHeadAndTail);
|
||||
|
||||
return { ARA::samplePositionAtTime (timeRange.getStart(), sampleRate),
|
||||
ARA::samplePositionAtTime (timeRange.getEnd(), sampleRate) };
|
||||
}
|
||||
|
||||
double ARAPlaybackRegion::getHeadTime() const
|
||||
{
|
||||
ARA::ARATimeDuration headTime {}, tailTime {};
|
||||
getDocumentController()->getPlaybackRegionHeadAndTailTime (toRef (this), &headTime, &tailTime);
|
||||
return headTime;
|
||||
}
|
||||
|
||||
double ARAPlaybackRegion::getTailTime() const
|
||||
{
|
||||
ARA::ARATimeDuration headTime {}, tailTime {};
|
||||
getDocumentController()->getPlaybackRegionHeadAndTailTime (toRef (this), &headTime, &tailTime);
|
||||
return tailTime;
|
||||
}
|
||||
|
||||
void ARAPlaybackRegion::notifyContentChanged (ARAContentUpdateScopes scopeFlags, bool notifyARAHost)
|
||||
{
|
||||
getDocumentController<ARADocumentController>()->internalNotifyPlaybackRegionContentChanged (this,
|
||||
scopeFlags,
|
||||
notifyARAHost);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ARADocumentListener::willBeginEditing ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::didEndEditing ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::willNotifyModelUpdates ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::didNotifyModelUpdates ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::willUpdateDocumentProperties ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARA::PlugIn::PropertiesPtr<ARA::ARADocumentProperties> newProperties) {}
|
||||
void ARADocumentListener::didUpdateDocumentProperties ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::didAddMusicalContextToDocument ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARAMusicalContext* musicalContext) {}
|
||||
void ARADocumentListener::willRemoveMusicalContextFromDocument ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARAMusicalContext* musicalContext) {}
|
||||
void ARADocumentListener::didReorderMusicalContextsInDocument ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::didAddRegionSequenceToDocument ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARARegionSequence* regionSequence) {}
|
||||
void ARADocumentListener::willRemoveRegionSequenceFromDocument ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARARegionSequence* regionSequence) {}
|
||||
void ARADocumentListener::didReorderRegionSequencesInDocument ([[maybe_unused]] ARADocument* document) {}
|
||||
void ARADocumentListener::didAddAudioSourceToDocument ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARAAudioSource* audioSource) {}
|
||||
void ARADocumentListener::willRemoveAudioSourceFromDocument ([[maybe_unused]] ARADocument* document,
|
||||
[[maybe_unused]] ARAAudioSource* audioSource) {}
|
||||
void ARADocumentListener::willDestroyDocument ([[maybe_unused]] ARADocument* document) {}
|
||||
|
||||
//==============================================================================
|
||||
void ARAMusicalContextListener::willUpdateMusicalContextProperties ([[maybe_unused]] ARAMusicalContext* musicalContext,
|
||||
[[maybe_unused]] ARA::PlugIn::PropertiesPtr<ARA::ARAMusicalContextProperties> newProperties) {}
|
||||
void ARAMusicalContextListener::didUpdateMusicalContextProperties ([[maybe_unused]] ARAMusicalContext* musicalContext) {}
|
||||
void ARAMusicalContextListener::doUpdateMusicalContextContent ([[maybe_unused]] ARAMusicalContext* musicalContext,
|
||||
[[maybe_unused]] ARAContentUpdateScopes scopeFlags) {}
|
||||
void ARAMusicalContextListener::didAddRegionSequenceToMusicalContext ([[maybe_unused]] ARAMusicalContext* musicalContext,
|
||||
[[maybe_unused]] ARARegionSequence* regionSequence) {}
|
||||
void ARAMusicalContextListener::willRemoveRegionSequenceFromMusicalContext ([[maybe_unused]] ARAMusicalContext* musicalContext,
|
||||
[[maybe_unused]] ARARegionSequence* regionSequence) {}
|
||||
void ARAMusicalContextListener::didReorderRegionSequencesInMusicalContext ([[maybe_unused]] ARAMusicalContext* musicalContext) {}
|
||||
void ARAMusicalContextListener::willDestroyMusicalContext ([[maybe_unused]] ARAMusicalContext* musicalContext) {}
|
||||
|
||||
//==============================================================================
|
||||
void ARAPlaybackRegionListener::willUpdatePlaybackRegionProperties ([[maybe_unused]] ARAPlaybackRegion* playbackRegion,
|
||||
[[maybe_unused]] ARA::PlugIn::PropertiesPtr<ARA::ARAPlaybackRegionProperties> newProperties) {}
|
||||
void ARAPlaybackRegionListener::didUpdatePlaybackRegionProperties ([[maybe_unused]] ARAPlaybackRegion* playbackRegion) {}
|
||||
void ARAPlaybackRegionListener::didUpdatePlaybackRegionContent ([[maybe_unused]] ARAPlaybackRegion* playbackRegion,
|
||||
[[maybe_unused]] ARAContentUpdateScopes scopeFlags) {}
|
||||
void ARAPlaybackRegionListener::willDestroyPlaybackRegion ([[maybe_unused]] ARAPlaybackRegion* playbackRegion) {}
|
||||
|
||||
//==============================================================================
|
||||
void ARARegionSequenceListener::willUpdateRegionSequenceProperties ([[maybe_unused]] ARARegionSequence* regionSequence,
|
||||
[[maybe_unused]] ARA::PlugIn::PropertiesPtr<ARA::ARARegionSequenceProperties> newProperties) {}
|
||||
void ARARegionSequenceListener::didUpdateRegionSequenceProperties ([[maybe_unused]] ARARegionSequence* regionSequence) {}
|
||||
void ARARegionSequenceListener::willRemovePlaybackRegionFromRegionSequence ([[maybe_unused]] ARARegionSequence* regionSequence,
|
||||
[[maybe_unused]] ARAPlaybackRegion* playbackRegion) {}
|
||||
void ARARegionSequenceListener::didAddPlaybackRegionToRegionSequence ([[maybe_unused]] ARARegionSequence* regionSequence,
|
||||
[[maybe_unused]] ARAPlaybackRegion* playbackRegion) {}
|
||||
void ARARegionSequenceListener::willDestroyRegionSequence ([[maybe_unused]] ARARegionSequence* regionSequence) {}
|
||||
|
||||
//==============================================================================
|
||||
void ARAAudioSourceListener::willUpdateAudioSourceProperties ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::PlugIn::PropertiesPtr<ARA::ARAAudioSourceProperties> newProperties) {}
|
||||
void ARAAudioSourceListener::didUpdateAudioSourceProperties ([[maybe_unused]] ARAAudioSource* audioSource) {}
|
||||
void ARAAudioSourceListener::doUpdateAudioSourceContent ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] ARAContentUpdateScopes scopeFlags) {}
|
||||
void ARAAudioSourceListener::didUpdateAudioSourceAnalysisProgress ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] ARA::ARAAnalysisProgressState state,
|
||||
[[maybe_unused]] float progress) {}
|
||||
void ARAAudioSourceListener::willEnableAudioSourceSamplesAccess ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] bool enable) {}
|
||||
void ARAAudioSourceListener::didEnableAudioSourceSamplesAccess ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] bool enable) {}
|
||||
void ARAAudioSourceListener::willDeactivateAudioSourceForUndoHistory ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] bool deactivate) {}
|
||||
void ARAAudioSourceListener::didDeactivateAudioSourceForUndoHistory ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] bool deactivate) {}
|
||||
void ARAAudioSourceListener::didAddAudioModificationToAudioSource ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] ARAAudioModification* audioModification) {}
|
||||
void ARAAudioSourceListener::willRemoveAudioModificationFromAudioSource ([[maybe_unused]] ARAAudioSource* audioSource,
|
||||
[[maybe_unused]] ARAAudioModification* audioModification) {}
|
||||
void ARAAudioSourceListener::willDestroyAudioSource ([[maybe_unused]] ARAAudioSource* audioSource) {}
|
||||
|
||||
//==============================================================================
|
||||
void ARAAudioModificationListener::willUpdateAudioModificationProperties ([[maybe_unused]] ARAAudioModification* audioModification,
|
||||
[[maybe_unused]] ARA::PlugIn::PropertiesPtr<ARA::ARAAudioModificationProperties> newProperties) {}
|
||||
void ARAAudioModificationListener::didUpdateAudioModificationProperties ([[maybe_unused]] ARAAudioModification* audioModification) {}
|
||||
void ARAAudioModificationListener::didUpdateAudioModificationContent ([[maybe_unused]] ARAAudioModification* audioModification,
|
||||
[[maybe_unused]] ARAContentUpdateScopes scopeFlags) {}
|
||||
void ARAAudioModificationListener::willDeactivateAudioModificationForUndoHistory ([[maybe_unused]] ARAAudioModification* audioModification,
|
||||
[[maybe_unused]] bool deactivate) {}
|
||||
void ARAAudioModificationListener::didDeactivateAudioModificationForUndoHistory ([[maybe_unused]] ARAAudioModification* audioModification,
|
||||
[[maybe_unused]] bool deactivate) {}
|
||||
void ARAAudioModificationListener::didAddPlaybackRegionToAudioModification ([[maybe_unused]] ARAAudioModification* audioModification,
|
||||
[[maybe_unused]] ARAPlaybackRegion* playbackRegion) {}
|
||||
void ARAAudioModificationListener::willRemovePlaybackRegionFromAudioModification ([[maybe_unused]] ARAAudioModification* audioModification,
|
||||
[[maybe_unused]] ARAPlaybackRegion* playbackRegion) {}
|
||||
void ARAAudioModificationListener::willDestroyAudioModification ([[maybe_unused]] ARAAudioModification* audioModification) {}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,983 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ARADocumentController;
|
||||
class ARADocument;
|
||||
class ARAMusicalContext;
|
||||
class ARARegionSequence;
|
||||
class ARAAudioSource;
|
||||
class ARAAudioModification;
|
||||
class ARAPlaybackRegion;
|
||||
|
||||
/** Base class used by the JUCE ARA model objects to provide listenable interfaces.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
template <class ListenerType>
|
||||
class JUCE_API ARAListenableModelClass
|
||||
{
|
||||
public:
|
||||
/** Constructor. */
|
||||
ARAListenableModelClass() = default;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~ARAListenableModelClass() = default;
|
||||
|
||||
/** Subscribe \p l to notified by changes to the object.
|
||||
@param l The listener instance.
|
||||
*/
|
||||
void addListener (ListenerType* l) { listeners.add (l); }
|
||||
|
||||
/** Unsubscribe \p l from object notifications.
|
||||
@param l The listener instance.
|
||||
*/
|
||||
void removeListener (ListenerType* l) { listeners.remove (l); }
|
||||
|
||||
/** Call the provided callback for each of the added listeners. */
|
||||
template <typename Callback>
|
||||
void notifyListeners (Callback&& callback)
|
||||
{
|
||||
listeners.call (callback);
|
||||
}
|
||||
|
||||
private:
|
||||
ListenerList<ListenerType> listeners;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARAListenableModelClass)
|
||||
};
|
||||
|
||||
/** Create a derived implementation of this class and pass it to ARAObject::visit() to retrieve the
|
||||
concrete type of a model object.
|
||||
|
||||
Combined with ARAObject::traverse() on the ARADocument object it is possible to discover the
|
||||
entire model graph.
|
||||
|
||||
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!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ARAObjectVisitor
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~ARAObjectVisitor() = default;
|
||||
|
||||
/** Called when visiting an ARADocument object. */
|
||||
virtual void visitDocument (juce::ARADocument&) {}
|
||||
|
||||
/** Called when visiting an ARAMusicalContext object. */
|
||||
virtual void visitMusicalContext (juce::ARAMusicalContext&) {}
|
||||
|
||||
/** Called when visiting an ARARegionSequence object. */
|
||||
virtual void visitRegionSequence (juce::ARARegionSequence&) {}
|
||||
|
||||
/** Called when visiting an ARAPlaybackRegion object. */
|
||||
virtual void visitPlaybackRegion (juce::ARAPlaybackRegion&) {}
|
||||
|
||||
/** Called when visiting an ARAAudioModification object. */
|
||||
virtual void visitAudioModification (juce::ARAAudioModification&) {}
|
||||
|
||||
/** Called when visiting an ARAAudioSource object. */
|
||||
virtual void visitAudioSource (juce::ARAAudioSource&) {}
|
||||
};
|
||||
|
||||
/** Common base class for all JUCE ARA model objects to aid with the discovery and traversal of the
|
||||
entire ARA model graph.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class ARAObject
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~ARAObject() = default;
|
||||
|
||||
/** Returns the number of ARA model objects aggregated by this object. Objects that are merely
|
||||
referred to, but not aggregated by the current object are not included in this count, e.g.
|
||||
a referenced RegionSequence does not count as a child of the referring PlaybackRegion.
|
||||
|
||||
See the ARA documentation's ARA Model Graph Overview for more details.
|
||||
*/
|
||||
virtual size_t getNumChildren() const noexcept = 0;
|
||||
|
||||
/** Returns the child object associated with the given index.
|
||||
|
||||
The index should be smaller than the value returned by getNumChildren().
|
||||
|
||||
Note that the index of a particular object may change when the ARA model graph is edited.
|
||||
*/
|
||||
virtual ARAObject* getChild (size_t index) = 0;
|
||||
|
||||
/** Returns the ARA model object that aggregates this object.
|
||||
|
||||
Returns nullptr for the ARADocument root object.
|
||||
*/
|
||||
virtual ARAObject* getParent() = 0;
|
||||
|
||||
/** Implements a depth first traversal of the ARA model graph starting from the current object,
|
||||
and visiting its children recursively.
|
||||
|
||||
The provided function should accept a single ARAObject& parameter.
|
||||
*/
|
||||
template <typename Fn>
|
||||
void traverse (Fn&& fn)
|
||||
{
|
||||
fn (*this);
|
||||
|
||||
for (size_t i = 0; i < getNumChildren(); ++i)
|
||||
{
|
||||
getChild (i)->traverse (fn);
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows the retrieval of the concrete type of a model object.
|
||||
|
||||
To use this, create a new class derived from ARAObjectVisitor and override its functions
|
||||
depending on which concrete types you are interested in.
|
||||
|
||||
Calling this function inside the function passed to ARAObject::traverse() allows you to
|
||||
map the entire ARA model graph.
|
||||
*/
|
||||
virtual void visit (ARAObjectVisitor& visitor) = 0;
|
||||
};
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARADocument object.
|
||||
|
||||
Use ARADocument::addListener() to register your listener with an ARADocument.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARADocumentListener
|
||||
{
|
||||
public:
|
||||
/** Destructor */
|
||||
virtual ~ARADocumentListener() = default;
|
||||
|
||||
/** Called before the document enters an editing state.
|
||||
@param document The document about to enter an editing state.
|
||||
*/
|
||||
virtual void willBeginEditing (ARADocument* document);
|
||||
|
||||
/** Called after the document exits an editing state.
|
||||
@param document The document about exit an editing state.
|
||||
*/
|
||||
virtual void didEndEditing (ARADocument* document);
|
||||
|
||||
/** Called before sending model updates do the host.
|
||||
@param document The document whose model updates are about to be sent.
|
||||
*/
|
||||
virtual void willNotifyModelUpdates (ARADocument* document);
|
||||
|
||||
/** Called after sending model updates do the host.
|
||||
@param document The document whose model updates have just been sent.
|
||||
*/
|
||||
virtual void didNotifyModelUpdates (ARADocument* document);
|
||||
|
||||
/** Called before the document's properties are updated.
|
||||
@param document The document whose properties will be updated.
|
||||
@param newProperties The document properties that will be assigned to \p document.
|
||||
*/
|
||||
virtual void willUpdateDocumentProperties (ARADocument* document,
|
||||
ARA::PlugIn::PropertiesPtr<ARA::ARADocumentProperties> newProperties);
|
||||
|
||||
/** Called after the document's properties are updated.
|
||||
@param document The document whose properties were updated.
|
||||
*/
|
||||
virtual void didUpdateDocumentProperties (ARADocument* document);
|
||||
|
||||
/** Called after a musical context is added to the document.
|
||||
@param document The document that \p musicalContext was added to.
|
||||
@param musicalContext The musical context that was added to \p document.
|
||||
*/
|
||||
virtual void didAddMusicalContextToDocument (ARADocument* document, ARAMusicalContext* musicalContext);
|
||||
|
||||
/** Called before a musical context is removed from the document.
|
||||
@param document The document that \p musicalContext will be removed from.
|
||||
@param musicalContext The musical context that will be removed from \p document.
|
||||
*/
|
||||
virtual void willRemoveMusicalContextFromDocument (ARADocument* document, ARAMusicalContext* musicalContext);
|
||||
|
||||
/** Called after the musical contexts are reordered in an ARA document
|
||||
|
||||
Musical contexts are sorted by their order index -
|
||||
this callback signals a change in this ordering within the document.
|
||||
|
||||
@param document The document with reordered musical contexts.
|
||||
*/
|
||||
virtual void didReorderMusicalContextsInDocument (ARADocument* document);
|
||||
|
||||
/** Called after a region sequence is added to the document.
|
||||
@param document The document that \p regionSequence was added to.
|
||||
@param regionSequence The region sequence that was added to \p document.
|
||||
*/
|
||||
virtual void didAddRegionSequenceToDocument (ARADocument* document, ARARegionSequence* regionSequence);
|
||||
|
||||
/** Called before a region sequence is removed from the document.
|
||||
@param document The document that \p regionSequence will be removed from.
|
||||
@param regionSequence The region sequence that will be removed from \p document.
|
||||
*/
|
||||
virtual void willRemoveRegionSequenceFromDocument (ARADocument* document, ARARegionSequence* regionSequence);
|
||||
|
||||
/** Called after the region sequences are reordered in an ARA document
|
||||
|
||||
Region sequences are sorted by their order index -
|
||||
this callback signals a change in this ordering within the document.
|
||||
|
||||
@param document The document with reordered region sequences.
|
||||
*/
|
||||
virtual void didReorderRegionSequencesInDocument (ARADocument* document);
|
||||
|
||||
/** Called after an audio source is added to the document.
|
||||
@param document The document that \p audioSource was added to.
|
||||
@param audioSource The audio source that was added to \p document.
|
||||
*/
|
||||
virtual void didAddAudioSourceToDocument (ARADocument* document, ARAAudioSource* audioSource);
|
||||
|
||||
/** Called before an audio source is removed from the document.
|
||||
@param document The document that \p audioSource will be removed from .
|
||||
@param audioSource The audio source that will be removed from \p document.
|
||||
*/
|
||||
virtual void willRemoveAudioSourceFromDocument (ARADocument* document, ARAAudioSource* audioSource);
|
||||
|
||||
/** Called before the document is destroyed by the ARA host.
|
||||
@param document The document that will be destroyed.
|
||||
*/
|
||||
virtual void willDestroyDocument (ARADocument* document);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class representing an ARA document.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARADocument : public ARA::PlugIn::Document,
|
||||
public ARAListenableModelClass<ARADocumentListener>,
|
||||
public ARAObject
|
||||
{
|
||||
public:
|
||||
using PropertiesPtr = ARA::PlugIn::PropertiesPtr<ARA::ARADocumentProperties>;
|
||||
using Listener = ARADocumentListener;
|
||||
|
||||
using ARA::PlugIn::Document::Document;
|
||||
|
||||
/** Returns the result of ARA::PlugIn::Document::getAudioSources() with the pointers within
|
||||
cast to ARAAudioSource*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateAudioSource(), then
|
||||
you can use the template parameter to cast the pointers to your subclass of ARAAudioSource.
|
||||
*/
|
||||
template <typename AudioSource_t = ARAAudioSource>
|
||||
const std::vector<AudioSource_t*>& getAudioSources() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::Document::getAudioSources<AudioSource_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::Document::getMusicalContexts() with the pointers within
|
||||
cast to ARAMusicalContext*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateMusicalContext(), then
|
||||
you can use the template parameter to cast the pointers to your subclass of ARAMusicalContext.
|
||||
*/
|
||||
template <typename MusicalContext_t = ARAMusicalContext>
|
||||
const std::vector<MusicalContext_t*>& getMusicalContexts() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::Document::getMusicalContexts<MusicalContext_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::Document::getRegionSequences() with the pointers within
|
||||
cast to ARARegionSequence*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateRegionSequence(), then
|
||||
you can use the template parameter to cast the pointers to your subclass of ARARegionSequence.
|
||||
*/
|
||||
template <typename RegionSequence_t = ARARegionSequence>
|
||||
const std::vector<RegionSequence_t*>& getRegionSequences() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::Document::getRegionSequences<RegionSequence_t>();
|
||||
}
|
||||
|
||||
size_t getNumChildren() const noexcept override;
|
||||
|
||||
ARAObject* getChild (size_t index) override;
|
||||
|
||||
ARAObject* getParent() override { return nullptr; }
|
||||
|
||||
void visit (ARAObjectVisitor& visitor) override { visitor.visitDocument (*this); }
|
||||
};
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARAMusicalContext object.
|
||||
|
||||
Use ARAMusicalContext::addListener() to register your listener with an ARAMusicalContext.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAMusicalContextListener
|
||||
{
|
||||
public:
|
||||
virtual ~ARAMusicalContextListener() = default;
|
||||
|
||||
/** Called before the musical context's properties are updated.
|
||||
@param musicalContext The musical context whose properties will be updated.
|
||||
@param newProperties The musical context properties that will be assigned to \p musicalContext.
|
||||
*/
|
||||
virtual void willUpdateMusicalContextProperties (ARAMusicalContext* musicalContext,
|
||||
ARA::PlugIn::PropertiesPtr<ARA::ARAMusicalContextProperties> newProperties);
|
||||
|
||||
/** Called after the musical context's properties are updated by the host.
|
||||
@param musicalContext The musical context whose properties were updated.
|
||||
*/
|
||||
virtual void didUpdateMusicalContextProperties (ARAMusicalContext* musicalContext);
|
||||
|
||||
/** Called when the musical context's content (i.e tempo entries or chords) changes.
|
||||
@param musicalContext The musical context with updated content.
|
||||
@param scopeFlags The scope of the content update indicating what has changed.
|
||||
*/
|
||||
virtual void doUpdateMusicalContextContent (ARAMusicalContext* musicalContext, ARAContentUpdateScopes scopeFlags);
|
||||
|
||||
/** Called after a region sequence is added to the musical context.
|
||||
@param musicalContext The musical context that \p regionSequence was added to.
|
||||
@param regionSequence The region sequence that was added to \p musicalContext.
|
||||
*/
|
||||
virtual void didAddRegionSequenceToMusicalContext (ARAMusicalContext* musicalContext, ARARegionSequence* regionSequence);
|
||||
|
||||
/** Called before a region sequence is removed from the musical context.
|
||||
@param musicalContext The musical context that \p regionSequence will be removed from.
|
||||
@param regionSequence The region sequence that will be removed from \p musicalContext.
|
||||
*/
|
||||
virtual void willRemoveRegionSequenceFromMusicalContext (ARAMusicalContext* musicalContext,
|
||||
ARARegionSequence* regionSequence);
|
||||
|
||||
/** Called after the region sequences are reordered in an ARA MusicalContext
|
||||
|
||||
Region sequences are sorted by their order index -
|
||||
this callback signals a change in this ordering within the musical context.
|
||||
|
||||
@param musicalContext The musical context with reordered region sequences.
|
||||
*/
|
||||
virtual void didReorderRegionSequencesInMusicalContext (ARAMusicalContext* musicalContext);
|
||||
|
||||
/** Called before the musical context is destroyed.
|
||||
@param musicalContext The musical context that will be destroyed.
|
||||
*/
|
||||
virtual void willDestroyMusicalContext (ARAMusicalContext* musicalContext);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class representing an ARA musical context.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAMusicalContext : public ARA::PlugIn::MusicalContext,
|
||||
public ARAListenableModelClass<ARAMusicalContextListener>,
|
||||
public ARAObject
|
||||
{
|
||||
public:
|
||||
using PropertiesPtr = ARA::PlugIn::PropertiesPtr<ARA::ARAMusicalContextProperties>;
|
||||
using Listener = ARAMusicalContextListener;
|
||||
|
||||
using ARA::PlugIn::MusicalContext::MusicalContext;
|
||||
|
||||
/** Returns the result of ARA::PlugIn::MusicalContext::getDocument() with the pointer cast
|
||||
to ARADocument*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateDocument(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARADocument.
|
||||
*/
|
||||
template <typename Document_t = ARADocument>
|
||||
Document_t* getDocument() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::MusicalContext::getDocument<Document_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::MusicalContext::getRegionSequences() with the pointers
|
||||
within cast to ARARegionSequence*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateRegionSequence(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARARegionSequence.
|
||||
*/
|
||||
template <typename RegionSequence_t = ARARegionSequence>
|
||||
const std::vector<RegionSequence_t*>& getRegionSequences() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::MusicalContext::getRegionSequences<RegionSequence_t>();
|
||||
}
|
||||
|
||||
size_t getNumChildren() const noexcept override { return 0; }
|
||||
|
||||
ARAObject* getChild (size_t) override { return nullptr; }
|
||||
|
||||
ARAObject* getParent() override { return getDocument(); }
|
||||
|
||||
void visit (ARAObjectVisitor& visitor) override { visitor.visitMusicalContext (*this); }
|
||||
};
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARAPlaybackRegion object.
|
||||
|
||||
Use ARAPlaybackRegion::addListener() to register your listener with an ARAPlaybackRegion.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAPlaybackRegionListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~ARAPlaybackRegionListener() = default;
|
||||
|
||||
/** Called before the playback region's properties are updated.
|
||||
@param playbackRegion The playback region whose properties will be updated.
|
||||
@param newProperties The playback region properties that will be assigned to \p playbackRegion.
|
||||
*/
|
||||
virtual void willUpdatePlaybackRegionProperties (ARAPlaybackRegion* playbackRegion,
|
||||
ARA::PlugIn::PropertiesPtr<ARA::ARAPlaybackRegionProperties> newProperties);
|
||||
|
||||
/** Called after the playback region's properties are updated.
|
||||
@param playbackRegion The playback region whose properties were updated.
|
||||
*/
|
||||
virtual void didUpdatePlaybackRegionProperties (ARAPlaybackRegion* playbackRegion);
|
||||
|
||||
/** Called when the playback region's content (i.e. samples or notes) changes.
|
||||
@param playbackRegion The playback region with updated content.
|
||||
@param scopeFlags The scope of the content update.
|
||||
*/
|
||||
virtual void didUpdatePlaybackRegionContent (ARAPlaybackRegion* playbackRegion,
|
||||
ARAContentUpdateScopes scopeFlags);
|
||||
|
||||
/** Called before the playback region is destroyed.
|
||||
@param playbackRegion The playback region that will be destroyed.
|
||||
*/
|
||||
virtual void willDestroyPlaybackRegion (ARAPlaybackRegion* playbackRegion);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class representing an ARA playback region.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAPlaybackRegion : public ARA::PlugIn::PlaybackRegion,
|
||||
public ARAListenableModelClass<ARAPlaybackRegionListener>,
|
||||
public ARAObject
|
||||
{
|
||||
public:
|
||||
using PropertiesPtr = ARA::PlugIn::PropertiesPtr<ARA::ARAPlaybackRegionProperties>;
|
||||
using Listener = ARAPlaybackRegionListener;
|
||||
|
||||
using ARA::PlugIn::PlaybackRegion::PlaybackRegion;
|
||||
|
||||
/** Returns the result of ARA::PlugIn::PlaybackRegion::getAudioModification() with the pointer cast
|
||||
to ARAAudioModification*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateAudioModification(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARAAudioModification.
|
||||
*/
|
||||
template <typename AudioModification_t = ARAAudioModification>
|
||||
AudioModification_t* getAudioModification() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlaybackRegion::getAudioModification<AudioModification_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::PlaybackRegion::getRegionSequence() with the pointer cast
|
||||
to ARARegionSequence*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateRegionSequence(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARARegionSequence.
|
||||
*/
|
||||
template <typename RegionSequence_t = ARARegionSequence>
|
||||
RegionSequence_t* getRegionSequence() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlaybackRegion::getRegionSequence<RegionSequence_t>();
|
||||
}
|
||||
|
||||
size_t getNumChildren() const noexcept override { return 0; }
|
||||
|
||||
ARAObject* getChild (size_t) override { return nullptr; }
|
||||
|
||||
ARAObject* getParent() override;
|
||||
|
||||
void visit (ARAObjectVisitor& visitor) override { visitor.visitPlaybackRegion (*this); }
|
||||
|
||||
/** Used in getTimeRange to indicate whether the head and tail times should be included in the result.
|
||||
*/
|
||||
enum class IncludeHeadAndTail { no, yes };
|
||||
|
||||
/** Returns the playback time range of this playback region.
|
||||
@param includeHeadAndTail Whether or not the range includes the head and tail
|
||||
time of all playback regions in the sequence.
|
||||
*/
|
||||
Range<double> getTimeRange (IncludeHeadAndTail includeHeadAndTail = IncludeHeadAndTail::no) const;
|
||||
|
||||
/** Returns the playback sample range of this playback region.
|
||||
@param sampleRate The rate at which the sample position should be calculated from
|
||||
the time range.
|
||||
@param includeHeadAndTail Whether or not the range includes the head and tail
|
||||
time of all playback regions in the sequence.
|
||||
*/
|
||||
Range<int64> getSampleRange (double sampleRate, IncludeHeadAndTail includeHeadAndTail = IncludeHeadAndTail::no) const;
|
||||
|
||||
/** Get the head length in seconds before the start of the region's playback time. */
|
||||
double getHeadTime() const;
|
||||
|
||||
/** Get the tail length in seconds after the end of the region's playback time. */
|
||||
double getTailTime() const;
|
||||
|
||||
/** Notify the ARA host and any listeners of a content update initiated by the plug-in.
|
||||
This must be called by the plug-in model management code on the message thread whenever updating
|
||||
the internal content representation, such as after the user edited the pitch of a note in the
|
||||
underlying audio modification.
|
||||
Listeners will be notified immediately. If \p notifyARAHost is true, a notification to the host
|
||||
will be enqueued and sent out the next time it polls for updates.
|
||||
|
||||
@param scopeFlags The scope of the content update.
|
||||
@param notifyARAHost If true, the ARA host will be notified of the content change.
|
||||
*/
|
||||
void notifyContentChanged (ARAContentUpdateScopes scopeFlags, bool notifyARAHost);
|
||||
};
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARARegionSequence object.
|
||||
|
||||
Use ARARegionSequence::addListener() to register your listener with an ARARegionSequence.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARARegionSequenceListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~ARARegionSequenceListener() = default;
|
||||
|
||||
/** Called before the region sequence's properties are updated.
|
||||
@param regionSequence The region sequence whose properties will be updated.
|
||||
@param newProperties The region sequence properties that will be assigned to \p regionSequence.
|
||||
*/
|
||||
virtual void willUpdateRegionSequenceProperties (ARARegionSequence* regionSequence,
|
||||
ARA::PlugIn::PropertiesPtr<ARA::ARARegionSequenceProperties> newProperties);
|
||||
|
||||
/** Called after the region sequence's properties are updated.
|
||||
@param regionSequence The region sequence whose properties were updated.
|
||||
*/
|
||||
virtual void didUpdateRegionSequenceProperties (ARARegionSequence* regionSequence);
|
||||
|
||||
/** Called before a playback region is removed from the region sequence.
|
||||
@param regionSequence The region sequence that \p playbackRegion will be removed from.
|
||||
@param playbackRegion The playback region that will be removed from \p regionSequence.
|
||||
*/
|
||||
virtual void willRemovePlaybackRegionFromRegionSequence (ARARegionSequence* regionSequence,
|
||||
ARAPlaybackRegion* playbackRegion);
|
||||
|
||||
/** Called after a playback region is added to the region sequence.
|
||||
@param regionSequence The region sequence that \p playbackRegion was added to.
|
||||
@param playbackRegion The playback region that was added to \p regionSequence.
|
||||
*/
|
||||
virtual void didAddPlaybackRegionToRegionSequence (ARARegionSequence* regionSequence,
|
||||
ARAPlaybackRegion* playbackRegion);
|
||||
|
||||
/** Called before the region sequence is destroyed.
|
||||
@param regionSequence The region sequence that will be destroyed.
|
||||
*/
|
||||
virtual void willDestroyRegionSequence (ARARegionSequence* regionSequence);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class representing an ARA region sequence.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARARegionSequence : public ARA::PlugIn::RegionSequence,
|
||||
public ARAListenableModelClass<ARARegionSequenceListener>,
|
||||
public ARAObject
|
||||
{
|
||||
public:
|
||||
using PropertiesPtr = ARA::PlugIn::PropertiesPtr<ARA::ARARegionSequenceProperties>;
|
||||
using Listener = ARARegionSequenceListener;
|
||||
|
||||
using ARA::PlugIn::RegionSequence::RegionSequence;
|
||||
|
||||
/** Returns the result of ARA::PlugIn::RegionSequence::getDocument() with the pointer cast
|
||||
to ARADocument*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateDocument(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARADocument.
|
||||
*/
|
||||
template <typename Document_t = ARADocument>
|
||||
Document_t* getDocument() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::RegionSequence::getDocument<Document_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::RegionSequence::getMusicalContext() with the pointer cast
|
||||
to ARAMusicalContext*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateMusicalContext(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARAMusicalContext.
|
||||
*/
|
||||
template <typename MusicalContext_t = ARAMusicalContext>
|
||||
MusicalContext_t* getMusicalContext() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::RegionSequence::getMusicalContext<MusicalContext_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::RegionSequence::getPlaybackRegions() with the pointers within cast
|
||||
to ARAPlaybackRegion*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreatePlaybackRegion(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARAPlaybackRegion.
|
||||
*/
|
||||
template <typename PlaybackRegion_t = ARAPlaybackRegion>
|
||||
const std::vector<PlaybackRegion_t*>& getPlaybackRegions() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::RegionSequence::getPlaybackRegions<PlaybackRegion_t>();
|
||||
}
|
||||
|
||||
size_t getNumChildren() const noexcept override;
|
||||
|
||||
ARAObject* getChild (size_t index) override;
|
||||
|
||||
ARAObject* getParent() override { return getDocument(); }
|
||||
|
||||
void visit (ARAObjectVisitor& visitor) override { visitor.visitRegionSequence (*this); }
|
||||
|
||||
/** Returns the playback time range covered by the regions in this sequence.
|
||||
@param includeHeadAndTail Whether or not the range includes the playback region's head and tail time.
|
||||
*/
|
||||
Range<double> getTimeRange (ARAPlaybackRegion::IncludeHeadAndTail includeHeadAndTail = ARAPlaybackRegion::IncludeHeadAndTail::no) const;
|
||||
|
||||
/** If all audio sources used by the playback regions in this region sequence have the same
|
||||
sample rate, this rate is returned here, otherwise 0.0 is returned.
|
||||
|
||||
If the region sequence has no playback regions, this also returns 0.0.
|
||||
*/
|
||||
double getCommonSampleRate() const;
|
||||
};
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARAAudioSource object.
|
||||
|
||||
Use ARAAudioSource::addListener() to register your listener with an ARAAudioSource.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAAudioSourceListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~ARAAudioSourceListener() = default;
|
||||
|
||||
/** Called before the audio source's properties are updated.
|
||||
@param audioSource The audio source whose properties will be updated.
|
||||
@param newProperties The audio source properties that will be assigned to \p audioSource.
|
||||
*/
|
||||
virtual void willUpdateAudioSourceProperties (ARAAudioSource* audioSource,
|
||||
ARA::PlugIn::PropertiesPtr<ARA::ARAAudioSourceProperties> newProperties);
|
||||
|
||||
/** Called after the audio source's properties are updated.
|
||||
@param audioSource The audio source whose properties were updated.
|
||||
*/
|
||||
virtual void didUpdateAudioSourceProperties (ARAAudioSource* audioSource);
|
||||
|
||||
/** Called when the audio source's content (i.e. samples or notes) changes.
|
||||
@param audioSource The audio source with updated content.
|
||||
@param scopeFlags The scope of the content update.
|
||||
*/
|
||||
virtual void doUpdateAudioSourceContent (ARAAudioSource* audioSource, ARAContentUpdateScopes scopeFlags);
|
||||
|
||||
/** Called to notify progress when an audio source is being analyzed.
|
||||
@param audioSource The audio source being analyzed.
|
||||
@param state Indicates start, intermediate update or completion of the analysis.
|
||||
@param progress Progress normalized to the 0..1 range.
|
||||
*/
|
||||
virtual void didUpdateAudioSourceAnalysisProgress (ARAAudioSource* audioSource,
|
||||
ARA::ARAAnalysisProgressState state,
|
||||
float progress);
|
||||
|
||||
/** Called before access to an audio source's samples is enabled or disabled.
|
||||
@param audioSource The audio source whose sample access state will be changed.
|
||||
@param enable A bool indicating whether or not sample access will be enabled or disabled.
|
||||
*/
|
||||
virtual void willEnableAudioSourceSamplesAccess (ARAAudioSource* audioSource,
|
||||
bool enable);
|
||||
|
||||
/** Called after access to an audio source's samples is enabled or disabled.
|
||||
@param audioSource The audio source whose sample access state was changed.
|
||||
@param enable A bool indicating whether or not sample access was enabled or disabled.
|
||||
*/
|
||||
virtual void didEnableAudioSourceSamplesAccess (ARAAudioSource* audioSource,
|
||||
bool enable);
|
||||
|
||||
/** Called before an audio source is activated or deactivated when being removed / added from the host's undo history.
|
||||
@param audioSource The audio source that will be activated or deactivated
|
||||
@param deactivate A bool indicating whether \p audioSource was deactivated or activated.
|
||||
*/
|
||||
virtual void willDeactivateAudioSourceForUndoHistory (ARAAudioSource* audioSource,
|
||||
bool deactivate);
|
||||
|
||||
/** Called after an audio source is activated or deactivated when being removed / added from the host's undo history.
|
||||
@param audioSource The audio source that was activated or deactivated
|
||||
@param deactivate A bool indicating whether \p audioSource was deactivated or activated.
|
||||
*/
|
||||
virtual void didDeactivateAudioSourceForUndoHistory (ARAAudioSource* audioSource,
|
||||
bool deactivate);
|
||||
|
||||
/** Called after an audio modification is added to the audio source.
|
||||
@param audioSource The region sequence that \p audioModification was added to.
|
||||
@param audioModification The playback region that was added to \p audioSource.
|
||||
*/
|
||||
virtual void didAddAudioModificationToAudioSource (ARAAudioSource* audioSource,
|
||||
ARAAudioModification* audioModification);
|
||||
|
||||
/** Called before an audio modification is removed from the audio source.
|
||||
@param audioSource The audio source that \p audioModification will be removed from.
|
||||
@param audioModification The audio modification that will be removed from \p audioSource.
|
||||
*/
|
||||
virtual void willRemoveAudioModificationFromAudioSource (ARAAudioSource* audioSource,
|
||||
ARAAudioModification* audioModification);
|
||||
|
||||
/** Called before the audio source is destroyed.
|
||||
@param audioSource The audio source that will be destroyed.
|
||||
*/
|
||||
virtual void willDestroyAudioSource (ARAAudioSource* audioSource);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class representing an ARA audio source.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAAudioSource : public ARA::PlugIn::AudioSource,
|
||||
public ARAListenableModelClass<ARAAudioSourceListener>,
|
||||
public ARAObject
|
||||
{
|
||||
public:
|
||||
using PropertiesPtr = ARA::PlugIn::PropertiesPtr<ARA::ARAAudioSourceProperties>;
|
||||
using ARAAnalysisProgressState = ARA::ARAAnalysisProgressState;
|
||||
using Listener = ARAAudioSourceListener;
|
||||
|
||||
using ARA::PlugIn::AudioSource::AudioSource;
|
||||
|
||||
/** Returns the result of ARA::PlugIn::AudioSource::getDocument() with the pointer cast
|
||||
to ARADocument*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateDocument(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARADocument.
|
||||
*/
|
||||
template <typename Document_t = ARADocument>
|
||||
Document_t* getDocument() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::AudioSource::getDocument<Document_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::AudioSource::getAudioModifications() with the pointers
|
||||
within cast to ARAAudioModification*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateAudioModification(),
|
||||
then you can use the template parameter to cast the pointers to your subclass of
|
||||
ARAAudioModification.
|
||||
*/
|
||||
template <typename AudioModification_t = ARAAudioModification>
|
||||
const std::vector<AudioModification_t*>& getAudioModifications() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::AudioSource::getAudioModifications<AudioModification_t>();
|
||||
}
|
||||
|
||||
size_t getNumChildren() const noexcept override;
|
||||
|
||||
ARAObject* getChild (size_t index) override;
|
||||
|
||||
ARAObject* getParent() override { return getDocument(); }
|
||||
|
||||
void visit (ARAObjectVisitor& visitor) override { visitor.visitAudioSource (*this); }
|
||||
|
||||
/** Notify the ARA host and any listeners of analysis progress.
|
||||
Contrary to most ARA functions, this call can be made from any thread.
|
||||
The implementation will enqueue these notifications and later post them from the message thread.
|
||||
Calling code must ensure start and completion state are always balanced,
|
||||
and must send updates in ascending order.
|
||||
*/
|
||||
void notifyAnalysisProgressStarted();
|
||||
|
||||
/** \copydoc notifyAnalysisProgressStarted
|
||||
@param progress Progress normalized to the 0..1 range.
|
||||
*/
|
||||
void notifyAnalysisProgressUpdated (float progress);
|
||||
|
||||
/** \copydoc notifyAnalysisProgressStarted
|
||||
*/
|
||||
void notifyAnalysisProgressCompleted();
|
||||
|
||||
/** Notify the ARA host and any listeners of a content update initiated by the plug-in.
|
||||
This must be called by the plug-in model management code on the message thread whenever updating
|
||||
the internal content representation, such as after successfully analyzing a new tempo map.
|
||||
Listeners will be notified immediately. If \p notifyARAHost is true, a notification to the host
|
||||
will be enqueued and sent out the next time it polls for updates.
|
||||
\p notifyARAHost must be false if the update was triggered by the host via doUpdateAudioSourceContent().
|
||||
Furthermore, \p notifyARAHost must be false if the updated content is being restored from an archive.
|
||||
|
||||
@param scopeFlags The scope of the content update.
|
||||
@param notifyARAHost If true, the ARA host will be notified of the content change.
|
||||
*/
|
||||
void notifyContentChanged (ARAContentUpdateScopes scopeFlags, bool notifyARAHost);
|
||||
|
||||
public:
|
||||
friend ARADocumentController;
|
||||
ARA::PlugIn::AnalysisProgressTracker internalAnalysisProgressTracker;
|
||||
};
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARAAudioModification object.
|
||||
|
||||
Use ARAAudioModification::addListener() to register your listener with an ARAAudioModification.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAAudioModificationListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~ARAAudioModificationListener() = default;
|
||||
|
||||
/** Called before the audio modification's properties are updated.
|
||||
@param audioModification The audio modification whose properties will be updated.
|
||||
@param newProperties The audio modification properties that will be assigned to \p audioModification.
|
||||
*/
|
||||
virtual void willUpdateAudioModificationProperties (ARAAudioModification* audioModification,
|
||||
ARA::PlugIn::PropertiesPtr<ARA::ARAAudioModificationProperties> newProperties);
|
||||
|
||||
/** Called after the audio modification's properties are updated.
|
||||
@param audioModification The audio modification whose properties were updated.
|
||||
*/
|
||||
virtual void didUpdateAudioModificationProperties (ARAAudioModification* audioModification);
|
||||
|
||||
/** Called when the audio modification's content (i.e. samples or notes) changes.
|
||||
@param audioModification The audio modification with updated content.
|
||||
@param scopeFlags The scope of the content update.
|
||||
*/
|
||||
virtual void didUpdateAudioModificationContent (ARAAudioModification* audioModification,
|
||||
ARAContentUpdateScopes scopeFlags);
|
||||
|
||||
/** Called before an audio modification is activated or deactivated when being removed / added from the host's undo history.
|
||||
@param audioModification The audio modification that was activated or deactivated
|
||||
@param deactivate A bool indicating whether \p audioModification was deactivated or activated.
|
||||
*/
|
||||
virtual void willDeactivateAudioModificationForUndoHistory (ARAAudioModification* audioModification,
|
||||
bool deactivate);
|
||||
|
||||
/** Called after an audio modification is activated or deactivated when being removed / added from the host's undo history.
|
||||
@param audioModification The audio modification that was activated or deactivated
|
||||
@param deactivate A bool indicating whether \p audioModification was deactivated or activated.
|
||||
*/
|
||||
virtual void didDeactivateAudioModificationForUndoHistory (ARAAudioModification* audioModification,
|
||||
bool deactivate);
|
||||
|
||||
/** Called after a playback region is added to the audio modification.
|
||||
@param audioModification The audio modification that \p playbackRegion was added to.
|
||||
@param playbackRegion The playback region that was added to \p audioModification.
|
||||
*/
|
||||
virtual void didAddPlaybackRegionToAudioModification (ARAAudioModification* audioModification,
|
||||
ARAPlaybackRegion* playbackRegion);
|
||||
|
||||
/** Called before a playback region is removed from the audio modification.
|
||||
@param audioModification The audio modification that \p playbackRegion will be removed from.
|
||||
@param playbackRegion The playback region that will be removed from \p audioModification.
|
||||
*/
|
||||
virtual void willRemovePlaybackRegionFromAudioModification (ARAAudioModification* audioModification,
|
||||
ARAPlaybackRegion* playbackRegion);
|
||||
|
||||
/** Called before the audio modification is destroyed.
|
||||
@param audioModification The audio modification that will be destroyed.
|
||||
*/
|
||||
virtual void willDestroyAudioModification (ARAAudioModification* audioModification);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class representing an ARA audio modification.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAAudioModification : public ARA::PlugIn::AudioModification,
|
||||
public ARAListenableModelClass<ARAAudioModificationListener>,
|
||||
public ARAObject
|
||||
{
|
||||
public:
|
||||
using PropertiesPtr = ARA::PlugIn::PropertiesPtr<ARA::ARAAudioModificationProperties>;
|
||||
using Listener = ARAAudioModificationListener;
|
||||
|
||||
using ARA::PlugIn::AudioModification::AudioModification;
|
||||
|
||||
/** Returns the result of ARA::PlugIn::AudioModification::getAudioSource() with the pointer cast
|
||||
to ARAAudioSource*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateAudioSource(), then you
|
||||
can use the template parameter to cast the pointers to your subclass of ARAAudioSource.
|
||||
*/
|
||||
template <typename AudioSource_t = ARAAudioSource>
|
||||
AudioSource_t* getAudioSource() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::AudioModification::getAudioSource<AudioSource_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::AudioModification::getPlaybackRegions() with the
|
||||
pointers within cast to ARAPlaybackRegion*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreatePlaybackRegion(), then
|
||||
you can use the template parameter to cast the pointers to your subclass of ARAPlaybackRegion.
|
||||
*/
|
||||
template <typename PlaybackRegion_t = ARAPlaybackRegion>
|
||||
const std::vector<PlaybackRegion_t*>& getPlaybackRegions() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::AudioModification::getPlaybackRegions<PlaybackRegion_t>();
|
||||
}
|
||||
|
||||
size_t getNumChildren() const noexcept override;
|
||||
|
||||
ARAObject* getChild (size_t index) override;
|
||||
|
||||
ARAObject* getParent() override { return getAudioSource(); }
|
||||
|
||||
void visit (ARAObjectVisitor& visitor) override { visitor.visitAudioModification (*this); }
|
||||
|
||||
/** Notify the ARA host and any listeners of a content update initiated by the plug-in.
|
||||
This must be called by the plug-in model management code on the message thread whenever updating
|
||||
the internal content representation, such as after the user editing the pitch of a note.
|
||||
Listeners will be notified immediately. If \p notifyARAHost is true, a notification to the host
|
||||
will be enqueued and sent out the next time it polls for updates.
|
||||
\p notifyARAHost must be false if the updated content is being restored from an archive.
|
||||
|
||||
@param scopeFlags The scope of the content update.
|
||||
@param notifyARAHost If true, the ARA host will be notified of the content change.
|
||||
*/
|
||||
void notifyContentChanged (ARAContentUpdateScopes scopeFlags, bool notifyARAHost);
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "juce_ARAPlugInInstanceRoles.h"
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
bool ARARenderer::processBlock ([[maybe_unused]] AudioBuffer<double>& buffer,
|
||||
[[maybe_unused]] AudioProcessor::Realtime realtime,
|
||||
[[maybe_unused]] const AudioPlayHead::PositionInfo& positionInfo) noexcept
|
||||
{
|
||||
// If you hit this assertion then either the caller called the double
|
||||
// precision version of processBlock on a processor which does not support it
|
||||
// (i.e. supportsDoublePrecisionProcessing() returns false), or the implementation
|
||||
// of the ARARenderer forgot to override the double precision version of this method
|
||||
jassertfalse;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ARARenderer::prepareToPlay ([[maybe_unused]] double sampleRate,
|
||||
[[maybe_unused]] int maximumSamplesPerBlock,
|
||||
[[maybe_unused]] int numChannels,
|
||||
[[maybe_unused]] AudioProcessor::ProcessingPrecision precision,
|
||||
[[maybe_unused]] AlwaysNonRealtime alwaysNonRealtime) {}
|
||||
|
||||
//==============================================================================
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
void ARAPlaybackRenderer::addPlaybackRegion (ARA::ARAPlaybackRegionRef playbackRegionRef) noexcept
|
||||
{
|
||||
if (araExtension)
|
||||
ARA_VALIDATE_API_STATE (! araExtension->isPrepared);
|
||||
|
||||
ARA::PlugIn::PlaybackRenderer::addPlaybackRegion (playbackRegionRef);
|
||||
}
|
||||
|
||||
void ARAPlaybackRenderer::removePlaybackRegion (ARA::ARAPlaybackRegionRef playbackRegionRef) noexcept
|
||||
{
|
||||
if (araExtension)
|
||||
ARA_VALIDATE_API_STATE (! araExtension->isPrepared);
|
||||
|
||||
ARA::PlugIn::PlaybackRenderer::removePlaybackRegion (playbackRegionRef);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ARAPlaybackRenderer::processBlock ([[maybe_unused]] AudioBuffer<float>& buffer,
|
||||
[[maybe_unused]] AudioProcessor::Realtime realtime,
|
||||
[[maybe_unused]] const AudioPlayHead::PositionInfo& positionInfo) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool ARAEditorRenderer::processBlock ([[maybe_unused]] AudioBuffer<float>& buffer,
|
||||
[[maybe_unused]] AudioProcessor::Realtime isNonRealtime,
|
||||
[[maybe_unused]] const AudioPlayHead::PositionInfo& positionInfo) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ARAEditorView::doNotifySelection (const ARA::PlugIn::ViewSelection* viewSelection) noexcept
|
||||
{
|
||||
listeners.call ([&] (Listener& l)
|
||||
{
|
||||
l.onNewSelection (*viewSelection);
|
||||
});
|
||||
}
|
||||
|
||||
void ARAEditorView::doNotifyHideRegionSequences (std::vector<ARA::PlugIn::RegionSequence*> const& regionSequences) noexcept
|
||||
{
|
||||
listeners.call ([&] (Listener& l)
|
||||
{
|
||||
l.onHideRegionSequences (ARA::vector_cast<ARARegionSequence*> (regionSequences));
|
||||
});
|
||||
}
|
||||
|
||||
void ARAEditorView::addListener (Listener* l)
|
||||
{
|
||||
listeners.add (l);
|
||||
}
|
||||
|
||||
void ARAEditorView::removeListener (Listener* l)
|
||||
{
|
||||
listeners.remove (l);
|
||||
}
|
||||
|
||||
void ARAEditorView::Listener::onNewSelection ([[maybe_unused]] const ARAViewSelection& viewSelection) {}
|
||||
void ARAEditorView::Listener::onHideRegionSequences ([[maybe_unused]] const std::vector<ARARegionSequence*>& regionSequences) {}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** Base class for a renderer fulfilling either the ARAPlaybackRenderer or the ARAEditorRenderer role.
|
||||
|
||||
Instances of either subclass are constructed by the DocumentController.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARARenderer
|
||||
{
|
||||
public:
|
||||
enum class AlwaysNonRealtime { no, yes };
|
||||
|
||||
virtual ~ARARenderer() = default;
|
||||
|
||||
/** Initialises the renderer for playback.
|
||||
|
||||
@param sampleRate The sample rate that will be used for the data that is sent
|
||||
to the renderer
|
||||
@param maximumSamplesPerBlock The maximum number of samples that will be in the blocks
|
||||
sent to process() method
|
||||
@param numChannels The number of channels that the process() method will be
|
||||
expected to handle
|
||||
@param precision This should be the same as the result of getProcessingPrecision()
|
||||
for the enclosing AudioProcessor
|
||||
@param alwaysNonRealtime yes if this renderer is never used in realtime (e.g. if
|
||||
providing data for views only)
|
||||
*/
|
||||
virtual void prepareToPlay (double sampleRate,
|
||||
int maximumSamplesPerBlock,
|
||||
int numChannels,
|
||||
AudioProcessor::ProcessingPrecision precision,
|
||||
AlwaysNonRealtime alwaysNonRealtime = AlwaysNonRealtime::no);
|
||||
|
||||
/** Frees render resources allocated in prepareToPlay(). */
|
||||
virtual void releaseResources() {}
|
||||
|
||||
/** Resets the internal state variables of the renderer. */
|
||||
virtual void reset() {}
|
||||
|
||||
/** Renders the output into the given buffer. Returns true if rendering executed without error,
|
||||
false otherwise.
|
||||
|
||||
@param buffer The output buffer for the rendering. ARAPlaybackRenderers will
|
||||
replace the sample data, while ARAEditorRenderer will add to it.
|
||||
@param realtime Indicates whether the call is executed under real time constraints.
|
||||
The value of this parameter may change from one call to the next,
|
||||
and if the value is yes, the rendering may fail if the required
|
||||
samples cannot be obtained in time.
|
||||
@param positionInfo Current song position, playback state and playback loop location.
|
||||
There should be no need to access the bpm, timeSig and ppqPosition
|
||||
members in any ARA renderer since ARA provides that information with
|
||||
random access in its model graph.
|
||||
|
||||
Returns false if non-ARA fallback rendering is required and true otherwise.
|
||||
*/
|
||||
virtual bool processBlock (AudioBuffer<float>& buffer,
|
||||
AudioProcessor::Realtime realtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo) noexcept = 0;
|
||||
|
||||
/** Renders the output into the given buffer. Returns true if rendering executed without error,
|
||||
false otherwise.
|
||||
|
||||
@param buffer The output buffer for the rendering. ARAPlaybackRenderers will
|
||||
replace the sample data, while ARAEditorRenderer will add to it.
|
||||
@param realtime Indicates whether the call is executed under real time constraints.
|
||||
The value of this parameter may change from one call to the next,
|
||||
and if the value is yes, the rendering may fail if the required
|
||||
samples cannot be obtained in time.
|
||||
@param positionInfo Current song position, playback state and playback loop location.
|
||||
There should be no need to access the bpm, timeSig and ppqPosition
|
||||
members in any ARA renderer since ARA provides that information with
|
||||
random access in its model graph.
|
||||
|
||||
Returns false if non-ARA fallback rendering is required and true otherwise.
|
||||
*/
|
||||
virtual bool processBlock (AudioBuffer<double>& buffer,
|
||||
AudioProcessor::Realtime realtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo) noexcept;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class for a renderer fulfilling the ARAPlaybackRenderer role as described in the ARA SDK.
|
||||
|
||||
Instances of this class are constructed by the DocumentController. If you are subclassing
|
||||
ARAPlaybackRenderer, make sure to call the base class implementation of any overridden function,
|
||||
except for processBlock.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAPlaybackRenderer : public ARA::PlugIn::PlaybackRenderer,
|
||||
public ARARenderer
|
||||
{
|
||||
public:
|
||||
using ARA::PlugIn::PlaybackRenderer::PlaybackRenderer;
|
||||
|
||||
bool processBlock (AudioBuffer<float>& buffer,
|
||||
AudioProcessor::Realtime realtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo) noexcept override;
|
||||
|
||||
using ARARenderer::processBlock;
|
||||
|
||||
// Shadowing templated getters to default to JUCE versions of the returned classes
|
||||
/** Returns the PlaybackRegions
|
||||
*
|
||||
* @tparam PlaybackRegion_t
|
||||
* @return
|
||||
*/
|
||||
template <typename PlaybackRegion_t = ARAPlaybackRegion>
|
||||
std::vector<PlaybackRegion_t*> const& getPlaybackRegions() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlaybackRenderer::getPlaybackRegions<PlaybackRegion_t>();
|
||||
}
|
||||
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
void addPlaybackRegion (ARA::ARAPlaybackRegionRef playbackRegionRef) noexcept override;
|
||||
void removePlaybackRegion (ARA::ARAPlaybackRegionRef playbackRegionRef) noexcept override;
|
||||
AudioProcessorARAExtension* araExtension {};
|
||||
#endif
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARAPlaybackRenderer)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class for a renderer fulfilling the ARAEditorRenderer role as described in the ARA SDK.
|
||||
|
||||
Instances of this class are constructed by the DocumentController. If you are subclassing
|
||||
ARAEditorRenderer, make sure to call the base class implementation of any overridden function,
|
||||
except for processBlock.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAEditorRenderer : public ARA::PlugIn::EditorRenderer,
|
||||
public ARARenderer
|
||||
{
|
||||
public:
|
||||
using ARA::PlugIn::EditorRenderer::EditorRenderer;
|
||||
|
||||
// Shadowing templated getters to default to JUCE versions of the returned classes
|
||||
template <typename PlaybackRegion_t = ARAPlaybackRegion>
|
||||
std::vector<PlaybackRegion_t*> const& getPlaybackRegions() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::EditorRenderer::getPlaybackRegions<PlaybackRegion_t>();
|
||||
}
|
||||
|
||||
template <typename RegionSequence_t = ARARegionSequence>
|
||||
std::vector<RegionSequence_t*> const& getRegionSequences() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::EditorRenderer::getRegionSequences<RegionSequence_t>();
|
||||
}
|
||||
|
||||
// By default, editor renderers will just let the signal pass through unaltered.
|
||||
// If you're overriding this to implement actual audio preview, remember to check
|
||||
// isNonRealtime of the process context - typically preview is limited to realtime.
|
||||
bool processBlock (AudioBuffer<float>& buffer,
|
||||
AudioProcessor::Realtime isNonRealtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo) noexcept override;
|
||||
|
||||
using ARARenderer::processBlock;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARAEditorRenderer)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class for fulfilling the ARAEditorView role as described in the ARA SDK.
|
||||
|
||||
Instances of this class are constructed by the DocumentController. If you are subclassing
|
||||
ARAEditorView, make sure to call the base class implementation of overridden functions.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API ARAEditorView : public ARA::PlugIn::EditorView
|
||||
{
|
||||
public:
|
||||
using ARA::PlugIn::EditorView::EditorView;
|
||||
|
||||
// Shadowing templated getters to default to JUCE versions of the returned classes
|
||||
template <typename RegionSequence_t = ARARegionSequence>
|
||||
const std::vector<RegionSequence_t*>& getHiddenRegionSequences() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::EditorView::getHiddenRegionSequences<RegionSequence_t>();
|
||||
}
|
||||
|
||||
// Base class implementation must be called if overridden
|
||||
void doNotifySelection (const ARA::PlugIn::ViewSelection* currentSelection) noexcept override;
|
||||
|
||||
// Base class implementation must be called if overridden
|
||||
void doNotifyHideRegionSequences (const std::vector<ARA::PlugIn::RegionSequence*>& regionSequences) noexcept override;
|
||||
|
||||
/** A base class for listeners that want to know about changes to an ARAEditorView object.
|
||||
|
||||
Use ARAEditorView::addListener() to register your listener with an ARAEditorView.
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Called when the editor view's selection changes.
|
||||
@param viewSelection The current selection state
|
||||
*/
|
||||
virtual void onNewSelection (const ARAViewSelection& viewSelection);
|
||||
|
||||
/** Called when region sequences are flagged as hidden in the host UI.
|
||||
@param regionSequences A vector containing all hidden region sequences.
|
||||
*/
|
||||
virtual void onHideRegionSequences (const std::vector<ARARegionSequence*>& regionSequences);
|
||||
};
|
||||
|
||||
/** \copydoc ARAListenableModelClass::addListener */
|
||||
void addListener (Listener* l);
|
||||
|
||||
/** \copydoc ARAListenableModelClass::removeListener */
|
||||
void removeListener (Listener* l);
|
||||
|
||||
private:
|
||||
ListenerList<Listener> listeners;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARAEditorView)
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if (JucePlugin_Enable_ARA || (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU))) && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
|
||||
namespace juce
|
||||
{
|
||||
#if ARA_ENABLE_INTERNAL_ASSERTS
|
||||
JUCE_API void JUCE_CALLTYPE handleARAAssertion (const char* file, const int line, const char* diagnosis) noexcept
|
||||
{
|
||||
#if (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS)
|
||||
DBG (diagnosis);
|
||||
#endif
|
||||
|
||||
logAssertion (file, line);
|
||||
|
||||
#if (JUCE_DEBUG && ! JUCE_DISABLE_ASSERTIONS)
|
||||
if (juce_isRunningUnderDebugger())
|
||||
JUCE_BREAK_IN_DEBUGGER;
|
||||
JUCE_ANALYZER_NORETURN
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
#include "juce_ARADocumentControllerCommon.cpp"
|
||||
#include "juce_ARADocumentController.cpp"
|
||||
#include "juce_ARAModelObjects.cpp"
|
||||
#include "juce_ARAPlugInInstanceRoles.cpp"
|
||||
#include "juce_AudioProcessor_ARAExtensions.cpp"
|
||||
|
||||
ARA_SETUP_DEBUG_MESSAGE_PREFIX (JucePlugin_Name);
|
||||
#endif
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
|
||||
// Include ARA SDK headers
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments",
|
||||
"-Wunused-parameter",
|
||||
"-Wfloat-equal")
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6387)
|
||||
|
||||
#include <ARA_Library/PlugIn/ARAPlug.h>
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
using ARAViewSelection = ARA::PlugIn::ViewSelection;
|
||||
using ARAContentUpdateScopes = ARA::ContentUpdateScopes;
|
||||
using ARARestoreObjectsFilter = ARA::PlugIn::RestoreObjectsFilter;
|
||||
using ARAStoreObjectsFilter = ARA::PlugIn::StoreObjectsFilter;
|
||||
|
||||
/** Converts an ARA::ARAUtf8String to a JUCE String. */
|
||||
inline String convertARAString (ARA::ARAUtf8String str)
|
||||
{
|
||||
return String (CharPointer_UTF8 (str));
|
||||
}
|
||||
|
||||
/** Converts a potentially NULL ARA::ARAUtf8String to a JUCE String.
|
||||
|
||||
Returns the JUCE equivalent of the provided string if it's not nullptr, and the fallback string
|
||||
otherwise.
|
||||
*/
|
||||
inline String convertOptionalARAString (ARA::ARAUtf8String str, const String& fallbackString = String())
|
||||
{
|
||||
return (str != nullptr) ? convertARAString (str) : fallbackString;
|
||||
}
|
||||
|
||||
/** Converts an ARA::ARAColor* to a JUCE Colour. */
|
||||
inline Colour convertARAColour (const ARA::ARAColor* colour)
|
||||
{
|
||||
return Colour::fromFloatRGBA (colour->r, colour->g, colour->b, 1.0f);
|
||||
}
|
||||
|
||||
/** Converts a potentially NULL ARA::ARAColor* to a JUCE Colour.
|
||||
|
||||
Returns the JUCE equivalent of the provided colour if it's not nullptr, and the fallback colour
|
||||
otherwise.
|
||||
*/
|
||||
inline Colour convertOptionalARAColour (const ARA::ARAColor* colour, const Colour& fallbackColour = Colour())
|
||||
{
|
||||
return (colour != nullptr) ? convertARAColour (colour) : fallbackColour;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
||||
#include "juce_ARAModelObjects.h"
|
||||
#include "juce_ARADocumentController.h"
|
||||
#include "juce_AudioProcessor_ARAExtensions.h"
|
||||
#include "juce_ARAPlugInInstanceRoles.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "juce_AudioProcessor_ARAExtensions.h"
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
bool AudioProcessorARAExtension::getTailLengthSecondsForARA (double& tailLength) const
|
||||
{
|
||||
if (! isBoundToARA())
|
||||
return false;
|
||||
|
||||
tailLength = 0.0;
|
||||
|
||||
if (auto playbackRenderer = getPlaybackRenderer())
|
||||
for (const auto& playbackRegion : playbackRenderer->getPlaybackRegions())
|
||||
tailLength = jmax (tailLength, playbackRegion->getTailTime());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioProcessorARAExtension::prepareToPlayForARA (double sampleRate,
|
||||
int samplesPerBlock,
|
||||
int numChannels,
|
||||
AudioProcessor::ProcessingPrecision precision)
|
||||
{
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
isPrepared = true;
|
||||
#endif
|
||||
|
||||
if (! isBoundToARA())
|
||||
return false;
|
||||
|
||||
if (auto playbackRenderer = getPlaybackRenderer())
|
||||
playbackRenderer->prepareToPlay (sampleRate, samplesPerBlock, numChannels, precision);
|
||||
|
||||
if (auto editorRenderer = getEditorRenderer())
|
||||
editorRenderer->prepareToPlay (sampleRate, samplesPerBlock, numChannels, precision);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioProcessorARAExtension::releaseResourcesForARA()
|
||||
{
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
isPrepared = false;
|
||||
#endif
|
||||
|
||||
if (! isBoundToARA())
|
||||
return false;
|
||||
|
||||
if (auto playbackRenderer = getPlaybackRenderer())
|
||||
playbackRenderer->releaseResources();
|
||||
|
||||
if (auto editorRenderer = getEditorRenderer())
|
||||
editorRenderer->releaseResources();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioProcessorARAExtension::processBlockForARA (AudioBuffer<float>& buffer,
|
||||
AudioProcessor::Realtime realtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo)
|
||||
{
|
||||
// validate that the host has prepared us before processing
|
||||
ARA_VALIDATE_API_STATE (isPrepared);
|
||||
|
||||
if (! isBoundToARA())
|
||||
return false;
|
||||
|
||||
// Render our ARA playback regions for this buffer.
|
||||
if (auto playbackRenderer = getPlaybackRenderer())
|
||||
playbackRenderer->processBlock (buffer, realtime, positionInfo);
|
||||
|
||||
// Render our ARA editor regions and sequences for this buffer.
|
||||
// This example does not support editor rendering and thus uses the default implementation,
|
||||
// which is a no-op and could be omitted in actual plug-ins to optimize performance.
|
||||
if (auto editorRenderer = getEditorRenderer())
|
||||
editorRenderer->processBlock (buffer, realtime, positionInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioProcessorARAExtension::processBlockForARA (AudioBuffer<float>& buffer,
|
||||
juce::AudioProcessor::Realtime realtime,
|
||||
AudioPlayHead* playhead)
|
||||
{
|
||||
return processBlockForARA (buffer,
|
||||
realtime,
|
||||
playhead != nullptr ? playhead->getPosition().orFallback (AudioPlayHead::PositionInfo{})
|
||||
: AudioPlayHead::PositionInfo{});
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void AudioProcessorARAExtension::didBindToARA() noexcept
|
||||
{
|
||||
// validate that the ARA binding is not established by the host while prepared to play
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
ARA_VALIDATE_API_STATE (! isPrepared);
|
||||
if (auto playbackRenderer = getPlaybackRenderer())
|
||||
playbackRenderer->araExtension = this;
|
||||
#endif
|
||||
|
||||
#if JUCE_ASSERTIONS_ENABLED_OR_LOGGED
|
||||
// validate proper subclassing of the instance role classes
|
||||
if (auto playbackRenderer = getPlaybackRenderer())
|
||||
jassert (dynamic_cast<ARAPlaybackRenderer*> (playbackRenderer) != nullptr);
|
||||
if (auto editorRenderer = getEditorRenderer())
|
||||
jassert (dynamic_cast<ARAEditorRenderer*> (editorRenderer) != nullptr);
|
||||
if (auto editorView = getEditorView())
|
||||
jassert (dynamic_cast<ARAEditorView*> (editorView) != nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
AudioProcessorEditorARAExtension::AudioProcessorEditorARAExtension (AudioProcessor* audioProcessor)
|
||||
: araProcessorExtension (dynamic_cast<AudioProcessorARAExtension*> (audioProcessor))
|
||||
{
|
||||
if (isARAEditorView())
|
||||
getARAEditorView()->setEditorOpen (true);
|
||||
}
|
||||
|
||||
AudioProcessorEditorARAExtension::~AudioProcessorEditorARAExtension()
|
||||
{
|
||||
if (isARAEditorView())
|
||||
getARAEditorView()->setEditorOpen (false);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class AudioProcessor;
|
||||
class ARAPlaybackRenderer;
|
||||
class ARAEditorRenderer;
|
||||
class ARAEditorView;
|
||||
|
||||
//==============================================================================
|
||||
/** Extension class meant to be subclassed by the plugin's implementation of @see AudioProcessor.
|
||||
|
||||
Subclassing AudioProcessorARAExtension allows access to the three possible plugin instance
|
||||
roles as defined by the ARA SDK. Hosts can assign any subset of roles to each plugin instance.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API AudioProcessorARAExtension : public ARA::PlugIn::PlugInExtension
|
||||
{
|
||||
public:
|
||||
AudioProcessorARAExtension() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the result of ARA::PlugIn::PlugInExtension::getPlaybackRenderer() with the pointer
|
||||
cast to ARAPlaybackRenderer*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreatePlaybackRenderer(),
|
||||
then you can use the template parameter to cast the pointers to your subclass of
|
||||
ARAPlaybackRenderer.
|
||||
*/
|
||||
template <typename PlaybackRenderer_t = ARAPlaybackRenderer>
|
||||
PlaybackRenderer_t* getPlaybackRenderer() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlugInExtension::getPlaybackRenderer<PlaybackRenderer_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::PlugInExtension::getEditorRenderer() with the pointer
|
||||
cast to ARAEditorRenderer*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateEditorRenderer(),
|
||||
then you can use the template parameter to cast the pointers to your subclass of
|
||||
ARAEditorRenderer.
|
||||
*/
|
||||
template <typename EditorRenderer_t = ARAEditorRenderer>
|
||||
EditorRenderer_t* getEditorRenderer() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlugInExtension::getEditorRenderer<EditorRenderer_t>();
|
||||
}
|
||||
|
||||
/** Returns the result of ARA::PlugIn::PlugInExtension::getEditorView() with the pointer
|
||||
cast to ARAEditorView*.
|
||||
|
||||
If you have overridden ARADocumentControllerSpecialisation::doCreateEditorView(),
|
||||
then you can use the template parameter to cast the pointers to your subclass of
|
||||
ARAEditorView.
|
||||
*/
|
||||
template <typename EditorView_t = ARAEditorView>
|
||||
EditorView_t* getEditorView() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlugInExtension::getEditorView<EditorView_t>();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if plugin instance fulfills the ARAPlaybackRenderer role. */
|
||||
bool isPlaybackRenderer() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlugInExtension::getPlaybackRenderer() != nullptr;
|
||||
}
|
||||
|
||||
/** Returns true if plugin instance fulfills the ARAEditorRenderer role. */
|
||||
bool isEditorRenderer() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlugInExtension::getEditorRenderer() != nullptr;
|
||||
}
|
||||
|
||||
/** Returns true if plugin instance fulfills the ARAEditorView role. */
|
||||
bool isEditorView() const noexcept
|
||||
{
|
||||
return ARA::PlugIn::PlugInExtension::getEditorView() != nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if ARA_VALIDATE_API_CALLS
|
||||
bool isPrepared { false };
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** Implementation helper for AudioProcessor::getTailLengthSeconds().
|
||||
|
||||
If bound to ARA, this traverses the instance roles to retrieve the respective tail time
|
||||
and returns true. Otherwise returns false and leaves tailLength unmodified.
|
||||
*/
|
||||
bool getTailLengthSecondsForARA (double& tailLength) const;
|
||||
|
||||
/** Implementation helper for AudioProcessor::prepareToPlay().
|
||||
|
||||
If bound to ARA, this traverses the instance roles to prepare them for play and returns
|
||||
true. Otherwise returns false and does nothing.
|
||||
*/
|
||||
bool prepareToPlayForARA (double sampleRate,
|
||||
int samplesPerBlock,
|
||||
int numChannels,
|
||||
AudioProcessor::ProcessingPrecision precision);
|
||||
|
||||
/** Implementation helper for AudioProcessor::releaseResources().
|
||||
|
||||
If bound to ARA, this traverses the instance roles to let them release resources and returns
|
||||
true. Otherwise returns false and does nothing.
|
||||
*/
|
||||
bool releaseResourcesForARA();
|
||||
|
||||
/** Implementation helper for AudioProcessor::processBlock().
|
||||
|
||||
If bound to ARA, this traverses the instance roles to let them process the block and returns
|
||||
true. Otherwise returns false and does nothing.
|
||||
|
||||
Use this overload if your rendering code already has a current positionInfo available.
|
||||
*/
|
||||
bool processBlockForARA (AudioBuffer<float>& buffer,
|
||||
AudioProcessor::Realtime realtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo);
|
||||
|
||||
/** Implementation helper for AudioProcessor::processBlock().
|
||||
|
||||
If bound to ARA, this traverses the instance roles to let them process the block and returns
|
||||
true. Otherwise returns false and does nothing.
|
||||
|
||||
Use this overload if your rendering code does not have a current positionInfo available.
|
||||
*/
|
||||
bool processBlockForARA (AudioBuffer<float>& buffer, AudioProcessor::Realtime isNonRealtime, AudioPlayHead* playhead);
|
||||
|
||||
//==============================================================================
|
||||
/** Optional hook for derived classes to perform any additional initialization that may be needed.
|
||||
|
||||
If overriding this, make sure you call the base class implementation from your override.
|
||||
*/
|
||||
void didBindToARA() noexcept override;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorARAExtension)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Extension class meant to be subclassed by the plugin's implementation of @see AudioProcessorEditor.
|
||||
|
||||
Subclassing AudioProcessorARAExtension allows access to the ARAEditorView instance role as
|
||||
described by the ARA SDK.
|
||||
|
||||
@tags{ARA}
|
||||
*/
|
||||
class JUCE_API AudioProcessorEditorARAExtension
|
||||
{
|
||||
public:
|
||||
/** Constructor. */
|
||||
explicit AudioProcessorEditorARAExtension (AudioProcessor* audioProcessor);
|
||||
|
||||
/** \copydoc AudioProcessorARAExtension::getEditorView */
|
||||
template <typename EditorView_t = ARAEditorView>
|
||||
EditorView_t* getARAEditorView() const noexcept
|
||||
{
|
||||
return (this->araProcessorExtension != nullptr) ? this->araProcessorExtension->getEditorView<EditorView_t>()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
/** \copydoc AudioProcessorARAExtension::isEditorView */
|
||||
bool isARAEditorView() const noexcept { return getARAEditorView() != nullptr; }
|
||||
|
||||
protected:
|
||||
/** Destructor. */
|
||||
~AudioProcessorEditorARAExtension();
|
||||
|
||||
private:
|
||||
AudioProcessorARAExtension* araProcessorExtension;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorEditorARAExtension)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,308 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class AAXPluginId
|
||||
{
|
||||
public:
|
||||
static std::optional<AAXPluginId> create (std::array<char, 4> letters)
|
||||
{
|
||||
std::array<size_t, 4> indices{};
|
||||
|
||||
for (size_t i = 0; i < letters.size(); ++i)
|
||||
{
|
||||
if (const auto index = findIndexOfChar (letters[i]))
|
||||
indices[i] = *index;
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return AAXPluginId { std::move (indices) };
|
||||
}
|
||||
|
||||
std::optional<AAXPluginId> withIncrementedLetter (size_t index, size_t increment) const
|
||||
{
|
||||
if (indices.size() <= index)
|
||||
return std::nullopt;
|
||||
|
||||
auto copy = *this;
|
||||
copy.indices[index] += increment;
|
||||
|
||||
if ((size_t) std::size (validChars) <= copy.indices[index])
|
||||
return std::nullopt;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
int32 getPluginId() const
|
||||
{
|
||||
int32 result = 0;
|
||||
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
result |= static_cast<int32> (validChars[indices[i]]) << (8 * (indices.size() - 1 - i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::optional<size_t> findIndexOfChar (char c)
|
||||
{
|
||||
const auto ptr = std::find (std::begin (validChars), std::end (validChars), c);
|
||||
return ptr != std::end (validChars) ? std::make_optional (std::distance (std::begin (validChars), ptr))
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
static inline constexpr char validChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
explicit AAXPluginId (std::array<size_t, 4> indicesIn)
|
||||
: indices (std::move (indicesIn))
|
||||
{}
|
||||
|
||||
std::array<size_t, 4> indices;
|
||||
};
|
||||
|
||||
static const AudioChannelSet channelSets[] { AudioChannelSet::disabled(),
|
||||
AudioChannelSet::mono(),
|
||||
AudioChannelSet::stereo(),
|
||||
AudioChannelSet::createLCR(),
|
||||
AudioChannelSet::createLCRS(),
|
||||
AudioChannelSet::quadraphonic(),
|
||||
AudioChannelSet::create5point0(),
|
||||
AudioChannelSet::create5point1(),
|
||||
AudioChannelSet::create6point0(),
|
||||
AudioChannelSet::create6point1(),
|
||||
AudioChannelSet::create7point0(),
|
||||
AudioChannelSet::create7point1(),
|
||||
AudioChannelSet::create7point0SDDS(),
|
||||
AudioChannelSet::create7point1SDDS(),
|
||||
AudioChannelSet::create7point0point2(),
|
||||
AudioChannelSet::create7point1point2(),
|
||||
AudioChannelSet::ambisonic (1),
|
||||
AudioChannelSet::ambisonic (2),
|
||||
AudioChannelSet::ambisonic (3),
|
||||
AudioChannelSet::create5point0point2(),
|
||||
AudioChannelSet::create5point1point2(),
|
||||
AudioChannelSet::create5point0point4(),
|
||||
AudioChannelSet::create5point1point4(),
|
||||
AudioChannelSet::create7point0point4(),
|
||||
AudioChannelSet::create7point1point4(),
|
||||
AudioChannelSet::create7point0point6(),
|
||||
AudioChannelSet::create7point1point6(),
|
||||
AudioChannelSet::create9point0point4(),
|
||||
AudioChannelSet::create9point1point4(),
|
||||
AudioChannelSet::create9point0point6(),
|
||||
AudioChannelSet::create9point1point6(),
|
||||
AudioChannelSet::ambisonic (4),
|
||||
AudioChannelSet::ambisonic (5),
|
||||
AudioChannelSet::ambisonic (6),
|
||||
AudioChannelSet::ambisonic (7) };
|
||||
|
||||
int32 AAXClientExtensions::getPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout,
|
||||
const AudioChannelSet& mainOutputLayout,
|
||||
bool idForAudioSuite) const
|
||||
{
|
||||
auto pluginId = [&]
|
||||
{
|
||||
auto opt = idForAudioSuite ? AAXPluginId::create ({ 'j', 'y', 'a', 'a' })
|
||||
: AAXPluginId::create ({ 'j', 'c', 'a', 'a' });
|
||||
jassert (opt.has_value());
|
||||
return *opt;
|
||||
}();
|
||||
|
||||
for (const auto& [channelSet, indexToModify] : { std::tuple (&mainInputLayout, (size_t) 2),
|
||||
std::tuple (&mainOutputLayout, (size_t) 3) })
|
||||
{
|
||||
const auto increment = (size_t) std::distance (std::begin (channelSets),
|
||||
std::find (std::begin (channelSets),
|
||||
std::end (channelSets),
|
||||
*channelSet));
|
||||
|
||||
if (auto modifiedPluginIdOpt = pluginId.withIncrementedLetter (indexToModify, increment);
|
||||
increment < (size_t) std::size (channelSets) && modifiedPluginIdOpt.has_value())
|
||||
{
|
||||
pluginId = *modifiedPluginIdOpt;
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
return pluginId.getPluginId();
|
||||
}
|
||||
|
||||
String AAXClientExtensions::getPageFileName() const
|
||||
{
|
||||
#ifdef JucePlugin_AAXPageTableFile
|
||||
JUCE_COMPILER_WARNING ("JucePlugin_AAXPageTableFile is deprecated, instead implement AAXClientExtensions::getPageFileName()")
|
||||
return JucePlugin_AAXPageTableFile;
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
static std::array<char, 4> toCharArray (int32 identifier)
|
||||
{
|
||||
std::array<char, 4> result;
|
||||
|
||||
for (size_t i = 0; i < result.size(); ++i)
|
||||
result[i] = static_cast<char> ((identifier >> (i * 8)) & 0xff);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool isValidAAXPluginId (int32 pluginId)
|
||||
{
|
||||
const auto chars = toCharArray (pluginId);
|
||||
|
||||
return std::all_of (std::begin (chars),
|
||||
std::end (chars),
|
||||
[] (const auto& c)
|
||||
{
|
||||
return AAXPluginId::findIndexOfChar (c).has_value();
|
||||
});
|
||||
}
|
||||
|
||||
static int32 getPluginIDForMainBusConfigJuce705 (const AudioChannelSet& mainInputLayout,
|
||||
const AudioChannelSet& mainOutputLayout,
|
||||
bool idForAudioSuite)
|
||||
{
|
||||
int uniqueFormatId = 0;
|
||||
|
||||
for (int dir = 0; dir < 2; ++dir)
|
||||
{
|
||||
const bool isInput = (dir == 0);
|
||||
auto& set = (isInput ? mainInputLayout : mainOutputLayout);
|
||||
int aaxFormatIndex = 0;
|
||||
|
||||
const AudioChannelSet sets[]
|
||||
{
|
||||
AudioChannelSet::disabled(),
|
||||
AudioChannelSet::mono(),
|
||||
AudioChannelSet::stereo(),
|
||||
AudioChannelSet::createLCR(),
|
||||
AudioChannelSet::createLCRS(),
|
||||
AudioChannelSet::quadraphonic(),
|
||||
AudioChannelSet::create5point0(),
|
||||
AudioChannelSet::create5point1(),
|
||||
AudioChannelSet::create6point0(),
|
||||
AudioChannelSet::create6point1(),
|
||||
AudioChannelSet::create7point0(),
|
||||
AudioChannelSet::create7point1(),
|
||||
AudioChannelSet::create7point0SDDS(),
|
||||
AudioChannelSet::create7point1SDDS(),
|
||||
AudioChannelSet::create7point0point2(),
|
||||
AudioChannelSet::create7point1point2(),
|
||||
AudioChannelSet::ambisonic (1),
|
||||
AudioChannelSet::ambisonic (2),
|
||||
AudioChannelSet::ambisonic (3),
|
||||
AudioChannelSet::create5point0point2(),
|
||||
AudioChannelSet::create5point1point2(),
|
||||
AudioChannelSet::create5point0point4(),
|
||||
AudioChannelSet::create5point1point4(),
|
||||
AudioChannelSet::create7point0point4(),
|
||||
AudioChannelSet::create7point1point4(),
|
||||
AudioChannelSet::create7point0point6(),
|
||||
AudioChannelSet::create7point1point6(),
|
||||
AudioChannelSet::create9point0point4(),
|
||||
AudioChannelSet::create9point1point4(),
|
||||
AudioChannelSet::create9point0point6(),
|
||||
AudioChannelSet::create9point1point6(),
|
||||
AudioChannelSet::ambisonic (4),
|
||||
AudioChannelSet::ambisonic (5),
|
||||
AudioChannelSet::ambisonic (6),
|
||||
AudioChannelSet::ambisonic (7)
|
||||
};
|
||||
|
||||
const auto index = (int) std::distance (std::begin (sets), std::find (std::begin (sets), std::end (sets), set));
|
||||
|
||||
if (index != (int) std::size (sets))
|
||||
aaxFormatIndex = index;
|
||||
else
|
||||
jassertfalse;
|
||||
|
||||
uniqueFormatId = (uniqueFormatId << 8) | aaxFormatIndex;
|
||||
}
|
||||
|
||||
return (idForAudioSuite ? 0x6a796161 /* 'jyaa' */ : 0x6a636161 /* 'jcaa' */) + uniqueFormatId;
|
||||
}
|
||||
|
||||
class AAXClientExtensionsTests final : public UnitTest
|
||||
{
|
||||
public:
|
||||
AAXClientExtensionsTests()
|
||||
: UnitTest ("AAXClientExtensionsTests", UnitTestCategories::audioProcessors)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
AAXClientExtensions extensions;
|
||||
|
||||
beginTest ("Previously valid PluginIds should be unchanged");
|
||||
{
|
||||
for (const auto& input : channelSets)
|
||||
for (const auto& output : channelSets)
|
||||
for (const auto idForAudioSuite : { false, true })
|
||||
if (const auto oldId = getPluginIDForMainBusConfigJuce705 (input, output, idForAudioSuite); isValidAAXPluginId (oldId))
|
||||
expect (extensions.getPluginIDForMainBusConfig (input, output, idForAudioSuite) == oldId);
|
||||
}
|
||||
|
||||
beginTest ("Valid, unique PluginIds should be generated for all configurations");
|
||||
{
|
||||
std::set<int32> pluginIds;
|
||||
|
||||
for (const auto& input : channelSets)
|
||||
for (const auto& output : channelSets)
|
||||
for (const auto idForAudioSuite : { false, true })
|
||||
pluginIds.insert (extensions.getPluginIDForMainBusConfig (input, output, idForAudioSuite));
|
||||
|
||||
for (auto identifier : pluginIds)
|
||||
expect (isValidAAXPluginId (identifier));
|
||||
|
||||
expect (pluginIds.size() == square (std::size (channelSets)) * 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static AAXClientExtensionsTests aaxClientExtensionsTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
An interface to allow an AudioProcessor to implement extended AAX-specific functionality.
|
||||
|
||||
To use this class, create an object that inherits from it, implement the methods, then return
|
||||
a pointer to the object in your AudioProcessor `getAAXClientExtensions()` method.
|
||||
|
||||
@see AudioProcessor, VST2ClientExtensions, VST3ClientExtensions
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct JUCE_API AAXClientExtensions
|
||||
{
|
||||
virtual ~AAXClientExtensions() = default;
|
||||
|
||||
/** AAX plug-ins need to report a unique "plug-in id" for every audio layout
|
||||
configuration that your AudioProcessor supports on the main bus. Override this
|
||||
function if you want your AudioProcessor to use a custom "plug-in id" (for example
|
||||
to stay backward compatible with older versions of JUCE).
|
||||
|
||||
The default implementation will compute a unique integer from the input and output
|
||||
layout and add this value to the 4 character code 'jcaa' (for native AAX) or 'jyaa'
|
||||
(for AudioSuite plug-ins).
|
||||
*/
|
||||
virtual int32 getPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout,
|
||||
const AudioChannelSet& mainOutputLayout,
|
||||
bool idForAudioSuite) const;
|
||||
|
||||
/** Returns an optional filename (including extension) for a page file to be used.
|
||||
|
||||
A page file allows an AAX plugin to specify how its parameters are displayed on
|
||||
various control surfaces. For more information read the Page Table Guide in the
|
||||
AAX SDK documentation.
|
||||
|
||||
By default this file will be searched for in `*.aaxplugin/Contents/Resources`.
|
||||
|
||||
@see getPageFileSearchPath
|
||||
*/
|
||||
virtual String getPageFileName() const;
|
||||
|
||||
/** Optionally returns a search path for finding a page table file.
|
||||
|
||||
This can be useful for specifying a location outside the plugin bundle so users can
|
||||
make changes to a page table file without breaking any code signatures.
|
||||
|
||||
If this function returns a default-constructed File, then a default location will be used.
|
||||
The AAX SDK states this location will be `*.aaxplugin/Contents/Resources`.
|
||||
|
||||
@note The returned path should be an absolute path to a directory.
|
||||
|
||||
@see getPageFileName
|
||||
*/
|
||||
virtual File getPageFileSearchPath() const { return {}; }
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterBool::AudioParameterBool (const ParameterID& idToUse,
|
||||
const String& nameToUse,
|
||||
bool def,
|
||||
const AudioParameterBoolAttributes& attributes)
|
||||
: RangedAudioParameter (idToUse, nameToUse, attributes.getAudioProcessorParameterWithIDAttributes()),
|
||||
value (def ? 1.0f : 0.0f),
|
||||
valueDefault (def),
|
||||
stringFromBoolFunction (attributes.getStringFromValueFunction() != nullptr
|
||||
? attributes.getStringFromValueFunction()
|
||||
: [] (bool v, int) { return v ? TRANS ("On") : TRANS ("Off"); }),
|
||||
boolFromStringFunction (attributes.getValueFromStringFunction() != nullptr
|
||||
? attributes.getValueFromStringFunction()
|
||||
: [] (const String& text)
|
||||
{
|
||||
static const StringArray onStrings { TRANS ("on"), TRANS ("yes"), TRANS ("true") };
|
||||
static const StringArray offStrings { TRANS ("off"), TRANS ("no"), TRANS ("false") };
|
||||
|
||||
String lowercaseText (text.toLowerCase());
|
||||
|
||||
for (auto& testText : onStrings)
|
||||
if (lowercaseText == testText)
|
||||
return true;
|
||||
|
||||
for (auto& testText : offStrings)
|
||||
if (lowercaseText == testText)
|
||||
return false;
|
||||
|
||||
return text.getIntValue() != 0;
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
AudioParameterBool::~AudioParameterBool()
|
||||
{
|
||||
#if __cpp_lib_atomic_is_always_lock_free
|
||||
static_assert (std::atomic<float>::is_always_lock_free,
|
||||
"AudioParameterBool requires a lock-free std::atomic<float>");
|
||||
#endif
|
||||
}
|
||||
|
||||
float AudioParameterBool::getValue() const { return value; }
|
||||
void AudioParameterBool::setValue (float newValue) { value = newValue; valueChanged (get()); }
|
||||
float AudioParameterBool::getDefaultValue() const { return valueDefault; }
|
||||
int AudioParameterBool::getNumSteps() const { return 2; }
|
||||
bool AudioParameterBool::isDiscrete() const { return true; }
|
||||
bool AudioParameterBool::isBoolean() const { return true; }
|
||||
void AudioParameterBool::valueChanged (bool) {}
|
||||
|
||||
float AudioParameterBool::getValueForText (const String& text) const
|
||||
{
|
||||
return boolFromStringFunction (text) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
String AudioParameterBool::getText (float v, int maximumLength) const
|
||||
{
|
||||
return stringFromBoolFunction (v >= 0.5f, maximumLength);
|
||||
}
|
||||
|
||||
AudioParameterBool& AudioParameterBool::operator= (bool newValue)
|
||||
{
|
||||
if (get() != newValue)
|
||||
setValueNotifyingHost (newValue ? 1.0f : 0.0f);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterBool.
|
||||
|
||||
@see AudioParameterBool(), RangedAudioParameterAttributes()
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class AudioParameterBoolAttributes : public RangedAudioParameterAttributes<AudioParameterBoolAttributes, bool> {};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Provides a class of AudioProcessorParameter that can be used as a boolean value.
|
||||
|
||||
@see AudioParameterFloat, AudioParameterInt, AudioParameterChoice
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioParameterBool : public RangedAudioParameter
|
||||
{
|
||||
public:
|
||||
/** Creates a AudioParameterBool with the specified parameters.
|
||||
|
||||
Note that the attributes argument is optional and only needs to be
|
||||
supplied if you want to change options from their default values.
|
||||
|
||||
Example usage:
|
||||
@code
|
||||
auto attributes = AudioParameterBoolAttributes().withStringFromValueFunction ([] (auto x, auto) { return x ? "On" : "Off"; })
|
||||
.withLabel ("enabled");
|
||||
auto param = std::make_unique<AudioParameterBool> ("paramID", "Parameter Name", false, attributes);
|
||||
@endcode
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param defaultValue The default value
|
||||
@param attributes Optional characteristics
|
||||
*/
|
||||
AudioParameterBool (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
bool defaultValue,
|
||||
const AudioParameterBoolAttributes& attributes = {});
|
||||
|
||||
/** Creates a AudioParameterBool with the specified parameters.
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param defaultValue The default value
|
||||
@param parameterLabel An optional label for the parameter's value
|
||||
@param stringFromBool An optional lambda function that converts a bool
|
||||
value to a string with a maximum length. This may
|
||||
be used by hosts to display the parameter's value.
|
||||
@param boolFromString An optional lambda function that parses a string and
|
||||
converts it into a bool value. Some hosts use this
|
||||
to allow users to type in parameter values.
|
||||
*/
|
||||
[[deprecated ("Prefer the signature taking an Attributes argument")]]
|
||||
AudioParameterBool (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
bool defaultValue,
|
||||
const String& parameterLabel,
|
||||
std::function<String (bool value, int maximumStringLength)> stringFromBool = nullptr,
|
||||
std::function<bool (const String& text)> boolFromString = nullptr)
|
||||
: AudioParameterBool (parameterID,
|
||||
parameterName,
|
||||
defaultValue,
|
||||
AudioParameterBoolAttributes().withLabel (parameterLabel)
|
||||
.withStringFromValueFunction (std::move (stringFromBool))
|
||||
.withValueFromStringFunction (std::move (boolFromString)))
|
||||
{
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
~AudioParameterBool() override;
|
||||
|
||||
/** Returns the parameter's current boolean value. */
|
||||
bool get() const noexcept { return value >= 0.5f; }
|
||||
|
||||
/** Returns the parameter's current boolean value. */
|
||||
operator bool() const noexcept { return get(); }
|
||||
|
||||
/** Changes the parameter's current value to a new boolean. */
|
||||
AudioParameterBool& operator= (bool newValue);
|
||||
|
||||
/** Returns the range of values that the parameter can take. */
|
||||
const NormalisableRange<float>& getNormalisableRange() const override { return range; }
|
||||
|
||||
protected:
|
||||
/** Override this method if you are interested in receiving callbacks
|
||||
when the parameter value changes.
|
||||
*/
|
||||
virtual void valueChanged (bool newValue);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
float getValue() const override;
|
||||
void setValue (float newValue) override;
|
||||
float getDefaultValue() const override;
|
||||
int getNumSteps() const override;
|
||||
bool isDiscrete() const override;
|
||||
bool isBoolean() const override;
|
||||
String getText (float, int) const override;
|
||||
float getValueForText (const String&) const override;
|
||||
|
||||
const NormalisableRange<float> range { 0.0f, 1.0f, 1.0f };
|
||||
std::atomic<float> value;
|
||||
const float valueDefault;
|
||||
std::function<String (bool, int)> stringFromBoolFunction;
|
||||
std::function<bool (const String&)> boolFromStringFunction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterBool)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterChoice::AudioParameterChoice (const ParameterID& idToUse,
|
||||
const String& nameToUse,
|
||||
const StringArray& c,
|
||||
int def,
|
||||
const AudioParameterChoiceAttributes& attributes)
|
||||
: RangedAudioParameter (idToUse, nameToUse, attributes.getAudioProcessorParameterWithIDAttributes()),
|
||||
choices (c),
|
||||
range ([this]
|
||||
{
|
||||
NormalisableRange<float> rangeWithInterval { 0.0f, (float) choices.size() - 1.0f,
|
||||
[] (float, float end, float v) { return jlimit (0.0f, end, v * end); },
|
||||
[] (float, float end, float v) { return jlimit (0.0f, 1.0f, v / end); },
|
||||
[] (float start, float end, float v) { return (float) roundToInt (juce::jlimit (start, end, v)); } };
|
||||
rangeWithInterval.interval = 1.0f;
|
||||
return rangeWithInterval;
|
||||
}()),
|
||||
value ((float) def),
|
||||
defaultValue (convertTo0to1 ((float) def)),
|
||||
stringFromIndexFunction (attributes.getStringFromValueFunction() != nullptr
|
||||
? attributes.getStringFromValueFunction()
|
||||
: [this] (int index, int) { return choices [index]; }),
|
||||
indexFromStringFunction (attributes.getValueFromStringFunction() != nullptr
|
||||
? attributes.getValueFromStringFunction()
|
||||
: [this] (const String& text) { return choices.indexOf (text); })
|
||||
{
|
||||
jassert (choices.size() > 1); // you must supply an actual set of items to choose from!
|
||||
}
|
||||
|
||||
AudioParameterChoice::~AudioParameterChoice()
|
||||
{
|
||||
#if __cpp_lib_atomic_is_always_lock_free
|
||||
static_assert (std::atomic<float>::is_always_lock_free,
|
||||
"AudioParameterChoice requires a lock-free std::atomic<float>");
|
||||
#endif
|
||||
}
|
||||
|
||||
float AudioParameterChoice::getValue() const { return convertTo0to1 (value); }
|
||||
void AudioParameterChoice::setValue (float newValue) { value = convertFrom0to1 (newValue); valueChanged (getIndex()); }
|
||||
float AudioParameterChoice::getDefaultValue() const { return defaultValue; }
|
||||
int AudioParameterChoice::getNumSteps() const { return choices.size(); }
|
||||
bool AudioParameterChoice::isDiscrete() const { return true; }
|
||||
float AudioParameterChoice::getValueForText (const String& text) const { return convertTo0to1 ((float) indexFromStringFunction (text)); }
|
||||
String AudioParameterChoice::getText (float v, int length) const { return stringFromIndexFunction ((int) convertFrom0to1 (v), length); }
|
||||
void AudioParameterChoice::valueChanged (int) {}
|
||||
|
||||
AudioParameterChoice& AudioParameterChoice::operator= (int newValue)
|
||||
{
|
||||
if (getIndex() != newValue)
|
||||
setValueNotifyingHost (convertTo0to1 ((float) newValue));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
struct AudioParameterChoiceTests final : public UnitTest
|
||||
{
|
||||
AudioParameterChoiceTests()
|
||||
: UnitTest ("AudioParameterChoice", UnitTestCategories::audioProcessorParameters)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("Three options switches at the correct points");
|
||||
{
|
||||
AudioParameterChoice choice ({}, {}, { "a", "b", "c" }, {});
|
||||
|
||||
choice.setValueNotifyingHost (0.0f);
|
||||
expectEquals (choice.getIndex(), 0);
|
||||
|
||||
choice.setValueNotifyingHost (0.2f);
|
||||
expectEquals (choice.getIndex(), 0);
|
||||
|
||||
choice.setValueNotifyingHost (0.3f);
|
||||
expectEquals (choice.getIndex(), 1);
|
||||
|
||||
choice.setValueNotifyingHost (0.7f);
|
||||
expectEquals (choice.getIndex(), 1);
|
||||
|
||||
choice.setValueNotifyingHost (0.8f);
|
||||
expectEquals (choice.getIndex(), 2);
|
||||
|
||||
choice.setValueNotifyingHost (1.0f);
|
||||
expectEquals (choice.getIndex(), 2);
|
||||
}
|
||||
|
||||
beginTest ("Out-of-bounds input");
|
||||
{
|
||||
AudioParameterChoice choiceParam ({}, {}, { "a", "b", "c" }, {});
|
||||
|
||||
choiceParam.setValueNotifyingHost (-0.5f);
|
||||
expectEquals (choiceParam.getIndex(), 0);
|
||||
|
||||
choiceParam.setValueNotifyingHost (1.5f);
|
||||
expectEquals (choiceParam.getIndex(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static AudioParameterChoiceTests audioParameterChoiceTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterChoice.
|
||||
|
||||
@see AudioParameterChoice(), RangedAudioParameterAttributes()
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class AudioParameterChoiceAttributes : public RangedAudioParameterAttributes<AudioParameterChoiceAttributes, int> {};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Provides a class of AudioProcessorParameter that can be used to select
|
||||
an indexed, named choice from a list.
|
||||
|
||||
@see AudioParameterFloat, AudioParameterInt, AudioParameterBool
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioParameterChoice : public RangedAudioParameter
|
||||
{
|
||||
public:
|
||||
/** Creates a AudioParameterChoice with the specified parameters.
|
||||
|
||||
Note that the attributes argument is optional and only needs to be
|
||||
supplied if you want to change options from their default values.
|
||||
|
||||
Example usage:
|
||||
@code
|
||||
auto attributes = AudioParameterChoiceAttributes().withLabel ("selected");
|
||||
auto param = std::make_unique<AudioParameterChoice> ("paramID", "Parameter Name", StringArray { "a", "b", "c" }, 0, attributes);
|
||||
@endcode
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param choices The set of choices to use
|
||||
@param defaultItemIndex The index of the default choice
|
||||
@param attributes Optional characteristics
|
||||
*/
|
||||
AudioParameterChoice (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
const StringArray& choices,
|
||||
int defaultItemIndex,
|
||||
const AudioParameterChoiceAttributes& attributes = {});
|
||||
|
||||
/** Creates a AudioParameterChoice with the specified parameters.
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param choicesToUse The set of choices to use
|
||||
@param defaultItemIndex The index of the default choice
|
||||
@param parameterLabel An optional label for the parameter's value
|
||||
@param stringFromIndex An optional lambda function that converts a choice
|
||||
index to a string with a maximum length. This may
|
||||
be used by hosts to display the parameter's value.
|
||||
@param indexFromString An optional lambda function that parses a string and
|
||||
converts it into a choice index. Some hosts use this
|
||||
to allow users to type in parameter values.
|
||||
*/
|
||||
[[deprecated ("Prefer the signature taking an Attributes argument")]]
|
||||
AudioParameterChoice (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
const StringArray& choicesToUse,
|
||||
int defaultItemIndex,
|
||||
const String& parameterLabel,
|
||||
std::function<String (int index, int maximumStringLength)> stringFromIndex = nullptr,
|
||||
std::function<int (const String& text)> indexFromString = nullptr)
|
||||
: AudioParameterChoice (parameterID,
|
||||
parameterName,
|
||||
choicesToUse,
|
||||
defaultItemIndex,
|
||||
AudioParameterChoiceAttributes().withLabel (parameterLabel)
|
||||
.withStringFromValueFunction (std::move (stringFromIndex))
|
||||
.withValueFromStringFunction (std::move (indexFromString)))
|
||||
{
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
~AudioParameterChoice() override;
|
||||
|
||||
/** Returns the current index of the selected item. */
|
||||
int getIndex() const noexcept { return roundToInt (value.load()); }
|
||||
|
||||
/** Returns the current index of the selected item. */
|
||||
operator int() const noexcept { return getIndex(); }
|
||||
|
||||
/** Returns the name of the currently selected item. */
|
||||
String getCurrentChoiceName() const noexcept { return choices[getIndex()]; }
|
||||
|
||||
/** Returns the name of the currently selected item. */
|
||||
operator String() const noexcept { return getCurrentChoiceName(); }
|
||||
|
||||
/** Changes the selected item to a new index. */
|
||||
AudioParameterChoice& operator= (int newValue);
|
||||
|
||||
/** Returns the range of values that the parameter can take. */
|
||||
const NormalisableRange<float>& getNormalisableRange() const override { return range; }
|
||||
|
||||
/** Provides access to the list of choices that this parameter is working with. */
|
||||
const StringArray choices;
|
||||
|
||||
protected:
|
||||
/** Override this method if you are interested in receiving callbacks
|
||||
when the parameter value changes.
|
||||
*/
|
||||
virtual void valueChanged (int newValue);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
float getValue() const override;
|
||||
void setValue (float newValue) override;
|
||||
float getDefaultValue() const override;
|
||||
int getNumSteps() const override;
|
||||
bool isDiscrete() const override;
|
||||
String getText (float, int) const override;
|
||||
float getValueForText (const String&) const override;
|
||||
|
||||
const NormalisableRange<float> range;
|
||||
std::atomic<float> value;
|
||||
const float defaultValue;
|
||||
std::function<String (int, int)> stringFromIndexFunction;
|
||||
std::function<int (const String&)> indexFromStringFunction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterChoice)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterFloat::AudioParameterFloat (const ParameterID& idToUse,
|
||||
const String& nameToUse,
|
||||
NormalisableRange<float> r,
|
||||
float def,
|
||||
const AudioParameterFloatAttributes& attributes)
|
||||
: RangedAudioParameter (idToUse, nameToUse, attributes.getAudioProcessorParameterWithIDAttributes()),
|
||||
range (r),
|
||||
value (def),
|
||||
valueDefault (def),
|
||||
stringFromValueFunction (attributes.getStringFromValueFunction()),
|
||||
valueFromStringFunction (attributes.getValueFromStringFunction())
|
||||
{
|
||||
if (stringFromValueFunction == nullptr)
|
||||
{
|
||||
auto numDecimalPlacesToDisplay = [this]
|
||||
{
|
||||
int numDecimalPlaces = 7;
|
||||
|
||||
if (! approximatelyEqual (range.interval, 0.0f))
|
||||
{
|
||||
if (approximatelyEqual (std::abs (range.interval - std::floor (range.interval)), 0.0f))
|
||||
return 0;
|
||||
|
||||
auto v = std::abs (roundToInt (range.interval * pow (10, numDecimalPlaces)));
|
||||
|
||||
while ((v % 10) == 0 && numDecimalPlaces > 0)
|
||||
{
|
||||
--numDecimalPlaces;
|
||||
v /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
return numDecimalPlaces;
|
||||
}();
|
||||
|
||||
stringFromValueFunction = [numDecimalPlacesToDisplay] (float v, int length)
|
||||
{
|
||||
String asText (v, numDecimalPlacesToDisplay);
|
||||
return length > 0 ? asText.substring (0, length) : asText;
|
||||
};
|
||||
}
|
||||
|
||||
if (valueFromStringFunction == nullptr)
|
||||
valueFromStringFunction = [] (const String& text) { return text.getFloatValue(); };
|
||||
}
|
||||
|
||||
AudioParameterFloat::AudioParameterFloat (const ParameterID& pid, const String& nm, float minValue, float maxValue, float def)
|
||||
: AudioParameterFloat (pid, nm, { minValue, maxValue, 0.01f }, def)
|
||||
{
|
||||
}
|
||||
|
||||
AudioParameterFloat::~AudioParameterFloat()
|
||||
{
|
||||
#if __cpp_lib_atomic_is_always_lock_free
|
||||
static_assert (std::atomic<float>::is_always_lock_free,
|
||||
"AudioParameterFloat requires a lock-free std::atomic<float>");
|
||||
#endif
|
||||
}
|
||||
|
||||
float AudioParameterFloat::getValue() const { return convertTo0to1 (value); }
|
||||
void AudioParameterFloat::setValue (float newValue) { value = convertFrom0to1 (newValue); valueChanged (get()); }
|
||||
float AudioParameterFloat::getDefaultValue() const { return convertTo0to1 (valueDefault); }
|
||||
int AudioParameterFloat::getNumSteps() const { return AudioProcessorParameterWithID::getNumSteps(); }
|
||||
String AudioParameterFloat::getText (float v, int length) const { return stringFromValueFunction (convertFrom0to1 (v), length); }
|
||||
float AudioParameterFloat::getValueForText (const String& text) const { return convertTo0to1 (valueFromStringFunction (text)); }
|
||||
void AudioParameterFloat::valueChanged (float) {}
|
||||
|
||||
AudioParameterFloat& AudioParameterFloat::operator= (float newValue)
|
||||
{
|
||||
if (! approximatelyEqual ((float) value, newValue))
|
||||
setValueNotifyingHost (convertTo0to1 (newValue));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterFloat.
|
||||
|
||||
@see AudioParameterFloat(), RangedAudioParameterAttributes()
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class AudioParameterFloatAttributes : public RangedAudioParameterAttributes<AudioParameterFloatAttributes, float> {};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A subclass of AudioProcessorParameter that provides an easy way to create a
|
||||
parameter which maps onto a given NormalisableRange.
|
||||
|
||||
@see AudioParameterInt, AudioParameterBool, AudioParameterChoice
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioParameterFloat : public RangedAudioParameter
|
||||
{
|
||||
public:
|
||||
/** Creates a AudioParameterFloat with the specified parameters.
|
||||
|
||||
Note that the attributes argument is optional and only needs to be
|
||||
supplied if you want to change options from their default values.
|
||||
|
||||
Example usage:
|
||||
@code
|
||||
auto attributes = AudioParameterFloatAttributes().withStringFromValueFunction ([] (auto x, auto) { return String (x * 100); })
|
||||
.withLabel ("%");
|
||||
auto param = std::make_unique<AudioParameterFloat> ("paramID", "Parameter Name", NormalisableRange<float>(), 0.5f, attributes);
|
||||
@endcode
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param normalisableRange The NormalisableRange to use
|
||||
@param defaultValue The non-normalised default value
|
||||
@param attributes Optional characteristics
|
||||
*/
|
||||
AudioParameterFloat (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
NormalisableRange<float> normalisableRange,
|
||||
float defaultValue,
|
||||
const AudioParameterFloatAttributes& attributes = {});
|
||||
|
||||
/** Creates a AudioParameterFloat with the specified parameters.
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param normalisableRange The NormalisableRange to use
|
||||
@param defaultValue The non-normalised default value
|
||||
@param parameterLabel An optional label for the parameter's value
|
||||
@param parameterCategory An optional parameter category
|
||||
@param stringFromValue An optional lambda function that converts a non-normalised
|
||||
value to a string with a maximum length. This may
|
||||
be used by hosts to display the parameter's value.
|
||||
@param valueFromString An optional lambda function that parses a string and
|
||||
converts it into a non-normalised value. Some hosts use
|
||||
this to allow users to type in parameter values.
|
||||
*/
|
||||
[[deprecated ("Prefer the signature taking an Attributes argument")]]
|
||||
AudioParameterFloat (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
NormalisableRange<float> normalisableRange,
|
||||
float defaultValue,
|
||||
const String& parameterLabel,
|
||||
Category parameterCategory = AudioProcessorParameter::genericParameter,
|
||||
std::function<String (float value, int maximumStringLength)> stringFromValue = nullptr,
|
||||
std::function<float (const String& text)> valueFromString = nullptr)
|
||||
: AudioParameterFloat (parameterID,
|
||||
parameterName,
|
||||
std::move (normalisableRange),
|
||||
defaultValue,
|
||||
AudioParameterFloatAttributes().withLabel (parameterLabel)
|
||||
.withCategory (parameterCategory)
|
||||
.withStringFromValueFunction (std::move (stringFromValue))
|
||||
.withValueFromStringFunction (std::move (valueFromString)))
|
||||
{
|
||||
}
|
||||
|
||||
/** Creates a AudioParameterFloat with an ID, name, and range.
|
||||
On creation, its value is set to the default value.
|
||||
For control over skew factors, you can use the other
|
||||
constructor and provide a NormalisableRange.
|
||||
*/
|
||||
AudioParameterFloat (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
float minValue,
|
||||
float maxValue,
|
||||
float defaultValue);
|
||||
|
||||
/** Destructor. */
|
||||
~AudioParameterFloat() override;
|
||||
|
||||
/** Returns the parameter's current value. */
|
||||
float get() const noexcept { return value; }
|
||||
|
||||
/** Returns the parameter's current value. */
|
||||
operator float() const noexcept { return value; }
|
||||
|
||||
/** Changes the parameter's current value. */
|
||||
AudioParameterFloat& operator= (float newValue);
|
||||
|
||||
/** Returns the range of values that the parameter can take. */
|
||||
const NormalisableRange<float>& getNormalisableRange() const override { return range; }
|
||||
|
||||
/** Provides access to the parameter's range. */
|
||||
NormalisableRange<float> range;
|
||||
|
||||
protected:
|
||||
/** Override this method if you are interested in receiving callbacks
|
||||
when the parameter value changes.
|
||||
*/
|
||||
virtual void valueChanged (float newValue);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
float getValue() const override;
|
||||
void setValue (float newValue) override;
|
||||
float getDefaultValue() const override;
|
||||
int getNumSteps() const override;
|
||||
String getText (float, int) const override;
|
||||
float getValueForText (const String&) const override;
|
||||
|
||||
std::atomic<float> value;
|
||||
const float valueDefault;
|
||||
std::function<String (float, int)> stringFromValueFunction;
|
||||
std::function<float (const String&)> valueFromStringFunction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterFloat)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterInt::AudioParameterInt (const ParameterID& idToUse, const String& nameToUse,
|
||||
int minValue, int maxValue, int def,
|
||||
const AudioParameterIntAttributes& attributes)
|
||||
: RangedAudioParameter (idToUse, nameToUse, attributes.getAudioProcessorParameterWithIDAttributes()),
|
||||
range ([minValue, maxValue]
|
||||
{
|
||||
NormalisableRange<float> rangeWithInterval { (float) minValue, (float) maxValue,
|
||||
[] (float start, float end, float v) { return jlimit (start, end, v * (end - start) + start); },
|
||||
[] (float start, float end, float v) { return jlimit (0.0f, 1.0f, (v - start) / (end - start)); },
|
||||
[] (float start, float end, float v) { return (float) roundToInt (juce::jlimit (start, end, v)); } };
|
||||
rangeWithInterval.interval = 1.0f;
|
||||
return rangeWithInterval;
|
||||
}()),
|
||||
value ((float) def),
|
||||
defaultValue (convertTo0to1 ((float) def)),
|
||||
stringFromIntFunction (attributes.getStringFromValueFunction() != nullptr
|
||||
? attributes.getStringFromValueFunction()
|
||||
: [] (int v, int) { return String (v); }),
|
||||
intFromStringFunction (attributes.getValueFromStringFunction() != nullptr
|
||||
? attributes.getValueFromStringFunction()
|
||||
: [] (const String& text) { return text.getIntValue(); })
|
||||
{
|
||||
jassert (minValue < maxValue); // must have a non-zero range of values!
|
||||
}
|
||||
|
||||
AudioParameterInt::~AudioParameterInt()
|
||||
{
|
||||
#if __cpp_lib_atomic_is_always_lock_free
|
||||
static_assert (std::atomic<float>::is_always_lock_free,
|
||||
"AudioParameterInt requires a lock-free std::atomic<float>");
|
||||
#endif
|
||||
}
|
||||
|
||||
float AudioParameterInt::getValue() const { return convertTo0to1 (value); }
|
||||
void AudioParameterInt::setValue (float newValue) { value = convertFrom0to1 (newValue); valueChanged (get()); }
|
||||
float AudioParameterInt::getDefaultValue() const { return defaultValue; }
|
||||
int AudioParameterInt::getNumSteps() const { return ((int) getNormalisableRange().getRange().getLength()) + 1; }
|
||||
float AudioParameterInt::getValueForText (const String& text) const { return convertTo0to1 ((float) intFromStringFunction (text)); }
|
||||
String AudioParameterInt::getText (float v, int length) const { return stringFromIntFunction ((int) convertFrom0to1 (v), length); }
|
||||
void AudioParameterInt::valueChanged (int) {}
|
||||
|
||||
AudioParameterInt& AudioParameterInt::operator= (int newValue)
|
||||
{
|
||||
if (get() != newValue)
|
||||
setValueNotifyingHost (convertTo0to1 ((float) newValue));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
//==============================================================================
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
struct AudioParameterIntTests final : public UnitTest
|
||||
{
|
||||
AudioParameterIntTests()
|
||||
: UnitTest ("AudioParameterInt", UnitTestCategories::audioProcessorParameters)
|
||||
{}
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
beginTest ("Three options switches at the correct points");
|
||||
{
|
||||
AudioParameterInt intParam ({}, {}, 1, 3, 1);
|
||||
|
||||
intParam.setValueNotifyingHost (0.0f);
|
||||
expectEquals (intParam.get(), 1);
|
||||
|
||||
intParam.setValueNotifyingHost (0.2f);
|
||||
expectEquals (intParam.get(), 1);
|
||||
|
||||
intParam.setValueNotifyingHost (0.3f);
|
||||
expectEquals (intParam.get(), 2);
|
||||
|
||||
intParam.setValueNotifyingHost (0.7f);
|
||||
expectEquals (intParam.get(), 2);
|
||||
|
||||
intParam.setValueNotifyingHost (0.8f);
|
||||
expectEquals (intParam.get(), 3);
|
||||
|
||||
intParam.setValueNotifyingHost (1.0f);
|
||||
expectEquals (intParam.get(), 3);
|
||||
}
|
||||
|
||||
beginTest ("Out-of-bounds input");
|
||||
{
|
||||
AudioParameterInt intParam ({}, {}, -1, 2, 0);
|
||||
|
||||
intParam.setValueNotifyingHost (-0.5f);
|
||||
expectEquals (intParam.get(), -1);
|
||||
|
||||
intParam.setValueNotifyingHost (1.5f);
|
||||
expectEquals (intParam.get(), 2);
|
||||
|
||||
intParam = -5;
|
||||
expectEquals (intParam.get(), -1);
|
||||
|
||||
intParam = 5;
|
||||
expectEquals (intParam.get(), 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static AudioParameterIntTests audioParameterIntTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterInt.
|
||||
|
||||
@see AudioParameterInt(), RangedAudioParameterAttributes()
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class AudioParameterIntAttributes : public RangedAudioParameterAttributes<AudioParameterIntAttributes, int> {};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Provides a class of AudioProcessorParameter that can be used as an
|
||||
integer value with a given range.
|
||||
|
||||
@see AudioParameterFloat, AudioParameterBool, AudioParameterChoice
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioParameterInt : public RangedAudioParameter
|
||||
{
|
||||
public:
|
||||
/** Creates a AudioParameterInt with the specified parameters.
|
||||
|
||||
Note that the attributes argument is optional and only needs to be
|
||||
supplied if you want to change options from their default values.
|
||||
|
||||
Example usage:
|
||||
@code
|
||||
auto attributes = AudioParameterIntAttributes().withStringFromValueFunction ([] (auto x, auto) { return String (x); })
|
||||
.withLabel ("things");
|
||||
auto param = std::make_unique<AudioParameterInt> ("paramID", "Parameter Name", 0, 100, 50, attributes);
|
||||
@endcode
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param minValue The minimum parameter value
|
||||
@param maxValue The maximum parameter value
|
||||
@param defaultValue The default value
|
||||
@param attributes Optional characteristics
|
||||
*/
|
||||
AudioParameterInt (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
int minValue,
|
||||
int maxValue,
|
||||
int defaultValue,
|
||||
const AudioParameterIntAttributes& attributes = {});
|
||||
|
||||
/** Creates a AudioParameterInt with the specified parameters.
|
||||
|
||||
@param parameterID The parameter ID to use
|
||||
@param parameterName The parameter name to use
|
||||
@param minValue The minimum parameter value
|
||||
@param maxValue The maximum parameter value
|
||||
@param defaultValueIn The default value
|
||||
@param parameterLabel An optional label for the parameter's value
|
||||
@param stringFromInt An optional lambda function that converts an int
|
||||
value to a string with a maximum length. This may
|
||||
be used by hosts to display the parameter's value.
|
||||
@param intFromString An optional lambda function that parses a string
|
||||
and converts it into an int. Some hosts use this
|
||||
to allow users to type in parameter values.
|
||||
*/
|
||||
[[deprecated ("Prefer the signature taking an Attributes argument")]]
|
||||
AudioParameterInt (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
int minValue,
|
||||
int maxValue,
|
||||
int defaultValueIn,
|
||||
const String& parameterLabel,
|
||||
std::function<String (int value, int maximumStringLength)> stringFromInt = nullptr,
|
||||
std::function<int (const String& text)> intFromString = nullptr)
|
||||
: AudioParameterInt (parameterID,
|
||||
parameterName,
|
||||
minValue,
|
||||
maxValue,
|
||||
defaultValueIn,
|
||||
AudioParameterIntAttributes().withLabel (parameterLabel)
|
||||
.withStringFromValueFunction (std::move (stringFromInt))
|
||||
.withValueFromStringFunction (std::move (intFromString)))
|
||||
{
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
~AudioParameterInt() override;
|
||||
|
||||
/** Returns the parameter's current value as an integer. */
|
||||
int get() const noexcept { return roundToInt (value.load()); }
|
||||
|
||||
/** Returns the parameter's current value as an integer. */
|
||||
operator int() const noexcept { return get(); }
|
||||
|
||||
/** Changes the parameter's current value to a new integer.
|
||||
The value passed in will be snapped to the permitted range before being used.
|
||||
*/
|
||||
AudioParameterInt& operator= (int newValue);
|
||||
|
||||
/** Returns the parameter's range. */
|
||||
Range<int> getRange() const noexcept { return { (int) getNormalisableRange().start, (int) getNormalisableRange().end }; }
|
||||
|
||||
/** Returns the range of values that the parameter can take. */
|
||||
const NormalisableRange<float>& getNormalisableRange() const override { return range; }
|
||||
|
||||
protected:
|
||||
/** Override this method if you are interested in receiving callbacks
|
||||
when the parameter value changes.
|
||||
*/
|
||||
virtual void valueChanged (int newValue);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
float getValue() const override;
|
||||
void setValue (float newValue) override;
|
||||
float getDefaultValue() const override;
|
||||
int getNumSteps() const override;
|
||||
String getText (float, int) const override;
|
||||
float getValueForText (const String&) const override;
|
||||
|
||||
const NormalisableRange<float> range;
|
||||
std::atomic<float> value;
|
||||
const float defaultValue;
|
||||
std::function<String (int, int)> stringFromIntFunction;
|
||||
std::function<int (const String&)> intFromStringFunction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterInt)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioProcessorParameterWithID::AudioProcessorParameterWithID (const ParameterID& idToUse,
|
||||
const String& nameToUse,
|
||||
const AudioProcessorParameterWithIDAttributes& attributes)
|
||||
: HostedAudioProcessorParameter (idToUse.getVersionHint()),
|
||||
paramID (idToUse.getParamID()),
|
||||
name (nameToUse),
|
||||
label (attributes.getLabel()),
|
||||
category (attributes.getCategory()),
|
||||
meta (attributes.getMeta()),
|
||||
automatable (attributes.getAutomatable()),
|
||||
inverted (attributes.getInverted())
|
||||
{
|
||||
}
|
||||
|
||||
String AudioProcessorParameterWithID::getName (int maximumStringLength) const { return name.substring (0, maximumStringLength); }
|
||||
String AudioProcessorParameterWithID::getLabel() const { return label; }
|
||||
AudioProcessorParameter::Category AudioProcessorParameterWithID::getCategory() const { return category; }
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
Combines a parameter ID and a version hint.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ParameterID
|
||||
{
|
||||
public:
|
||||
ParameterID() = default;
|
||||
|
||||
/** Constructs an instance.
|
||||
|
||||
Note that this constructor implicitly converts from Strings and string-like types.
|
||||
|
||||
@param identifier A string that uniquely identifies a single parameter
|
||||
@param versionHint Influences parameter ordering in Audio Unit plugins.
|
||||
Used to provide backwards compatibility of Audio Unit plugins in
|
||||
Logic and GarageBand.
|
||||
@see AudioProcessorParameter (int)
|
||||
*/
|
||||
template <typename StringLike, typename = DisableIfSameOrDerived<ParameterID, StringLike>>
|
||||
ParameterID (StringLike&& identifier, int versionHint = 0)
|
||||
: paramID (std::forward<StringLike> (identifier)), version (versionHint) {}
|
||||
|
||||
/** @see AudioProcessorParameterWithID::paramID */
|
||||
auto getParamID() const { return paramID; }
|
||||
|
||||
/** @see AudioProcessorParameter (int) */
|
||||
auto getVersionHint() const { return version; }
|
||||
|
||||
private:
|
||||
String paramID;
|
||||
int version = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
An instance of this class may be passed to the constructor of an AudioProcessorParameterWithID
|
||||
to set optional characteristics of that parameter.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class AudioProcessorParameterWithIDAttributes
|
||||
{
|
||||
using This = AudioProcessorParameterWithIDAttributes;
|
||||
|
||||
public:
|
||||
using Category = AudioProcessorParameter::Category;
|
||||
|
||||
/** An optional label for the parameter's value */
|
||||
[[nodiscard]] auto withLabel (String x) const { return withMember (*this, &This::label, std::move (x)); }
|
||||
|
||||
/** The semantics of this parameter */
|
||||
[[nodiscard]] auto withCategory (Category x) const { return withMember (*this, &This::category, std::move (x)); }
|
||||
|
||||
/** @see AudioProcessorParameter::isMetaParameter() */
|
||||
[[nodiscard]] auto withMeta (bool x) const { return withMember (*this, &This::meta, std::move (x)); }
|
||||
|
||||
/** @see AudioProcessorParameter::isAutomatable() */
|
||||
[[nodiscard]] auto withAutomatable (bool x) const { return withMember (*this, &This::automatable, std::move (x)); }
|
||||
|
||||
/** @see AudioProcessorParameter::isOrientationInverted() */
|
||||
[[nodiscard]] auto withInverted (bool x) const { return withMember (*this, &This::inverted, std::move (x)); }
|
||||
|
||||
/** An optional label for the parameter's value */
|
||||
[[nodiscard]] auto getLabel() const { return label; }
|
||||
|
||||
/** The semantics of this parameter */
|
||||
[[nodiscard]] auto getCategory() const { return category; }
|
||||
|
||||
/** @see AudioProcessorParameter::isMetaParameter() */
|
||||
[[nodiscard]] auto getMeta() const { return meta; }
|
||||
|
||||
/** @see AudioProcessorParameter::isAutomatable() */
|
||||
[[nodiscard]] auto getAutomatable() const { return automatable; }
|
||||
|
||||
/** @see AudioProcessorParameter::isOrientationInverted() */
|
||||
[[nodiscard]] auto getInverted() const { return inverted; }
|
||||
|
||||
private:
|
||||
String label;
|
||||
Category category = AudioProcessorParameter::genericParameter;
|
||||
bool meta = false, automatable = true, inverted = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This abstract base class is used by some AudioProcessorParameter helper classes.
|
||||
|
||||
@see AudioParameterFloat, AudioParameterInt, AudioParameterBool, AudioParameterChoice
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioProcessorParameterWithID : public HostedAudioProcessorParameter
|
||||
{
|
||||
public:
|
||||
/** The creation of this object requires providing a name and ID which will be constant for its lifetime.
|
||||
|
||||
Given that AudioProcessorParameterWithID is abstract, you'll probably call this constructor
|
||||
from a derived class constructor, e.g.
|
||||
@code
|
||||
MyParameterType (String paramID, String name, String label, bool automatable)
|
||||
: AudioProcessorParameterWithID (paramID, name, AudioProcessorParameterWithIDAttributes().withLabel (label)
|
||||
.withAutomatable (automatable))
|
||||
{
|
||||
}
|
||||
@endcode
|
||||
|
||||
@param parameterID Specifies the identifier, and optionally the parameter's version hint.
|
||||
@param parameterName The user-facing parameter name.
|
||||
@param attributes Other parameter properties.
|
||||
*/
|
||||
AudioProcessorParameterWithID (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
const AudioProcessorParameterWithIDAttributes& attributes = {});
|
||||
|
||||
/** The creation of this object requires providing a name and ID which will be
|
||||
constant for its lifetime.
|
||||
|
||||
@param parameterID Used to uniquely identify the parameter
|
||||
@param parameterName The user-facing name of the parameter
|
||||
@param parameterLabel An optional label for the parameter's value
|
||||
@param parameterCategory The semantics of this parameter
|
||||
*/
|
||||
[[deprecated ("Prefer the signature taking an Attributes argument")]]
|
||||
AudioProcessorParameterWithID (const ParameterID& parameterID,
|
||||
const String& parameterName,
|
||||
const String& parameterLabel,
|
||||
Category parameterCategory = AudioProcessorParameter::genericParameter)
|
||||
: AudioProcessorParameterWithID (parameterID,
|
||||
parameterName,
|
||||
AudioProcessorParameterWithIDAttributes().withLabel (parameterLabel)
|
||||
.withCategory (parameterCategory))
|
||||
{
|
||||
}
|
||||
|
||||
/** Provides access to the parameter's ID string. */
|
||||
const String paramID;
|
||||
|
||||
/** Provides access to the parameter's name. */
|
||||
const String name;
|
||||
|
||||
/** Provides access to the parameter's label. */
|
||||
const String label;
|
||||
|
||||
/** Provides access to the parameter's category. */
|
||||
const Category category;
|
||||
|
||||
String getName (int) const override;
|
||||
String getLabel() const override;
|
||||
Category getCategory() const override;
|
||||
|
||||
String getParameterID() const override { return paramID; }
|
||||
bool isMetaParameter() const override { return meta; }
|
||||
bool isAutomatable() const override { return automatable; }
|
||||
bool isOrientationInverted() const override { return inverted; }
|
||||
|
||||
private:
|
||||
bool meta = false, automatable = true, inverted = false;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterWithID)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/** @cond */
|
||||
|
||||
// Forward declarations to avoid leaking implementation details.
|
||||
namespace Steinberg::Vst
|
||||
{
|
||||
class IComponent;
|
||||
} // namespace Steinberg::Vst
|
||||
|
||||
/** @endcond */
|
||||
|
||||
//==============================================================================
|
||||
#if TARGET_OS_IPHONE
|
||||
struct OpaqueAudioComponentInstance;
|
||||
typedef struct OpaqueAudioComponentInstance* AudioComponentInstance;
|
||||
#else
|
||||
struct ComponentInstanceRecord;
|
||||
typedef struct ComponentInstanceRecord* AudioComponentInstance;
|
||||
#endif
|
||||
|
||||
typedef AudioComponentInstance AudioUnit;
|
||||
|
||||
//==============================================================================
|
||||
/* If you are including the VST headers inside a namespace this forward
|
||||
declaration may cause a collision with the contents of `aeffect.h`.
|
||||
|
||||
If that is the case you can avoid the collision by placing a `struct AEffect;`
|
||||
forward declaration inside the namespace and before the inclusion of the VST
|
||||
headers, e.g. @code
|
||||
|
||||
namespace Vst2
|
||||
{
|
||||
struct AEffect;
|
||||
#include <pluginterfaces/vst2.x/aeffect.h>
|
||||
#include <pluginterfaces/vst2.x/aeffectx.h>
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
struct AEffect;
|
||||
|
||||
//==============================================================================
|
||||
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.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct ExtensionsVisitor
|
||||
{
|
||||
/** Indicates that there is no platform specific information available. */
|
||||
struct Unknown {};
|
||||
|
||||
/** Can be used to retrieve information about a VST3 that is wrapped by an AudioProcessor. */
|
||||
struct VST3Client
|
||||
{
|
||||
virtual ~VST3Client() = default;
|
||||
virtual Steinberg::Vst::IComponent* 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 AudioUnit 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 AEffect* getAEffectPtr() const noexcept = 0;
|
||||
};
|
||||
|
||||
/** Can be used to retrieve information about a plugin that provides ARA extensions. */
|
||||
struct ARAClient
|
||||
{
|
||||
virtual ~ARAClient() = default;
|
||||
virtual void createARAFactoryAsync (std::function<void (ARAFactoryWrapper)>) const = 0;
|
||||
};
|
||||
|
||||
ExtensionsVisitor() = default;
|
||||
|
||||
ExtensionsVisitor (const ExtensionsVisitor&) = default;
|
||||
ExtensionsVisitor (ExtensionsVisitor&&) = default;
|
||||
|
||||
ExtensionsVisitor& operator= (const ExtensionsVisitor&) = default;
|
||||
ExtensionsVisitor& operator= (ExtensionsVisitor&&) = default;
|
||||
|
||||
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&) {}
|
||||
|
||||
/** Called with ARA-specific information. */
|
||||
virtual void visitARAClient (const ARAClient&) {}
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/** @cond */
|
||||
namespace juce
|
||||
{
|
||||
|
||||
template <size_t requiredFlagBitsPerItem>
|
||||
class FlagCache
|
||||
{
|
||||
using FlagType = uint32_t;
|
||||
|
||||
public:
|
||||
FlagCache() = default;
|
||||
|
||||
explicit FlagCache (size_t items)
|
||||
: flags (divCeil (items, groupsPerWord))
|
||||
{
|
||||
std::fill (flags.begin(), flags.end(), 0);
|
||||
}
|
||||
|
||||
void set (size_t index, FlagType bits)
|
||||
{
|
||||
const auto flagIndex = index / groupsPerWord;
|
||||
jassert (flagIndex < flags.size());
|
||||
const auto groupIndex = index - (flagIndex * groupsPerWord);
|
||||
flags[flagIndex].fetch_or (moveToGroupPosition (bits, groupIndex), std::memory_order_acq_rel);
|
||||
}
|
||||
|
||||
/* Calls the supplied callback for any entries with non-zero flags, and
|
||||
sets all flags to zero.
|
||||
*/
|
||||
template <typename Callback>
|
||||
void ifSet (Callback&& callback)
|
||||
{
|
||||
for (size_t flagIndex = 0; flagIndex < flags.size(); ++flagIndex)
|
||||
{
|
||||
const auto prevFlags = flags[flagIndex].exchange (0, std::memory_order_acq_rel);
|
||||
|
||||
for (size_t group = 0; group < groupsPerWord; ++group)
|
||||
{
|
||||
const auto masked = moveFromGroupPosition (prevFlags, group);
|
||||
|
||||
if (masked != 0)
|
||||
callback ((flagIndex * groupsPerWord) + group, masked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
std::fill (flags.begin(), flags.end(), 0);
|
||||
}
|
||||
|
||||
private:
|
||||
/* Given the flags for a single item, and a group index, shifts the flags
|
||||
so that they are positioned at the appropriate location for that group
|
||||
index.
|
||||
|
||||
e.g. If the flag type is a uint32_t, and there are 2 flags per item,
|
||||
then each uint32_t will hold flags for 16 items. The flags for item 0
|
||||
are the least significant two bits; the flags for item 15 are the most
|
||||
significant two bits.
|
||||
*/
|
||||
static constexpr FlagType moveToGroupPosition (FlagType ungrouped, size_t groupIndex)
|
||||
{
|
||||
return (ungrouped & groupMask) << (groupIndex * bitsPerFlagGroup);
|
||||
}
|
||||
|
||||
/* Given a set of grouped flags for multiple items, and a group index,
|
||||
extracts the flags set for an item at that group index.
|
||||
|
||||
e.g. If the flag type is a uint32_t, and there are 2 flags per item,
|
||||
then each uint32_t will hold flags for 16 items. Asking for groupIndex
|
||||
0 will return the least significant two bits; asking for groupIndex 15
|
||||
will return the most significant two bits.
|
||||
*/
|
||||
static constexpr FlagType moveFromGroupPosition (FlagType grouped, size_t groupIndex)
|
||||
{
|
||||
return (grouped >> (groupIndex * bitsPerFlagGroup)) & groupMask;
|
||||
}
|
||||
|
||||
static constexpr size_t findNextPowerOfTwoImpl (size_t n, size_t shift)
|
||||
{
|
||||
return shift == 32 ? n : findNextPowerOfTwoImpl (n | (n >> shift), shift * 2);
|
||||
}
|
||||
|
||||
static constexpr size_t findNextPowerOfTwo (size_t value)
|
||||
{
|
||||
return findNextPowerOfTwoImpl (value - 1, 1) + 1;
|
||||
}
|
||||
|
||||
static constexpr size_t divCeil (size_t a, size_t b)
|
||||
{
|
||||
return (a / b) + ((a % b) != 0);
|
||||
}
|
||||
|
||||
static constexpr size_t bitsPerFlagGroup = findNextPowerOfTwo (requiredFlagBitsPerItem);
|
||||
static constexpr size_t groupsPerWord = (8 * sizeof (FlagType)) / bitsPerFlagGroup;
|
||||
static constexpr FlagType groupMask = ((FlagType) 1 << requiredFlagBitsPerItem) - 1;
|
||||
|
||||
std::vector<std::atomic<FlagType>> flags;
|
||||
};
|
||||
|
||||
template <size_t requiredFlagBitsPerItem>
|
||||
class FlaggedFloatCache
|
||||
{
|
||||
public:
|
||||
FlaggedFloatCache() = default;
|
||||
|
||||
explicit FlaggedFloatCache (size_t sizeIn)
|
||||
: values (sizeIn),
|
||||
flags (sizeIn)
|
||||
{
|
||||
std::fill (values.begin(), values.end(), 0.0f);
|
||||
}
|
||||
|
||||
size_t size() const noexcept { return values.size(); }
|
||||
|
||||
float exchangeValue (size_t index, float value)
|
||||
{
|
||||
jassert (index < size());
|
||||
return values[index].exchange (value, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void setBits (size_t index, uint32_t bits) { flags.set (index, bits); }
|
||||
|
||||
void setValueAndBits (size_t index, float value, uint32_t bits)
|
||||
{
|
||||
exchangeValue (index, value);
|
||||
setBits (index, bits);
|
||||
}
|
||||
|
||||
float get (size_t index) const noexcept
|
||||
{
|
||||
jassert (index < size());
|
||||
return values[index].load (std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
/* Calls the supplied callback for any entries which have been modified
|
||||
since the last call to this function.
|
||||
*/
|
||||
template <typename Callback>
|
||||
void ifSet (Callback&& callback)
|
||||
{
|
||||
flags.ifSet ([this, &callback] (size_t groupIndex, uint32_t bits)
|
||||
{
|
||||
callback (groupIndex, values[groupIndex].load (std::memory_order_relaxed), bits);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::atomic<float>> values;
|
||||
FlagCache<requiredFlagBitsPerItem> flags;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/** @endcond */
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
int RangedAudioParameter::getNumSteps() const
|
||||
{
|
||||
const auto& range = getNormalisableRange();
|
||||
|
||||
if (range.interval > 0)
|
||||
return (static_cast<int> ((range.end - range.start) / range.interval) + 1);
|
||||
|
||||
return getDefaultNumParameterSteps();
|
||||
}
|
||||
|
||||
float RangedAudioParameter::convertTo0to1 (float v) const noexcept
|
||||
{
|
||||
const auto& range = getNormalisableRange();
|
||||
return range.convertTo0to1 (range.snapToLegalValue (v));
|
||||
}
|
||||
|
||||
float RangedAudioParameter::convertFrom0to1 (float v) const noexcept
|
||||
{
|
||||
const auto& range = getNormalisableRange();
|
||||
return range.snapToLegalValue (range.convertFrom0to1 (jlimit (0.0f, 1.0f, v)));
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
@internal
|
||||
|
||||
Holds common attributes of audio parameters.
|
||||
|
||||
CRTP is used here because we want the Attributes types for each parameter
|
||||
(Float, Bool, Choice, Int) to be distinct and extensible in the future.
|
||||
i.e. the identifiers AudioParameterFloatAttributes and RangedAudioParameterAttributes<float>
|
||||
should not be interchangable because we might need to add float-specific attributes in
|
||||
the future. Users should not refer directly to RangedAudioParameterAttributes.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
template <typename Derived, typename Value>
|
||||
class RangedAudioParameterAttributes
|
||||
{
|
||||
using This = RangedAudioParameterAttributes;
|
||||
|
||||
public:
|
||||
using Category = AudioProcessorParameter::Category;
|
||||
|
||||
using StringFromValue = std::function<String (Value, int)>;
|
||||
using ValueFromString = std::function<Value (const String&)>;
|
||||
|
||||
/** An optional lambda function that converts a non-normalised value to a string with a maximum length. This may be used by hosts to display the parameter's value. */
|
||||
[[nodiscard]] auto withStringFromValueFunction (StringFromValue x) const { return withMember (asDerived(), &Derived::stringFromValue, std::move (x)); }
|
||||
|
||||
/** An optional lambda function that parses a string and converts it into a non-normalised value. Some hosts use this to allow users to type in parameter values. */
|
||||
[[nodiscard]] auto withValueFromStringFunction (ValueFromString x) const { return withMember (asDerived(), &Derived::valueFromString, std::move (x)); }
|
||||
|
||||
/** See AudioProcessorParameterWithIDAttributes::withLabel() */
|
||||
[[nodiscard]] auto withLabel (String x) const { return withMember (asDerived(), &Derived::attributes, attributes.withLabel (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameterWithIDAttributes::withCategory() */
|
||||
[[nodiscard]] auto withCategory (Category x) const { return withMember (asDerived(), &Derived::attributes, attributes.withCategory (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameter::isMetaParameter() */
|
||||
[[nodiscard]] auto withMeta (bool x) const { return withMember (asDerived(), &Derived::attributes, attributes.withMeta (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameter::isAutomatable() */
|
||||
[[nodiscard]] auto withAutomatable (bool x) const { return withMember (asDerived(), &Derived::attributes, attributes.withAutomatable (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameter::isOrientationInverted() */
|
||||
[[nodiscard]] auto withInverted (bool x) const { return withMember (asDerived(), &Derived::attributes, attributes.withInverted (std::move (x))); }
|
||||
|
||||
/** An optional lambda function that converts a non-normalised value to a string with a maximum length. This may be used by hosts to display the parameter's value. */
|
||||
[[nodiscard]] const auto& getStringFromValueFunction() const { return stringFromValue; }
|
||||
|
||||
/** An optional lambda function that parses a string and converts it into a non-normalised value. Some hosts use this to allow users to type in parameter values. */
|
||||
[[nodiscard]] const auto& getValueFromStringFunction() const { return valueFromString; }
|
||||
|
||||
/** Gets attributes that would also apply to an AudioProcessorParameterWithID */
|
||||
[[nodiscard]] const auto& getAudioProcessorParameterWithIDAttributes() const { return attributes; }
|
||||
|
||||
private:
|
||||
auto& asDerived() const { return *static_cast<const Derived*> (this); }
|
||||
|
||||
AudioProcessorParameterWithIDAttributes attributes;
|
||||
StringFromValue stringFromValue;
|
||||
ValueFromString valueFromString;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This abstract base class is used by some AudioProcessorParameter helper classes.
|
||||
|
||||
@see AudioParameterFloat, AudioParameterInt, AudioParameterBool, AudioParameterChoice
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API RangedAudioParameter : public AudioProcessorParameterWithID
|
||||
{
|
||||
public:
|
||||
using AudioProcessorParameterWithID::AudioProcessorParameterWithID;
|
||||
|
||||
/** Returns the range of values that the parameter can take. */
|
||||
virtual const NormalisableRange<float>& getNormalisableRange() const = 0;
|
||||
|
||||
/** Returns the number of steps for this parameter based on the normalisable range's interval.
|
||||
If you are using lambda functions to define the normalisable range's snapping behaviour
|
||||
then you should override this function so that it returns the number of snapping points.
|
||||
*/
|
||||
int getNumSteps() const override;
|
||||
|
||||
/** Normalises and snaps a value based on the normalisable range. */
|
||||
float convertTo0to1 (float v) const noexcept;
|
||||
|
||||
/** Denormalises and snaps a value based on the normalisable range. */
|
||||
float convertFrom0to1 (float v) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
pointer_sized_int VST2ClientExtensions::handleVstPluginCanDo ([[maybe_unused]] int32 index,
|
||||
[[maybe_unused]] pointer_sized_int value,
|
||||
[[maybe_unused]] void* ptr,
|
||||
[[maybe_unused]] float opt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VST2ClientExtensions::handleVstHostCallbackAvailable ([[maybe_unused]] std::function<VstHostCallbackType>&& callback) {}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
An interface to allow an AudioProcessor to implement extended VST2-specific functionality.
|
||||
|
||||
To use this class, create an object that inherits from it, implement the methods, then return
|
||||
a pointer to the object in your AudioProcessor::getVST2ClientExtensions() method.
|
||||
|
||||
@see AudioProcessor, AAXClientExtensions, VST3ClientExtensions
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct VST2ClientExtensions
|
||||
{
|
||||
virtual ~VST2ClientExtensions() = default;
|
||||
|
||||
/** This is called by the VST plug-in wrapper when it receives unhandled
|
||||
plug-in "can do" calls from the host.
|
||||
*/
|
||||
virtual pointer_sized_int handleVstPluginCanDo (int32 index,
|
||||
pointer_sized_int value,
|
||||
void* ptr,
|
||||
float opt);
|
||||
|
||||
/** This is called by the VST plug-in wrapper when it receives unhandled
|
||||
vendor specific calls from the host.
|
||||
*/
|
||||
virtual pointer_sized_int handleVstManufacturerSpecific (int32 index,
|
||||
pointer_sized_int value,
|
||||
void* ptr,
|
||||
float opt) = 0;
|
||||
|
||||
/** The host callback function type. */
|
||||
using VstHostCallbackType = pointer_sized_int (int32 opcode,
|
||||
int32 index,
|
||||
pointer_sized_int value,
|
||||
void* ptr,
|
||||
float opt);
|
||||
|
||||
/** This is called once by the VST plug-in wrapper after its constructor.
|
||||
You can use the supplied function to query the VST host.
|
||||
*/
|
||||
virtual void handleVstHostCallbackAvailable (std::function<VstHostCallbackType>&& callback);
|
||||
};
|
||||
|
||||
using VSTCallbackHandler [[deprecated ("replace with VST2ClientExtensions")]] = VST2ClientExtensions;
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
std::map<uint32_t, String> VST3ClientExtensions::getCompatibleParameterIds (const VST3Interface::Id&) const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
uint32_t VST3ClientExtensions::convertJuceParameterId (const String& parameterId, bool studioOneCompatible)
|
||||
{
|
||||
auto hash = (uint32_t) (parameterId.hashCode());
|
||||
|
||||
if (studioOneCompatible)
|
||||
hash &= 0x7fffffff;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,273 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/** @cond */
|
||||
|
||||
// Forward declaration to avoid leaking implementation details.
|
||||
namespace Steinberg
|
||||
{
|
||||
class FUnknown;
|
||||
using TUID = char[16];
|
||||
} // namespace Steinberg
|
||||
|
||||
/** @endcond */
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
An interface to allow an AudioProcessor to implement extended VST3-specific functionality.
|
||||
|
||||
To use this class, create an object that inherits from it, implement the methods, then return
|
||||
a pointer to the object in your AudioProcessor::getVST3ClientExtensions() method.
|
||||
|
||||
@see AudioProcessor, AAXClientExtensions, VST2ClientExtensions
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct VST3ClientExtensions
|
||||
{
|
||||
virtual ~VST3ClientExtensions() = default;
|
||||
|
||||
/** This function may be used by implementations of queryInterface()
|
||||
in the VST3's implementation of IEditController to return
|
||||
additional supported interfaces.
|
||||
*/
|
||||
virtual int32_t queryIEditController (const Steinberg::TUID, void** obj)
|
||||
{
|
||||
*obj = nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** This function may be used by implementations of queryInterface()
|
||||
in the VST3's implementation of IAudioProcessor to return
|
||||
additional supported interfaces.
|
||||
*/
|
||||
virtual int32_t queryIAudioProcessor (const Steinberg::TUID, void** obj)
|
||||
{
|
||||
*obj = nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** This may be called by the VST3 wrapper when the host sets an
|
||||
IComponentHandler for the plugin to use.
|
||||
|
||||
You should not make any assumptions about how and when this will be
|
||||
called - this function may not be called at all!
|
||||
*/
|
||||
virtual void setIComponentHandler (Steinberg::FUnknown*) {}
|
||||
|
||||
/** This may be called shortly after the AudioProcessor is constructed
|
||||
with the current IHostApplication.
|
||||
|
||||
You should not make any assumptions about how and when this will be
|
||||
called - this function may not be called at all!
|
||||
*/
|
||||
virtual void setIHostApplication (Steinberg::FUnknown*) {}
|
||||
|
||||
/** This function will be called to check whether the first input bus
|
||||
should be designated as "kMain" or "kAux". Return true if the
|
||||
first bus should be kMain, or false if the bus should be kAux.
|
||||
|
||||
All other input buses will always be designated kAux.
|
||||
*/
|
||||
virtual bool getPluginHasMainInput() const { return true; }
|
||||
|
||||
/** This function should return a map of VST3 parameter IDs and the JUCE
|
||||
parameters they map to.
|
||||
|
||||
This information is used to implement the IRemapParamID interface.
|
||||
Hosts can use this to preserve automation data when a session was saved
|
||||
using a compatible plugin that has different parameter IDs.
|
||||
|
||||
Not all hosts will take this information into account. Therefore,
|
||||
parameter IDs should be maintained between plugin versions. For JUCE
|
||||
plugins migrating from VST2 to VST3 the best method for achieving this
|
||||
is enabling JUCE_FORCE_LEGACY_PARAM_IDS. However, if a plugin has
|
||||
already been released without enabling this flag, this method offers an
|
||||
alternative approach that won't cause any further compatibility issues.
|
||||
|
||||
The key in the map is an integer which may represent a VST3 parameter
|
||||
identifier (Vst::ParamID) or VST2 parameter index.
|
||||
You should include a map entry for every parameter ID in the compatible
|
||||
plugin.
|
||||
For VST2 or JUCE plugins these IDs can be determined in the following ways.
|
||||
- Use the parameter index if any of the following apply:
|
||||
- the InterfaceId argument refers to a compatible VST2 plugin, or
|
||||
- the InterfaceId argument refers to a JUCE VST3 plugin with
|
||||
JUCE_FORCE_LEGACY_PARAM_IDS enabled, or
|
||||
- the InterfaceId argument refers to a JUCE plugin, but the parameter
|
||||
in the compatible plugin doesn't inherit from
|
||||
HostedAudioProcessorParameter (this case is unlikely).
|
||||
- Otherwise, use convertJuceParameterId() for JUCE VST3 plugins where
|
||||
JUCE_FORCE_LEGACY_PARAM_IDS is disabled, and where the compatible
|
||||
parameter derives from HostedAudioProcessorParameter.
|
||||
- For non-JUCE VST3s, use the Vst::ParamIDs exported by the compatible
|
||||
VST3.
|
||||
|
||||
The value in the map is the JUCE parameter ID for the parameter to map
|
||||
to, or an empty string to indicate that there is no parameter to map to.
|
||||
If a parameter doesn't inherit from HostedAudioProcessorParameter its ID
|
||||
will be the parameter index as a string, for example "1". Otherwise,
|
||||
always use the actual parameter ID (even if JUCE_FORCE_LEGACY_PARAM_IDS
|
||||
is enabled).
|
||||
|
||||
In the unlikely event that two plugins share the same plugin ID, and
|
||||
both have a different parameters that share the same parameter ID, it
|
||||
may be possible to determine which version of the plugin is being loaded
|
||||
during setStateInformation(). This method will always be called after
|
||||
setStateInformation(), so that the map with the correct mapping can be
|
||||
provided when queried.
|
||||
|
||||
Below is an example of how you might implement this function for a JUCE
|
||||
VST3 plugin where JUCE_VST3_CAN_REPLACE_VST2 is enabled, but
|
||||
JUCE_FORCE_LEGACY_PARAM_IDS is disabled.
|
||||
|
||||
@code
|
||||
std::map<uint32_t, String> getCompatibleParameterIds (const InterfaceId&) const override
|
||||
{
|
||||
return { { 0, "Frequency" },
|
||||
{ 1, "CutOff" },
|
||||
{ 2, "Gain" },
|
||||
{ 3, "Bypass" } };
|
||||
}
|
||||
@endcode
|
||||
|
||||
@param compatibleClass A plugin identifier, either for the current
|
||||
plugin or one listed in JUCE_VST3_COMPATIBLE_CLASSES.
|
||||
This parameter allows the implementation to
|
||||
return a different parameter map for each
|
||||
compatible class. Use VST3Interface::jucePluginId()
|
||||
and VST3Interface::vst2PluginId() to determine
|
||||
the class IDs used by JUCE plugins. When
|
||||
JUCE_VST3_CAN_REPLACE_VST2 is set, the ID
|
||||
denoting the VST2 version of the plugin will
|
||||
match the ID of the VST3 that replaces it. In
|
||||
this case, assuming there are no collisions
|
||||
between the VST2 parameter indices and the VST3
|
||||
ParamIDs you should only include the VST2
|
||||
mappings in the returned map. In the unlikely
|
||||
event of a collision you should inspect the
|
||||
state that was most recently passed to
|
||||
setStateInformation() to determine whether the
|
||||
host is loading a VST2 state that requires
|
||||
parameter remapping. If you determine that no
|
||||
remapping is necessary, you can indicate this by
|
||||
returning an empty map.
|
||||
|
||||
@returns A map where each key is a VST3 parameter ID in the compatible
|
||||
plugin, and the value is the unique JUCE parameter ID in the
|
||||
current plugin that it should be mapped to.
|
||||
|
||||
@see JUCE_VST3_COMPATIBLE_CLASSES, VST3Interface::jucePluginId, VST3Interface::vst2PluginId, VST3Interface::hexStringToId
|
||||
*/
|
||||
virtual std::map<uint32_t, String> getCompatibleParameterIds (const VST3Interface::Id& compatibleClass) const;
|
||||
|
||||
|
||||
/** Returns the VST3 compatible parameter ID reported for a given JUCE
|
||||
parameter.
|
||||
|
||||
Internally JUCE will use this method to determine the Vst::ParamID for
|
||||
a HostedAudioProcessorParameter, unless JUCE_FORCE_LEGACY_PARAM_IDS is
|
||||
enabled, in which case it will use the parameter index.
|
||||
|
||||
@see getCompatibleParameterIds
|
||||
*/
|
||||
static uint32_t convertJuceParameterId (const String& parameterId,
|
||||
bool studioOneCompatible = true);
|
||||
|
||||
private:
|
||||
/** Instead of overriding this function you should define the preprocessor
|
||||
definition JUCE_VST3_COMPATIBLE_CLASSES as described in the docs.
|
||||
|
||||
@see JUCE_VST3_COMPATIBLE_CLASSES
|
||||
*/
|
||||
virtual std::vector<VST3Interface::Id> getCompatibleClasses() const final
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
#if DOXYGEN
|
||||
/** An optional user defined preprocessor definition for declaring a comma
|
||||
separated list of VST2 and VST3 plugin identifiers that this VST3 plugin
|
||||
can replace in a DAW session.
|
||||
|
||||
The definition of this preprocessor must be defined at the project
|
||||
level, normally in your CMake or Projucer project files.
|
||||
|
||||
This information will be used to implement the IPluginCompatibility
|
||||
interface.
|
||||
|
||||
If JUCE_VST3_CAN_REPLACE_VST2 is enabled, the VST3 plugin will have the
|
||||
same identifier as the VST2 plugin and therefore you don't need to
|
||||
implement this preprocessor definition.
|
||||
|
||||
This preprocessor definition can contain code that depends on any class
|
||||
or function defined as part of the VST3Interface struct but should avoid
|
||||
any other dependencies!
|
||||
|
||||
Each compatible class is a 16-byte array that corresponds to the VST3
|
||||
interface identifier as reported by a plugins IComponent interface.
|
||||
For VST2 or JUCE plugins these identifiers can be determined in the
|
||||
following ways:
|
||||
- Use VST3Interface::vst2PluginId() for any VST2 plugins or JUCE VST3
|
||||
plugin with JUCE_VST3_CAN_REPLACE_VST3 enabled
|
||||
- Use VST3Interface::jucePluginId() for any other JUCE VST3 plugins
|
||||
|
||||
Examples
|
||||
|
||||
@code
|
||||
// Defines a VST2 plugin this VST3 can replace
|
||||
JUCE_VST3_COMPATIBLE_CLASSES=VST3Interface::vst2PluginId ('Plug', "Plugin Name")
|
||||
|
||||
// Defines a VST3 plugin this VST3 can replace
|
||||
JUCE_VST3_COMPATIBLE_CLASSES=VST3Interface::jucePluginId ('Manu', 'Plug')
|
||||
|
||||
// Defines both a VST2 and a VST3 plugin this VST3 can replace
|
||||
JUCE_VST3_COMPATIBLE_CLASSES=VST3Interface::vst2PluginId ('Plug', "Plugin Name"), VST3Interface::jucePluginId ('Manu', 'Plug')
|
||||
|
||||
// Defines a non-JUCE VST3 plugin this VST3 can replace
|
||||
JUCE_VST3_COMPATIBLE_CLASSES=VST3Interface::hexStringToId ("0F1E2D3C4B5A69788796A5B4C3D2E1F0")
|
||||
@endcode
|
||||
|
||||
If the parameter IDs between compatible versions differ
|
||||
VST3ClientExtensions::getCompatibleParameterIds() should also be overridden.
|
||||
|
||||
@see VST3Interface VST3ClientExtensions::getCompatibleParameterIds()
|
||||
*/
|
||||
#define JUCE_VST3_COMPATIBLE_CLASSES
|
||||
#endif // DOXYGEN
|
||||
|
||||
} // namespace juce
|
||||
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE framework.
|
||||
Copyright (c) Raw Material Software Limited
|
||||
|
||||
JUCE is an open source framework subject to commercial or open source
|
||||
licensing.
|
||||
|
||||
By downloading, installing, or using the JUCE framework, or combining the
|
||||
JUCE framework with any other source code, object code, content or any other
|
||||
copyrightable work, you agree to the terms of the JUCE End User Licence
|
||||
Agreement, and all incorporated terms including the JUCE Privacy Policy and
|
||||
the JUCE Website Terms of Service, as applicable, which will bind you. If you
|
||||
do not agree to the terms of these agreements, we will not license the JUCE
|
||||
framework to you, and you must discontinue the installation or download
|
||||
process and cease use of the JUCE framework.
|
||||
|
||||
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
|
||||
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
|
||||
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
|
||||
|
||||
Or:
|
||||
|
||||
You may also use this code under the terms of the AGPLv3:
|
||||
https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
|
||||
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
|
||||
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Useful functions and classes for defining VST3 Interface Ids.
|
||||
|
||||
The classes and functions in this struct are intentionally lightweight,
|
||||
requiring almost no JUCE or Steinberg VST3 SDK dependencies.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct VST3Interface
|
||||
{
|
||||
/** An enum indicating the various VST3 interface types.
|
||||
|
||||
In most cases users shouldn't need to concern themselves with any interfaces
|
||||
other than the component, which is used to report the actual audio effect.
|
||||
*/
|
||||
enum class Type
|
||||
{
|
||||
ara,
|
||||
controller,
|
||||
compatibility,
|
||||
component,
|
||||
processor
|
||||
};
|
||||
|
||||
/** A type storing the byte values for a unique VST3 interface identifier. */
|
||||
using Id = std::array<std::byte, 16>;
|
||||
|
||||
/** Returns a 16-byte array indicating the VST3 interface ID used for a given
|
||||
VST2 plugin.
|
||||
|
||||
Internally JUCE will use this method to assign an ID for the component and
|
||||
controller interfaces when JUCE_VST3_CAN_REPLACE_VST2 is enabled.
|
||||
|
||||
@see jucePluginId, hexStringToId
|
||||
*/
|
||||
static Id vst2PluginId (uint32_t pluginCode,
|
||||
const char* pluginName,
|
||||
Type interfaceType = Type::component)
|
||||
{
|
||||
Id iid{};
|
||||
|
||||
iid[0] = (std::byte) 'V';
|
||||
iid[1] = (std::byte) 'S';
|
||||
iid[2] = (std::byte) std::invoke ([&]
|
||||
{
|
||||
switch (interfaceType)
|
||||
{
|
||||
case Type::controller: return 'E';
|
||||
case Type::component: return 'T';
|
||||
case Type::ara: [[fallthrough]];
|
||||
case Type::compatibility: [[fallthrough]];
|
||||
case Type::processor: break;
|
||||
}
|
||||
|
||||
// A VST2 plugin only has two possible interfaces
|
||||
// - component (the audio effect)
|
||||
// - controller (the editor/UI)
|
||||
jassertfalse;
|
||||
return '\0';
|
||||
});
|
||||
iid[3] = (std::byte) (pluginCode >> 24);
|
||||
iid[4] = (std::byte) (pluginCode >> 16);
|
||||
iid[5] = (std::byte) (pluginCode >> 8);
|
||||
iid[6] = (std::byte) pluginCode;
|
||||
|
||||
for (size_t index = 7; index < iid.size() && *pluginName != 0; ++index)
|
||||
{
|
||||
iid[index] = (std::byte) std::tolower (*pluginName);
|
||||
++pluginName;
|
||||
}
|
||||
|
||||
#if JUCE_WINDOWS
|
||||
std::swap (iid[0], iid[3]);
|
||||
std::swap (iid[1], iid[2]);
|
||||
std::swap (iid[4], iid[5]);
|
||||
std::swap (iid[6], iid[7]);
|
||||
#endif
|
||||
|
||||
return iid;
|
||||
}
|
||||
|
||||
/** Returns a 16-byte array indicating the VST3 interface ID used for a given
|
||||
JUCE VST3 plugin.
|
||||
|
||||
Internally this is what JUCE will use to assign an ID to each VST3 interface,
|
||||
unless JUCE_VST3_CAN_REPLACE_VST2 is enabled.
|
||||
|
||||
@see vst2PluginId, hexStringToId
|
||||
*/
|
||||
static inline Id jucePluginId (uint32_t manufacturerCode,
|
||||
uint32_t pluginCode,
|
||||
Type interfaceType = Type::component)
|
||||
{
|
||||
const auto word0 = std::invoke ([&]() -> uint32_t
|
||||
{
|
||||
switch (interfaceType)
|
||||
{
|
||||
case Type::ara: [[fallthrough]];
|
||||
case Type::controller: [[fallthrough]];
|
||||
case Type::compatibility: [[fallthrough]];
|
||||
case Type::component: return 0xABCDEF01;
|
||||
case Type::processor: return 0x0101ABAB;
|
||||
}
|
||||
|
||||
jassertfalse;
|
||||
return 0;
|
||||
});
|
||||
|
||||
const auto word1 = std::invoke ([&]() -> uint32_t
|
||||
{
|
||||
switch (interfaceType)
|
||||
{
|
||||
case Type::ara: return 0xA1B2C3D4;
|
||||
case Type::controller: return 0x1234ABCD;
|
||||
case Type::compatibility: return 0xC0DEF00D;
|
||||
case Type::component: return 0x9182FAEB;
|
||||
case Type::processor: return 0xABCDEF01;
|
||||
}
|
||||
|
||||
jassertfalse;
|
||||
return 0;
|
||||
});
|
||||
|
||||
constexpr auto getByteFromLSB = [] (uint32_t word, int byteIndex)
|
||||
{
|
||||
jassert (0 <= byteIndex && byteIndex <= 3);
|
||||
return (std::byte) ((word >> (byteIndex * 8)) & 0xff);
|
||||
};
|
||||
|
||||
#if JUCE_WINDOWS
|
||||
constexpr auto isWindows = true;
|
||||
#else
|
||||
constexpr auto isWindows = false;
|
||||
#endif
|
||||
|
||||
return {
|
||||
getByteFromLSB (word0, isWindows ? 0 : 3),
|
||||
getByteFromLSB (word0, isWindows ? 1 : 2),
|
||||
getByteFromLSB (word0, isWindows ? 2 : 1),
|
||||
getByteFromLSB (word0, isWindows ? 3 : 0),
|
||||
|
||||
getByteFromLSB (word1, isWindows ? 2 : 3),
|
||||
getByteFromLSB (word1, isWindows ? 3 : 2),
|
||||
getByteFromLSB (word1, isWindows ? 0 : 1),
|
||||
getByteFromLSB (word1, isWindows ? 1 : 0),
|
||||
|
||||
getByteFromLSB (manufacturerCode, 3),
|
||||
getByteFromLSB (manufacturerCode, 2),
|
||||
getByteFromLSB (manufacturerCode, 1),
|
||||
getByteFromLSB (manufacturerCode, 0),
|
||||
|
||||
getByteFromLSB (pluginCode, 3),
|
||||
getByteFromLSB (pluginCode, 2),
|
||||
getByteFromLSB (pluginCode, 1),
|
||||
getByteFromLSB (pluginCode, 0)
|
||||
};
|
||||
}
|
||||
|
||||
/** Converts a 32-character hex notation string to a VST3 interface ID.
|
||||
|
||||
@see jucePluginId, vst2PluginId
|
||||
*/
|
||||
static inline Id hexStringToId (const char* hex)
|
||||
{
|
||||
jassert (std::strlen (hex) == 32);
|
||||
|
||||
const auto getByteValue = [](const char* str)
|
||||
{
|
||||
const auto getCharacterValue = [](const char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (std::byte) (c - '0');
|
||||
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return (std::byte) (c - 'A' + 10);
|
||||
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return (std::byte) (c - 'a' + 10);
|
||||
|
||||
// Invalid hex character!
|
||||
jassertfalse;
|
||||
return std::byte{};
|
||||
};
|
||||
|
||||
return getCharacterValue (str[0]) << 4
|
||||
| getCharacterValue (str[1]);
|
||||
};
|
||||
|
||||
return { getByteValue (hex),
|
||||
getByteValue (hex + 2),
|
||||
getByteValue (hex + 4),
|
||||
getByteValue (hex + 6),
|
||||
getByteValue (hex + 8),
|
||||
getByteValue (hex + 10),
|
||||
getByteValue (hex + 12),
|
||||
getByteValue (hex + 14),
|
||||
getByteValue (hex + 16),
|
||||
getByteValue (hex + 18),
|
||||
getByteValue (hex + 20),
|
||||
getByteValue (hex + 22),
|
||||
getByteValue (hex + 24),
|
||||
getByteValue (hex + 26),
|
||||
getByteValue (hex + 28),
|
||||
getByteValue (hex + 30) };
|
||||
}
|
||||
|
||||
VST3Interface() = delete;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
Loading…
Add table
Add a link
Reference in a new issue