migrating to the latest JUCE version
This commit is contained in:
67
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADebug.h
vendored
Normal file
67
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADebug.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_core/system/juce_PlatformDefs.h>
|
||||
|
||||
#ifndef JUCE_API
|
||||
#define JUCE_API
|
||||
#endif
|
||||
|
||||
#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
|
971
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp
vendored
Normal file
971
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp
vendored
Normal file
@ -0,0 +1,971 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ARADocumentControllerSpecialisation::ARADocumentControllerImpl : public ARADocumentController,
|
||||
private juce::Timer
|
||||
{
|
||||
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;
|
||||
|
||||
//==============================================================================
|
||||
// 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;
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
//==============================================================================
|
||||
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;
|
||||
|
||||
//==============================================================================
|
||||
// juce::Timer overrides
|
||||
void timerCallback() override;
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
/** @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;
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ARADocumentControllerSpecialisation* specialisation;
|
||||
std::atomic<bool> internalAnalysisProgressIsSynced { true };
|
||||
ScopedJuceInitialiser_GUI libraryInitialiser;
|
||||
int activeAudioSourcesCount = 0;
|
||||
|
||||
//==============================================================================
|
||||
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 (isTimerRunning() && (activeAudioSourcesCount == 0))
|
||||
stopTimer();
|
||||
else if (! isTimerRunning() && (activeAudioSourcesCount > 0))
|
||||
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);
|
||||
}
|
||||
|
||||
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::timerCallback()
|
||||
{
|
||||
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 (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
juce::ignoreUnused (audioSource, type);
|
||||
return false;
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::doGetAudioSourceContentGrade (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
// Overriding doIsAudioSourceContentAvailable() requires overriding
|
||||
// doGetAudioSourceContentGrade() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (audioSource, type);
|
||||
return ARA::kARAContentGradeInitial;
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::doCreateAudioSourceContentReader (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range)
|
||||
{
|
||||
// Overriding doIsAudioSourceContentAvailable() requires overriding
|
||||
// doCreateAudioSourceContentReader() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (audioSource, type, range);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsAudioModificationContentAvailable (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
juce::ignoreUnused (audioModification, type);
|
||||
return false;
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::doGetAudioModificationContentGrade (const ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
// Overriding doIsAudioModificationContentAvailable() requires overriding
|
||||
// doGetAudioModificationContentGrade() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (audioModification, type);
|
||||
return ARA::kARAContentGradeInitial;
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::doCreateAudioModificationContentReader (ARA::PlugIn::AudioModification* audioModification,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range)
|
||||
{
|
||||
// Overriding doIsAudioModificationContentAvailable() requires overriding
|
||||
// doCreateAudioModificationContentReader() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (audioModification, type, range);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsPlaybackRegionContentAvailable (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
juce::ignoreUnused (playbackRegion, type);
|
||||
return false;
|
||||
}
|
||||
|
||||
ARA::ARAContentGrade ARADocumentControllerSpecialisation::doGetPlaybackRegionContentGrade (const ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
// Overriding doIsPlaybackRegionContentAvailable() requires overriding
|
||||
// doGetPlaybackRegionContentGrade() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (playbackRegion, type);
|
||||
return ARA::kARAContentGradeInitial;
|
||||
}
|
||||
|
||||
ARA::PlugIn::ContentReader* ARADocumentControllerSpecialisation::doCreatePlaybackRegionContentReader (ARA::PlugIn::PlaybackRegion* playbackRegion,
|
||||
ARA::ARAContentType type,
|
||||
const ARA::ARAContentTimeRange* range)
|
||||
{
|
||||
// Overriding doIsPlaybackRegionContentAvailable() requires overriding
|
||||
// doCreatePlaybackRegionContentReader() accordingly!
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (playbackRegion, type, range);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ARADocumentControllerSpecialisation::doIsAudioSourceContentAnalysisIncomplete (const ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAContentType type)
|
||||
{
|
||||
juce::ignoreUnused (audioSource, type);
|
||||
return false;
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::doRequestAudioSourceContentAnalysis (ARA::PlugIn::AudioSource* audioSource,
|
||||
std::vector<ARA::ARAContentType> const& contentTypes)
|
||||
{
|
||||
juce::ignoreUnused (audioSource, contentTypes);
|
||||
}
|
||||
|
||||
ARA::ARAInt32 ARADocumentControllerSpecialisation::doGetProcessingAlgorithmsCount() { return 0; }
|
||||
|
||||
const ARA::ARAProcessingAlgorithmProperties*
|
||||
ARADocumentControllerSpecialisation::doGetProcessingAlgorithmProperties (ARA::ARAInt32 algorithmIndex)
|
||||
{
|
||||
juce::ignoreUnused (algorithmIndex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ARA::ARAInt32 ARADocumentControllerSpecialisation::doGetProcessingAlgorithmForAudioSource (const ARA::PlugIn::AudioSource* audioSource)
|
||||
{
|
||||
// doGetProcessingAlgorithmForAudioSource() must be implemented if the supported
|
||||
// algorithm count is greater than zero.
|
||||
if (getDocumentController()->getProcessingAlgorithmsCount() > 0)
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (audioSource);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ARADocumentControllerSpecialisation::doRequestProcessingAlgorithmForAudioSource (ARA::PlugIn::AudioSource* audioSource,
|
||||
ARA::ARAInt32 algorithmIndex)
|
||||
{
|
||||
// doRequestProcessingAlgorithmForAudioSource() must be implemented if the supported
|
||||
// algorithm count is greater than zero.
|
||||
if (getDocumentController()->getProcessingAlgorithmsCount() > 0)
|
||||
jassertfalse;
|
||||
|
||||
juce::ignoreUnused (audioSource, algorithmIndex);
|
||||
}
|
||||
|
||||
} // namespace juce
|
520
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.h
vendored
Normal file
520
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.h
vendored
Normal file
@ -0,0 +1,520 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#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<ARADocumentControllerSpecialisation, SpecialisationType>::value,
|
||||
"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);
|
||||
|
||||
//==============================================================================
|
||||
// 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
|
71
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentControllerCommon.cpp
vendored
Normal file
71
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentControllerCommon.cpp
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
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
|
199
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.cpp
vendored
Normal file
199
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.cpp
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
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 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);
|
||||
}
|
||||
|
||||
} // namespace juce
|
1145
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.h
vendored
Normal file
1145
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
92
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.cpp
vendored
Normal file
92
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.cpp
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "juce_ARAPlugInInstanceRoles.h"
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
bool ARARenderer::processBlock (AudioBuffer<double>& buffer,
|
||||
AudioProcessor::Realtime realtime,
|
||||
const AudioPlayHead::PositionInfo& positionInfo) noexcept
|
||||
{
|
||||
ignoreUnused (buffer, realtime, positionInfo);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#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
|
||||
|
||||
//==============================================================================
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace juce
|
275
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.h
vendored
Normal file
275
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.h
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
ignoreUnused (sampleRate, maximumSamplesPerBlock, numChannels, precision, alwaysNonRealtime);
|
||||
}
|
||||
|
||||
/** 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
|
||||
{
|
||||
ignoreUnused (buffer, realtime, positionInfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
ignoreUnused (buffer, isNonRealtime, positionInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
using ARARenderer::processBlock;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARAEditorRenderer)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class for a renderer 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>
|
||||
std::vector<RegionSequence_t*> const& 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 (std::vector<ARA::PlugIn::RegionSequence*> const& 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;
|
||||
|
||||
ARA_DISABLE_UNREFERENCED_PARAMETER_WARNING_BEGIN
|
||||
|
||||
/** Called when the editor view's selection changes.
|
||||
@param viewSelection The current selection state
|
||||
*/
|
||||
virtual void onNewSelection (const ARA::PlugIn::ViewSelection& viewSelection)
|
||||
{
|
||||
ignoreUnused (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 (std::vector<ARARegionSequence*> const& regionSequences)
|
||||
{
|
||||
ignoreUnused (regionSequences);
|
||||
}
|
||||
|
||||
ARA_DISABLE_UNREFERENCED_PARAMETER_WARNING_END
|
||||
};
|
||||
|
||||
/** \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)
|
||||
};
|
||||
|
||||
}
|
56
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.cpp
vendored
Normal file
56
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.cpp
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#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
|
85
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.h
vendored
Normal file
85
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.h
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
|
||||
// Include ARA SDK headers
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments",
|
||||
"-Wunused-parameter")
|
||||
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
|
154
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.cpp
vendored
Normal file
154
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.cpp
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#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_DISABLE_ASSERTIONS)
|
||||
// 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
|
204
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.h
vendored
Normal file
204
deps/juce/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.h
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#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,105 +1,95 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterBool::AudioParameterBool (const String& idToUse, const String& nameToUse,
|
||||
bool def, const String& labelToUse,
|
||||
std::function<String (bool, int)> stringFromBool,
|
||||
std::function<bool (const String&)> boolFromString)
|
||||
: RangedAudioParameter (idToUse, nameToUse, labelToUse),
|
||||
value (def ? 1.0f : 0.0f),
|
||||
defaultValue (value),
|
||||
stringFromBoolFunction (stringFromBool),
|
||||
boolFromStringFunction (boolFromString)
|
||||
{
|
||||
if (stringFromBoolFunction == nullptr)
|
||||
stringFromBoolFunction = [] (bool v, int) { return v ? TRANS("On") : TRANS("Off"); };
|
||||
|
||||
if (boolFromStringFunction == nullptr)
|
||||
{
|
||||
StringArray onStrings;
|
||||
onStrings.add (TRANS("on"));
|
||||
onStrings.add (TRANS("yes"));
|
||||
onStrings.add (TRANS("true"));
|
||||
|
||||
StringArray offStrings;
|
||||
offStrings.add (TRANS("off"));
|
||||
offStrings.add (TRANS("no"));
|
||||
offStrings.add (TRANS("false"));
|
||||
|
||||
boolFromStringFunction = [onStrings, offStrings] (const String& text)
|
||||
{
|
||||
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 defaultValue; }
|
||||
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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
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,98 +1,138 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@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.
|
||||
*/
|
||||
AudioParameterBool (const String& parameterID, const String& parameterName, bool defaultValue,
|
||||
const String& parameterLabel = String(),
|
||||
std::function<String (bool value, int maximumStringLength)> stringFromBool = nullptr,
|
||||
std::function<bool (const String& text)> boolFromString = nullptr);
|
||||
|
||||
/** 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 defaultValue;
|
||||
std::function<String (bool, int)> stringFromBoolFunction;
|
||||
std::function<bool (const String&)> boolFromStringFunction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterBool)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterBool.
|
||||
|
||||
@see AudioParameterBool(), RangedAudioParameterAttributes()
|
||||
*/
|
||||
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,136 +1,136 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterChoice::AudioParameterChoice (const String& idToUse, const String& nameToUse,
|
||||
const StringArray& c, int def, const String& labelToUse,
|
||||
std::function<String (int, int)> stringFromIndex,
|
||||
std::function<int (const String&)> indexFromString)
|
||||
: RangedAudioParameter (idToUse, nameToUse, labelToUse), 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 (stringFromIndex),
|
||||
indexFromStringFunction (indexFromString)
|
||||
{
|
||||
jassert (choices.size() > 1); // you must supply an actual set of items to choose from!
|
||||
|
||||
if (stringFromIndexFunction == nullptr)
|
||||
stringFromIndexFunction = [this] (int index, int) { return choices [index]; };
|
||||
|
||||
if (indexFromStringFunction == nullptr)
|
||||
indexFromStringFunction = [this] (const String& text) { return choices.indexOf (text); };
|
||||
}
|
||||
|
||||
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 : 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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
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 : 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,110 +1,151 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@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 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.
|
||||
*/
|
||||
AudioParameterChoice (const String& parameterID, const String& parameterName,
|
||||
const StringArray& choices,
|
||||
int defaultItemIndex,
|
||||
const String& parameterLabel = String(),
|
||||
std::function<String (int index, int maximumStringLength)> stringFromIndex = nullptr,
|
||||
std::function<int (const String& text)> indexFromString = nullptr);
|
||||
|
||||
/** 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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterChoice.
|
||||
|
||||
@see AudioParameterChoice(), RangedAudioParameterAttributes()
|
||||
*/
|
||||
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,102 +1,104 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterFloat::AudioParameterFloat (const String& idToUse, const String& nameToUse,
|
||||
NormalisableRange<float> r, float def,
|
||||
const String& labelToUse, Category categoryToUse,
|
||||
std::function<String (float, int)> stringFromValue,
|
||||
std::function<float (const String&)> valueFromString)
|
||||
: RangedAudioParameter (idToUse, nameToUse, labelToUse, categoryToUse),
|
||||
range (r), value (def), defaultValue (def),
|
||||
stringFromValueFunction (stringFromValue),
|
||||
valueFromStringFunction (valueFromString)
|
||||
{
|
||||
if (stringFromValueFunction == nullptr)
|
||||
{
|
||||
auto numDecimalPlacesToDisplay = [this]
|
||||
{
|
||||
int numDecimalPlaces = 7;
|
||||
|
||||
if (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 (String pid, 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 (defaultValue); }
|
||||
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 (value != newValue)
|
||||
setValueNotifyingHost (convertTo0to1 (newValue));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
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 (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 (value != newValue)
|
||||
setValueNotifyingHost (convertTo0to1 (newValue));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,116 +1,158 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@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.
|
||||
*/
|
||||
AudioParameterFloat (const String& parameterID,
|
||||
const String& parameterName,
|
||||
NormalisableRange<float> normalisableRange,
|
||||
float defaultValue,
|
||||
const String& parameterLabel = String(),
|
||||
Category parameterCategory = AudioProcessorParameter::genericParameter,
|
||||
std::function<String (float value, int maximumStringLength)> stringFromValue = nullptr,
|
||||
std::function<float (const String& text)> valueFromString = nullptr);
|
||||
|
||||
/** 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 (String parameterID,
|
||||
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 defaultValue;
|
||||
std::function<String (float, int)> stringFromValueFunction;
|
||||
std::function<float (const String&)> valueFromStringFunction;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioParameterFloat)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterFloat.
|
||||
|
||||
@see AudioParameterFloat(), RangedAudioParameterAttributes()
|
||||
*/
|
||||
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,141 +1,137 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioParameterInt::AudioParameterInt (const String& idToUse, const String& nameToUse,
|
||||
int minValue, int maxValue, int def,
|
||||
const String& labelToUse,
|
||||
std::function<String (int, int)> stringFromInt,
|
||||
std::function<int (const String&)> intFromString)
|
||||
: RangedAudioParameter (idToUse, nameToUse, labelToUse),
|
||||
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 (stringFromInt),
|
||||
intFromStringFunction (intFromString)
|
||||
{
|
||||
jassert (minValue < maxValue); // must have a non-zero range of values!
|
||||
|
||||
if (stringFromIntFunction == nullptr)
|
||||
stringFromIntFunction = [] (int v, int) { return String (v); };
|
||||
|
||||
if (intFromStringFunction == nullptr)
|
||||
intFromStringFunction = [] (const String& text) { return text.getIntValue(); };
|
||||
}
|
||||
|
||||
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 : 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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
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 : 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,106 +1,152 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@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 parameterLabel An optional label for the parameter's value
|
||||
@param stringFromInt An optional lambda function that converts a 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.
|
||||
*/
|
||||
AudioParameterInt (const String& parameterID, const String& parameterName,
|
||||
int minValue, int maxValue,
|
||||
int defaultValue,
|
||||
const String& parameterLabel = String(),
|
||||
std::function<String (int value, int maximumStringLength)> stringFromInt = nullptr,
|
||||
std::function<int (const String& text)> intFromString = nullptr);
|
||||
|
||||
/** 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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Properties of an AudioParameterInt.
|
||||
|
||||
@see AudioParameterInt(), RangedAudioParameterAttributes()
|
||||
*/
|
||||
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 a 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,40 +1,47 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioProcessorParameterWithID::AudioProcessorParameterWithID (const String& idToUse,
|
||||
const String& nameToUse,
|
||||
const String& labelToUse,
|
||||
AudioProcessorParameter::Category categoryToUse)
|
||||
: paramID (idToUse), name (nameToUse), label (labelToUse), category (categoryToUse) {}
|
||||
AudioProcessorParameterWithID::~AudioProcessorParameterWithID() {}
|
||||
|
||||
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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
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,70 +1,187 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
This abstract base class is used by some AudioProcessorParameter helper classes.
|
||||
|
||||
@see AudioParameterFloat, AudioParameterInt, AudioParameterBool, AudioParameterChoice
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioProcessorParameterWithID : public AudioProcessorParameter
|
||||
{
|
||||
public:
|
||||
/** The creation of this object requires providing a name and ID which will be
|
||||
constant for its lifetime.
|
||||
*/
|
||||
AudioProcessorParameterWithID (const String& parameterID,
|
||||
const String& parameterName,
|
||||
const String& parameterLabel = {},
|
||||
Category parameterCategory = AudioProcessorParameter::genericParameter);
|
||||
|
||||
/** Destructor. */
|
||||
~AudioProcessorParameterWithID() override;
|
||||
|
||||
/** 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;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameterWithID)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
Combines a parameter ID and a version hint.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
class AudioProcessorParameterWithIDAttributes
|
||||
{
|
||||
using This = AudioProcessorParameterWithIDAttributes;
|
||||
|
||||
public:
|
||||
using Category = AudioProcessorParameter::Category;
|
||||
|
||||
/** An optional label for the parameter's value */
|
||||
JUCE_NODISCARD auto withLabel (String x) const { return withMember (*this, &This::label, std::move (x)); }
|
||||
|
||||
/** The semantics of this parameter */
|
||||
JUCE_NODISCARD auto withCategory (Category x) const { return withMember (*this, &This::category, std::move (x)); }
|
||||
|
||||
/** @see AudioProcessorParameter::isMetaParameter() */
|
||||
JUCE_NODISCARD auto withMeta (bool x) const { return withMember (*this, &This::meta, std::move (x)); }
|
||||
|
||||
/** @see AudioProcessorParameter::isAutomatable() */
|
||||
JUCE_NODISCARD auto withAutomatable (bool x) const { return withMember (*this, &This::automatable, std::move (x)); }
|
||||
|
||||
/** @see AudioProcessorParameter::isOrientationInverted() */
|
||||
JUCE_NODISCARD auto withInverted (bool x) const { return withMember (*this, &This::inverted, std::move (x)); }
|
||||
|
||||
/** An optional label for the parameter's value */
|
||||
JUCE_NODISCARD auto getLabel() const { return label; }
|
||||
|
||||
/** The semantics of this parameter */
|
||||
JUCE_NODISCARD auto getCategory() const { return category; }
|
||||
|
||||
/** @see AudioProcessorParameter::isMetaParameter() */
|
||||
JUCE_NODISCARD auto getMeta() const { return meta; }
|
||||
|
||||
/** @see AudioProcessorParameter::isAutomatable() */
|
||||
JUCE_NODISCARD auto getAutomatable() const { return automatable; }
|
||||
|
||||
/** @see AudioProcessorParameter::isOrientationInverted() */
|
||||
JUCE_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
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,88 +1,149 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** Create a derived implementation of this class and pass it to
|
||||
AudioPluginInstance::getExtensions() to retrieve format-specific
|
||||
information about a plugin instance.
|
||||
|
||||
Note that the references passed to the visit member functions are only
|
||||
guaranteed to live for the duration of the function call, so don't
|
||||
store pointers to these objects! If you need to store and reuse
|
||||
format-specific information, it is recommended to copy the result
|
||||
of the function calls that you care about. For example, you should
|
||||
store the result of VST::getAEffectPtr() rather than storing a pointer
|
||||
to the VST instance.
|
||||
|
||||
@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 void* getIComponentPtr() const noexcept = 0;
|
||||
|
||||
virtual MemoryBlock getPreset() const = 0;
|
||||
virtual bool setPreset (const MemoryBlock&) const = 0;
|
||||
};
|
||||
|
||||
/** Can be used to retrieve information about an AudioUnit that is wrapped by an AudioProcessor. */
|
||||
struct AudioUnitClient
|
||||
{
|
||||
virtual ~AudioUnitClient() = default;
|
||||
virtual void* getAudioUnitHandle() const noexcept = 0;
|
||||
};
|
||||
|
||||
/** Can be used to retrieve information about a VST that is wrapped by an AudioProcessor. */
|
||||
struct VSTClient
|
||||
{
|
||||
virtual ~VSTClient() = default;
|
||||
virtual void* getAEffectPtr() const noexcept = 0;
|
||||
};
|
||||
|
||||
virtual ~ExtensionsVisitor() = default;
|
||||
|
||||
/** Will be called if there is no platform specific information available. */
|
||||
virtual void visitUnknown (const Unknown&) {}
|
||||
|
||||
/** Called with VST3-specific information. */
|
||||
virtual void visitVST3Client (const VST3Client&) {}
|
||||
|
||||
/** Called with VST-specific information. */
|
||||
virtual void visitVSTClient (const VSTClient&) {}
|
||||
|
||||
/** Called with AU-specific information. */
|
||||
virtual void visitAudioUnitClient (const AudioUnitClient&) {}
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
// Forward declarations to avoid leaking implementation details.
|
||||
namespace Steinberg
|
||||
{
|
||||
namespace Vst
|
||||
{
|
||||
class IComponent;
|
||||
}
|
||||
} // namespace Steinberg
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#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
|
||||
|
182
deps/juce/modules/juce_audio_processors/utilities/juce_FlagCache.h
vendored
Normal file
182
deps/juce/modules/juce_audio_processors/utilities/juce_FlagCache.h
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if ! DOXYGEN
|
||||
|
||||
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(); }
|
||||
|
||||
void setValue (size_t index, float value)
|
||||
{
|
||||
jassert (index < size());
|
||||
values[index].store (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)
|
||||
{
|
||||
setValue (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
|
||||
|
||||
#endif
|
66
deps/juce/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp
vendored
Normal file
66
deps/juce/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
static void removeScaleFactorListenerFromAllPeers (ComponentPeer::ScaleFactorListener& listener)
|
||||
{
|
||||
for (int i = 0; i < ComponentPeer::getNumPeers(); ++i)
|
||||
ComponentPeer::getPeer (i)->removeScaleFactorListener (&listener);
|
||||
}
|
||||
|
||||
NativeScaleFactorNotifier::NativeScaleFactorNotifier (Component* comp, std::function<void (float)> onScaleChanged)
|
||||
: ComponentMovementWatcher (comp),
|
||||
scaleChanged (std::move (onScaleChanged))
|
||||
{
|
||||
componentPeerChanged();
|
||||
}
|
||||
|
||||
NativeScaleFactorNotifier::~NativeScaleFactorNotifier()
|
||||
{
|
||||
removeScaleFactorListenerFromAllPeers (*this);
|
||||
}
|
||||
|
||||
void NativeScaleFactorNotifier::nativeScaleFactorChanged (double newScaleFactor)
|
||||
{
|
||||
NullCheckedInvocation::invoke (scaleChanged, (float) newScaleFactor);
|
||||
}
|
||||
|
||||
void NativeScaleFactorNotifier::componentPeerChanged()
|
||||
{
|
||||
removeScaleFactorListenerFromAllPeers (*this);
|
||||
|
||||
if (auto* x = getComponent())
|
||||
peer = x->getPeer();
|
||||
|
||||
if (auto* x = peer)
|
||||
{
|
||||
x->addScaleFactorListener (this);
|
||||
nativeScaleFactorChanged (x->getPlatformScaleFactor());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace juce
|
67
deps/juce/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h
vendored
Normal file
67
deps/juce/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
Calls a function every time the native scale factor of a component's peer changes.
|
||||
|
||||
This is used in the VST and VST3 wrappers to ensure that the editor's scale is kept in sync with
|
||||
the scale of its containing component.
|
||||
*/
|
||||
class NativeScaleFactorNotifier : private ComponentMovementWatcher,
|
||||
private ComponentPeer::ScaleFactorListener
|
||||
{
|
||||
public:
|
||||
/** Constructs an instance.
|
||||
|
||||
While the instance is alive, it will listen for changes to the scale factor of the
|
||||
comp's peer, and will call onScaleChanged whenever this scale factor changes.
|
||||
|
||||
@param comp The component to observe
|
||||
@param onScaleChanged A function that will be called when the backing scale factor changes
|
||||
*/
|
||||
NativeScaleFactorNotifier (Component* comp, std::function<void (float)> onScaleChanged);
|
||||
~NativeScaleFactorNotifier() override;
|
||||
|
||||
private:
|
||||
void nativeScaleFactorChanged (double newScaleFactor) override;
|
||||
void componentPeerChanged() override;
|
||||
|
||||
using ComponentMovementWatcher::componentVisibilityChanged;
|
||||
void componentVisibilityChanged() override {}
|
||||
|
||||
using ComponentMovementWatcher::componentMovedOrResized;
|
||||
void componentMovedOrResized (bool, bool) override {}
|
||||
|
||||
ComponentPeer* peer = nullptr;
|
||||
std::function<void (float)> scaleChanged;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (NativeScaleFactorNotifier)
|
||||
JUCE_DECLARE_NON_MOVEABLE (NativeScaleFactorNotifier)
|
||||
};
|
||||
|
||||
} // namespace juce
|
@ -1,271 +1,269 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ParameterAttachment::ParameterAttachment (RangedAudioParameter& param,
|
||||
std::function<void (float)> parameterChangedCallback,
|
||||
UndoManager* um)
|
||||
: parameter (param),
|
||||
undoManager (um),
|
||||
setValue (std::move (parameterChangedCallback))
|
||||
{
|
||||
parameter.addListener (this);
|
||||
}
|
||||
|
||||
ParameterAttachment::~ParameterAttachment()
|
||||
{
|
||||
parameter.removeListener (this);
|
||||
cancelPendingUpdate();
|
||||
}
|
||||
|
||||
void ParameterAttachment::sendInitialUpdate()
|
||||
{
|
||||
parameterValueChanged ({}, parameter.getValue());
|
||||
}
|
||||
|
||||
void ParameterAttachment::setValueAsCompleteGesture (float newDenormalisedValue)
|
||||
{
|
||||
callIfParameterValueChanged (newDenormalisedValue, [this] (float f)
|
||||
{
|
||||
beginGesture();
|
||||
parameter.setValueNotifyingHost (f);
|
||||
endGesture();
|
||||
});
|
||||
}
|
||||
|
||||
void ParameterAttachment::beginGesture()
|
||||
{
|
||||
if (undoManager != nullptr)
|
||||
undoManager->beginNewTransaction();
|
||||
|
||||
parameter.beginChangeGesture();
|
||||
}
|
||||
|
||||
void ParameterAttachment::setValueAsPartOfGesture (float newDenormalisedValue)
|
||||
{
|
||||
callIfParameterValueChanged (newDenormalisedValue, [this] (float f)
|
||||
{
|
||||
parameter.setValueNotifyingHost (f);
|
||||
});
|
||||
}
|
||||
|
||||
void ParameterAttachment::endGesture()
|
||||
{
|
||||
parameter.endChangeGesture();
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
void ParameterAttachment::callIfParameterValueChanged (float newDenormalisedValue,
|
||||
Callback&& callback)
|
||||
{
|
||||
const auto newValue = normalise (newDenormalisedValue);
|
||||
|
||||
if (parameter.getValue() != newValue)
|
||||
callback (newValue);
|
||||
}
|
||||
|
||||
void ParameterAttachment::parameterValueChanged (int, float newValue)
|
||||
{
|
||||
lastValue = newValue;
|
||||
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread())
|
||||
{
|
||||
cancelPendingUpdate();
|
||||
handleAsyncUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterAttachment::handleAsyncUpdate()
|
||||
{
|
||||
if (setValue != nullptr)
|
||||
setValue (parameter.convertFrom0to1 (lastValue));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
SliderParameterAttachment::SliderParameterAttachment (RangedAudioParameter& param,
|
||||
Slider& s,
|
||||
UndoManager* um)
|
||||
: slider (s),
|
||||
attachment (param, [this] (float f) { setValue (f); }, um)
|
||||
{
|
||||
slider.valueFromTextFunction = [¶m] (const String& text) { return (double) param.convertFrom0to1 (param.getValueForText (text)); };
|
||||
slider.textFromValueFunction = [¶m] (double value) { return param.getText (param.convertTo0to1 ((float) value), 0); };
|
||||
slider.setDoubleClickReturnValue (true, param.convertFrom0to1 (param.getDefaultValue()));
|
||||
|
||||
auto range = param.getNormalisableRange();
|
||||
|
||||
auto convertFrom0To1Function = [range] (double currentRangeStart,
|
||||
double currentRangeEnd,
|
||||
double normalisedValue) mutable
|
||||
{
|
||||
range.start = (float) currentRangeStart;
|
||||
range.end = (float) currentRangeEnd;
|
||||
return (double) range.convertFrom0to1 ((float) normalisedValue);
|
||||
};
|
||||
|
||||
auto convertTo0To1Function = [range] (double currentRangeStart,
|
||||
double currentRangeEnd,
|
||||
double mappedValue) mutable
|
||||
{
|
||||
range.start = (float) currentRangeStart;
|
||||
range.end = (float) currentRangeEnd;
|
||||
return (double) range.convertTo0to1 ((float) mappedValue);
|
||||
};
|
||||
|
||||
auto snapToLegalValueFunction = [range] (double currentRangeStart,
|
||||
double currentRangeEnd,
|
||||
double mappedValue) mutable
|
||||
{
|
||||
range.start = (float) currentRangeStart;
|
||||
range.end = (float) currentRangeEnd;
|
||||
return (double) range.snapToLegalValue ((float) mappedValue);
|
||||
};
|
||||
|
||||
NormalisableRange<double> newRange { (double) range.start,
|
||||
(double) range.end,
|
||||
std::move (convertFrom0To1Function),
|
||||
std::move (convertTo0To1Function),
|
||||
std::move (snapToLegalValueFunction) };
|
||||
newRange.interval = range.interval;
|
||||
newRange.skew = range.skew;
|
||||
newRange.symmetricSkew = range.symmetricSkew;
|
||||
|
||||
slider.setNormalisableRange (newRange);
|
||||
|
||||
sendInitialUpdate();
|
||||
slider.valueChanged();
|
||||
slider.addListener (this);
|
||||
}
|
||||
|
||||
SliderParameterAttachment::~SliderParameterAttachment()
|
||||
{
|
||||
slider.removeListener (this);
|
||||
}
|
||||
|
||||
void SliderParameterAttachment::sendInitialUpdate() { attachment.sendInitialUpdate(); }
|
||||
|
||||
void SliderParameterAttachment::setValue (float newValue)
|
||||
{
|
||||
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
|
||||
slider.setValue (newValue, sendNotificationSync);
|
||||
}
|
||||
|
||||
void SliderParameterAttachment::sliderValueChanged (Slider*)
|
||||
{
|
||||
if (ignoreCallbacks || ModifierKeys::currentModifiers.isRightButtonDown())
|
||||
return;
|
||||
|
||||
attachment.setValueAsPartOfGesture ((float) slider.getValue());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ComboBoxParameterAttachment::ComboBoxParameterAttachment (RangedAudioParameter& param,
|
||||
ComboBox& c,
|
||||
UndoManager* um)
|
||||
: comboBox (c),
|
||||
storedParameter (param),
|
||||
attachment (param, [this] (float f) { setValue (f); }, um)
|
||||
{
|
||||
sendInitialUpdate();
|
||||
comboBox.addListener (this);
|
||||
}
|
||||
|
||||
ComboBoxParameterAttachment::~ComboBoxParameterAttachment()
|
||||
{
|
||||
comboBox.removeListener (this);
|
||||
}
|
||||
|
||||
void ComboBoxParameterAttachment::sendInitialUpdate()
|
||||
{
|
||||
attachment.sendInitialUpdate();
|
||||
}
|
||||
|
||||
void ComboBoxParameterAttachment::setValue (float newValue)
|
||||
{
|
||||
const auto normValue = storedParameter.convertTo0to1 (newValue);
|
||||
const auto index = roundToInt (normValue * (float) (comboBox.getNumItems() - 1));
|
||||
|
||||
if (index == comboBox.getSelectedItemIndex())
|
||||
return;
|
||||
|
||||
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
|
||||
comboBox.setSelectedItemIndex (index, sendNotificationSync);
|
||||
}
|
||||
|
||||
void ComboBoxParameterAttachment::comboBoxChanged (ComboBox*)
|
||||
{
|
||||
if (ignoreCallbacks)
|
||||
return;
|
||||
|
||||
const auto numItems = comboBox.getNumItems();
|
||||
const auto selected = (float) comboBox.getSelectedItemIndex();
|
||||
const auto newValue = numItems > 1 ? selected / (float) (numItems - 1)
|
||||
: 0.0f;
|
||||
|
||||
attachment.setValueAsCompleteGesture (storedParameter.convertFrom0to1 (newValue));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ButtonParameterAttachment::ButtonParameterAttachment (RangedAudioParameter& param,
|
||||
Button& b,
|
||||
UndoManager* um)
|
||||
: button (b),
|
||||
attachment (param, [this] (float f) { setValue (f); }, um)
|
||||
{
|
||||
sendInitialUpdate();
|
||||
button.addListener (this);
|
||||
}
|
||||
|
||||
ButtonParameterAttachment::~ButtonParameterAttachment()
|
||||
{
|
||||
button.removeListener (this);
|
||||
}
|
||||
|
||||
void ButtonParameterAttachment::sendInitialUpdate()
|
||||
{
|
||||
attachment.sendInitialUpdate();
|
||||
}
|
||||
|
||||
void ButtonParameterAttachment::setValue (float newValue)
|
||||
{
|
||||
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
|
||||
button.setToggleState (newValue >= 0.5f, sendNotificationSync);
|
||||
}
|
||||
|
||||
void ButtonParameterAttachment::buttonClicked (Button*)
|
||||
{
|
||||
if (ignoreCallbacks)
|
||||
return;
|
||||
|
||||
attachment.setValueAsCompleteGesture (button.getToggleState() ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ParameterAttachment::ParameterAttachment (RangedAudioParameter& param,
|
||||
std::function<void (float)> parameterChangedCallback,
|
||||
UndoManager* um)
|
||||
: parameter (param),
|
||||
undoManager (um),
|
||||
setValue (std::move (parameterChangedCallback))
|
||||
{
|
||||
parameter.addListener (this);
|
||||
}
|
||||
|
||||
ParameterAttachment::~ParameterAttachment()
|
||||
{
|
||||
parameter.removeListener (this);
|
||||
cancelPendingUpdate();
|
||||
}
|
||||
|
||||
void ParameterAttachment::sendInitialUpdate()
|
||||
{
|
||||
parameterValueChanged ({}, parameter.getValue());
|
||||
}
|
||||
|
||||
void ParameterAttachment::setValueAsCompleteGesture (float newDenormalisedValue)
|
||||
{
|
||||
callIfParameterValueChanged (newDenormalisedValue, [this] (float f)
|
||||
{
|
||||
beginGesture();
|
||||
parameter.setValueNotifyingHost (f);
|
||||
endGesture();
|
||||
});
|
||||
}
|
||||
|
||||
void ParameterAttachment::beginGesture()
|
||||
{
|
||||
if (undoManager != nullptr)
|
||||
undoManager->beginNewTransaction();
|
||||
|
||||
parameter.beginChangeGesture();
|
||||
}
|
||||
|
||||
void ParameterAttachment::setValueAsPartOfGesture (float newDenormalisedValue)
|
||||
{
|
||||
callIfParameterValueChanged (newDenormalisedValue, [this] (float f)
|
||||
{
|
||||
parameter.setValueNotifyingHost (f);
|
||||
});
|
||||
}
|
||||
|
||||
void ParameterAttachment::endGesture()
|
||||
{
|
||||
parameter.endChangeGesture();
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
void ParameterAttachment::callIfParameterValueChanged (float newDenormalisedValue,
|
||||
Callback&& callback)
|
||||
{
|
||||
const auto newValue = normalise (newDenormalisedValue);
|
||||
|
||||
if (parameter.getValue() != newValue)
|
||||
callback (newValue);
|
||||
}
|
||||
|
||||
void ParameterAttachment::parameterValueChanged (int, float newValue)
|
||||
{
|
||||
lastValue = newValue;
|
||||
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread())
|
||||
{
|
||||
cancelPendingUpdate();
|
||||
handleAsyncUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterAttachment::handleAsyncUpdate()
|
||||
{
|
||||
if (setValue != nullptr)
|
||||
setValue (parameter.convertFrom0to1 (lastValue));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
SliderParameterAttachment::SliderParameterAttachment (RangedAudioParameter& param,
|
||||
Slider& s,
|
||||
UndoManager* um)
|
||||
: slider (s),
|
||||
attachment (param, [this] (float f) { setValue (f); }, um)
|
||||
{
|
||||
slider.valueFromTextFunction = [¶m] (const String& text) { return (double) param.convertFrom0to1 (param.getValueForText (text)); };
|
||||
slider.textFromValueFunction = [¶m] (double value) { return param.getText (param.convertTo0to1 ((float) value), 0); };
|
||||
slider.setDoubleClickReturnValue (true, param.convertFrom0to1 (param.getDefaultValue()));
|
||||
|
||||
auto range = param.getNormalisableRange();
|
||||
|
||||
auto convertFrom0To1Function = [range] (double currentRangeStart,
|
||||
double currentRangeEnd,
|
||||
double normalisedValue) mutable
|
||||
{
|
||||
range.start = (float) currentRangeStart;
|
||||
range.end = (float) currentRangeEnd;
|
||||
return (double) range.convertFrom0to1 ((float) normalisedValue);
|
||||
};
|
||||
|
||||
auto convertTo0To1Function = [range] (double currentRangeStart,
|
||||
double currentRangeEnd,
|
||||
double mappedValue) mutable
|
||||
{
|
||||
range.start = (float) currentRangeStart;
|
||||
range.end = (float) currentRangeEnd;
|
||||
return (double) range.convertTo0to1 ((float) mappedValue);
|
||||
};
|
||||
|
||||
auto snapToLegalValueFunction = [range] (double currentRangeStart,
|
||||
double currentRangeEnd,
|
||||
double mappedValue) mutable
|
||||
{
|
||||
range.start = (float) currentRangeStart;
|
||||
range.end = (float) currentRangeEnd;
|
||||
return (double) range.snapToLegalValue ((float) mappedValue);
|
||||
};
|
||||
|
||||
NormalisableRange<double> newRange { (double) range.start,
|
||||
(double) range.end,
|
||||
std::move (convertFrom0To1Function),
|
||||
std::move (convertTo0To1Function),
|
||||
std::move (snapToLegalValueFunction) };
|
||||
newRange.interval = range.interval;
|
||||
newRange.skew = range.skew;
|
||||
newRange.symmetricSkew = range.symmetricSkew;
|
||||
|
||||
slider.setNormalisableRange (newRange);
|
||||
|
||||
sendInitialUpdate();
|
||||
slider.valueChanged();
|
||||
slider.addListener (this);
|
||||
}
|
||||
|
||||
SliderParameterAttachment::~SliderParameterAttachment()
|
||||
{
|
||||
slider.removeListener (this);
|
||||
}
|
||||
|
||||
void SliderParameterAttachment::sendInitialUpdate() { attachment.sendInitialUpdate(); }
|
||||
|
||||
void SliderParameterAttachment::setValue (float newValue)
|
||||
{
|
||||
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
|
||||
slider.setValue (newValue, sendNotificationSync);
|
||||
}
|
||||
|
||||
void SliderParameterAttachment::sliderValueChanged (Slider*)
|
||||
{
|
||||
if (! ignoreCallbacks)
|
||||
attachment.setValueAsPartOfGesture ((float) slider.getValue());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ComboBoxParameterAttachment::ComboBoxParameterAttachment (RangedAudioParameter& param,
|
||||
ComboBox& c,
|
||||
UndoManager* um)
|
||||
: comboBox (c),
|
||||
storedParameter (param),
|
||||
attachment (param, [this] (float f) { setValue (f); }, um)
|
||||
{
|
||||
sendInitialUpdate();
|
||||
comboBox.addListener (this);
|
||||
}
|
||||
|
||||
ComboBoxParameterAttachment::~ComboBoxParameterAttachment()
|
||||
{
|
||||
comboBox.removeListener (this);
|
||||
}
|
||||
|
||||
void ComboBoxParameterAttachment::sendInitialUpdate()
|
||||
{
|
||||
attachment.sendInitialUpdate();
|
||||
}
|
||||
|
||||
void ComboBoxParameterAttachment::setValue (float newValue)
|
||||
{
|
||||
const auto normValue = storedParameter.convertTo0to1 (newValue);
|
||||
const auto index = roundToInt (normValue * (float) (comboBox.getNumItems() - 1));
|
||||
|
||||
if (index == comboBox.getSelectedItemIndex())
|
||||
return;
|
||||
|
||||
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
|
||||
comboBox.setSelectedItemIndex (index, sendNotificationSync);
|
||||
}
|
||||
|
||||
void ComboBoxParameterAttachment::comboBoxChanged (ComboBox*)
|
||||
{
|
||||
if (ignoreCallbacks)
|
||||
return;
|
||||
|
||||
const auto numItems = comboBox.getNumItems();
|
||||
const auto selected = (float) comboBox.getSelectedItemIndex();
|
||||
const auto newValue = numItems > 1 ? selected / (float) (numItems - 1)
|
||||
: 0.0f;
|
||||
|
||||
attachment.setValueAsCompleteGesture (storedParameter.convertFrom0to1 (newValue));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ButtonParameterAttachment::ButtonParameterAttachment (RangedAudioParameter& param,
|
||||
Button& b,
|
||||
UndoManager* um)
|
||||
: button (b),
|
||||
attachment (param, [this] (float f) { setValue (f); }, um)
|
||||
{
|
||||
sendInitialUpdate();
|
||||
button.addListener (this);
|
||||
}
|
||||
|
||||
ButtonParameterAttachment::~ButtonParameterAttachment()
|
||||
{
|
||||
button.removeListener (this);
|
||||
}
|
||||
|
||||
void ButtonParameterAttachment::sendInitialUpdate()
|
||||
{
|
||||
attachment.sendInitialUpdate();
|
||||
}
|
||||
|
||||
void ButtonParameterAttachment::setValue (float newValue)
|
||||
{
|
||||
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
|
||||
button.setToggleState (newValue >= 0.5f, sendNotificationSync);
|
||||
}
|
||||
|
||||
void ButtonParameterAttachment::buttonClicked (Button*)
|
||||
{
|
||||
if (ignoreCallbacks)
|
||||
return;
|
||||
|
||||
attachment.setValueAsCompleteGesture (button.getToggleState() ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,251 +1,251 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Used to implement 'attachments' or 'controllers' that link a plug-in
|
||||
parameter to a UI element.
|
||||
|
||||
To implement a new attachment type, create a new class which includes an
|
||||
instance of this class as a data member. Your class should pass a function
|
||||
to the constructor of the ParameterAttachment, which will then be called on
|
||||
the message thread when the parameter changes. You can use this function to
|
||||
update the state of the UI control. Your class should also register as a
|
||||
listener of the UI control and respond to respond to changes in the UI element
|
||||
by calling either setValueAsCompleteGesture or beginGesture,
|
||||
setValueAsPartOfGesture and endGesture.
|
||||
|
||||
Make sure to call `sendInitialUpdate` at the end of your new attachment's
|
||||
constructor, so that the UI immediately reflects the state of the parameter.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ParameterAttachment : private AudioProcessorParameter::Listener,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
/** Listens to a parameter and calls the the provided function in response to
|
||||
parameter changes. If an undoManager is supplied `beginNewTransaction` will
|
||||
be called on it whenever the UI requests a parameter change via this attachment.
|
||||
|
||||
@param parameter The parameter to which this attachment will listen
|
||||
@param parameterChangedCallback The function that will be called on the message thread in response
|
||||
to parameter changes
|
||||
@param undoManager The UndoManager that will be used to begin transactions when the UI
|
||||
requests a parameter change.
|
||||
*/
|
||||
ParameterAttachment (RangedAudioParameter& parameter,
|
||||
std::function<void (float)> parameterChangedCallback,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~ParameterAttachment() override;
|
||||
|
||||
/** Calls the parameterChangedCallback function that was registered in
|
||||
the constructor, making the UI reflect the current parameter state.
|
||||
|
||||
This function should be called after doing any necessary setup on
|
||||
the UI control that is being managed (e.g. adding ComboBox entries,
|
||||
making buttons toggle-able).
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
/** Triggers a full gesture message on the managed parameter.
|
||||
|
||||
Call this in the listener callback of the UI control in response
|
||||
to a one-off change in the UI like a button-press.
|
||||
*/
|
||||
void setValueAsCompleteGesture (float newDenormalisedValue);
|
||||
|
||||
/** Begins a gesture on the managed parameter.
|
||||
|
||||
Call this when the UI is about to begin a continuous interaction,
|
||||
like when the mouse button is pressed on a slider.
|
||||
*/
|
||||
void beginGesture();
|
||||
|
||||
/** Updates the parameter value during a gesture.
|
||||
|
||||
Call this during a continuous interaction, like a slider value
|
||||
changed callback.
|
||||
*/
|
||||
void setValueAsPartOfGesture (float newDenormalisedValue);
|
||||
|
||||
/** Ends a gesture on the managed parameter.
|
||||
|
||||
Call this when the UI has finished a continuous interaction,
|
||||
like when the mouse button is released on a slider.
|
||||
*/
|
||||
void endGesture();
|
||||
|
||||
private:
|
||||
float normalise (float f) const { return parameter.convertTo0to1 (f); }
|
||||
|
||||
template <typename Callback>
|
||||
void callIfParameterValueChanged (float newDenormalisedValue, Callback&& callback);
|
||||
|
||||
void parameterValueChanged (int, float) override;
|
||||
void parameterGestureChanged (int, bool) override {}
|
||||
void handleAsyncUpdate() override;
|
||||
|
||||
RangedAudioParameter& parameter;
|
||||
std::atomic<float> lastValue { 0.0f };
|
||||
UndoManager* undoManager = nullptr;
|
||||
std::function<void (float)> setValue;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterAttachment)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** An object of this class maintains a connection between a Slider and a
|
||||
plug-in parameter.
|
||||
|
||||
During the lifetime of this object it keeps the two things in sync, making
|
||||
it easy to connect a slider to a parameter. When this object is deleted, the
|
||||
connection is broken. Make sure that your parameter and Slider are not
|
||||
deleted before this object!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class SliderParameterAttachment : private Slider::Listener
|
||||
{
|
||||
public:
|
||||
/** Creates a connection between a plug-in parameter and a Slider.
|
||||
|
||||
@param parameter The parameter to use
|
||||
@param slider The Slider to use
|
||||
@param undoManager An optional UndoManager
|
||||
*/
|
||||
SliderParameterAttachment (RangedAudioParameter& parameter, Slider& slider,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~SliderParameterAttachment() override;
|
||||
|
||||
/** Call this after setting up your slider in the case where you need to do
|
||||
extra setup after constructing this attachment.
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
private:
|
||||
void setValue (float newValue);
|
||||
void sliderValueChanged (Slider*) override;
|
||||
|
||||
void sliderDragStarted (Slider*) override { attachment.beginGesture(); }
|
||||
void sliderDragEnded (Slider*) override { attachment.endGesture(); }
|
||||
|
||||
Slider& slider;
|
||||
ParameterAttachment attachment;
|
||||
bool ignoreCallbacks = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** An object of this class maintains a connection between a ComboBox and a
|
||||
plug-in parameter.
|
||||
|
||||
ComboBox items will be spaced linearly across the range of the parameter. For
|
||||
example if the range is specified by NormalisableRange<float> (-0.5f, 0.5f, 0.5f)
|
||||
and you add three items then the first will be mapped to a value of -0.5, the
|
||||
second to 0, and the third to 0.5.
|
||||
|
||||
During the lifetime of this object it keeps the two things in sync, making it
|
||||
easy to connect a combo box to a parameter. When this object is deleted, the
|
||||
connection is broken. Make sure that your parameter and ComboBox are not deleted
|
||||
before this object!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ComboBoxParameterAttachment : private ComboBox::Listener
|
||||
{
|
||||
public:
|
||||
/** Creates a connection between a plug-in parameter and a ComboBox.
|
||||
|
||||
@param parameter The parameter to use
|
||||
@param combo The ComboBox to use
|
||||
@param undoManager An optional UndoManager
|
||||
*/
|
||||
ComboBoxParameterAttachment (RangedAudioParameter& parameter, ComboBox& combo,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~ComboBoxParameterAttachment() override;
|
||||
|
||||
/** Call this after setting up your combo box in the case where you need to do
|
||||
extra setup after constructing this attachment.
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
private:
|
||||
void setValue (float newValue);
|
||||
void comboBoxChanged (ComboBox*) override;
|
||||
|
||||
ComboBox& comboBox;
|
||||
RangedAudioParameter& storedParameter;
|
||||
ParameterAttachment attachment;
|
||||
bool ignoreCallbacks = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** An object of this class maintains a connection between a Button and a
|
||||
plug-in parameter.
|
||||
|
||||
During the lifetime of this object it keeps the two things in sync, making it
|
||||
easy to connect a button to a parameter. When this object is deleted, the
|
||||
connection is broken. Make sure that your parameter and Button are not deleted
|
||||
before this object!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ButtonParameterAttachment : private Button::Listener
|
||||
{
|
||||
public:
|
||||
/** Creates a connection between a plug-in parameter and a Button.
|
||||
|
||||
@param parameter The parameter to use
|
||||
@param button The Button to use
|
||||
@param undoManager An optional UndoManager
|
||||
*/
|
||||
ButtonParameterAttachment (RangedAudioParameter& parameter, Button& button,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~ButtonParameterAttachment() override;
|
||||
|
||||
/** Call this after setting up your button in the case where you need to do
|
||||
extra setup after constructing this attachment.
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
private:
|
||||
void setValue (float newValue);
|
||||
void buttonClicked (Button*) override;
|
||||
|
||||
Button& button;
|
||||
ParameterAttachment attachment;
|
||||
bool ignoreCallbacks = false;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** Used to implement 'attachments' or 'controllers' that link a plug-in
|
||||
parameter to a UI element.
|
||||
|
||||
To implement a new attachment type, create a new class which includes an
|
||||
instance of this class as a data member. Your class should pass a function
|
||||
to the constructor of the ParameterAttachment, which will then be called on
|
||||
the message thread when the parameter changes. You can use this function to
|
||||
update the state of the UI control. Your class should also register as a
|
||||
listener of the UI control and respond to respond to changes in the UI element
|
||||
by calling either setValueAsCompleteGesture or beginGesture,
|
||||
setValueAsPartOfGesture and endGesture.
|
||||
|
||||
Make sure to call `sendInitialUpdate` at the end of your new attachment's
|
||||
constructor, so that the UI immediately reflects the state of the parameter.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ParameterAttachment : private AudioProcessorParameter::Listener,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
/** Listens to a parameter and calls the the provided function in response to
|
||||
parameter changes. If an undoManager is supplied `beginNewTransaction` will
|
||||
be called on it whenever the UI requests a parameter change via this attachment.
|
||||
|
||||
@param parameter The parameter to which this attachment will listen
|
||||
@param parameterChangedCallback The function that will be called on the message thread in response
|
||||
to parameter changes
|
||||
@param undoManager The UndoManager that will be used to begin transactions when the UI
|
||||
requests a parameter change.
|
||||
*/
|
||||
ParameterAttachment (RangedAudioParameter& parameter,
|
||||
std::function<void (float)> parameterChangedCallback,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~ParameterAttachment() override;
|
||||
|
||||
/** Calls the parameterChangedCallback function that was registered in
|
||||
the constructor, making the UI reflect the current parameter state.
|
||||
|
||||
This function should be called after doing any necessary setup on
|
||||
the UI control that is being managed (e.g. adding ComboBox entries,
|
||||
making buttons toggle-able).
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
/** Triggers a full gesture message on the managed parameter.
|
||||
|
||||
Call this in the listener callback of the UI control in response
|
||||
to a one-off change in the UI like a button-press.
|
||||
*/
|
||||
void setValueAsCompleteGesture (float newDenormalisedValue);
|
||||
|
||||
/** Begins a gesture on the managed parameter.
|
||||
|
||||
Call this when the UI is about to begin a continuous interaction,
|
||||
like when the mouse button is pressed on a slider.
|
||||
*/
|
||||
void beginGesture();
|
||||
|
||||
/** Updates the parameter value during a gesture.
|
||||
|
||||
Call this during a continuous interaction, like a slider value
|
||||
changed callback.
|
||||
*/
|
||||
void setValueAsPartOfGesture (float newDenormalisedValue);
|
||||
|
||||
/** Ends a gesture on the managed parameter.
|
||||
|
||||
Call this when the UI has finished a continuous interaction,
|
||||
like when the mouse button is released on a slider.
|
||||
*/
|
||||
void endGesture();
|
||||
|
||||
private:
|
||||
float normalise (float f) const { return parameter.convertTo0to1 (f); }
|
||||
|
||||
template <typename Callback>
|
||||
void callIfParameterValueChanged (float newDenormalisedValue, Callback&& callback);
|
||||
|
||||
void parameterValueChanged (int, float) override;
|
||||
void parameterGestureChanged (int, bool) override {}
|
||||
void handleAsyncUpdate() override;
|
||||
|
||||
RangedAudioParameter& parameter;
|
||||
std::atomic<float> lastValue { 0.0f };
|
||||
UndoManager* undoManager = nullptr;
|
||||
std::function<void (float)> setValue;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterAttachment)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** An object of this class maintains a connection between a Slider and a
|
||||
plug-in parameter.
|
||||
|
||||
During the lifetime of this object it keeps the two things in sync, making
|
||||
it easy to connect a slider to a parameter. When this object is deleted, the
|
||||
connection is broken. Make sure that your parameter and Slider are not
|
||||
deleted before this object!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class SliderParameterAttachment : private Slider::Listener
|
||||
{
|
||||
public:
|
||||
/** Creates a connection between a plug-in parameter and a Slider.
|
||||
|
||||
@param parameter The parameter to use
|
||||
@param slider The Slider to use
|
||||
@param undoManager An optional UndoManager
|
||||
*/
|
||||
SliderParameterAttachment (RangedAudioParameter& parameter, Slider& slider,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~SliderParameterAttachment() override;
|
||||
|
||||
/** Call this after setting up your slider in the case where you need to do
|
||||
extra setup after constructing this attachment.
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
private:
|
||||
void setValue (float newValue);
|
||||
void sliderValueChanged (Slider*) override;
|
||||
|
||||
void sliderDragStarted (Slider*) override { attachment.beginGesture(); }
|
||||
void sliderDragEnded (Slider*) override { attachment.endGesture(); }
|
||||
|
||||
Slider& slider;
|
||||
ParameterAttachment attachment;
|
||||
bool ignoreCallbacks = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** An object of this class maintains a connection between a ComboBox and a
|
||||
plug-in parameter.
|
||||
|
||||
ComboBox items will be spaced linearly across the range of the parameter. For
|
||||
example if the range is specified by NormalisableRange<float> (-0.5f, 0.5f, 0.5f)
|
||||
and you add three items then the first will be mapped to a value of -0.5, the
|
||||
second to 0, and the third to 0.5.
|
||||
|
||||
During the lifetime of this object it keeps the two things in sync, making it
|
||||
easy to connect a combo box to a parameter. When this object is deleted, the
|
||||
connection is broken. Make sure that your parameter and ComboBox are not deleted
|
||||
before this object!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ComboBoxParameterAttachment : private ComboBox::Listener
|
||||
{
|
||||
public:
|
||||
/** Creates a connection between a plug-in parameter and a ComboBox.
|
||||
|
||||
@param parameter The parameter to use
|
||||
@param combo The ComboBox to use
|
||||
@param undoManager An optional UndoManager
|
||||
*/
|
||||
ComboBoxParameterAttachment (RangedAudioParameter& parameter, ComboBox& combo,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~ComboBoxParameterAttachment() override;
|
||||
|
||||
/** Call this after setting up your combo box in the case where you need to do
|
||||
extra setup after constructing this attachment.
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
private:
|
||||
void setValue (float newValue);
|
||||
void comboBoxChanged (ComboBox*) override;
|
||||
|
||||
ComboBox& comboBox;
|
||||
RangedAudioParameter& storedParameter;
|
||||
ParameterAttachment attachment;
|
||||
bool ignoreCallbacks = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** An object of this class maintains a connection between a Button and a
|
||||
plug-in parameter.
|
||||
|
||||
During the lifetime of this object it keeps the two things in sync, making it
|
||||
easy to connect a button to a parameter. When this object is deleted, the
|
||||
connection is broken. Make sure that your parameter and Button are not deleted
|
||||
before this object!
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class ButtonParameterAttachment : private Button::Listener
|
||||
{
|
||||
public:
|
||||
/** Creates a connection between a plug-in parameter and a Button.
|
||||
|
||||
@param parameter The parameter to use
|
||||
@param button The Button to use
|
||||
@param undoManager An optional UndoManager
|
||||
*/
|
||||
ButtonParameterAttachment (RangedAudioParameter& parameter, Button& button,
|
||||
UndoManager* undoManager = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~ButtonParameterAttachment() override;
|
||||
|
||||
/** Call this after setting up your button in the case where you need to do
|
||||
extra setup after constructing this attachment.
|
||||
*/
|
||||
void sendInitialUpdate();
|
||||
|
||||
private:
|
||||
void setValue (float newValue);
|
||||
void buttonClicked (Button*) override;
|
||||
|
||||
Button& button;
|
||||
ParameterAttachment attachment;
|
||||
bool ignoreCallbacks = false;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,315 +1,315 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
|
||||
void JUCE_CALLTYPE juce_switchToHostApplication();
|
||||
juce::Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
|
||||
#endif
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
Image JUCE_API getIconFromApplication (const String&, const int);
|
||||
|
||||
AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined;
|
||||
std::function<bool (AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr;
|
||||
String PluginHostType::hostIdReportedByWrapper;
|
||||
|
||||
bool PluginHostType::isInterAppAudioConnected() const
|
||||
{
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
|
||||
return juce_isInterAppAudioConnected();
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PluginHostType::switchToHostApplication() const
|
||||
{
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
|
||||
juce_switchToHostApplication();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor)
|
||||
{
|
||||
#if JucePlugin_Build_AAX
|
||||
if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_AAX
|
||||
&& jucePlugInIsRunningInAudioSuiteFn != nullptr)
|
||||
{
|
||||
return jucePlugInIsRunningInAudioSuiteFn (processor);
|
||||
}
|
||||
#endif
|
||||
|
||||
ignoreUnused (processor);
|
||||
return false;
|
||||
}
|
||||
|
||||
Image PluginHostType::getHostIcon (int size) const
|
||||
{
|
||||
ignoreUnused (size);
|
||||
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
if (isInterAppAudioConnected())
|
||||
return juce_getIAAHostIcon (size);
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC
|
||||
String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
|
||||
return getIconFromApplication (bundlePath, size);
|
||||
#endif
|
||||
|
||||
return Image();
|
||||
}
|
||||
|
||||
const char* PluginHostType::getHostDescription() const noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case AbletonLive6: return "Ableton Live 6";
|
||||
case AbletonLive7: return "Ableton Live 7";
|
||||
case AbletonLive8: return "Ableton Live 8";
|
||||
case AbletonLive9: return "Ableton Live 9";
|
||||
case AbletonLive10: return "Ableton Live 10";
|
||||
case AbletonLive11: return "Ableton Live 11";
|
||||
case AbletonLiveGeneric: return "Ableton Live";
|
||||
case AdobeAudition: return "Adobe Audition";
|
||||
case AdobePremierePro: return "Adobe Premiere";
|
||||
case AppleGarageBand: return "Apple GarageBand";
|
||||
case AppleLogic: return "Apple Logic";
|
||||
case AppleMainStage: return "Apple MainStage";
|
||||
case Ardour: return "Ardour";
|
||||
case AULab: return "AU Lab";
|
||||
case AvidProTools: return "ProTools";
|
||||
case BitwigStudio: return "Bitwig Studio";
|
||||
case CakewalkSonar8: return "Cakewalk Sonar 8";
|
||||
case CakewalkSonarGeneric: return "Cakewalk Sonar";
|
||||
case CakewalkByBandlab: return "Cakewalk by Bandlab";
|
||||
case DaVinciResolve: return "DaVinci Resolve";
|
||||
case DigitalPerformer: return "DigitalPerformer";
|
||||
case FinalCut: return "Final Cut";
|
||||
case FruityLoops: return "FruityLoops";
|
||||
case JUCEPluginHost: return "JUCE AudioPluginHost";
|
||||
case MagixSamplitude: return "Magix Samplitude";
|
||||
case MagixSequoia: return "Magix Sequoia";
|
||||
case pluginval: return "pluginval";
|
||||
case MergingPyramix: return "Pyramix";
|
||||
case MuseReceptorGeneric: return "Muse Receptor";
|
||||
case Reaper: return "Reaper";
|
||||
case Reason: return "Reason";
|
||||
case Renoise: return "Renoise";
|
||||
case SADiE: return "SADiE";
|
||||
case SteinbergCubase4: return "Steinberg Cubase 4";
|
||||
case SteinbergCubase5: return "Steinberg Cubase 5";
|
||||
case SteinbergCubase5Bridged: return "Steinberg Cubase 5 Bridged";
|
||||
case SteinbergCubase6: return "Steinberg Cubase 6";
|
||||
case SteinbergCubase7: return "Steinberg Cubase 7";
|
||||
case SteinbergCubase8: return "Steinberg Cubase 8";
|
||||
case SteinbergCubase8_5: return "Steinberg Cubase 8.5";
|
||||
case SteinbergCubase9: return "Steinberg Cubase 9";
|
||||
case SteinbergCubase9_5: return "Steinberg Cubase 9.5";
|
||||
case SteinbergCubase10: return "Steinberg Cubase 10";
|
||||
case SteinbergCubase10_5: return "Steinberg Cubase 10.5";
|
||||
case SteinbergCubaseGeneric: return "Steinberg Cubase";
|
||||
case SteinbergNuendo3: return "Steinberg Nuendo 3";
|
||||
case SteinbergNuendo4: return "Steinberg Nuendo 4";
|
||||
case SteinbergNuendo5: return "Steinberg Nuendo 5";
|
||||
case SteinbergNuendoGeneric: return "Steinberg Nuendo";
|
||||
case SteinbergWavelab5: return "Steinberg Wavelab 5";
|
||||
case SteinbergWavelab6: return "Steinberg Wavelab 6";
|
||||
case SteinbergWavelab7: return "Steinberg Wavelab 7";
|
||||
case SteinbergWavelab8: return "Steinberg Wavelab 8";
|
||||
case SteinbergWavelabGeneric: return "Steinberg Wavelab";
|
||||
case SteinbergTestHost: return "Steinberg TestHost";
|
||||
case StudioOne: return "Studio One";
|
||||
case Tracktion3: return "Tracktion 3";
|
||||
case TracktionGeneric: return "Tracktion";
|
||||
case TracktionWaveform: return "Tracktion Waveform";
|
||||
case VBVSTScanner: return "VBVSTScanner";
|
||||
case ViennaEnsemblePro: return "Vienna Ensemble Pro";
|
||||
case WaveBurner: return "WaveBurner";
|
||||
case UnknownHost:
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
PluginHostType::HostType PluginHostType::getHostType()
|
||||
{
|
||||
auto hostPath = getHostPath();
|
||||
auto hostFilename = File (hostPath).getFileName();
|
||||
|
||||
#if JUCE_MAC
|
||||
if (hostPath.containsIgnoreCase ("Final Cut Pro.app")) return FinalCut;
|
||||
if (hostPath.containsIgnoreCase ("Final Cut Pro Trial.app")) return FinalCut;
|
||||
if (hostPath.containsIgnoreCase ("Live 6")) return AbletonLive6;
|
||||
if (hostPath.containsIgnoreCase ("Live 7")) return AbletonLive7;
|
||||
if (hostPath.containsIgnoreCase ("Live 8")) return AbletonLive8;
|
||||
if (hostPath.containsIgnoreCase ("Live 9")) return AbletonLive9;
|
||||
if (hostPath.containsIgnoreCase ("Live 10")) return AbletonLive10;
|
||||
if (hostPath.containsIgnoreCase ("Live 11")) return AbletonLive11;
|
||||
if (hostFilename.containsIgnoreCase ("Live")) return AbletonLiveGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Audition")) return AdobeAudition;
|
||||
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
|
||||
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
|
||||
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
|
||||
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
|
||||
if (hostFilename.containsIgnoreCase ("AU Lab")) return AULab;
|
||||
if (hostFilename.containsIgnoreCase ("Pro Tools")) return AvidProTools;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo 3")) return SteinbergNuendo3;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo 4")) return SteinbergNuendo4;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo 5")) return SteinbergNuendo5;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 4")) return SteinbergCubase4;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 5")) return SteinbergCubase5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 6")) return SteinbergCubase6;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 7")) return SteinbergCubase7;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 8.app")) return SteinbergCubase8;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 8.5.app")) return SteinbergCubase8_5;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 9.app")) return SteinbergCubase9;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 9.5.app")) return SteinbergCubase9_5;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 10.app")) return SteinbergCubase10;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 10.5.app")) return SteinbergCubase10_5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
|
||||
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("WaveBurner")) return WaveBurner;
|
||||
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
|
||||
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
|
||||
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
|
||||
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
|
||||
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
|
||||
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
|
||||
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
|
||||
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
|
||||
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
|
||||
if (hostFilename.containsIgnoreCase ("OsxFL")) return FruityLoops;
|
||||
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
|
||||
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
|
||||
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
|
||||
|
||||
if (hostIdReportedByWrapper == "com.apple.logic.pro") return AppleLogic;
|
||||
if (hostIdReportedByWrapper == "com.apple.garageband") return AppleGarageBand;
|
||||
if (hostIdReportedByWrapper == "com.apple.mainstage") return AppleMainStage;
|
||||
|
||||
const auto procName = nsStringToJuce ([[NSRunningApplication currentApplication] localizedName]);
|
||||
|
||||
const auto matchesInOrder = [&] (const StringArray& strings)
|
||||
{
|
||||
return procName.matchesWildcard ("AUHostingService*(" + strings.joinIntoString ("*") + ")", false);
|
||||
};
|
||||
|
||||
// Depending on localization settings, spaces are not always plain ascii spaces
|
||||
if (matchesInOrder ({ "Logic", "Pro" })) return AppleLogic;
|
||||
if (matchesInOrder ({ "GarageBand" })) return AppleGarageBand;
|
||||
if (matchesInOrder ({ "MainStage" })) return AppleMainStage;
|
||||
if (matchesInOrder ({ "Final", "Cut", "Pro" })) return FinalCut;
|
||||
|
||||
#elif JUCE_WINDOWS
|
||||
if (hostFilename.containsIgnoreCase ("Live 6")) return AbletonLive6;
|
||||
if (hostFilename.containsIgnoreCase ("Live 7")) return AbletonLive7;
|
||||
if (hostFilename.containsIgnoreCase ("Live 8")) return AbletonLive8;
|
||||
if (hostFilename.containsIgnoreCase ("Live 9")) return AbletonLive9;
|
||||
if (hostFilename.containsIgnoreCase ("Live 10")) return AbletonLive10;
|
||||
if (hostFilename.containsIgnoreCase ("Live 11")) return AbletonLive11;
|
||||
if (hostFilename.containsIgnoreCase ("Live ")) return AbletonLiveGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Audition")) return AdobeAudition;
|
||||
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
|
||||
if (hostFilename.containsIgnoreCase ("ProTools")) return AvidProTools;
|
||||
if (hostPath.containsIgnoreCase ("SONAR 8")) return CakewalkSonar8;
|
||||
if (hostFilename.containsIgnoreCase ("SONAR")) return CakewalkSonarGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Cakewalk.exe")) return CakewalkByBandlab;
|
||||
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
|
||||
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
|
||||
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
|
||||
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
|
||||
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
|
||||
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase4")) return SteinbergCubase4;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase5")) return SteinbergCubase5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase6")) return SteinbergCubase6;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase7")) return SteinbergCubase7;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase8.exe")) return SteinbergCubase8;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase8.5.exe")) return SteinbergCubase8_5;
|
||||
// Later version of Cubase scan plug-ins with a separate executable "vst2xscanner"
|
||||
if (hostFilename.containsIgnoreCase ("Cubase9.5.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 9.5")) return SteinbergCubase9_5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase9.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 9")) return SteinbergCubase9;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase10.5.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 10.5")) return SteinbergCubase10_5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase10.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 10")) return SteinbergCubase10;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("VSTBridgeApp")) return SteinbergCubase5Bridged;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 5")) return SteinbergWavelab5;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 6")) return SteinbergWavelab6;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
|
||||
if (hostPath.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("TestHost")) return SteinbergTestHost;
|
||||
if (hostFilename.containsIgnoreCase ("rm-host")) return MuseReceptorGeneric;
|
||||
if (hostFilename.startsWith ("FL")) return FruityLoops;
|
||||
if (hostFilename.contains ("ilbridge.")) return FruityLoops;
|
||||
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
|
||||
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
|
||||
if (hostFilename.containsIgnoreCase ("VST_Scanner")) return VBVSTScanner;
|
||||
if (hostPath.containsIgnoreCase ("Merging Technologies")) return MergingPyramix;
|
||||
if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude;
|
||||
if (hostFilename.startsWithIgnoreCase ("Sequoia")) return MagixSequoia;
|
||||
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
|
||||
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
|
||||
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
|
||||
if (hostPath.containsIgnoreCase ("Bitwig Studio")) return BitwigStudio;
|
||||
if (hostFilename.containsIgnoreCase ("Sadie")) return SADiE;
|
||||
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
|
||||
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
|
||||
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
|
||||
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
if (hostFilename.containsIgnoreCase ("Ardour")) return Ardour;
|
||||
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
|
||||
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
|
||||
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
|
||||
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
|
||||
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
|
||||
|
||||
#elif JUCE_IOS
|
||||
#elif JUCE_ANDROID
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
return UnknownHost;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
bool JUCE_CALLTYPE juce_isInterAppAudioConnected();
|
||||
void JUCE_CALLTYPE juce_switchToHostApplication();
|
||||
juce::Image JUCE_CALLTYPE juce_getIAAHostIcon (int);
|
||||
#endif
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
Image JUCE_API getIconFromApplication (const String&, const int);
|
||||
|
||||
AudioProcessor::WrapperType PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Undefined;
|
||||
std::function<bool (AudioProcessor&)> PluginHostType::jucePlugInIsRunningInAudioSuiteFn = nullptr;
|
||||
String PluginHostType::hostIdReportedByWrapper;
|
||||
|
||||
bool PluginHostType::isInterAppAudioConnected() const
|
||||
{
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
|
||||
return juce_isInterAppAudioConnected();
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PluginHostType::switchToHostApplication() const
|
||||
{
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
if (getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
|
||||
juce_switchToHostApplication();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PluginHostType::isInAAXAudioSuite (AudioProcessor& processor)
|
||||
{
|
||||
#if JucePlugin_Build_AAX
|
||||
if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_AAX
|
||||
&& jucePlugInIsRunningInAudioSuiteFn != nullptr)
|
||||
{
|
||||
return jucePlugInIsRunningInAudioSuiteFn (processor);
|
||||
}
|
||||
#endif
|
||||
|
||||
ignoreUnused (processor);
|
||||
return false;
|
||||
}
|
||||
|
||||
Image PluginHostType::getHostIcon (int size) const
|
||||
{
|
||||
ignoreUnused (size);
|
||||
|
||||
#if JucePlugin_Enable_IAA && JucePlugin_Build_Standalone && JUCE_IOS && (! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP)
|
||||
if (isInterAppAudioConnected())
|
||||
return juce_getIAAHostIcon (size);
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC
|
||||
String bundlePath (getHostPath().upToLastOccurrenceOf (".app", true, true));
|
||||
return getIconFromApplication (bundlePath, size);
|
||||
#endif
|
||||
|
||||
return Image();
|
||||
}
|
||||
|
||||
const char* PluginHostType::getHostDescription() const noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case AbletonLive6: return "Ableton Live 6";
|
||||
case AbletonLive7: return "Ableton Live 7";
|
||||
case AbletonLive8: return "Ableton Live 8";
|
||||
case AbletonLive9: return "Ableton Live 9";
|
||||
case AbletonLive10: return "Ableton Live 10";
|
||||
case AbletonLive11: return "Ableton Live 11";
|
||||
case AbletonLiveGeneric: return "Ableton Live";
|
||||
case AdobeAudition: return "Adobe Audition";
|
||||
case AdobePremierePro: return "Adobe Premiere";
|
||||
case AppleGarageBand: return "Apple GarageBand";
|
||||
case AppleLogic: return "Apple Logic";
|
||||
case AppleMainStage: return "Apple MainStage";
|
||||
case Ardour: return "Ardour";
|
||||
case AULab: return "AU Lab";
|
||||
case AvidProTools: return "ProTools";
|
||||
case BitwigStudio: return "Bitwig Studio";
|
||||
case CakewalkSonar8: return "Cakewalk Sonar 8";
|
||||
case CakewalkSonarGeneric: return "Cakewalk Sonar";
|
||||
case CakewalkByBandlab: return "Cakewalk by Bandlab";
|
||||
case DaVinciResolve: return "DaVinci Resolve";
|
||||
case DigitalPerformer: return "DigitalPerformer";
|
||||
case FinalCut: return "Final Cut";
|
||||
case FruityLoops: return "FruityLoops";
|
||||
case JUCEPluginHost: return "JUCE AudioPluginHost";
|
||||
case MagixSamplitude: return "Magix Samplitude";
|
||||
case MagixSequoia: return "Magix Sequoia";
|
||||
case pluginval: return "pluginval";
|
||||
case MergingPyramix: return "Pyramix";
|
||||
case MuseReceptorGeneric: return "Muse Receptor";
|
||||
case Reaper: return "Reaper";
|
||||
case Reason: return "Reason";
|
||||
case Renoise: return "Renoise";
|
||||
case SADiE: return "SADiE";
|
||||
case SteinbergCubase4: return "Steinberg Cubase 4";
|
||||
case SteinbergCubase5: return "Steinberg Cubase 5";
|
||||
case SteinbergCubase5Bridged: return "Steinberg Cubase 5 Bridged";
|
||||
case SteinbergCubase6: return "Steinberg Cubase 6";
|
||||
case SteinbergCubase7: return "Steinberg Cubase 7";
|
||||
case SteinbergCubase8: return "Steinberg Cubase 8";
|
||||
case SteinbergCubase8_5: return "Steinberg Cubase 8.5";
|
||||
case SteinbergCubase9: return "Steinberg Cubase 9";
|
||||
case SteinbergCubase9_5: return "Steinberg Cubase 9.5";
|
||||
case SteinbergCubase10: return "Steinberg Cubase 10";
|
||||
case SteinbergCubase10_5: return "Steinberg Cubase 10.5";
|
||||
case SteinbergCubaseGeneric: return "Steinberg Cubase";
|
||||
case SteinbergNuendo3: return "Steinberg Nuendo 3";
|
||||
case SteinbergNuendo4: return "Steinberg Nuendo 4";
|
||||
case SteinbergNuendo5: return "Steinberg Nuendo 5";
|
||||
case SteinbergNuendoGeneric: return "Steinberg Nuendo";
|
||||
case SteinbergWavelab5: return "Steinberg Wavelab 5";
|
||||
case SteinbergWavelab6: return "Steinberg Wavelab 6";
|
||||
case SteinbergWavelab7: return "Steinberg Wavelab 7";
|
||||
case SteinbergWavelab8: return "Steinberg Wavelab 8";
|
||||
case SteinbergWavelabGeneric: return "Steinberg Wavelab";
|
||||
case SteinbergTestHost: return "Steinberg TestHost";
|
||||
case StudioOne: return "Studio One";
|
||||
case Tracktion3: return "Tracktion 3";
|
||||
case TracktionGeneric: return "Tracktion";
|
||||
case TracktionWaveform: return "Tracktion Waveform";
|
||||
case VBVSTScanner: return "VBVSTScanner";
|
||||
case ViennaEnsemblePro: return "Vienna Ensemble Pro";
|
||||
case WaveBurner: return "WaveBurner";
|
||||
case UnknownHost:
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
PluginHostType::HostType PluginHostType::getHostType()
|
||||
{
|
||||
auto hostPath = getHostPath();
|
||||
auto hostFilename = File (hostPath).getFileName();
|
||||
|
||||
#if JUCE_MAC
|
||||
if (hostPath.containsIgnoreCase ("Final Cut Pro.app")) return FinalCut;
|
||||
if (hostPath.containsIgnoreCase ("Final Cut Pro Trial.app")) return FinalCut;
|
||||
if (hostPath.containsIgnoreCase ("Live 6")) return AbletonLive6;
|
||||
if (hostPath.containsIgnoreCase ("Live 7")) return AbletonLive7;
|
||||
if (hostPath.containsIgnoreCase ("Live 8")) return AbletonLive8;
|
||||
if (hostPath.containsIgnoreCase ("Live 9")) return AbletonLive9;
|
||||
if (hostPath.containsIgnoreCase ("Live 10")) return AbletonLive10;
|
||||
if (hostPath.containsIgnoreCase ("Live 11")) return AbletonLive11;
|
||||
if (hostFilename.containsIgnoreCase ("Live")) return AbletonLiveGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Audition")) return AdobeAudition;
|
||||
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
|
||||
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
|
||||
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
|
||||
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
|
||||
if (hostFilename.containsIgnoreCase ("AU Lab")) return AULab;
|
||||
if (hostFilename.containsIgnoreCase ("Pro Tools")) return AvidProTools;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo 3")) return SteinbergNuendo3;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo 4")) return SteinbergNuendo4;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo 5")) return SteinbergNuendo5;
|
||||
if (hostFilename.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 4")) return SteinbergCubase4;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 5")) return SteinbergCubase5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 6")) return SteinbergCubase6;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase 7")) return SteinbergCubase7;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 8.app")) return SteinbergCubase8;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 8.5.app")) return SteinbergCubase8_5;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 9.app")) return SteinbergCubase9;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 9.5.app")) return SteinbergCubase9_5;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 10.app")) return SteinbergCubase10;
|
||||
if (hostPath.containsIgnoreCase ("Cubase 10.5.app")) return SteinbergCubase10_5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
|
||||
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("WaveBurner")) return WaveBurner;
|
||||
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
|
||||
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
|
||||
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
|
||||
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
|
||||
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
|
||||
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
|
||||
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
|
||||
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
|
||||
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
|
||||
if (hostFilename.containsIgnoreCase ("OsxFL")) return FruityLoops;
|
||||
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
|
||||
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
|
||||
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
|
||||
|
||||
if (hostIdReportedByWrapper == "com.apple.logic.pro") return AppleLogic;
|
||||
if (hostIdReportedByWrapper == "com.apple.garageband") return AppleGarageBand;
|
||||
if (hostIdReportedByWrapper == "com.apple.mainstage") return AppleMainStage;
|
||||
|
||||
const auto procName = nsStringToJuce ([[NSRunningApplication currentApplication] localizedName]);
|
||||
|
||||
const auto matchesInOrder = [&] (const StringArray& strings)
|
||||
{
|
||||
return procName.matchesWildcard ("AUHostingService*(" + strings.joinIntoString ("*") + ")", false);
|
||||
};
|
||||
|
||||
// Depending on localization settings, spaces are not always plain ascii spaces
|
||||
if (matchesInOrder ({ "Logic", "Pro" })) return AppleLogic;
|
||||
if (matchesInOrder ({ "GarageBand" })) return AppleGarageBand;
|
||||
if (matchesInOrder ({ "MainStage" })) return AppleMainStage;
|
||||
if (matchesInOrder ({ "Final", "Cut", "Pro" })) return FinalCut;
|
||||
|
||||
#elif JUCE_WINDOWS
|
||||
if (hostFilename.containsIgnoreCase ("Live 6")) return AbletonLive6;
|
||||
if (hostFilename.containsIgnoreCase ("Live 7")) return AbletonLive7;
|
||||
if (hostFilename.containsIgnoreCase ("Live 8")) return AbletonLive8;
|
||||
if (hostFilename.containsIgnoreCase ("Live 9")) return AbletonLive9;
|
||||
if (hostFilename.containsIgnoreCase ("Live 10")) return AbletonLive10;
|
||||
if (hostFilename.containsIgnoreCase ("Live 11")) return AbletonLive11;
|
||||
if (hostFilename.containsIgnoreCase ("Live ")) return AbletonLiveGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Audition")) return AdobeAudition;
|
||||
if (hostFilename.containsIgnoreCase ("Adobe Premiere")) return AdobePremierePro;
|
||||
if (hostFilename.containsIgnoreCase ("ProTools")) return AvidProTools;
|
||||
if (hostPath.containsIgnoreCase ("SONAR 8")) return CakewalkSonar8;
|
||||
if (hostFilename.containsIgnoreCase ("SONAR")) return CakewalkSonarGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Cakewalk.exe")) return CakewalkByBandlab;
|
||||
if (hostFilename.containsIgnoreCase ("GarageBand")) return AppleGarageBand;
|
||||
if (hostFilename.containsIgnoreCase ("Logic")) return AppleLogic;
|
||||
if (hostFilename.containsIgnoreCase ("MainStage")) return AppleMainStage;
|
||||
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
|
||||
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
|
||||
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("reaper")) return Reaper;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase4")) return SteinbergCubase4;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase5")) return SteinbergCubase5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase6")) return SteinbergCubase6;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase7")) return SteinbergCubase7;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase8.exe")) return SteinbergCubase8;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase8.5.exe")) return SteinbergCubase8_5;
|
||||
// Later version of Cubase scan plug-ins with a separate executable "vst2xscanner"
|
||||
if (hostFilename.containsIgnoreCase ("Cubase9.5.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 9.5")) return SteinbergCubase9_5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase9.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 9")) return SteinbergCubase9;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase10.5.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 10.5")) return SteinbergCubase10_5;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase10.exe")
|
||||
|| hostPath.containsIgnoreCase ("Cubase 10")) return SteinbergCubase10;
|
||||
if (hostFilename.containsIgnoreCase ("Cubase")) return SteinbergCubaseGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("VSTBridgeApp")) return SteinbergCubase5Bridged;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 5")) return SteinbergWavelab5;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 6")) return SteinbergWavelab6;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 7")) return SteinbergWavelab7;
|
||||
if (hostPath.containsIgnoreCase ("Wavelab 8")) return SteinbergWavelab8;
|
||||
if (hostPath.containsIgnoreCase ("Nuendo")) return SteinbergNuendoGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric;
|
||||
if (hostFilename.containsIgnoreCase ("TestHost")) return SteinbergTestHost;
|
||||
if (hostFilename.containsIgnoreCase ("rm-host")) return MuseReceptorGeneric;
|
||||
if (hostFilename.startsWith ("FL")) return FruityLoops;
|
||||
if (hostFilename.contains ("ilbridge.")) return FruityLoops;
|
||||
if (hostPath.containsIgnoreCase ("Studio One")) return StudioOne;
|
||||
if (hostPath.containsIgnoreCase ("Digital Performer")) return DigitalPerformer;
|
||||
if (hostFilename.containsIgnoreCase ("VST_Scanner")) return VBVSTScanner;
|
||||
if (hostPath.containsIgnoreCase ("Merging Technologies")) return MergingPyramix;
|
||||
if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude;
|
||||
if (hostFilename.startsWithIgnoreCase ("Sequoia")) return MagixSequoia;
|
||||
if (hostFilename.containsIgnoreCase ("Reason")) return Reason;
|
||||
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
|
||||
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
|
||||
if (hostPath.containsIgnoreCase ("Bitwig Studio")) return BitwigStudio;
|
||||
if (hostFilename.containsIgnoreCase ("Sadie")) return SADiE;
|
||||
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
|
||||
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
|
||||
if (hostFilename.containsIgnoreCase ("Vienna Ensemble Pro")) return ViennaEnsemblePro;
|
||||
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
if (hostFilename.containsIgnoreCase ("Ardour")) return Ardour;
|
||||
if (hostFilename.startsWithIgnoreCase ("Waveform")) return TracktionWaveform;
|
||||
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
|
||||
if (hostFilename.startsWith ("Bitwig")) return BitwigStudio;
|
||||
if (hostFilename.containsIgnoreCase ("pluginval")) return pluginval;
|
||||
if (hostFilename.containsIgnoreCase ("AudioPluginHost")) return JUCEPluginHost;
|
||||
|
||||
#elif JUCE_IOS
|
||||
#elif JUCE_ANDROID
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
return UnknownHost;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,247 +1,247 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A useful utility class to determine the host or DAW in which your plugin is
|
||||
loaded.
|
||||
|
||||
Declare a PluginHostType object in your class to use it.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class PluginHostType
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
PluginHostType() : type (getHostType()) {}
|
||||
PluginHostType (const PluginHostType& other) = default;
|
||||
PluginHostType& operator= (const PluginHostType& other) = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Represents the host type and also its version for some hosts. */
|
||||
enum HostType
|
||||
{
|
||||
UnknownHost, /**< Represents an unknown host. */
|
||||
AbletonLive6, /**< Represents Ableton Live 6. */
|
||||
AbletonLive7, /**< Represents Ableton Live 7. */
|
||||
AbletonLive8, /**< Represents Ableton Live 8. */
|
||||
AbletonLive9, /**< Represents Ableton Live 9. */
|
||||
AbletonLive10, /**< Represents Ableton Live 10. */
|
||||
AbletonLive11, /**< Represents Ableton Live 11. */
|
||||
AbletonLiveGeneric, /**< Represents Ableton Live. */
|
||||
AdobeAudition, /**< Represents Adobe Audition. */
|
||||
AdobePremierePro, /**< Represents Adobe Premiere Pro. */
|
||||
AppleGarageBand, /**< Represents Apple GarageBand. */
|
||||
AppleLogic, /**< Represents Apple Logic Pro. */
|
||||
AppleMainStage, /**< Represents Apple Main Stage. */
|
||||
Ardour, /**< Represents Ardour. */
|
||||
AULab, /**< Represents AU Lab. */
|
||||
AvidProTools, /**< Represents Avid Pro Tools. */
|
||||
BitwigStudio, /**< Represents Bitwig Studio. */
|
||||
CakewalkSonar8, /**< Represents Cakewalk Sonar 8. */
|
||||
CakewalkSonarGeneric, /**< Represents Cakewalk Sonar. */
|
||||
CakewalkByBandlab, /**< Represents Cakewalk by Bandlab. */
|
||||
DaVinciResolve, /**< Represents DaVinci Resolve. */
|
||||
DigitalPerformer, /**< Represents Digital Performer. */
|
||||
FinalCut, /**< Represents Apple Final Cut Pro. */
|
||||
FruityLoops, /**< Represents Fruity Loops. */
|
||||
JUCEPluginHost, /**< Represents the JUCE AudioPluginHost */
|
||||
MagixSamplitude, /**< Represents Magix Samplitude. */
|
||||
MagixSequoia, /**< Represents Magix Sequoia. */
|
||||
MergingPyramix, /**< Represents Merging Pyramix. */
|
||||
MuseReceptorGeneric, /**< Represents Muse Receptor. */
|
||||
pluginval, /**< Represents pluginval. */
|
||||
Reaper, /**< Represents Cockos Reaper. */
|
||||
Reason, /**< Represents Reason. */
|
||||
Renoise, /**< Represents Renoise. */
|
||||
SADiE, /**< Represents SADiE. */
|
||||
SteinbergCubase4, /**< Represents Steinberg Cubase 4. */
|
||||
SteinbergCubase5, /**< Represents Steinberg Cubase 5. */
|
||||
SteinbergCubase5Bridged, /**< Represents Steinberg Cubase 5 Bridged. */
|
||||
SteinbergCubase6, /**< Represents Steinberg Cubase 6. */
|
||||
SteinbergCubase7, /**< Represents Steinberg Cubase 7. */
|
||||
SteinbergCubase8, /**< Represents Steinberg Cubase 8. */
|
||||
SteinbergCubase8_5, /**< Represents Steinberg Cubase 8.5. */
|
||||
SteinbergCubase9, /**< Represents Steinberg Cubase 9. */
|
||||
SteinbergCubase9_5, /**< Represents Steinberg Cubase 9.5. */
|
||||
SteinbergCubase10, /**< Represents Steinberg Cubase 10. */
|
||||
SteinbergCubase10_5, /**< Represents Steinberg Cubase 10.5. */
|
||||
SteinbergCubaseGeneric, /**< Represents Steinberg Cubase. */
|
||||
SteinbergNuendo3, /**< Represents Steinberg Nuendo 3. */
|
||||
SteinbergNuendo4, /**< Represents Steinberg Nuendo 4. */
|
||||
SteinbergNuendo5, /**< Represents Steinberg Nuendo 5. */
|
||||
SteinbergNuendoGeneric, /**< Represents Steinberg Nuendo. */
|
||||
SteinbergWavelab5, /**< Represents Steinberg Wavelab 5. */
|
||||
SteinbergWavelab6, /**< Represents Steinberg Wavelab 6. */
|
||||
SteinbergWavelab7, /**< Represents Steinberg Wavelab 7. */
|
||||
SteinbergWavelab8, /**< Represents Steinberg Wavelab 8. */
|
||||
SteinbergWavelabGeneric, /**< Represents Steinberg Wavelab. */
|
||||
SteinbergTestHost, /**< Represents Steinberg's VST3 Test Host. */
|
||||
StudioOne, /**< Represents PreSonus Studio One. */
|
||||
Tracktion3, /**< Represents Tracktion 3. */
|
||||
TracktionGeneric, /**< Represents Tracktion. */
|
||||
TracktionWaveform, /**< Represents Tracktion Waveform. */
|
||||
VBVSTScanner, /**< Represents VB Audio VST Scanner. */
|
||||
ViennaEnsemblePro, /**< Represents Vienna Ensemble Pro. */
|
||||
WaveBurner /**< Represents Apple WaveBurner. */
|
||||
};
|
||||
|
||||
HostType type;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the host is any version of Ableton Live. */
|
||||
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8
|
||||
|| type == AbletonLive9 || type == AbletonLive10 || type == AbletonLive11
|
||||
|| type == AbletonLiveGeneric; }
|
||||
/** Returns true if the host is Adobe Audition. */
|
||||
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
|
||||
/** Returns true if the host is Ardour. */
|
||||
bool isArdour() const noexcept { return type == Ardour; }
|
||||
/** Returns true if the host is AU Lab. */
|
||||
bool isAULab() const noexcept { return type == AULab; }
|
||||
/** Returns true if the host is Bitwig Studio. */
|
||||
bool isBitwigStudio() const noexcept { return type == BitwigStudio; }
|
||||
/** Returns true if the host is any version of Steinberg Cubase. */
|
||||
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6
|
||||
|| type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubase8_5 || type == SteinbergCubase9
|
||||
|| type == SteinbergCubase9_5 || type == SteinbergCubase10 || type == SteinbergCubase10_5 || type == SteinbergCubaseGeneric; }
|
||||
/** Returns true if the host is Steinberg Cubase 7 or later. */
|
||||
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
|
||||
/** Returns true if the host is Steinberg Cubase 5 Bridged. */
|
||||
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
|
||||
/** Returns true if the host is DaVinci Resolve. */
|
||||
bool isDaVinciResolve() const noexcept { return type == DaVinciResolve; }
|
||||
/** Returns true if the host is Digital Performer. */
|
||||
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
|
||||
/** Returns true if the host is Apple Final Cut Pro. */
|
||||
bool isFinalCut() const noexcept { return type == FinalCut; }
|
||||
/** Returns true if the host is Fruity Loops. */
|
||||
bool isFruityLoops() const noexcept { return type == FruityLoops; }
|
||||
/** Returns true if the host is Apple GarageBand. */
|
||||
bool isGarageBand() const noexcept { return type == AppleGarageBand; }
|
||||
/** Returns true if the host is the JUCE AudioPluginHost */
|
||||
bool isJUCEPluginHost() const noexcept { return type == JUCEPluginHost; }
|
||||
/** Returns true if the host is Apple Logic Pro. */
|
||||
bool isLogic() const noexcept { return type == AppleLogic; }
|
||||
/** Returns true if the host is Apple MainStage. */
|
||||
bool isMainStage() const noexcept { return type == AppleMainStage; }
|
||||
/** Returns true if the host is any version of Steinberg Nuendo. */
|
||||
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
|
||||
/** Returns true if the host is pluginval. */
|
||||
bool isPluginval() const noexcept { return type == pluginval; }
|
||||
/** Returns true if the host is Adobe Premiere Pro. */
|
||||
bool isPremiere() const noexcept { return type == AdobePremierePro; }
|
||||
/** Returns true if the host is Avid Pro Tools. */
|
||||
bool isProTools() const noexcept { return type == AvidProTools; }
|
||||
/** Returns true if the host is Merging Pyramix. */
|
||||
bool isPyramix() const noexcept { return type == MergingPyramix; }
|
||||
/** Returns true if the host is Muse Receptor. */
|
||||
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
|
||||
/** Returns true if the host is Cockos Reaper. */
|
||||
bool isReaper() const noexcept { return type == Reaper; }
|
||||
/** Returns true if the host is Reason. */
|
||||
bool isReason() const noexcept { return type == Reason; }
|
||||
/** Returns true if the host is Renoise. */
|
||||
bool isRenoise() const noexcept { return type == Renoise; }
|
||||
/** Returns true if the host is SADiE. */
|
||||
bool isSADiE() const noexcept { return type == SADiE; }
|
||||
/** Returns true if the host is Magix Samplitude. */
|
||||
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
|
||||
/** Returns true if the host is Magix Sequoia. */
|
||||
bool isSequoia() const noexcept { return type == MagixSequoia; }
|
||||
/** Returns true if the host is any version of Cakewalk Sonar. */
|
||||
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric || type == CakewalkByBandlab; }
|
||||
/** Returns true if the host is Steinberg's VST3 Test Host. */
|
||||
bool isSteinbergTestHost() const noexcept { return type == SteinbergTestHost; }
|
||||
/** Returns true if the host is any product from Steinberg. */
|
||||
bool isSteinberg() const noexcept { return isCubase() || isNuendo() || isWavelab() || isSteinbergTestHost(); }
|
||||
/** Returns true if the host is PreSonus Studio One. */
|
||||
bool isStudioOne() const noexcept { return type == StudioOne; }
|
||||
/** Returns true if the host is any version of Tracktion. */
|
||||
bool isTracktion() const noexcept { return type == Tracktion3 || type == TracktionGeneric || isTracktionWaveform(); }
|
||||
/** Returns true if the host is Tracktion Waveform. */
|
||||
bool isTracktionWaveform() const noexcept { return type == TracktionWaveform; }
|
||||
/** Returns true if the host is VB Audio VST Scanner. */
|
||||
bool isVBVSTScanner() const noexcept { return type == VBVSTScanner; }
|
||||
/** Returns true if the host is Vienna Ensemble Pro. */
|
||||
bool isViennaEnsemblePro() const noexcept { return type == ViennaEnsemblePro; }
|
||||
/** Returns true if the host is Apple WaveBurner. */
|
||||
bool isWaveBurner() const noexcept { return type == WaveBurner; }
|
||||
/** Returns true if the host is any version of Steinberg WaveLab. */
|
||||
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
|
||||
/** Returns true if the host is Steinberg WaveLab 6 or below. */
|
||||
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a human-readable description of the host. */
|
||||
const char* getHostDescription() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the plugin is connected with Inter-App Audio on iOS. */
|
||||
bool isInterAppAudioConnected() const;
|
||||
/** Switches to the host application when Inter-App Audio is used on iOS. */
|
||||
void switchToHostApplication() const;
|
||||
/** Gets the host app's icon when Inter-App Audio is used on iOS. */
|
||||
Image getHostIcon (int size) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the complete absolute path of the host application executable. */
|
||||
static String getHostPath()
|
||||
{
|
||||
return File::getSpecialLocation (File::hostApplicationPath).getFullPathName();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Returns the plug-in format via which the plug-in file was loaded. This value is
|
||||
identical to AudioProcessor::wrapperType of the main audio processor of this
|
||||
plug-in. This function is useful for code that does not have access to the
|
||||
plug-in's main audio processor.
|
||||
|
||||
@see AudioProcessor::wrapperType
|
||||
*/
|
||||
static AudioProcessor::WrapperType getPluginLoadedAs() noexcept { return jucePlugInClientCurrentWrapperType; }
|
||||
|
||||
/** Returns true if the AudioProcessor instance is an AAX plug-in running in AudioSuite. */
|
||||
static bool isInAAXAudioSuite (AudioProcessor&);
|
||||
|
||||
//==============================================================================
|
||||
|
||||
#ifndef DOXYGEN
|
||||
// @internal
|
||||
static AudioProcessor::WrapperType jucePlugInClientCurrentWrapperType;
|
||||
static std::function<bool (AudioProcessor&)> jucePlugInIsRunningInAudioSuiteFn;
|
||||
static String hostIdReportedByWrapper;
|
||||
#endif
|
||||
|
||||
private:
|
||||
static HostType getHostType();
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A useful utility class to determine the host or DAW in which your plugin is
|
||||
loaded.
|
||||
|
||||
Declare a PluginHostType object in your class to use it.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class PluginHostType
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
PluginHostType() : type (getHostType()) {}
|
||||
PluginHostType (const PluginHostType& other) = default;
|
||||
PluginHostType& operator= (const PluginHostType& other) = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Represents the host type and also its version for some hosts. */
|
||||
enum HostType
|
||||
{
|
||||
UnknownHost, /**< Represents an unknown host. */
|
||||
AbletonLive6, /**< Represents Ableton Live 6. */
|
||||
AbletonLive7, /**< Represents Ableton Live 7. */
|
||||
AbletonLive8, /**< Represents Ableton Live 8. */
|
||||
AbletonLive9, /**< Represents Ableton Live 9. */
|
||||
AbletonLive10, /**< Represents Ableton Live 10. */
|
||||
AbletonLive11, /**< Represents Ableton Live 11. */
|
||||
AbletonLiveGeneric, /**< Represents Ableton Live. */
|
||||
AdobeAudition, /**< Represents Adobe Audition. */
|
||||
AdobePremierePro, /**< Represents Adobe Premiere Pro. */
|
||||
AppleGarageBand, /**< Represents Apple GarageBand. */
|
||||
AppleLogic, /**< Represents Apple Logic Pro. */
|
||||
AppleMainStage, /**< Represents Apple Main Stage. */
|
||||
Ardour, /**< Represents Ardour. */
|
||||
AULab, /**< Represents AU Lab. */
|
||||
AvidProTools, /**< Represents Avid Pro Tools. */
|
||||
BitwigStudio, /**< Represents Bitwig Studio. */
|
||||
CakewalkSonar8, /**< Represents Cakewalk Sonar 8. */
|
||||
CakewalkSonarGeneric, /**< Represents Cakewalk Sonar. */
|
||||
CakewalkByBandlab, /**< Represents Cakewalk by Bandlab. */
|
||||
DaVinciResolve, /**< Represents DaVinci Resolve. */
|
||||
DigitalPerformer, /**< Represents Digital Performer. */
|
||||
FinalCut, /**< Represents Apple Final Cut Pro. */
|
||||
FruityLoops, /**< Represents Fruity Loops. */
|
||||
JUCEPluginHost, /**< Represents the JUCE AudioPluginHost */
|
||||
MagixSamplitude, /**< Represents Magix Samplitude. */
|
||||
MagixSequoia, /**< Represents Magix Sequoia. */
|
||||
MergingPyramix, /**< Represents Merging Pyramix. */
|
||||
MuseReceptorGeneric, /**< Represents Muse Receptor. */
|
||||
pluginval, /**< Represents pluginval. */
|
||||
Reaper, /**< Represents Cockos Reaper. */
|
||||
Reason, /**< Represents Reason. */
|
||||
Renoise, /**< Represents Renoise. */
|
||||
SADiE, /**< Represents SADiE. */
|
||||
SteinbergCubase4, /**< Represents Steinberg Cubase 4. */
|
||||
SteinbergCubase5, /**< Represents Steinberg Cubase 5. */
|
||||
SteinbergCubase5Bridged, /**< Represents Steinberg Cubase 5 Bridged. */
|
||||
SteinbergCubase6, /**< Represents Steinberg Cubase 6. */
|
||||
SteinbergCubase7, /**< Represents Steinberg Cubase 7. */
|
||||
SteinbergCubase8, /**< Represents Steinberg Cubase 8. */
|
||||
SteinbergCubase8_5, /**< Represents Steinberg Cubase 8.5. */
|
||||
SteinbergCubase9, /**< Represents Steinberg Cubase 9. */
|
||||
SteinbergCubase9_5, /**< Represents Steinberg Cubase 9.5. */
|
||||
SteinbergCubase10, /**< Represents Steinberg Cubase 10. */
|
||||
SteinbergCubase10_5, /**< Represents Steinberg Cubase 10.5. */
|
||||
SteinbergCubaseGeneric, /**< Represents Steinberg Cubase. */
|
||||
SteinbergNuendo3, /**< Represents Steinberg Nuendo 3. */
|
||||
SteinbergNuendo4, /**< Represents Steinberg Nuendo 4. */
|
||||
SteinbergNuendo5, /**< Represents Steinberg Nuendo 5. */
|
||||
SteinbergNuendoGeneric, /**< Represents Steinberg Nuendo. */
|
||||
SteinbergWavelab5, /**< Represents Steinberg Wavelab 5. */
|
||||
SteinbergWavelab6, /**< Represents Steinberg Wavelab 6. */
|
||||
SteinbergWavelab7, /**< Represents Steinberg Wavelab 7. */
|
||||
SteinbergWavelab8, /**< Represents Steinberg Wavelab 8. */
|
||||
SteinbergWavelabGeneric, /**< Represents Steinberg Wavelab. */
|
||||
SteinbergTestHost, /**< Represents Steinberg's VST3 Test Host. */
|
||||
StudioOne, /**< Represents PreSonus Studio One. */
|
||||
Tracktion3, /**< Represents Tracktion 3. */
|
||||
TracktionGeneric, /**< Represents Tracktion. */
|
||||
TracktionWaveform, /**< Represents Tracktion Waveform. */
|
||||
VBVSTScanner, /**< Represents VB Audio VST Scanner. */
|
||||
ViennaEnsemblePro, /**< Represents Vienna Ensemble Pro. */
|
||||
WaveBurner /**< Represents Apple WaveBurner. */
|
||||
};
|
||||
|
||||
HostType type;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the host is any version of Ableton Live. */
|
||||
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8
|
||||
|| type == AbletonLive9 || type == AbletonLive10 || type == AbletonLive11
|
||||
|| type == AbletonLiveGeneric; }
|
||||
/** Returns true if the host is Adobe Audition. */
|
||||
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
|
||||
/** Returns true if the host is Ardour. */
|
||||
bool isArdour() const noexcept { return type == Ardour; }
|
||||
/** Returns true if the host is AU Lab. */
|
||||
bool isAULab() const noexcept { return type == AULab; }
|
||||
/** Returns true if the host is Bitwig Studio. */
|
||||
bool isBitwigStudio() const noexcept { return type == BitwigStudio; }
|
||||
/** Returns true if the host is any version of Steinberg Cubase. */
|
||||
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6
|
||||
|| type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubase8_5 || type == SteinbergCubase9
|
||||
|| type == SteinbergCubase9_5 || type == SteinbergCubase10 || type == SteinbergCubase10_5 || type == SteinbergCubaseGeneric; }
|
||||
/** Returns true if the host is Steinberg Cubase 7 or later. */
|
||||
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
|
||||
/** Returns true if the host is Steinberg Cubase 5 Bridged. */
|
||||
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
|
||||
/** Returns true if the host is DaVinci Resolve. */
|
||||
bool isDaVinciResolve() const noexcept { return type == DaVinciResolve; }
|
||||
/** Returns true if the host is Digital Performer. */
|
||||
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
|
||||
/** Returns true if the host is Apple Final Cut Pro. */
|
||||
bool isFinalCut() const noexcept { return type == FinalCut; }
|
||||
/** Returns true if the host is Fruity Loops. */
|
||||
bool isFruityLoops() const noexcept { return type == FruityLoops; }
|
||||
/** Returns true if the host is Apple GarageBand. */
|
||||
bool isGarageBand() const noexcept { return type == AppleGarageBand; }
|
||||
/** Returns true if the host is the JUCE AudioPluginHost */
|
||||
bool isJUCEPluginHost() const noexcept { return type == JUCEPluginHost; }
|
||||
/** Returns true if the host is Apple Logic Pro. */
|
||||
bool isLogic() const noexcept { return type == AppleLogic; }
|
||||
/** Returns true if the host is Apple MainStage. */
|
||||
bool isMainStage() const noexcept { return type == AppleMainStage; }
|
||||
/** Returns true if the host is any version of Steinberg Nuendo. */
|
||||
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
|
||||
/** Returns true if the host is pluginval. */
|
||||
bool isPluginval() const noexcept { return type == pluginval; }
|
||||
/** Returns true if the host is Adobe Premiere Pro. */
|
||||
bool isPremiere() const noexcept { return type == AdobePremierePro; }
|
||||
/** Returns true if the host is Avid Pro Tools. */
|
||||
bool isProTools() const noexcept { return type == AvidProTools; }
|
||||
/** Returns true if the host is Merging Pyramix. */
|
||||
bool isPyramix() const noexcept { return type == MergingPyramix; }
|
||||
/** Returns true if the host is Muse Receptor. */
|
||||
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
|
||||
/** Returns true if the host is Cockos Reaper. */
|
||||
bool isReaper() const noexcept { return type == Reaper; }
|
||||
/** Returns true if the host is Reason. */
|
||||
bool isReason() const noexcept { return type == Reason; }
|
||||
/** Returns true if the host is Renoise. */
|
||||
bool isRenoise() const noexcept { return type == Renoise; }
|
||||
/** Returns true if the host is SADiE. */
|
||||
bool isSADiE() const noexcept { return type == SADiE; }
|
||||
/** Returns true if the host is Magix Samplitude. */
|
||||
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
|
||||
/** Returns true if the host is Magix Sequoia. */
|
||||
bool isSequoia() const noexcept { return type == MagixSequoia; }
|
||||
/** Returns true if the host is any version of Cakewalk Sonar. */
|
||||
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric || type == CakewalkByBandlab; }
|
||||
/** Returns true if the host is Steinberg's VST3 Test Host. */
|
||||
bool isSteinbergTestHost() const noexcept { return type == SteinbergTestHost; }
|
||||
/** Returns true if the host is any product from Steinberg. */
|
||||
bool isSteinberg() const noexcept { return isCubase() || isNuendo() || isWavelab() || isSteinbergTestHost(); }
|
||||
/** Returns true if the host is PreSonus Studio One. */
|
||||
bool isStudioOne() const noexcept { return type == StudioOne; }
|
||||
/** Returns true if the host is any version of Tracktion. */
|
||||
bool isTracktion() const noexcept { return type == Tracktion3 || type == TracktionGeneric || isTracktionWaveform(); }
|
||||
/** Returns true if the host is Tracktion Waveform. */
|
||||
bool isTracktionWaveform() const noexcept { return type == TracktionWaveform; }
|
||||
/** Returns true if the host is VB Audio VST Scanner. */
|
||||
bool isVBVSTScanner() const noexcept { return type == VBVSTScanner; }
|
||||
/** Returns true if the host is Vienna Ensemble Pro. */
|
||||
bool isViennaEnsemblePro() const noexcept { return type == ViennaEnsemblePro; }
|
||||
/** Returns true if the host is Apple WaveBurner. */
|
||||
bool isWaveBurner() const noexcept { return type == WaveBurner; }
|
||||
/** Returns true if the host is any version of Steinberg WaveLab. */
|
||||
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
|
||||
/** Returns true if the host is Steinberg WaveLab 6 or below. */
|
||||
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a human-readable description of the host. */
|
||||
const char* getHostDescription() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the plugin is connected with Inter-App Audio on iOS. */
|
||||
bool isInterAppAudioConnected() const;
|
||||
/** Switches to the host application when Inter-App Audio is used on iOS. */
|
||||
void switchToHostApplication() const;
|
||||
/** Gets the host app's icon when Inter-App Audio is used on iOS. */
|
||||
Image getHostIcon (int size) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the complete absolute path of the host application executable. */
|
||||
static String getHostPath()
|
||||
{
|
||||
return File::getSpecialLocation (File::hostApplicationPath).getFullPathName();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Returns the plug-in format via which the plug-in file was loaded. This value is
|
||||
identical to AudioProcessor::wrapperType of the main audio processor of this
|
||||
plug-in. This function is useful for code that does not have access to the
|
||||
plug-in's main audio processor.
|
||||
|
||||
@see AudioProcessor::wrapperType
|
||||
*/
|
||||
static AudioProcessor::WrapperType getPluginLoadedAs() noexcept { return jucePlugInClientCurrentWrapperType; }
|
||||
|
||||
/** Returns true if the AudioProcessor instance is an AAX plug-in running in AudioSuite. */
|
||||
static bool isInAAXAudioSuite (AudioProcessor&);
|
||||
|
||||
//==============================================================================
|
||||
|
||||
#ifndef DOXYGEN
|
||||
// @internal
|
||||
static AudioProcessor::WrapperType jucePlugInClientCurrentWrapperType;
|
||||
static std::function<bool (AudioProcessor&)> jucePlugInIsRunningInAudioSuiteFn;
|
||||
static String hostIdReportedByWrapper;
|
||||
#endif
|
||||
|
||||
private:
|
||||
static HostType getHostType();
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,59 +1,51 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
RangedAudioParameter::RangedAudioParameter (const String& parameterID,
|
||||
const String& parameterName,
|
||||
const String& parameterLabel,
|
||||
Category parameterCategory)
|
||||
: AudioProcessorParameterWithID (parameterID, parameterName, parameterLabel, parameterCategory)
|
||||
{
|
||||
}
|
||||
|
||||
int RangedAudioParameter::getNumSteps() const
|
||||
{
|
||||
const auto& range = getNormalisableRange();
|
||||
|
||||
if (range.interval > 0)
|
||||
return (static_cast<int> ((range.end - range.start) / range.interval) + 1);
|
||||
|
||||
return AudioProcessor::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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
int RangedAudioParameter::getNumSteps() const
|
||||
{
|
||||
const auto& range = getNormalisableRange();
|
||||
|
||||
if (range.interval > 0)
|
||||
return (static_cast<int> ((range.end - range.start) / range.interval) + 1);
|
||||
|
||||
return AudioProcessor::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,63 +1,118 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
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:
|
||||
/** The creation of this object requires providing a name and ID which will be
|
||||
constant for its lifetime.
|
||||
*/
|
||||
RangedAudioParameter (const String& parameterID,
|
||||
const String& parameterName,
|
||||
const String& parameterLabel = {},
|
||||
Category parameterCategory = AudioProcessorParameter::genericParameter);
|
||||
|
||||
/** 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
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/**
|
||||
@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.
|
||||
*/
|
||||
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. */
|
||||
JUCE_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. */
|
||||
JUCE_NODISCARD auto withValueFromStringFunction (ValueFromString x) const { return withMember (asDerived(), &Derived::valueFromString, std::move (x)); }
|
||||
|
||||
/** See AudioProcessorParameterWithIDAttributes::withLabel() */
|
||||
JUCE_NODISCARD auto withLabel (String x) const { return withMember (asDerived(), &Derived::attributes, attributes.withLabel (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameterWithIDAttributes::withCategory() */
|
||||
JUCE_NODISCARD auto withCategory (Category x) const { return withMember (asDerived(), &Derived::attributes, attributes.withCategory (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameter::isMetaParameter() */
|
||||
JUCE_NODISCARD auto withMeta (bool x) const { return withMember (asDerived(), &Derived::attributes, attributes.withMeta (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameter::isAutomatable() */
|
||||
JUCE_NODISCARD auto withAutomatable (bool x) const { return withMember (asDerived(), &Derived::attributes, attributes.withAutomatable (std::move (x))); }
|
||||
|
||||
/** See AudioProcessorParameter::isOrientationInverted() */
|
||||
JUCE_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. */
|
||||
JUCE_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. */
|
||||
JUCE_NODISCARD const auto& getValueFromStringFunction() const { return valueFromString; }
|
||||
|
||||
/** Gets attributes that would also apply to an AudioProcessorParameterWithID */
|
||||
JUCE_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,95 +1,99 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// Forward declaration to avoid leaking implementation details.
|
||||
namespace Steinberg
|
||||
{
|
||||
class FUnknown;
|
||||
using TUID = char[16];
|
||||
}
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** An interface to allow an AudioProcessor to implement extended VST3-specific
|
||||
functionality.
|
||||
|
||||
To use this class, ensure that your AudioProcessor publicly inherits
|
||||
from VST3ClientExtensions.
|
||||
|
||||
@see VSTCallbackHandler
|
||||
|
||||
@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; }
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
// Forward declaration to avoid leaking implementation details.
|
||||
namespace Steinberg
|
||||
{
|
||||
class FUnknown;
|
||||
using TUID = char[16];
|
||||
} // namespace Steinberg
|
||||
|
||||
#endif
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** An interface to allow an AudioProcessor to implement extended VST3-specific
|
||||
functionality.
|
||||
|
||||
To use this class, ensure that your AudioProcessor publicly inherits
|
||||
from VST3ClientExtensions.
|
||||
|
||||
@see VSTCallbackHandler
|
||||
|
||||
@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; }
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,80 +1,80 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** An interface to allow an AudioProcessor to send and receive VST specific calls from
|
||||
the host.
|
||||
|
||||
To use this class, ensure that your AudioProcessor publicly inherits
|
||||
from VSTCallbackHandler.
|
||||
|
||||
@see VST3ClientExtensions
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct VSTCallbackHandler
|
||||
{
|
||||
virtual ~VSTCallbackHandler() = 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)
|
||||
{
|
||||
ignoreUnused (index, value, ptr, opt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
|
||||
// Note: VS2013 prevents a "using" declaration here
|
||||
/** The host callback function type. */
|
||||
typedef pointer_sized_int (VstHostCallbackType) (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)
|
||||
{
|
||||
ignoreUnused (callback);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
/** An interface to allow an AudioProcessor to send and receive VST specific calls from
|
||||
the host.
|
||||
|
||||
To use this class, ensure that your AudioProcessor publicly inherits
|
||||
from VSTCallbackHandler.
|
||||
|
||||
@see VST3ClientExtensions
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
struct VSTCallbackHandler
|
||||
{
|
||||
virtual ~VSTCallbackHandler() = 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)
|
||||
{
|
||||
ignoreUnused (index, value, ptr, opt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
|
||||
// Note: VS2013 prevents a "using" declaration here
|
||||
/** The host callback function type. */
|
||||
typedef pointer_sized_int (VstHostCallbackType) (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)
|
||||
{
|
||||
ignoreUnused (callback);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
Reference in New Issue
Block a user