Browse Source

Update juce

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.5.0
falkTX 2 years ago
parent
commit
bb406540aa
100 changed files with 7534 additions and 869 deletions
  1. +3
    -2
      source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
  2. +11
    -4
      source/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp
  3. +23
    -4
      source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h
  4. +27
    -4
      source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp
  5. +27
    -4
      source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h
  6. +6
    -6
      source/modules/juce_audio_processors/format_types/LV2_SDK/generate_lv2_bundle_sources.py
  7. +11
    -4
      source/modules/juce_audio_processors/format_types/LV2_SDK/juce_lv2_config.h
  8. +11
    -4
      source/modules/juce_audio_processors/format_types/LV2_SDK/lilv_config.h
  9. +11
    -4
      source/modules/juce_audio_processors/format_types/LV2_SDK/serd_config.h
  10. +11
    -4
      source/modules/juce_audio_processors/format_types/LV2_SDK/sord_config.h
  11. +76
    -0
      source/modules/juce_audio_processors/format_types/juce_ARACommon.cpp
  12. +85
    -0
      source/modules/juce_audio_processors/format_types/juce_ARACommon.h
  13. +458
    -0
      source/modules/juce_audio_processors/format_types/juce_ARAHosting.cpp
  14. +740
    -0
      source/modules/juce_audio_processors/format_types/juce_ARAHosting.h
  15. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_AU_Shared.h
  16. +12
    -4
      source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h
  17. +291
    -241
      source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  18. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp
  19. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h
  20. +51
    -41
      source/modules/juce_audio_processors/format_types/juce_LV2Common.h
  21. +83
    -69
      source/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp
  22. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.h
  23. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LV2PluginFormat_test.cpp
  24. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LV2Resources.h
  25. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LV2SupportLibs.cpp
  26. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp
  27. +78
    -65
      source/modules/juce_audio_processors/format_types/juce_VST3Common.h
  28. +21
    -4
      source/modules/juce_audio_processors/format_types/juce_VST3Headers.h
  29. +175
    -23
      source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
  30. +12
    -4
      source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h
  31. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp
  32. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_VSTCommon.h
  33. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h
  34. +21
    -123
      source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  35. +11
    -4
      source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h
  36. +190
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/ipslcontextinfo.h
  37. +108
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/ipsleditcontroller.h
  38. +53
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/ipslgainreduction.h
  39. +121
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/ipslhostcommands.h
  40. +53
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/ipslviewembedding.h
  41. +67
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/ipslviewscaling.h
  42. +57
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/pslauextensions.h
  43. +111
    -0
      source/modules/juce_audio_processors/format_types/pslextensions/pslvst2extensions.h
  44. +35
    -19
      source/modules/juce_audio_processors/juce_audio_processors.cpp
  45. +44
    -12
      source/modules/juce_audio_processors/juce_audio_processors.h
  46. +40
    -0
      source/modules/juce_audio_processors/juce_audio_processors_ara.cpp
  47. +11
    -4
      source/modules/juce_audio_processors/juce_audio_processors_lv2_libs.cpp
  48. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp
  49. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h
  50. +15
    -5
      source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
  51. +41
    -6
      source/modules/juce_audio_processors/processors/juce_AudioProcessor.h
  52. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp
  53. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h
  54. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h
  55. +13
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  56. +15
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
  57. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h
  58. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h
  59. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp
  60. +11
    -4
      source/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h
  61. +11
    -4
      source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp
  62. +11
    -4
      source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h
  63. +11
    -4
      source/modules/juce_audio_processors/processors/juce_HostedAudioProcessorParameter.h
  64. +13
    -4
      source/modules/juce_audio_processors/processors/juce_PluginDescription.cpp
  65. +14
    -4
      source/modules/juce_audio_processors/processors/juce_PluginDescription.h
  66. +11
    -4
      source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp
  67. +11
    -4
      source/modules/juce_audio_processors/scanning/juce_KnownPluginList.h
  68. +11
    -4
      source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp
  69. +11
    -4
      source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h
  70. +11
    -4
      source/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp
  71. +11
    -4
      source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h
  72. +971
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp
  73. +520
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.h
  74. +71
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentControllerCommon.cpp
  75. +199
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.cpp
  76. +1145
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.h
  77. +92
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.cpp
  78. +271
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.h
  79. +32
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.cpp
  80. +85
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.h
  81. +156
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.cpp
  82. +204
    -0
      source/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.h
  83. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp
  84. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h
  85. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.cpp
  86. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h
  87. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.cpp
  88. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h
  89. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.cpp
  90. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h
  91. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp
  92. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h
  93. +13
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp
  94. +13
    -4
      source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
  95. +22
    -5
      source/modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h
  96. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_FlagCache.h
  97. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp
  98. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h
  99. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp
  100. +11
    -4
      source/modules/juce_audio_processors/utilities/juce_ParameterAttachments.h

+ 3
- 2
source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp View File

@@ -1088,6 +1088,7 @@ void AudioDeviceManager::setDefaultMidiOutputDevice (const String& identifier)
{ {
if (defaultMidiOutputDeviceInfo.identifier != identifier) if (defaultMidiOutputDeviceInfo.identifier != identifier)
{ {
std::unique_ptr<MidiOutput> oldMidiPort;
Array<AudioIODeviceCallback*> oldCallbacks; Array<AudioIODeviceCallback*> oldCallbacks;
{ {
@@ -1099,7 +1100,7 @@ void AudioDeviceManager::setDefaultMidiOutputDevice (const String& identifier)
for (int i = oldCallbacks.size(); --i >= 0;) for (int i = oldCallbacks.size(); --i >= 0;)
oldCallbacks.getUnchecked (i)->audioDeviceStopped(); oldCallbacks.getUnchecked (i)->audioDeviceStopped();
defaultMidiOutput.reset();
std::swap (oldMidiPort, defaultMidiOutput);
if (identifier.isNotEmpty()) if (identifier.isNotEmpty())
defaultMidiOutput = MidiOutput::openDevice (identifier); defaultMidiOutput = MidiOutput::openDevice (identifier);
@@ -1119,7 +1120,7 @@ void AudioDeviceManager::setDefaultMidiOutputDevice (const String& identifier)
} }
updateXml(); updateXml();
sendChangeMessage();
sendSynchronousChangeMessage();
} }
} }


+ 11
- 4
source/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 23
- 4
source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -133,6 +140,18 @@ public:
/** Returns true if instantiation of this plugin type must be done from a non-message thread. */ /** Returns true if instantiation of this plugin type must be done from a non-message thread. */
virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0; virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0;
/** A callback lambda that is passed to getARAFactory() */
using ARAFactoryCreationCallback = std::function<void (ARAFactoryResult)>;
/** Tries to create an ::ARAFactoryWrapper for this description.
The result of the operation will be wrapped into an ARAFactoryResult,
which will be passed to a callback object supplied by the caller.
@see AudioPluginFormatManager::createARAFactoryAsync
*/
virtual void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) { callback ({}); }
protected: protected:
//============================================================================== //==============================================================================
friend class AudioPluginFormatManager; friend class AudioPluginFormatManager;


+ 27
- 4
source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -129,6 +136,22 @@ std::unique_ptr<AudioPluginInstance> AudioPluginFormatManager::createPluginInsta
return {}; return {};
} }
void AudioPluginFormatManager::createARAFactoryAsync (const PluginDescription& description,
AudioPluginFormat::ARAFactoryCreationCallback callback) const
{
String errorMessage;
if (auto* format = findFormatForDescription (description, errorMessage))
{
format->createARAFactoryAsync (description, callback);
}
else
{
errorMessage = NEEDS_TRANS ("Couldn't find format for the provided description");
callback ({ {}, std::move (errorMessage) });
}
}
void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description, void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description,
double initialSampleRate, int initialBufferSize, double initialSampleRate, int initialBufferSize,
AudioPluginFormat::PluginCreationCallback callback) AudioPluginFormat::PluginCreationCallback callback)


+ 27
- 4
source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -102,6 +109,22 @@ public:
double initialSampleRate, int initialBufferSize, double initialSampleRate, int initialBufferSize,
AudioPluginFormat::PluginCreationCallback callback); AudioPluginFormat::PluginCreationCallback callback);
/** Tries to create an ::ARAFactoryWrapper for this description.
The result of the operation will be wrapped into an ARAFactoryResult,
which will be passed to a callback object supplied by the caller.
The operation may fail, in which case the callback will be called with
with a result object where ARAFactoryResult::araFactory.get() will return
a nullptr.
In case of success the returned ::ARAFactoryWrapper will ensure that
modules required for the correct functioning of the ARAFactory will remain
loaded for the lifetime of the object.
*/
void createARAFactoryAsync (const PluginDescription& description,
AudioPluginFormat::ARAFactoryCreationCallback callback) const;
/** Checks that the file or component for this plugin actually still exists. /** Checks that the file or component for this plugin actually still exists.
(This won't try to load the plugin) (This won't try to load the plugin)
*/ */


+ 6
- 6
source/modules/juce_audio_processors/format_types/LV2_SDK/generate_lv2_bundle_sources.py View File

@@ -6,10 +6,10 @@
# JUCE is an open source library subject to commercial or open-source # JUCE is an open source library subject to commercial or open-source
# licensing. # 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).
# 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-6-licence
# End User License Agreement: www.juce.com/juce-7-licence
# Privacy Policy: www.juce.com/juce-privacy-policy # Privacy Policy: www.juce.com/juce-privacy-policy
# #
# Or: You may also use this code under the terms of the GPL v3 (see # Or: You may also use this code under the terms of the GPL v3 (see
@@ -57,10 +57,10 @@ FUNCTION_TEMPLATE = """/*
JUCE is an open source library subject to commercial or open-source JUCE is an open source library subject to commercial or open-source
licensing. 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).
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-6-licence
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy Privacy Policy: www.juce.com/juce-privacy-policy


Or: You may also use this code under the terms of the GPL v3 (see Or: You may also use this code under the terms of the GPL v3 (see


+ 11
- 4
source/modules/juce_audio_processors/format_types/LV2_SDK/juce_lv2_config.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/LV2_SDK/lilv_config.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================


This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited


You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.


For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/LV2_SDK/serd_config.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================


This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited


You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.


For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/LV2_SDK/sord_config.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================


This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited


You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.


For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 76
- 0
source/modules/juce_audio_processors/format_types/juce_ARACommon.cpp View File

@@ -0,0 +1,76 @@
/*
==============================================================================
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 (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU) && (JUCE_MAC || JUCE_WINDOWS))
#include <ARA_Library/Debug/ARADebug.h>
namespace juce
{
static void dummyARAInterfaceAssert (ARA::ARAAssertCategory, const void*, const char*)
{}
static ARA::ARAInterfaceConfiguration createInterfaceConfig (const ARA::ARAFactory* araFactory)
{
static auto* assertFunction = &dummyARAInterfaceAssert;
#if ARA_VALIDATE_API_CALLS
assertFunction = &::ARA::ARAInterfaceAssert;
static std::once_flag flag;
std::call_once (flag, [] { ARA::ARASetExternalAssertReference (&assertFunction); });
#endif
return makeARASizedStruct (&ARA::ARAInterfaceConfiguration::assertFunctionAddress,
jmin (araFactory->highestSupportedApiGeneration, (ARA::ARAAPIGeneration) ARA::kARAAPIGeneration_2_X_Draft),
&assertFunction);
}
static std::shared_ptr<const ARA::ARAFactory> getOrCreateARAFactory (const ARA::ARAFactory* ptr,
std::function<void (const ARA::ARAFactory*)> onDelete)
{
JUCE_ASSERT_MESSAGE_THREAD
static std::unordered_map<const ARA::ARAFactory*, std::weak_ptr<const ARA::ARAFactory>> cache;
auto& cachePtr = cache[ptr];
if (const auto obj = cachePtr.lock())
return obj;
const auto interfaceConfig = createInterfaceConfig (ptr);
ptr->initializeARAWithConfiguration (&interfaceConfig);
const auto obj = std::shared_ptr<const ARA::ARAFactory> (ptr, [deleter = std::move (onDelete)] (const ARA::ARAFactory* factory)
{
factory->uninitializeARA();
deleter (factory);
});
cachePtr = obj;
return obj;
}
}
#endif

+ 85
- 0
source/modules/juce_audio_processors/format_types/juce_ARACommon.h View 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.
==============================================================================
*/
#pragma once
namespace ARA
{
struct ARAFactory;
}
namespace juce
{
/** Encapsulates an ARAFactory pointer and makes sure that it remains in a valid state
for the lifetime of the ARAFactoryWrapper object.
@tags{ARA}
*/
class ARAFactoryWrapper
{
public:
ARAFactoryWrapper() = default;
/** @internal
Used by the framework to encapsulate ARAFactory pointers loaded from plugins.
*/
explicit ARAFactoryWrapper (std::shared_ptr<const ARA::ARAFactory> factoryIn) : factory (std::move (factoryIn)) {}
/** Returns the contained ARAFactory pointer, which can be a nullptr.
The validity of the returned pointer is only guaranteed for the lifetime of this wrapper.
*/
const ARA::ARAFactory* get() const noexcept { return factory.get(); }
private:
std::shared_ptr<const ARA::ARAFactory> factory;
};
/** Represents the result of AudioPluginFormatManager::createARAFactoryAsync().
If the operation fails then #araFactory will contain `nullptr`, and #errorMessage may
contain a reason for the failure.
The araFactory member ensures that the module necessary for the correct functioning
of the factory will remain loaded.
@tags{ARA}
*/
struct ARAFactoryResult
{
ARAFactoryWrapper araFactory;
String errorMessage;
};
template <typename Obj, typename Member, typename... Ts>
constexpr Obj makeARASizedStruct (Member Obj::* member, Ts&&... ts)
{
return { reinterpret_cast<uintptr_t> (&(static_cast<const Obj*> (nullptr)->*member)) + sizeof (Member),
std::forward<Ts> (ts)... };
}
} // namespace juce

+ 458
- 0
source/modules/juce_audio_processors/format_types/juce_ARAHosting.cpp View File

@@ -0,0 +1,458 @@
/*
==============================================================================
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 (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU) && (JUCE_MAC || JUCE_WINDOWS))
#include "juce_ARAHosting.h"
#include <ARA_Library/Debug/ARADebug.h>
#include <ARA_Library/Dispatch/ARAHostDispatch.cpp>
namespace juce
{
struct ARAEditGuardState
{
public:
/* Returns true if this controller wasn't previously present. */
bool add (ARA::Host::DocumentController& dc)
{
const std::lock_guard<std::mutex> lock (mutex);
return ++counts[&dc] == 1;
}
/* Returns true if this controller is no longer present. */
bool remove (ARA::Host::DocumentController& dc)
{
const std::lock_guard<std::mutex> lock (mutex);
return --counts[&dc] == 0;
}
private:
std::map<ARA::Host::DocumentController*, int> counts;
std::mutex mutex;
};
static ARAEditGuardState editGuardState;
ARAEditGuard::ARAEditGuard (ARA::Host::DocumentController& dcIn) : dc (dcIn)
{
if (editGuardState.add (dc))
dc.beginEditing();
}
ARAEditGuard::~ARAEditGuard()
{
if (editGuardState.remove (dc))
dc.endEditing();
}
//==============================================================================
namespace ARAHostModel
{
//==============================================================================
AudioSource::AudioSource (ARA::ARAAudioSourceHostRef hostRef,
ARA::Host::DocumentController& dc,
const ARA::ARAAudioSourceProperties& props)
: ManagedARAHandle (dc, [&]
{
const ARAEditGuard guard (dc);
return dc.createAudioSource (hostRef, &props);
}())
{
}
void AudioSource::update (const ARA::ARAAudioSourceProperties& props)
{
const ARAEditGuard guard (getDocumentController());
getDocumentController().updateAudioSourceProperties (getPluginRef(), &props);
}
void AudioSource::enableAudioSourceSamplesAccess (bool x)
{
const ARAEditGuard guard (getDocumentController());
getDocumentController().enableAudioSourceSamplesAccess (getPluginRef(), x);
}
void AudioSource::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
{
dc.destroyAudioSource (ptr);
}
//==============================================================================
AudioModification::AudioModification (ARA::ARAAudioModificationHostRef hostRef,
ARA::Host::DocumentController& dc,
AudioSource& s,
const ARA::ARAAudioModificationProperties& props)
: ManagedARAHandle (dc, [&]
{
const ARAEditGuard guard (dc);
return dc.createAudioModification (s.getPluginRef(), hostRef, &props);
}()),
source (s)
{
}
void AudioModification::update (const ARA::ARAAudioModificationProperties& props)
{
const ARAEditGuard guard (getDocumentController());
getDocumentController().updateAudioModificationProperties (getPluginRef(), &props);
}
void AudioModification::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
{
dc.destroyAudioModification (ptr);
}
//==============================================================================
class PlaybackRegion::Impl : public ManagedARAHandle<Impl, ARA::ARAPlaybackRegionRef>,
public DeletionListener
{
public:
Impl (ARA::ARAPlaybackRegionHostRef hostRef,
ARA::Host::DocumentController& dc,
AudioModification& m,
const ARA::ARAPlaybackRegionProperties& props);
~Impl() override
{
for (const auto& l : listeners)
l->removeListener (*this);
}
/* Updates the state of the corresponding %ARA model object.
Places the DocumentController in editable state.
You can use getEmptyProperties() to acquire a properties struct where the `structSize`
field has already been correctly set.
*/
void update (const ARA::ARAPlaybackRegionProperties& props);
auto& getAudioModification() const { return modification; }
static void destroy (ARA::Host::DocumentController&, Ptr);
void addListener (DeletionListener& l) { listeners.insert (&l); }
void removeListener (DeletionListener& l) noexcept override { listeners.erase (&l); }
private:
AudioModification* modification = nullptr;
std::unordered_set<DeletionListener*> listeners;
};
PlaybackRegion::Impl::Impl (ARA::ARAPlaybackRegionHostRef hostRef,
ARA::Host::DocumentController& dc,
AudioModification& m,
const ARA::ARAPlaybackRegionProperties& props)
: ManagedARAHandle (dc, [&]
{
const ARAEditGuard guard (dc);
return dc.createPlaybackRegion (m.getPluginRef(), hostRef, &props);
}()),
modification (&m)
{
}
PlaybackRegion::~PlaybackRegion() = default;
void PlaybackRegion::Impl::update (const ARA::ARAPlaybackRegionProperties& props)
{
const ARAEditGuard guard (getDocumentController());
getDocumentController().updatePlaybackRegionProperties (getPluginRef(), &props);
}
void PlaybackRegion::Impl::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
{
dc.destroyPlaybackRegion (ptr);
}
PlaybackRegion::PlaybackRegion (ARA::ARAPlaybackRegionHostRef hostRef,
ARA::Host::DocumentController& dc,
AudioModification& m,
const ARA::ARAPlaybackRegionProperties& props)
: impl (std::make_unique<Impl> (hostRef, dc, m, props))
{
}
void PlaybackRegion::update (const ARA::ARAPlaybackRegionProperties& props) { impl->update (props); }
void PlaybackRegion::addListener (DeletionListener& x) { impl->addListener (x); }
auto& PlaybackRegion::getAudioModification() const { return impl->getAudioModification(); }
ARA::ARAPlaybackRegionRef PlaybackRegion::getPluginRef() const noexcept { return impl->getPluginRef(); }
DeletionListener& PlaybackRegion::getDeletionListener() const noexcept { return *impl.get(); }
//==============================================================================
MusicalContext::MusicalContext (ARA::ARAMusicalContextHostRef hostRef,
ARA::Host::DocumentController& dc,
const ARA::ARAMusicalContextProperties& props)
: ManagedARAHandle (dc, [&]
{
const ARAEditGuard guard (dc);
return dc.createMusicalContext (hostRef, &props);
}())
{
}
void MusicalContext::update (const ARA::ARAMusicalContextProperties& props)
{
const ARAEditGuard guard (getDocumentController());
return getDocumentController().updateMusicalContextProperties (getPluginRef(), &props);
}
void MusicalContext::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
{
dc.destroyMusicalContext (ptr);
}
//==============================================================================
RegionSequence::RegionSequence (ARA::ARARegionSequenceHostRef hostRef,
ARA::Host::DocumentController& dc,
const ARA::ARARegionSequenceProperties& props)
: ManagedARAHandle (dc, [&]
{
const ARAEditGuard guard (dc);
return dc.createRegionSequence (hostRef, &props);
}())
{
}
void RegionSequence::update (const ARA::ARARegionSequenceProperties& props)
{
const ARAEditGuard guard (getDocumentController());
return getDocumentController().updateRegionSequenceProperties (getPluginRef(), &props);
}
void RegionSequence::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
{
dc.destroyRegionSequence (ptr);
}
//==============================================================================
PlaybackRendererInterface PlugInExtensionInstance::getPlaybackRendererInterface() const
{
if (instance != nullptr)
return PlaybackRendererInterface (instance->playbackRendererRef, instance->playbackRendererInterface);
return {};
}
EditorRendererInterface PlugInExtensionInstance::getEditorRendererInterface() const
{
if (instance != nullptr)
return EditorRendererInterface (instance->editorRendererRef, instance->editorRendererInterface);
return {};
}
} // namespace ARAHostModel
//==============================================================================
class ARAHostDocumentController::Impl
{
public:
Impl (ARAFactoryWrapper araFactoryIn,
std::unique_ptr<ARA::Host::DocumentControllerHostInstance>&& dcHostInstanceIn,
const ARA::ARADocumentControllerInstance* documentControllerInstance)
: araFactory (std::move (araFactoryIn)),
dcHostInstance (std::move (dcHostInstanceIn)),
documentController (documentControllerInstance)
{
}
~Impl()
{
documentController.destroyDocumentController();
}
static std::unique_ptr<Impl>
createImpl (ARAFactoryWrapper araFactory,
const String& documentName,
std::unique_ptr<ARA::Host::AudioAccessControllerInterface>&& audioAccessController,
std::unique_ptr<ARA::Host::ArchivingControllerInterface>&& archivingController,
std::unique_ptr<ARA::Host::ContentAccessControllerInterface>&& contentAccessController,
std::unique_ptr<ARA::Host::ModelUpdateControllerInterface>&& modelUpdateController,
std::unique_ptr<ARA::Host::PlaybackControllerInterface>&& playbackController)
{
std::unique_ptr<ARA::Host::DocumentControllerHostInstance> dcHostInstance =
std::make_unique<ARA::Host::DocumentControllerHostInstance> (audioAccessController.release(),
archivingController.release(),
contentAccessController.release(),
modelUpdateController.release(),
playbackController.release());
const auto documentProperties = makeARASizedStruct (&ARA::ARADocumentProperties::name, documentName.toRawUTF8());
if (auto* dci = araFactory.get()->createDocumentControllerWithDocument (dcHostInstance.get(), &documentProperties))
return std::make_unique<Impl> (std::move (araFactory), std::move (dcHostInstance), dci);
return {};
}
ARAHostModel::PlugInExtensionInstance bindDocumentToPluginInstance (AudioPluginInstance& instance,
ARA::ARAPlugInInstanceRoleFlags knownRoles,
ARA::ARAPlugInInstanceRoleFlags assignedRoles)
{
const auto makeVisitor = [] (auto vst3Fn, auto auFn)
{
using Vst3Fn = decltype (vst3Fn);
using AuFn = decltype (auFn);
struct Visitor : ExtensionsVisitor, Vst3Fn, AuFn
{
explicit Visitor (Vst3Fn vst3Fn, AuFn auFn) : Vst3Fn (std::move (vst3Fn)), AuFn (std::move (auFn)) {}
void visitVST3Client (const VST3Client& x) override { Vst3Fn::operator() (x); }
void visitAudioUnitClient (const AudioUnitClient& x) override { AuFn::operator() (x); }
};
return Visitor { std::move (vst3Fn), std::move (auFn) };
};
const ARA::ARAPlugInExtensionInstance* pei = nullptr;
auto visitor = makeVisitor ([this, &pei, knownRoles, assignedRoles] (const ExtensionsVisitor::VST3Client& vst3Client)
{
auto* iComponentPtr = vst3Client.getIComponentPtr();
VSTComSmartPtr<ARA::IPlugInEntryPoint2> araEntryPoint;
if (araEntryPoint.loadFrom (iComponentPtr))
pei = araEntryPoint->bindToDocumentControllerWithRoles (documentController.getRef(), knownRoles, assignedRoles);
},
#if JUCE_PLUGINHOST_AU && JUCE_MAC
[this, &pei, knownRoles, assignedRoles] (const ExtensionsVisitor::AudioUnitClient& auClient)
{
auto audioUnit = auClient.getAudioUnitHandle();
auto propertySize = (UInt32) sizeof (ARA::ARAAudioUnitPlugInExtensionBinding);
const auto expectedPropertySize = propertySize;
ARA::ARAAudioUnitPlugInExtensionBinding audioUnitBinding { ARA::kARAAudioUnitMagic,
documentController.getRef(),
nullptr,
knownRoles,
assignedRoles };
auto status = AudioUnitGetProperty (audioUnit,
ARA::kAudioUnitProperty_ARAPlugInExtensionBindingWithRoles,
kAudioUnitScope_Global,
0,
&audioUnitBinding,
&propertySize);
if (status == noErr
&& propertySize == expectedPropertySize
&& audioUnitBinding.inOutMagicNumber == ARA::kARAAudioUnitMagic
&& audioUnitBinding.inDocumentControllerRef == documentController.getRef()
&& audioUnitBinding.outPlugInExtension != nullptr)
{
pei = audioUnitBinding.outPlugInExtension;
}
else
jassertfalse;
}
#else
[] (const auto&) {}
#endif
);
instance.getExtensions (visitor);
return ARAHostModel::PlugInExtensionInstance { pei };
}
auto& getDocumentController() { return documentController; }
private:
ARAFactoryWrapper araFactory;
std::unique_ptr<ARA::Host::DocumentControllerHostInstance> dcHostInstance;
ARA::Host::DocumentController documentController;
};
ARAHostDocumentController::ARAHostDocumentController (std::unique_ptr<Impl>&& implIn)
: impl { std::move (implIn) }
{}
std::unique_ptr<ARAHostDocumentController> ARAHostDocumentController::create (ARAFactoryWrapper factory,
const String& documentName,
std::unique_ptr<ARA::Host::AudioAccessControllerInterface> audioAccessController,
std::unique_ptr<ARA::Host::ArchivingControllerInterface> archivingController,
std::unique_ptr<ARA::Host::ContentAccessControllerInterface> contentAccessController,
std::unique_ptr<ARA::Host::ModelUpdateControllerInterface> modelUpdateController,
std::unique_ptr<ARA::Host::PlaybackControllerInterface> playbackController)
{
if (auto impl = Impl::createImpl (std::move (factory),
documentName,
std::move (audioAccessController),
std::move (archivingController),
std::move (contentAccessController),
std::move (modelUpdateController),
std::move (playbackController)))
{
return rawToUniquePtr (new ARAHostDocumentController (std::move (impl)));
}
return {};
}
ARAHostDocumentController::~ARAHostDocumentController() = default;
ARA::Host::DocumentController& ARAHostDocumentController::getDocumentController() const
{
return impl->getDocumentController();
}
ARAHostModel::PlugInExtensionInstance ARAHostDocumentController::bindDocumentToPluginInstance (AudioPluginInstance& instance,
ARA::ARAPlugInInstanceRoleFlags knownRoles,
ARA::ARAPlugInInstanceRoleFlags assignedRoles)
{
return impl->bindDocumentToPluginInstance (instance, knownRoles, assignedRoles);
}
void createARAFactoryAsync (AudioPluginInstance& instance, std::function<void (ARAFactoryWrapper)> cb)
{
if (! instance.getPluginDescription().hasARAExtension)
cb (ARAFactoryWrapper{});
struct Extensions : public ExtensionsVisitor
{
Extensions (std::function<void (ARAFactoryWrapper)> callbackIn)
: callback (std::move (callbackIn))
{}
void visitARAClient (const ARAClient& araClient) override
{
araClient.createARAFactoryAsync (std::move (callback));
}
std::function<void (ARAFactoryWrapper)> callback;
};
Extensions extensions { std::move(cb) };
instance.getExtensions (extensions);
}
} // namespace juce
#endif

+ 740
- 0
source/modules/juce_audio_processors/format_types/juce_ARAHosting.h View File

@@ -0,0 +1,740 @@
/*
==============================================================================
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
#if (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU) && (JUCE_MAC || JUCE_WINDOWS)) || DOXYGEN
// Include ARA SDK headers
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments")
#include <ARA_API/ARAInterface.h>
#include <ARA_Library/Dispatch/ARAHostDispatch.h>
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
//==============================================================================
namespace juce
{
/** Reference counting helper class to ensure that the DocumentController is in editable state.
When adding, removing or modifying %ARA model objects the enclosing DocumentController must be
in editable state.
You can achieve this by using the %ARA Library calls
ARA::Host::DocumentController::beginEditing() and ARA::Host::DocumentController::endEditing().
However, putting the DocumentController in and out of editable state is a potentially costly
operation, thus it makes sense to group multiple modifications together and change the editable
state only once.
ARAEditGuard keeps track of all scopes that want to edit a particular DocumentController and
will trigger beginEditing() and endEditing() only for the outermost scope. This allows you to
merge multiple editing operations into one by putting ARAEditGuard in their enclosing scope.
@tags{ARA}
*/
class ARAEditGuard
{
public:
explicit ARAEditGuard (ARA::Host::DocumentController& dcIn);
~ARAEditGuard();
private:
ARA::Host::DocumentController& dc;
};
namespace ARAHostModel
{
//==============================================================================
/** Allows converting, without warnings, between pointers of two unrelated types.
This is a bit like ARA_MAP_HOST_REF, but not macro-based.
To use it, add a line like this to a type that needs to deal in host references:
@code
using Converter = ConversionFunctions<ThisType*, ARAHostRef>;
@endcode
Now, you can convert back and forth with host references by calling
Converter::toHostRef() and Converter::fromHostRef().
@tags{ARA}
*/
template <typename A, typename B>
struct ConversionFunctions
{
static_assert (sizeof (A) <= sizeof (B),
"It is only possible to convert between types of the same size");
static B toHostRef (A value)
{
return readUnaligned<B> (&value);
}
static A fromHostRef (B value)
{
return readUnaligned<A> (&value);
}
};
//==============================================================================
template <typename Base, typename PtrIn>
class ManagedARAHandle
{
public:
using Ptr = PtrIn;
ManagedARAHandle (ARA::Host::DocumentController& dc, Ptr ptr) noexcept
: handle (ptr, Deleter { dc }) {}
auto& getDocumentController() const { return handle.get_deleter().documentController; }
Ptr getPluginRef() const { return handle.get(); }
private:
struct Deleter
{
void operator() (Ptr ptr) const noexcept
{
const ARAEditGuard guard (documentController);
Base::destroy (documentController, ptr);
}
ARA::Host::DocumentController& documentController;
};
std::unique_ptr<std::remove_pointer_t<Ptr>, Deleter> handle;
};
//==============================================================================
/** Helper class for the host side implementation of the %ARA %AudioSource model object.
Its intended use is to add a member variable of this type to your host side %AudioSource
implementation. Then it provides a RAII approach to managing the lifetime of the corresponding
objects created inside the DocumentController. When the host side object is instantiated an ARA
model object is also created in the DocumentController. When the host side object is deleted it
will be removed from the DocumentController as well.
The class will automatically put the DocumentController into editable state for operations that
mandate this e.g. creation, deletion or updating.
You can encapsulate multiple such operations into a scope with an ARAEditGuard in order to invoke
the editable state of the DocumentController only once.
@tags{ARA}
*/
class AudioSource : public ManagedARAHandle<AudioSource, ARA::ARAAudioSourceRef>
{
public:
/** Returns an %ARA versioned struct with the `structSize` correctly set for the currently
used SDK version.
You should leave `structSize` unchanged, and fill out the rest of the fields appropriately
for the host implementation of the %ARA model object.
*/
static constexpr auto getEmptyProperties() { return makeARASizedStruct (&ARA::ARAAudioSourceProperties::merits64BitSamples); }
/** Creates an AudioSource object. During construction it registers an %ARA %AudioSource model
object with the DocumentController that refers to the provided hostRef. When this object
is deleted the corresponding DocumentController model object will also be deregistered.
You can acquire a correctly versioned `ARA::ARAAudioSourceProperties` struct by calling
getEmptyProperties().
Places the DocumentController in editable state.
@see ARAEditGuard
*/
AudioSource (ARA::ARAAudioSourceHostRef hostRef,
ARA::Host::DocumentController& dc,
const ARA::ARAAudioSourceProperties& props);
/** Destructor. Temporarily places the DocumentController in an editable state. */
~AudioSource() = default;
/** Updates the state of the corresponding %ARA model object.
Places the DocumentController in editable state.
You can use getEmptyProperties() to acquire a properties struct where the `structSize`
field has already been correctly set.
*/
void update (const ARA::ARAAudioSourceProperties& props);
/** Changes the plugin's access to the %AudioSource samples through the DocumentController.
Places the DocumentController in editable state.
*/
void enableAudioSourceSamplesAccess (bool);
/** Called by ManagedARAHandle to deregister the model object during the destruction of
AudioSource.
You shouldn't call this function manually.
*/
static void destroy (ARA::Host::DocumentController&, Ptr);
};
/** Helper class for the host side implementation of the %ARA %AudioModification model object.
Its intended use is to add a member variable of this type to your host side %AudioModification
implementation. Then it provides a RAII approach to managing the lifetime of the corresponding
objects created inside the DocumentController. When the host side object is instantiated an ARA
model object is also created in the DocumentController. When the host side object is deleted it
will be removed from the DocumentController as well.
The class will automatically put the DocumentController into editable state for operations that
mandate this e.g. creation, deletion or updating.
You can encapsulate multiple such operations into a scope with an ARAEditGuard in order to invoke
the editable state of the DocumentController only once.
@tags{ARA}
*/
class AudioModification : public ManagedARAHandle<AudioModification, ARA::ARAAudioModificationRef>
{
public:
/** Returns an %ARA versioned struct with the `structSize` correctly set for the currently
used SDK version.
You should leave `structSize` unchanged, and fill out the rest of the fields appropriately
for the host implementation of the %ARA model object.
*/
static constexpr auto getEmptyProperties()
{
return makeARASizedStruct (&ARA::ARAAudioModificationProperties::persistentID);
}
/** Creates an AudioModification object. During construction it registers an %ARA %AudioModification model
object with the DocumentController that refers to the provided hostRef. When this object
is deleted the corresponding DocumentController model object will also be deregistered.
You can acquire a correctly versioned `ARA::ARAAudioModificationProperties` struct by calling
getEmptyProperties().
Places the DocumentController in editable state.
@see ARAEditGuard
*/
AudioModification (ARA::ARAAudioModificationHostRef hostRef,
ARA::Host::DocumentController& dc,
AudioSource& s,
const ARA::ARAAudioModificationProperties& props);
/** Updates the state of the corresponding %ARA model object.
Places the DocumentController in editable state.
You can use getEmptyProperties() to acquire a properties struct where the `structSize`
field has already been correctly set.
*/
void update (const ARA::ARAAudioModificationProperties& props);
/** Returns the AudioSource containing this AudioModification. */
auto& getAudioSource() const { return source; }
/** Called by ManagedARAHandle to deregister the model object during the destruction of
AudioModification.
You shouldn't call this function manually.
*/
static void destroy (ARA::Host::DocumentController&, Ptr);
private:
AudioSource& source;
};
struct DeletionListener
{
virtual ~DeletionListener() = default;
virtual void removeListener (DeletionListener& other) noexcept = 0;
};
struct PlaybackRegion
{
public:
/** Returns an %ARA versioned struct with the `structSize` correctly set for the currently
used SDK version.
You should leave `structSize` unchanged, and fill out the rest of the fields appropriately
for the host implementation of the %ARA model object.
*/
static constexpr auto getEmptyProperties()
{
return makeARASizedStruct (&ARA::ARAPlaybackRegionProperties::color);
}
PlaybackRegion (ARA::ARAPlaybackRegionHostRef hostRef,
ARA::Host::DocumentController& dc,
AudioModification& m,
const ARA::ARAPlaybackRegionProperties& props);
~PlaybackRegion();
/** Updates the state of the corresponding %ARA model object.
Places the DocumentController in editable state.
You can use getEmptyProperties() to acquire a properties struct where the `structSize`
field has already been correctly set.
*/
void update (const ARA::ARAPlaybackRegionProperties& props);
/** Adds a DeletionListener object that will be notified when the PlaybackRegion object
is deleted.
Used by the PlaybackRegionRegistry.
@see PlaybackRendererInterface, EditorRendererInterface
*/
void addListener (DeletionListener& x);
/** Returns the AudioModification containing this PlaybackRegion. */
auto& getAudioModification() const;
/** Returns the plugin side reference to the PlaybackRegion */
ARA::ARAPlaybackRegionRef getPluginRef() const noexcept;
DeletionListener& getDeletionListener() const noexcept;
private:
class Impl;
std::unique_ptr<Impl> impl;
};
/** Helper class for the host side implementation of the %ARA %MusicalContext model object.
Its intended use is to add a member variable of this type to your host side %MusicalContext
implementation. Then it provides a RAII approach to managing the lifetime of the corresponding
objects created inside the DocumentController. When the host side object is instantiated an ARA
model object is also created in the DocumentController. When the host side object is deleted it
will be removed from the DocumentController as well.
The class will automatically put the DocumentController into editable state for operations that
mandate this e.g. creation, deletion or updating.
You can encapsulate multiple such operations into a scope with an ARAEditGuard in order to invoke
the editable state of the DocumentController only once.
@tags{ARA}
*/
class MusicalContext : public ManagedARAHandle<MusicalContext, ARA::ARAMusicalContextRef>
{
public:
/** Returns an %ARA versioned struct with the `structSize` correctly set for the currently
used SDK version.
You should leave `structSize` unchanged, and fill out the rest of the fields appropriately
for the host implementation of the %ARA model object.
*/
static constexpr auto getEmptyProperties()
{
return makeARASizedStruct (&ARA::ARAMusicalContextProperties::color);
}
/** Creates a MusicalContext object. During construction it registers an %ARA %MusicalContext model
object with the DocumentController that refers to the provided hostRef. When this object
is deleted the corresponding DocumentController model object will also be deregistered.
You can acquire a correctly versioned `ARA::ARAMusicalContextProperties` struct by calling
getEmptyProperties().
Places the DocumentController in editable state.
@see ARAEditGuard
*/
MusicalContext (ARA::ARAMusicalContextHostRef hostRef,
ARA::Host::DocumentController& dc,
const ARA::ARAMusicalContextProperties& props);
/** Updates the state of the corresponding %ARA model object.
Places the DocumentController in editable state.
You can use getEmptyProperties() to acquire a properties struct where the `structSize`
field has already been correctly set.
*/
void update (const ARA::ARAMusicalContextProperties& props);
/** Called by ManagedARAHandle to deregister the model object during the destruction of
AudioModification.
You shouldn't call this function manually.
*/
static void destroy (ARA::Host::DocumentController&, Ptr);
};
/** Helper class for the host side implementation of the %ARA %RegionSequence model object.
Its intended use is to add a member variable of this type to your host side %RegionSequence
implementation. Then it provides a RAII approach to managing the lifetime of the corresponding
objects created inside the DocumentController. When the host side object is instantiated an ARA
model object is also created in the DocumentController. When the host side object is deleted it
will be removed from the DocumentController as well.
The class will automatically put the DocumentController into editable state for operations that
mandate this e.g. creation, deletion or updating.
You can encapsulate multiple such operations into a scope with an ARAEditGuard in order to invoke
the editable state of the DocumentController only once.
@tags{ARA}
*/
class RegionSequence : public ManagedARAHandle<RegionSequence, ARA::ARARegionSequenceRef>
{
public:
/** Returns an %ARA versioned struct with the `structSize` correctly set for the currently
used SDK version.
You should leave `structSize` unchanged, and fill out the rest of the fields appropriately
for the host implementation of the %ARA model object.
*/
static constexpr auto getEmptyProperties()
{
return makeARASizedStruct (&ARA::ARARegionSequenceProperties::color);
}
/** Creates a RegionSequence object. During construction it registers an %ARA %RegionSequence model
object with the DocumentController that refers to the provided hostRef. When this object
is deleted the corresponding DocumentController model object will also be deregistered.
You can acquire a correctly versioned `ARA::ARARegionSequenceProperties` struct by calling
getEmptyProperties().
Places the DocumentController in editable state.
@see ARAEditGuard
*/
RegionSequence (ARA::ARARegionSequenceHostRef hostRef,
ARA::Host::DocumentController& dc,
const ARA::ARARegionSequenceProperties& props);
/** Updates the state of the corresponding %ARA model object.
Places the DocumentController in editable state.
You can use getEmptyProperties() to acquire a properties struct where the `structSize`
field has already been correctly set.
*/
void update (const ARA::ARARegionSequenceProperties& props);
/** Called by ManagedARAHandle to deregister the model object during the destruction of
AudioModification.
You shouldn't call this function manually.
*/
static void destroy (ARA::Host::DocumentController&, Ptr);
};
//==============================================================================
/** Base class used by the ::PlaybackRendererInterface and ::EditorRendererInterface
plugin extension interfaces.
Hosts will want to create one or typically more %ARA plugin extension instances per plugin for
the purpose of playback and editor rendering. The PlaybackRegions created by the host then have
to be assigned to these instances through the appropriate interfaces.
Whether a PlaybackRegion or an assigned RendererInterface is deleted first depends on the host
implementation and exact use case.
By using these helper classes you can ensure that the %ARA DocumentController remains in a
valid state in both situations. In order to use them acquire an object from
PlugInExtensionInstance::getPlaybackRendererInterface() or
PlugInExtensionInstance::getEditorRendererInterface().
Then call add() to register a PlaybackRegion with that particular PlugInExtensionInstance's
interface.
Now when you delete that PlaybackRegion it will be deregistered from that extension instance.
If however you want to delete the plugin extension instance before the PlaybackRegion, you can
delete the PlaybackRegionRegistry instance before deleting the plugin extension instance, which
takes care of deregistering all PlaybackRegions.
When adding or removing PlaybackRegions the plugin instance must be in an unprepared state i.e.
before AudioProcessor::prepareToPlay() or after AudioProcessor::releaseResources().
@code
auto playbackRenderer = std::make_unique<PlaybackRendererInterface> (plugInExtensionInstance.getPlaybackRendererInterface());
auto playbackRegion = std::make_unique<PlaybackRegion> (documentController, regionSequence, audioModification, audioSource);
// Either of the following three code variations are valid
// (1) ===================================================
playbackRenderer.add (playbackRegion);
playbackRenderer.remove (playbackRegion);
// (2) ===================================================
playbackRenderer.add (playbackRegion);
playbackRegion.reset();
// (3) ===================================================
playbackRenderer.add (playbackRegion);
playbackRenderer.reset();
@endcode
@see PluginExtensionInstance
@tags{ARA}
*/
template <typename RendererRef, typename Interface>
class PlaybackRegionRegistry
{
public:
PlaybackRegionRegistry() = default;
PlaybackRegionRegistry (RendererRef rendererRefIn, const Interface* interfaceIn)
: registry (std::make_unique<Registry> (rendererRefIn, interfaceIn))
{
}
/** Adds a PlaybackRegion to the corresponding ::PlaybackRendererInterface or ::EditorRendererInterface.
The plugin instance must be in an unprepared state i.e. before AudioProcessor::prepareToPlay() or
after AudioProcessor::releaseResources().
*/
void add (PlaybackRegion& region) { registry->add (region); }
/** Removes a PlaybackRegion from the corresponding ::PlaybackRendererInterface or ::EditorRendererInterface.
The plugin instance must be in an unprepared state i.e. before AudioProcessor::prepareToPlay() or
after AudioProcessor::releaseResources().
*/
void remove (PlaybackRegion& region) { registry->remove (region); }
/** Returns true if the underlying %ARA plugin extension instance fulfills the corresponding role. */
bool isValid() { return registry->isValid(); }
private:
class Registry : private DeletionListener
{
public:
Registry (RendererRef rendererRefIn, const Interface* interfaceIn)
: rendererRef (rendererRefIn), rendererInterface (interfaceIn)
{
}
Registry (const Registry&) = delete;
Registry (Registry&&) noexcept = delete;
Registry& operator= (const Registry&) = delete;
Registry& operator= (Registry&&) noexcept = delete;
~Registry() override
{
for (const auto& region : regions)
doRemoveListener (*region.first);
}
bool isValid() { return rendererRef != nullptr && rendererInterface != nullptr; }
void add (PlaybackRegion& region)
{
if (isValid())
rendererInterface->addPlaybackRegion (rendererRef, region.getPluginRef());
regions.emplace (&region.getDeletionListener(), region.getPluginRef());
region.addListener (*this);
}
void remove (PlaybackRegion& region)
{
doRemoveListener (region.getDeletionListener());
}
private:
void doRemoveListener (DeletionListener& listener) noexcept
{
listener.removeListener (*this);
removeListener (listener);
}
void removeListener (DeletionListener& listener) noexcept override
{
const auto it = regions.find (&listener);
if (it == regions.end())
{
jassertfalse;
return;
}
if (isValid())
rendererInterface->removePlaybackRegion (rendererRef, it->second);
regions.erase (it);
}
RendererRef rendererRef = nullptr;
const Interface* rendererInterface = nullptr;
std::map<DeletionListener*, ARA::ARAPlaybackRegionRef> regions;
};
std::unique_ptr<Registry> registry;
};
//==============================================================================
/** Helper class for managing the lifetimes of %ARA plugin extension instances and PlaybackRegions.
You can read more about its usage at PlaybackRegionRegistry.
@see PlaybackRegion, PlaybackRegionRegistry
@tags{ARA}
*/
using PlaybackRendererInterface = PlaybackRegionRegistry<ARA::ARAPlaybackRendererRef, ARA::ARAPlaybackRendererInterface>;
//==============================================================================
/** Helper class for managing the lifetimes of %ARA plugin extension instances and PlaybackRegions.
You can read more about its usage at PlaybackRegionRegistry.
@see PlaybackRegion, PlaybackRegionRegistry
@tags{ARA}
*/
using EditorRendererInterface = PlaybackRegionRegistry<ARA::ARAEditorRendererRef, ARA::ARAEditorRendererInterface>;
//==============================================================================
/** Wrapper class for `ARA::ARAPlugInExtensionInstance*`.
Returned by ARAHostDocumentController::bindDocumentToPluginInstance(). The corresponding
ARAHostDocumentController must remain valid as long as the plugin extension is in use.
*/
class PlugInExtensionInstance final
{
public:
/** Creates an empty PlugInExtensionInstance object.
Calling isValid() on such an object will return false.
*/
PlugInExtensionInstance() = default;
/** Creates a PlugInExtensionInstance object that wraps a `const ARA::ARAPlugInExtensionInstance*`.
The intended way to obtain a PlugInExtensionInstance object is to call
ARAHostDocumentController::bindDocumentToPluginInstance(), which is using this constructor.
*/
explicit PlugInExtensionInstance (const ARA::ARAPlugInExtensionInstance* instanceIn)
: instance (instanceIn)
{
}
/** Returns the PlaybackRendererInterface for the extension instance.
Depending on what roles were passed into
ARAHostDocumentController::bindDocumentToPluginInstance() one particular instance may not
fulfill a given role. You can use PlaybackRendererInterface::isValid() to see if this
interface was provided by the instance.
*/
PlaybackRendererInterface getPlaybackRendererInterface() const;
/** Returns the EditorRendererInterface for the extension instance.
Depending on what roles were passed into
ARAHostDocumentController::bindDocumentToPluginInstance() one particular instance may not
fulfill a given role. You can use EditorRendererInterface::isValid() to see if this
interface was provided by the instance.
*/
EditorRendererInterface getEditorRendererInterface() const;
/** Returns false if the PlugInExtensionInstance was default constructed and represents
no binding to an ARAHostDocumentController.
*/
bool isValid() const noexcept { return instance != nullptr; }
private:
const ARA::ARAPlugInExtensionInstance* instance = nullptr;
};
} // namespace ARAHostModel
//==============================================================================
/** Wrapper class for `ARA::Host::DocumentController`.
In order to create an ARAHostDocumentController from an ARAFactoryWrapper you must
provide at least two mandatory host side interfaces. You can create these implementations
by inheriting from the base classes in the `ARA::Host` namespace.
@tags{ARA}
*/
class ARAHostDocumentController final
{
public:
/** Factory function.
You must check if the returned pointer is valid.
*/
static std::unique_ptr<ARAHostDocumentController>
create (ARAFactoryWrapper factory,
const String& documentName,
std::unique_ptr<ARA::Host::AudioAccessControllerInterface> audioAccessController,
std::unique_ptr<ARA::Host::ArchivingControllerInterface> archivingController,
std::unique_ptr<ARA::Host::ContentAccessControllerInterface> contentAccessController = nullptr,
std::unique_ptr<ARA::Host::ModelUpdateControllerInterface> modelUpdateController = nullptr,
std::unique_ptr<ARA::Host::PlaybackControllerInterface> playbackController = nullptr);
~ARAHostDocumentController();
/** Returns the underlying ARA::Host::DocumentController reference. */
ARA::Host::DocumentController& getDocumentController() const;
/** Binds the ARAHostDocumentController and its enclosed document to a plugin instance.
The resulting ARAHostModel::PlugInExtensionInstance is responsible for fulfilling the
ARA specific roles of the plugin.
A single DocumentController can be bound to multiple plugin instances, which is a typical
practice among hosts.
*/
ARAHostModel::PlugInExtensionInstance bindDocumentToPluginInstance (AudioPluginInstance& instance,
ARA::ARAPlugInInstanceRoleFlags knownRoles,
ARA::ARAPlugInInstanceRoleFlags assignedRoles);
private:
class Impl;
std::unique_ptr<Impl> impl;
explicit ARAHostDocumentController (std::unique_ptr<Impl>&& implIn);
};
/** Calls the provided callback with an ARAFactoryWrapper object obtained from the provided
AudioPluginInstance.
If the provided AudioPluginInstance has no ARA extensions, the callback will be called with an
ARAFactoryWrapper that wraps a nullptr.
The object passed to the callback must be checked even if the plugin instance reports having
ARA extensions.
*/
void createARAFactoryAsync (AudioPluginInstance& instance, std::function<void (ARAFactoryWrapper)> cb);
} // namespace juce
//==============================================================================
#undef ARA_REF
#undef ARA_HOST_REF
#endif

+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_AU_Shared.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 12
- 4
source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -47,6 +54,7 @@ public:
StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive, bool) override; StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive, bool) override;
bool doesPluginStillExist (const PluginDescription&) override; bool doesPluginStillExist (const PluginDescription&) override;
FileSearchPath getDefaultLocationsToSearch() override; FileSearchPath getDefaultLocationsToSearch() override;
void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) override;
private: private:
//============================================================================== //==============================================================================


+ 291
- 241
source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -24,14 +31,15 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
#include <AudioUnit/AUCocoaUIView.h> #include <AudioUnit/AUCocoaUIView.h>
#include <CoreAudioKit/AUGenericView.h> #include <CoreAudioKit/AUGenericView.h>
#include <AudioToolbox/AudioUnitUtilities.h> #include <AudioToolbox/AudioUnitUtilities.h>
#endif
#include <CoreMIDI/MIDIServices.h>
#if JUCE_PLUGINHOST_ARA
#include <ARA_API/ARAAudioUnit.h>
#endif
#if JUCE_SUPPORT_CARBON
#include <AudioUnit/AudioUnitCarbonView.h>
#endif #endif
#include <CoreMIDI/MIDIServices.h>
#include <CoreAudioKit/AUViewController.h> #include <CoreAudioKit/AUViewController.h>
#include <juce_audio_basics/native/juce_mac_CoreAudioTimeConversions.h> #include <juce_audio_basics/native/juce_mac_CoreAudioTimeConversions.h>
@@ -426,8 +434,198 @@ namespace AudioUnitFormatHelpers
} }
} }
static bool hasARAExtension (AudioUnit audioUnit)
{
#if JUCE_PLUGINHOST_ARA
UInt32 propertySize = sizeof (ARA::ARAAudioUnitFactory);
Boolean isWriteable = FALSE;
OSStatus status = AudioUnitGetPropertyInfo (audioUnit,
ARA::kAudioUnitProperty_ARAFactory,
kAudioUnitScope_Global,
0,
&propertySize,
&isWriteable);
if ((status == noErr) && (propertySize == sizeof (ARA::ARAAudioUnitFactory)) && ! isWriteable)
return true;
#else
ignoreUnused (audioUnit);
#endif
return false;
}
struct AudioUnitDeleter
{
void operator() (AudioUnit au) const { AudioComponentInstanceDispose (au); }
};
using AudioUnitUniquePtr = std::unique_ptr<std::remove_pointer_t<AudioUnit>, AudioUnitDeleter>;
using AudioUnitSharedPtr = std::shared_ptr<std::remove_pointer_t<AudioUnit>>;
using AudioUnitWeakPtr = std::weak_ptr<std::remove_pointer_t<AudioUnit>>;
static std::shared_ptr<const ARA::ARAFactory> getARAFactory (AudioUnitSharedPtr audioUnit)
{
#if JUCE_PLUGINHOST_ARA
jassert (audioUnit != nullptr);
UInt32 propertySize = sizeof (ARA::ARAAudioUnitFactory);
ARA::ARAAudioUnitFactory audioUnitFactory { ARA::kARAAudioUnitMagic, nullptr };
if (hasARAExtension (audioUnit.get()))
{
OSStatus status = AudioUnitGetProperty (audioUnit.get(),
ARA::kAudioUnitProperty_ARAFactory,
kAudioUnitScope_Global,
0,
&audioUnitFactory,
&propertySize);
if ((status == noErr)
&& (propertySize == sizeof (ARA::ARAAudioUnitFactory))
&& (audioUnitFactory.inOutMagicNumber == ARA::kARAAudioUnitMagic))
{
jassert (audioUnitFactory.outFactory != nullptr);
return getOrCreateARAFactory (audioUnitFactory.outFactory,
[owningAuPtr = std::move (audioUnit)] (const ARA::ARAFactory*) {});
}
}
#else
ignoreUnused (audioUnit);
#endif
return {};
}
struct VersionedAudioComponent
{
AudioComponent audioComponent = nullptr;
bool isAUv3 = false;
bool operator< (const VersionedAudioComponent& other) const { return audioComponent < other.audioComponent; }
};
using AudioUnitCreationCallback = std::function<void (AudioUnit, OSStatus)>;
static void createAudioUnit (VersionedAudioComponent versionedComponent, AudioUnitCreationCallback callback)
{
struct AUAsyncInitializationCallback
{
typedef void (^AUCompletionCallbackBlock)(AudioComponentInstance, OSStatus);
explicit AUAsyncInitializationCallback (AudioUnitCreationCallback inOriginalCallback)
: originalCallback (std::move (inOriginalCallback))
{
block = CreateObjCBlock (this, &AUAsyncInitializationCallback::completion);
}
AUCompletionCallbackBlock getBlock() noexcept { return block; }
void completion (AudioComponentInstance audioUnit, OSStatus err)
{
originalCallback (audioUnit, err);
delete this;
}
double sampleRate;
int framesPerBuffer;
AudioUnitCreationCallback originalCallback;
ObjCBlock<AUCompletionCallbackBlock> block;
};
auto callbackBlock = new AUAsyncInitializationCallback (std::move (callback));
if (versionedComponent.isAUv3)
{
if (@available (macOS 10.11, *))
{
AudioComponentInstantiate (versionedComponent.audioComponent, kAudioComponentInstantiation_LoadOutOfProcess,
callbackBlock->getBlock());
return;
}
}
AudioComponentInstance audioUnit;
auto err = AudioComponentInstanceNew (versionedComponent.audioComponent, &audioUnit);
callbackBlock->completion (err != noErr ? nullptr : audioUnit, err);
}
struct AudioComponentResult
{
explicit AudioComponentResult (String error) : errorMessage (std::move (error)) {}
explicit AudioComponentResult (VersionedAudioComponent auComponent) : component (std::move (auComponent)) {}
bool isValid() const { return component.audioComponent != nullptr; }
VersionedAudioComponent component;
String errorMessage;
};
static AudioComponentResult getAudioComponent (AudioUnitPluginFormat& format, const PluginDescription& desc)
{
using namespace AudioUnitFormatHelpers;
AudioUnitPluginFormat audioUnitPluginFormat;
if (! format.fileMightContainThisPluginType (desc.fileOrIdentifier))
return AudioComponentResult { NEEDS_TRANS ("Plug-in description is not an AudioUnit plug-in") };
String pluginName, version, manufacturer;
AudioComponentDescription componentDesc;
AudioComponent auComponent;
String errMessage = NEEDS_TRANS ("Cannot find AudioUnit from description");
if (! getComponentDescFromIdentifier (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer)
&& ! getComponentDescFromFile (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer))
{
return AudioComponentResult { errMessage };
}
if ((auComponent = AudioComponentFindNext (nullptr, &componentDesc)) == nullptr)
{
return AudioComponentResult { errMessage };
}
if (AudioComponentGetDescription (auComponent, &componentDesc) != noErr)
{
return AudioComponentResult { errMessage };
}
const bool isAUv3 = AudioUnitFormatHelpers::isPluginAUv3 (componentDesc);
return AudioComponentResult { { auComponent, isAUv3 } };
}
static void getOrCreateARAAudioUnit (VersionedAudioComponent auComponent, std::function<void (AudioUnitSharedPtr)> callback)
{
static std::map<VersionedAudioComponent, AudioUnitWeakPtr> audioUnitARACache;
if (auto audioUnit = audioUnitARACache[auComponent].lock())
{
callback (std::move (audioUnit));
return;
}
createAudioUnit (auComponent, [auComponent, cb = std::move (callback)] (AudioUnit audioUnit, OSStatus err)
{
cb ([auComponent, audioUnit, err]() -> AudioUnitSharedPtr
{
if (err != noErr)
return nullptr;
AudioUnitSharedPtr auPtr { AudioUnitUniquePtr { audioUnit } };
audioUnitARACache[auComponent] = auPtr;
return auPtr;
}());
});
}
//============================================================================== //==============================================================================
class AudioUnitPluginWindowCarbon;
class AudioUnitPluginWindowCocoa; class AudioUnitPluginWindowCocoa;
//============================================================================== //==============================================================================
@@ -979,6 +1177,23 @@ public:
desc.numInputChannels = getTotalNumInputChannels(); desc.numInputChannels = getTotalNumInputChannels();
desc.numOutputChannels = getTotalNumOutputChannels(); desc.numOutputChannels = getTotalNumOutputChannels();
desc.isInstrument = (componentDesc.componentType == kAudioUnitType_MusicDevice); desc.isInstrument = (componentDesc.componentType == kAudioUnitType_MusicDevice);
#if JUCE_PLUGINHOST_ARA
desc.hasARAExtension = [&]
{
UInt32 propertySize = sizeof (ARA::ARAAudioUnitFactory);
Boolean isWriteable = FALSE;
OSStatus status = AudioUnitGetPropertyInfo (audioUnit,
ARA::kAudioUnitProperty_ARAFactory,
kAudioUnitScope_Global,
0,
&propertySize,
&isWriteable);
return (status == noErr) && (propertySize == sizeof (ARA::ARAAudioUnitFactory)) && ! isWriteable;
}();
#endif
} }
void getExtensions (ExtensionsVisitor& visitor) const override void getExtensions (ExtensionsVisitor& visitor) const override
@@ -993,6 +1208,33 @@ public:
}; };
visitor.visitAudioUnitClient (Extensions { this }); visitor.visitAudioUnitClient (Extensions { this });
#ifdef JUCE_PLUGINHOST_ARA
struct ARAExtensions : public ExtensionsVisitor::ARAClient
{
explicit ARAExtensions (const AudioUnitPluginInstance* instanceIn) : instance (instanceIn) {}
void createARAFactoryAsync (std::function<void (ARAFactoryWrapper)> cb) const override
{
getOrCreateARAAudioUnit ({ instance->auComponent, instance->isAUv3 },
[origCb = std::move (cb)] (auto dylibKeepAliveAudioUnit)
{
origCb ([&]() -> ARAFactoryWrapper
{
if (dylibKeepAliveAudioUnit != nullptr)
return ARAFactoryWrapper { ::juce::getARAFactory (std::move (dylibKeepAliveAudioUnit)) };
return ARAFactoryWrapper { nullptr };
}());
});
}
const AudioUnitPluginInstance* instance = nullptr;
};
if (hasARAExtension (audioUnit))
visitor.visitARAClient (ARAExtensions (this));
#endif
} }
void* getPlatformSpecificData() override { return audioUnit; } void* getPlatformSpecificData() override { return audioUnit; }
@@ -1124,9 +1366,9 @@ public:
{ {
if (prepared) if (prepared)
{ {
AudioUnitUninitialize (audioUnit);
resetBuses(); resetBuses();
AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0); AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0);
AudioUnitUninitialize (audioUnit);
outputBufferList.clear(); outputBufferList.clear();
prepared = false; prepared = false;
@@ -1615,7 +1857,6 @@ public:
private: private:
//============================================================================== //==============================================================================
friend class AudioUnitPluginWindowCarbon;
friend class AudioUnitPluginWindowCocoa; friend class AudioUnitPluginWindowCocoa;
friend class AudioUnitPluginFormat; friend class AudioUnitPluginFormat;
@@ -2594,162 +2835,12 @@ private:
} }
}; };
#if JUCE_SUPPORT_CARBON
//==============================================================================
class AudioUnitPluginWindowCarbon : public AudioProcessorEditor
{
public:
AudioUnitPluginWindowCarbon (AudioUnitPluginInstance& p)
: AudioProcessorEditor (&p),
plugin (p),
audioComponent (nullptr),
viewComponent (nullptr)
{
innerWrapper.reset (new InnerWrapperComponent (*this));
addAndMakeVisible (innerWrapper.get());
setOpaque (true);
setVisible (true);
setSize (400, 300);
UInt32 propertySize;
if (AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_GetUIComponentList,
kAudioUnitScope_Global, 0, &propertySize, NULL) == noErr
&& propertySize > 0)
{
HeapBlock<AudioComponentDescription> views (propertySize / sizeof (AudioComponentDescription));
if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_GetUIComponentList,
kAudioUnitScope_Global, 0, &views[0], &propertySize) == noErr)
{
audioComponent = AudioComponentFindNext (nullptr, &views[0]);
}
}
}
~AudioUnitPluginWindowCarbon()
{
innerWrapper = nullptr;
if (isValid())
plugin.editorBeingDeleted (this);
}
bool isValid() const noexcept { return audioComponent != nullptr; }
//==============================================================================
void paint (Graphics& g) override
{
g.fillAll (Colours::black);
}
void resized() override
{
if (innerWrapper != nullptr)
innerWrapper->setSize (getWidth(), getHeight());
}
//==============================================================================
bool keyStateChanged (bool) override { return false; }
bool keyPressed (const KeyPress&) override { return false; }
//==============================================================================
AudioUnit getAudioUnit() const { return plugin.audioUnit; }
AudioUnitCarbonView getViewComponent()
{
if (viewComponent == nullptr && audioComponent != nullptr)
AudioComponentInstanceNew (audioComponent, &viewComponent);
return viewComponent;
}
void closeViewComponent()
{
if (viewComponent != nullptr)
{
JUCE_AU_LOG ("Closing AU GUI: " + plugin.getName());
AudioComponentInstanceDispose (viewComponent);
viewComponent = nullptr;
}
}
private:
//==============================================================================
AudioUnitPluginInstance& plugin;
AudioComponent audioComponent;
AudioUnitCarbonView viewComponent;
//==============================================================================
class InnerWrapperComponent : public CarbonViewWrapperComponent
{
public:
InnerWrapperComponent (AudioUnitPluginWindowCarbon& w) : owner (w) {}
~InnerWrapperComponent()
{
deleteWindow();
}
HIViewRef attachView (WindowRef windowRef, HIViewRef rootView) override
{
JUCE_AU_LOG ("Opening AU GUI: " + owner.plugin.getName());
AudioUnitCarbonView carbonView = owner.getViewComponent();
if (carbonView == 0)
return 0;
Float32Point pos = { 0, 0 };
Float32Point size = { 250, 200 };
HIViewRef pluginView = 0;
AudioUnitCarbonViewCreate (carbonView, owner.getAudioUnit(), windowRef, rootView,
&pos, &size, (ControlRef*) &pluginView);
return pluginView;
}
void removeView (HIViewRef) override
{
owner.closeViewComponent();
}
private:
AudioUnitPluginWindowCarbon& owner;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerWrapperComponent)
};
friend class InnerWrapperComponent;
std::unique_ptr<InnerWrapperComponent> innerWrapper;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioUnitPluginWindowCarbon)
};
#endif
//============================================================================== //==============================================================================
AudioProcessorEditor* AudioUnitPluginInstance::createEditor() AudioProcessorEditor* AudioUnitPluginInstance::createEditor()
{ {
std::unique_ptr<AudioProcessorEditor> w (new AudioUnitPluginWindowCocoa (*this, false)); std::unique_ptr<AudioProcessorEditor> w (new AudioUnitPluginWindowCocoa (*this, false));
if (! static_cast<AudioUnitPluginWindowCocoa*> (w.get())->isValid()) if (! static_cast<AudioUnitPluginWindowCocoa*> (w.get())->isValid())
w.reset();
#if JUCE_SUPPORT_CARBON
if (w == nullptr)
{
w.reset (new AudioUnitPluginWindowCarbon (*this));
if (! static_cast<AudioUnitPluginWindowCarbon*> (w.get())->isValid())
w.reset();
}
#endif
if (w == nullptr)
w.reset (new AudioUnitPluginWindowCocoa (*this, true)); // use AUGenericView as a fallback w.reset (new AudioUnitPluginWindowCocoa (*this, true)); // use AUGenericView as a fallback
return w.release(); return w.release();
@@ -2795,95 +2886,54 @@ void AudioUnitPluginFormat::createPluginInstance (const PluginDescription& desc,
double rate, int blockSize, double rate, int blockSize,
PluginCreationCallback callback) PluginCreationCallback callback)
{ {
using namespace AudioUnitFormatHelpers;
auto auComponentResult = getAudioComponent (*this, desc);
if (fileMightContainThisPluginType (desc.fileOrIdentifier))
if (! auComponentResult.isValid())
{ {
String pluginName, version, manufacturer;
AudioComponentDescription componentDesc;
AudioComponent auComponent;
String errMessage = NEEDS_TRANS ("Cannot find AudioUnit from description");
if ((! getComponentDescFromIdentifier (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer))
&& (! getComponentDescFromFile (desc.fileOrIdentifier, componentDesc, pluginName, version, manufacturer)))
{
callback (nullptr, errMessage);
return;
}
if ((auComponent = AudioComponentFindNext (nullptr, &componentDesc)) == nullptr)
{
callback (nullptr, errMessage);
return;
}
if (AudioComponentGetDescription (auComponent, &componentDesc) != noErr)
{
callback (nullptr, errMessage);
return;
}
struct AUAsyncInitializationCallback
{
typedef void (^AUCompletionCallbackBlock)(AudioComponentInstance, OSStatus);
AUAsyncInitializationCallback (double inSampleRate, int inFramesPerBuffer,
PluginCreationCallback inOriginalCallback)
: sampleRate (inSampleRate), framesPerBuffer (inFramesPerBuffer),
originalCallback (std::move (inOriginalCallback))
{
block = CreateObjCBlock (this, &AUAsyncInitializationCallback::completion);
}
AUCompletionCallbackBlock getBlock() noexcept { return block; }
void completion (AudioComponentInstance audioUnit, OSStatus err)
{
if (err == noErr)
{
std::unique_ptr<AudioUnitPluginInstance> instance (new AudioUnitPluginInstance (audioUnit));
callback (nullptr, std::move (auComponentResult.errorMessage));
return;
}
if (instance->initialise (sampleRate, framesPerBuffer))
originalCallback (std::move (instance), {});
else
originalCallback (nullptr, NEEDS_TRANS ("Unable to initialise the AudioUnit plug-in"));
}
else
{
auto errMsg = TRANS ("An OS error occurred during initialisation of the plug-in (XXX)");
originalCallback (nullptr, errMsg.replace ("XXX", String (err)));
}
createAudioUnit (auComponentResult.component,
[rate, blockSize, origCallback = std::move (callback)] (AudioUnit audioUnit, OSStatus err)
{
if (err == noErr)
{
auto instance = std::make_unique<AudioUnitPluginInstance> (audioUnit);
delete this;
}
if (instance->initialise (rate, blockSize))
origCallback (std::move (instance), {});
else
origCallback (nullptr, NEEDS_TRANS ("Unable to initialise the AudioUnit plug-in"));
}
else
{
auto errMsg = TRANS ("An OS error occurred during initialisation of the plug-in (XXX)");
origCallback (nullptr, errMsg.replace ("XXX", String (err)));
}
});
}
double sampleRate;
int framesPerBuffer;
PluginCreationCallback originalCallback;
ObjCBlock<AUCompletionCallbackBlock> block;
};
void AudioUnitPluginFormat::createARAFactoryAsync (const PluginDescription& desc, ARAFactoryCreationCallback callback)
{
auto auComponentResult = getAudioComponent (*this, desc);
auto callbackBlock = new AUAsyncInitializationCallback (rate, blockSize, std::move (callback));
if (! auComponentResult.isValid())
{
callback ({ {}, "Failed to create AudioComponent for " + desc.descriptiveName });
return;
}
if (AudioUnitFormatHelpers::isPluginAUv3 (componentDesc))
{
if (@available (macOS 10.11, *))
getOrCreateARAAudioUnit (auComponentResult.component, [cb = std::move (callback)] (auto dylibKeepAliveAudioUnit)
{
cb ([&]() -> ARAFactoryResult
{ {
AudioComponentInstantiate (auComponent, kAudioComponentInstantiation_LoadOutOfProcess,
callbackBlock->getBlock());
if (dylibKeepAliveAudioUnit != nullptr)
return { ARAFactoryWrapper { ::juce::getARAFactory (std::move (dylibKeepAliveAudioUnit)) }, "" };
return;
}
}
AudioComponentInstance audioUnit;
auto err = AudioComponentInstanceNew(auComponent, &audioUnit);
callbackBlock->completion (err != noErr ? nullptr : audioUnit, err);
}
else
{
callback (nullptr, NEEDS_TRANS ("Plug-in description is not an AudioUnit plug-in"));
}
return { {}, "Failed to create ARAFactory from the provided AudioUnit" };
}());
});
} }
bool AudioUnitPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription& desc) const bool AudioUnitPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription& desc) const


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 51
- 41
source/modules/juce_audio_processors/format_types/juce_LV2Common.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -19,6 +26,7 @@
#pragma once #pragma once
#include "juce_lv2_config.h" #include "juce_lv2_config.h"
#include "juce_core/containers/juce_Optional.h"
#ifdef Bool #ifdef Bool
#undef Bool // previously defined in X11/Xlib.h #undef Bool // previously defined in X11/Xlib.h
@@ -127,61 +135,61 @@ struct ObjectTraits { static constexpr auto construct = lv2_atom_forge_object;
using SequenceFrame = ScopedFrame<SequenceTraits>; using SequenceFrame = ScopedFrame<SequenceTraits>;
using ObjectFrame = ScopedFrame<ObjectTraits>; using ObjectFrame = ScopedFrame<ObjectTraits>;
template <typename Value, typename Callback>
bool withValue (const Optional<Value>& opt, Callback&& callback)
{
if (! opt.hasValue())
return false;
callback (*opt);
return true;
}
struct NumericAtomParser struct NumericAtomParser
{ {
explicit NumericAtomParser (LV2_URID_Map mapFeatureIn) explicit NumericAtomParser (LV2_URID_Map mapFeatureIn)
: mapFeature (mapFeatureIn) {} : mapFeature (mapFeatureIn) {}
template <typename Type>
struct ParseResult
{
ParseResult (Type type) : value (type), successful (true) {}
ParseResult() : value(), successful (false) {}
template <typename Fn>
ParseResult andThen (Fn&& fn) const
{
if (successful)
fn (value);
template <typename T> struct Tag { LV2_URID urid; };
return *this;
}
template <typename Target, typename... Types>
static Optional<Target> tryParse (const LV2_Atom&, const void*)
{
return {};
}
operator bool() const noexcept { return successful; }
template <typename Target, typename Head, typename... Tail>
static Optional<Target> tryParse (const LV2_Atom& atom, const void* data, Tag<Head> head, Tag<Tail>... tail)
{
if (atom.type == head.urid && atom.size == sizeof (Head))
return static_cast<Target> (*reinterpret_cast<const Head*> (data));
Type value;
bool successful;
};
return tryParse<Target> (atom, data, tail...);
}
template <typename Target> template <typename Target>
ParseResult<Target> parseNumericAtom (const LV2_Atom* atom, const void* data) const
Optional<Target> parseNumericAtom (const LV2_Atom* atom, const void* data) const
{ {
if (atom == nullptr) if (atom == nullptr)
return {}; return {};
if (atom->type == mLV2_ATOM__Int && atom->size == sizeof (int32_t))
return { static_cast<Target> (*static_cast<const int32_t*> (data)) };
if (atom->type == mLV2_ATOM__Long && atom->size == sizeof (int64_t))
return { static_cast<Target> (*static_cast<const int64_t*> (data)) };
if (atom->type == mLV2_ATOM__Float && atom->size == sizeof (float))
return { static_cast<Target> (*static_cast<const float*> (data)) };
if (atom->type == mLV2_ATOM__Double && atom->size == sizeof (double))
return { static_cast<Target> (*static_cast<const double*> (data)) };
return {};
return tryParse<Target> (*atom,
data,
Tag<int32_t> { mLV2_ATOM__Bool },
Tag<int32_t> { mLV2_ATOM__Int },
Tag<int64_t> { mLV2_ATOM__Long },
Tag<float> { mLV2_ATOM__Float },
Tag<double> { mLV2_ATOM__Double });
} }
template <typename Target> template <typename Target>
ParseResult<Target> parseNumericAtom (const LV2_Atom* atom) const
Optional<Target> parseNumericAtom (const LV2_Atom* atom) const
{ {
return parseNumericAtom<Target> (atom, atom + 1); return parseNumericAtom<Target> (atom, atom + 1);
} }
template <typename Target> template <typename Target>
ParseResult<Target> parseNumericOption (const LV2_Options_Option* option) const
Optional<Target> parseNumericOption (const LV2_Options_Option* option) const
{ {
if (option != nullptr) if (option != nullptr)
{ {
@@ -240,8 +248,10 @@ struct PatchSetHelper
lv2_atom_object_query (object, query); lv2_atom_object_query (object, query);
if (isPlugin (subject))
setPluginProperty (property, value, std::forward<Callback> (callback));
if (! isPlugin (subject))
return;
setPluginProperty (property, value, std::forward<Callback> (callback));
} }
template <typename Callback> template <typename Callback>
@@ -270,14 +280,14 @@ struct PatchSetHelper
const auto parseResult = parser.parseNumericAtom<float> (value); const auto parseResult = parser.parseNumericAtom<float> (value);
if (! parseResult.successful)
if (! parseResult.hasValue())
{ {
// Didn't understand the type of this atom. // Didn't understand the type of this atom.
jassertfalse; jassertfalse;
return; return;
} }
callback.setParameter (reinterpret_cast<const LV2_Atom_URID*> (property)->body, parseResult.value);
callback.setParameter (reinterpret_cast<const LV2_Atom_URID*> (property)->body, *parseResult);
} }
NumericAtomParser parser; NumericAtomParser parser;


+ 83
- 69
source/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -30,12 +37,11 @@ namespace juce
namespace lv2_host namespace lv2_host
{ {
template <typename Struct, typename Member, typename Value>
auto with (Struct&& s, Member&& member, Value&& value) noexcept
template <typename Struct, typename Value>
auto with (Struct s, Value Struct::* member, Value value) noexcept
{ {
auto copy = std::forward<Struct> (s);
copy.*member = std::forward<Value> (value);
return copy;
s.*member = std::move (value);
return s;
} }
/* Converts a void* to an LV2_Atom* if the buffer looks like it holds a well-formed Atom, or /* Converts a void* to an LV2_Atom* if the buffer looks like it holds a well-formed Atom, or
@@ -1682,7 +1688,7 @@ private:
template <size_t Alignment> template <size_t Alignment>
static SingleSizeAlignedStorage<Alignment> grow (SingleSizeAlignedStorage<Alignment> storage, size_t size) static SingleSizeAlignedStorage<Alignment> grow (SingleSizeAlignedStorage<Alignment> storage, size_t size)
{ {
if (storage.size() <= size)
if (size <= storage.size())
return storage; return storage;
SingleSizeAlignedStorage<Alignment> newStorage { jmax (size, (storage.size() * 3) / 2) }; SingleSizeAlignedStorage<Alignment> newStorage { jmax (size, (storage.size() * 3) / 2) };
@@ -2122,6 +2128,8 @@ private:
JUCE_LEAK_DETECTOR (PortMap) JUCE_LEAK_DETECTOR (PortMap)
}; };
struct FreeString { void operator() (void* ptr) const noexcept { lilv_free (ptr); } };
class PluginState class PluginState
{ {
public: public:
@@ -2140,7 +2148,6 @@ public:
std::string toString (LilvWorld* world, LV2_URID_Map* map, LV2_URID_Unmap* unmap, const char* uri) const std::string toString (LilvWorld* world, LV2_URID_Map* map, LV2_URID_Unmap* unmap, const char* uri) const
{ {
struct FreeString { void operator() (void* ptr) const noexcept { lilv_free (ptr); } };
std::unique_ptr<char, FreeString> result { lilv_state_to_string (world, std::unique_ptr<char, FreeString> result { lilv_state_to_string (world,
map, map,
unmap, unmap,
@@ -2256,17 +2263,16 @@ struct UiDescriptorLibrary
class UiDescriptorArgs class UiDescriptorArgs
{ {
public: public:
const char* libraryPath = nullptr;
const char* uiUri = nullptr;
String libraryPath;
String uiUri;
auto withLibraryPath (const char* v) const noexcept { return with (&UiDescriptorArgs::libraryPath, v); }
auto withUiUri (const char* v) const noexcept { return with (&UiDescriptorArgs::uiUri, v); }
auto withLibraryPath (String v) const noexcept { return with (&UiDescriptorArgs::libraryPath, v); }
auto withUiUri (String v) const noexcept { return with (&UiDescriptorArgs::uiUri, v); }
private: private:
template <typename Member>
UiDescriptorArgs with (Member&& member, const char* value) const noexcept
UiDescriptorArgs with (String UiDescriptorArgs::* member, String value) const noexcept
{ {
return juce::lv2_host::with (*this, std::forward<Member> (member), value);
return juce::lv2_host::with (*this, member, std::move (value));
} }
}; };
@@ -2280,7 +2286,7 @@ public:
explicit UiDescriptor (const UiDescriptorArgs& args) explicit UiDescriptor (const UiDescriptorArgs& args)
: library (args.libraryPath), : library (args.libraryPath),
descriptor (extractUiDescriptor (library, args.uiUri))
descriptor (extractUiDescriptor (library, args.uiUri.toRawUTF8()))
{} {}
void portEvent (LV2UI_Handle ui, void portEvent (LV2UI_Handle ui,
@@ -2342,8 +2348,7 @@ private:
JUCE_LEAK_DETECTOR (UiDescriptor) JUCE_LEAK_DETECTOR (UiDescriptor)
}; };
enum class UpdateUi { no, yes };
enum class UpdateProcessor { no, yes };
enum class Update { no, yes };
/* A bit like the FlaggedFloatCache used by the VST3 host/client. /* A bit like the FlaggedFloatCache used by the VST3 host/client.
@@ -2366,12 +2371,12 @@ public:
size_t size() const noexcept { return values.size(); } size_t size() const noexcept { return values.size(); }
void set (size_t index, float value, UpdateUi updateUi, UpdateProcessor updateProcessor)
void set (size_t index, float value, Update update)
{ {
jassert (index < size()); jassert (index < size());
values[index].store (value, std::memory_order_relaxed); values[index].store (value, std::memory_order_relaxed);
needsUiUpdate .set (index, updateUi == UpdateUi::yes ? 1 : 0);
needsProcessorUpdate.set (index, updateProcessor == UpdateProcessor::yes ? 1 : 0);
needsUiUpdate .set (index, update == Update::yes ? 1 : 0);
needsProcessorUpdate.set (index, update == Update::yes ? 1 : 0);
} }
float get (size_t index) const noexcept float get (size_t index) const noexcept
@@ -2431,18 +2436,18 @@ public:
void setValue (float f) override void setValue (float f) override
{ {
cache.set ((size_t) getParameterIndex(), range.convertFrom0to1 (f), UpdateUi::yes, UpdateProcessor::yes);
cache.set ((size_t) getParameterIndex(), range.convertFrom0to1 (f), Update::yes);
} }
void setDenormalisedValueFromUi (float denormalised)
void setDenormalisedValue (float denormalised)
{ {
cache.set ((size_t) getParameterIndex(), denormalised, UpdateUi::no, UpdateProcessor::yes);
cache.set ((size_t) getParameterIndex(), denormalised, Update::yes);
sendValueChangedMessageToListeners (range.convertTo0to1 (denormalised)); sendValueChangedMessageToListeners (range.convertTo0to1 (denormalised));
} }
void setDenormalisedValueWithoutTriggeringUpdate (float denormalised) void setDenormalisedValueWithoutTriggeringUpdate (float denormalised)
{ {
cache.set ((size_t) getParameterIndex(), denormalised, UpdateUi::no, UpdateProcessor::no);
cache.set ((size_t) getParameterIndex(), denormalised, Update::no);
sendValueChangedMessageToListeners (range.convertTo0to1 (denormalised)); sendValueChangedMessageToListeners (range.convertTo0to1 (denormalised));
} }
@@ -2564,20 +2569,25 @@ private:
class UiInstanceArgs class UiInstanceArgs
{ {
public: public:
const char* bundlePath = nullptr;
const char* pluginUri = nullptr;
File bundlePath;
URL pluginUri;
auto withBundlePath (const char* v) const noexcept { return with (&UiInstanceArgs::bundlePath, v); }
auto withPluginUri (const char* v) const noexcept { return with (&UiInstanceArgs::pluginUri, v); }
auto withBundlePath (File v) const noexcept { return with (&UiInstanceArgs::bundlePath, std::move (v)); }
auto withPluginUri (URL v) const noexcept { return with (&UiInstanceArgs::pluginUri, std::move (v)); }
private: private:
template <typename Member> template <typename Member>
UiInstanceArgs with (Member&& member, const char* value) const noexcept
UiInstanceArgs with (Member UiInstanceArgs::* member, Member value) const noexcept
{ {
return juce::lv2_host::with (*this, std::forward<Member> (member), value);
return juce::lv2_host::with (*this, member, std::move (value));
} }
}; };
static File bundlePathFromUri (const char* uri)
{
return File { std::unique_ptr<char, FreeString> { lilv_file_uri_parse (uri, nullptr) }.get() };
}
/* /*
Creates and holds a UI instance for a plugin with a specific URI, using the provided descriptor. Creates and holds a UI instance for a plugin with a specific URI, using the provided descriptor.
*/ */
@@ -2665,14 +2675,14 @@ private:
using Instance = std::unique_ptr<void, void (*) (LV2UI_Handle)>; using Instance = std::unique_ptr<void, void (*) (LV2UI_Handle)>;
using Idle = int (*) (LV2UI_Handle); using Idle = int (*) (LV2UI_Handle);
Instance makeInstance (const char* pluginUri, const char* bundlePath, const LV2_Feature* const* features)
Instance makeInstance (const URL& pluginUri, const File& bundlePath, const LV2_Feature* const* features)
{ {
if (descriptor->get() == nullptr) if (descriptor->get() == nullptr)
return { nullptr, [] (LV2UI_Handle) {} }; return { nullptr, [] (LV2UI_Handle) {} };
return Instance { descriptor->get()->instantiate (descriptor->get(), return Instance { descriptor->get()->instantiate (descriptor->get(),
pluginUri,
bundlePath,
pluginUri.toString (false).toRawUTF8(),
File::addTrailingSeparator (bundlePath.getFullPathName()).toRawUTF8(),
writeFunction, writeFunction,
this, this,
&widget, &widget,
@@ -2752,10 +2762,9 @@ public:
auto withSampleRate (float v) const { return with (&UiFeaturesDataOptions::sampleRate, v); } auto withSampleRate (float v) const { return with (&UiFeaturesDataOptions::sampleRate, v); }
private: private:
template <typename Member, typename Value>
UiFeaturesDataOptions with (Member&& member, Value&& value) const
UiFeaturesDataOptions with (float UiFeaturesDataOptions::* member, float value) const
{ {
return juce::lv2_host::with (*this, std::forward<Member> (member), std::forward<Value> (value));
return juce::lv2_host::with (*this, member, value);
} }
}; };
@@ -3034,8 +3043,8 @@ public:
*this, *this,
touchListener, touchListener,
&uiDescriptor, &uiDescriptor,
UiInstanceArgs{}.withBundlePath (uiBundleUri.toRawUTF8())
.withPluginUri (instance.instance.getUri()),
UiInstanceArgs{}.withBundlePath (bundlePathFromUri (uiBundleUri.toRawUTF8()))
.withPluginUri (URL (instance.instance.getUri())),
viewComponent.getWidget(), viewComponent.getWidget(),
instance, instance,
opts)), opts)),
@@ -3168,14 +3177,6 @@ private:
float getEffectiveScale() const { return nativeScaleFactor * userScaleFactor; } float getEffectiveScale() const { return nativeScaleFactor * userScaleFactor; }
float getTopLevelDesktopScale() const
{
if (auto* comp = getTopLevelComponent())
return comp->getDesktopScaleFactor();
return 1.0f;
}
// If possible, try to keep platform-specific handing restricted to the implementation of // If possible, try to keep platform-specific handing restricted to the implementation of
// ViewComponent. Keep the interface of ViewComponent consistent on all platforms. // ViewComponent. Keep the interface of ViewComponent consistent on all platforms.
#if JUCE_LINUX || JUCE_BSD #if JUCE_LINUX || JUCE_BSD
@@ -4107,11 +4108,14 @@ static SupportedParameter getInfoForPatchParameter (World& worldIn,
jassertfalse; // A ScalePoint must have both a rdfs:label and a rdf:value jassertfalse; // A ScalePoint must have both a rdfs:label and a rdf:value
} }
const auto minimum = getValue (LV2_CORE__minimum, 0.0f);
const auto maximum = getValue (LV2_CORE__maximum, 1.0f);
return { { std::move (parsedScalePoints), return { { std::move (parsedScalePoints),
"des:" + String::fromUTF8 (property.getTyped()), "des:" + String::fromUTF8 (property.getTyped()),
getValue (LV2_CORE__default, 0.0f),
getValue (LV2_CORE__minimum, 0.0f),
getValue (LV2_CORE__maximum, 1.0f),
getValue (LV2_CORE__default, (minimum + maximum) * 0.5f),
minimum,
maximum,
typeUrid == urids.mLV2_ATOM__Bool || hasPortProperty (LV2_CORE__toggled), typeUrid == urids.mLV2_ATOM__Bool || hasPortProperty (LV2_CORE__toggled),
typeUrid == urids.mLV2_ATOM__Int || typeUrid == urids.mLV2_ATOM__Long, typeUrid == urids.mLV2_ATOM__Int || typeUrid == urids.mLV2_ATOM__Long,
hasPortProperty (LV2_CORE__enumeration) }, hasPortProperty (LV2_CORE__enumeration) },
@@ -4402,7 +4406,8 @@ public:
numSamples, numSamples,
sampleRate); sampleRate);
setStateInformation (mb.getData(), (int) mb.getSize());
// prepareToPlay is *guaranteed* not to be called concurrently with processBlock
setStateInformationImpl (mb.getData(), (int) mb.getSize(), ConcurrentWithAudioCallback::no);
jassert (numSamples == instance->features.getMaxBlockSize()); jassert (numSamples == instance->features.getMaxBlockSize());
@@ -4487,7 +4492,8 @@ public:
return; return;
lastAppliedPreset = newProgram; lastAppliedPreset = newProgram;
applyStateWithAppropriateLocking (loadStateWithUri (presetUris[(size_t) newProgram]));
applyStateWithAppropriateLocking (loadStateWithUri (presetUris[(size_t) newProgram]),
ConcurrentWithAudioCallback::yes);
} }
const String getProgramName (int program) override const String getProgramName (int program) override
@@ -4524,16 +4530,7 @@ public:
void setStateInformation (const void* data, int size) override void setStateInformation (const void* data, int size) override
{ {
JUCE_ASSERT_MESSAGE_THREAD;
if (data == nullptr || size == 0)
return;
auto begin = static_cast<const char*> (data);
std::vector<char> copy (begin, begin + size);
copy.push_back (0);
auto mapFeature = instance->symap->getMapFeature();
applyStateWithAppropriateLocking (PluginState { lilv_state_new_from_string (world->get(), &mapFeature, copy.data()) });
setStateInformationImpl (data, size, ConcurrentWithAudioCallback::yes);
} }
void setNonRealtime (bool newValue) noexcept override void setNonRealtime (bool newValue) noexcept override
@@ -4573,6 +4570,8 @@ public:
AudioProcessorParameter* getBypassParameter() const override { return bypassParam; } AudioProcessorParameter* getBypassParameter() const override { return bypassParam; }
private: private:
enum class ConcurrentWithAudioCallback { no, yes };
LV2AudioPluginInstance (std::shared_ptr<World> worldIn, LV2AudioPluginInstance (std::shared_ptr<World> worldIn,
const Plugin& pluginIn, const Plugin& pluginIn,
std::unique_ptr<InstanceWithSupports>&& in, std::unique_ptr<InstanceWithSupports>&& in,
@@ -4593,7 +4592,22 @@ private:
std::move (uiDescriptorIn), std::move (uiDescriptorIn),
[this] { postChangedParametersToUi(); }) [this] { postChangedParametersToUi(); })
{ {
applyStateWithAppropriateLocking (std::move (stateToApply));
applyStateWithAppropriateLocking (std::move (stateToApply), ConcurrentWithAudioCallback::no);
}
void setStateInformationImpl (const void* data, int size, ConcurrentWithAudioCallback concurrent)
{
JUCE_ASSERT_MESSAGE_THREAD;
if (data == nullptr || size == 0)
return;
auto begin = static_cast<const char*> (data);
std::vector<char> copy (begin, begin + size);
copy.push_back (0);
auto mapFeature = instance->symap->getMapFeature();
applyStateWithAppropriateLocking (PluginState { lilv_state_new_from_string (world->get(), &mapFeature, copy.data()) },
concurrent);
} }
// This does *not* destroy the editor component. // This does *not* destroy the editor component.
@@ -4691,13 +4705,13 @@ private:
return instance.get(); return instance.get();
} }
void applyStateWithAppropriateLocking (PluginState&& state)
void applyStateWithAppropriateLocking (PluginState&& state, ConcurrentWithAudioCallback concurrent)
{ {
PortMap portStateManager (instance->ports); PortMap portStateManager (instance->ports);
// If a plugin supports threadSafeRestore, its restore method is thread-safe // If a plugin supports threadSafeRestore, its restore method is thread-safe
// and may be called concurrently with audio class functions. // and may be called concurrently with audio class functions.
if (hasThreadSafeRestore)
if (hasThreadSafeRestore || concurrent == ConcurrentWithAudioCallback::no)
{ {
state.restore (*instance, portStateManager); state.restore (*instance, portStateManager);
} }
@@ -4841,7 +4855,7 @@ private:
if (auto* param = parameterValues.getParamByPortIndex (header.portIndex)) if (auto* param = parameterValues.getParamByPortIndex (header.portIndex))
{ {
param->setDenormalisedValueFromUi (value);
param->setDenormalisedValue (value);
} }
else if (auto* port = controlPortStructure.getControlPortByIndex (header.portIndex)) else if (auto* port = controlPortStructure.getControlPortByIndex (header.portIndex))
{ {


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LV2PluginFormat_test.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LV2Resources.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LV2SupportLibs.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 78
- 65
source/modules/juce_audio_processors/format_types/juce_VST3Common.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -1040,24 +1047,18 @@ public:
} }
} }
static void hostToPluginEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer,
Steinberg::Vst::IParameterChanges* parameterChanges,
const StoredMidiMapping& midiMapping)
template <typename Callback>
static void hostToPluginEventList (Steinberg::Vst::IEventList& result,
MidiBuffer& midiBuffer,
StoredMidiMapping& mapping,
Callback&& callback)
{ {
toEventList (result,
midiBuffer,
parameterChanges,
&midiMapping,
EventConversionKind::hostToPlugin);
toEventList (result, midiBuffer, &mapping, callback);
} }
static void pluginToHostEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer) static void pluginToHostEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer)
{ {
toEventList (result,
midiBuffer,
nullptr,
nullptr,
EventConversionKind::pluginToHost);
toEventList (result, midiBuffer, nullptr, [] (auto&&...) {});
} }
private: private:
@@ -1073,48 +1074,70 @@ private:
pluginToHost pluginToHost
}; };
static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer,
Steinberg::Vst::IParameterChanges* parameterChanges,
const StoredMidiMapping* midiMapping,
EventConversionKind kind)
template <typename Callback>
static bool sendMappedParameter (const MidiMessage& msg,
StoredMidiMapping* midiMapping,
Callback&& callback)
{ {
enum { maxNumEvents = 2048 }; // Steinberg's Host Checker states that no more than 2048 events are allowed at once
int numEvents = 0;
if (midiMapping == nullptr)
return false;
for (const auto metadata : midiBuffer)
{
if (++numEvents > maxNumEvents)
break;
const auto controlEvent = toVst3ControlEvent (msg);
auto msg = metadata.getMessage();
if (! controlEvent.hasValue())
return false;
if (midiMapping != nullptr && parameterChanges != nullptr)
{
Vst3MidiControlEvent controlEvent;
const auto controlParamID = midiMapping->getMapping (createSafeChannel (msg.getChannel()),
controlEvent->controllerNumber);
if (toVst3ControlEvent (msg, controlEvent))
{
const auto controlParamID = midiMapping->getMapping (createSafeChannel (msg.getChannel()),
controlEvent.controllerNumber);
if (controlParamID != Steinberg::Vst::kNoParamId)
callback (controlParamID, controlEvent->paramValue);
if (controlParamID != Steinberg::Vst::kNoParamId)
{
Steinberg::int32 ignore;
return true;
}
if (auto* queue = parameterChanges->addParameterData (controlParamID, ignore))
queue->addPoint (metadata.samplePosition, controlEvent.paramValue, ignore);
}
template <typename Callback>
static void processMidiMessage (Steinberg::Vst::IEventList& result,
const MidiMessageMetadata metadata,
StoredMidiMapping* midiMapping,
Callback&& callback)
{
const auto msg = metadata.getMessage();
continue;
}
}
if (sendMappedParameter (msg, midiMapping, std::forward<Callback> (callback)))
return;
if (auto maybeEvent = createVstEvent (msg, metadata.data, kind))
{
maybeEvent->busIndex = 0;
maybeEvent->sampleOffset = metadata.samplePosition;
result.addEvent (*maybeEvent);
}
const auto kind = midiMapping != nullptr ? EventConversionKind::hostToPlugin
: EventConversionKind::pluginToHost;
auto maybeEvent = createVstEvent (msg, metadata.data, kind);
if (! maybeEvent.hasValue())
return;
maybeEvent->busIndex = 0;
maybeEvent->sampleOffset = metadata.samplePosition;
result.addEvent (*maybeEvent);
}
/* If mapping is non-null, the conversion is assumed to be host-to-plugin, or otherwise
plugin-to-host.
*/
template <typename Callback>
static void toEventList (Steinberg::Vst::IEventList& result,
MidiBuffer& midiBuffer,
StoredMidiMapping* midiMapping,
Callback&& callback)
{
enum { maxNumEvents = 2048 }; // Steinberg's Host Checker states that no more than 2048 events are allowed at once
int numEvents = 0;
for (const auto metadata : midiBuffer)
{
if (++numEvents > maxNumEvents)
break;
processMidiMessage (result, metadata, midiMapping, std::forward<Callback> (callback));
} }
} }
@@ -1361,28 +1384,18 @@ private:
Steinberg::Vst::ParamValue paramValue; Steinberg::Vst::ParamValue paramValue;
}; };
static bool toVst3ControlEvent (const MidiMessage& msg, Vst3MidiControlEvent& result)
static Optional<Vst3MidiControlEvent> toVst3ControlEvent (const MidiMessage& msg)
{ {
if (msg.isController()) if (msg.isController())
{
result = { (Steinberg::Vst::CtrlNumber) msg.getControllerNumber(), msg.getControllerValue() / 127.0};
return true;
}
return Vst3MidiControlEvent { (Steinberg::Vst::CtrlNumber) msg.getControllerNumber(), msg.getControllerValue() / 127.0 };
if (msg.isPitchWheel()) if (msg.isPitchWheel())
{
result = { Steinberg::Vst::kPitchBend, msg.getPitchWheelValue() / 16383.0};
return true;
}
return Vst3MidiControlEvent { Steinberg::Vst::kPitchBend, msg.getPitchWheelValue() / 16383.0};
if (msg.isChannelPressure()) if (msg.isChannelPressure())
{
result = { Steinberg::Vst::kAfterTouch, msg.getChannelPressureValue() / 127.0};
return true;
}
return Vst3MidiControlEvent { Steinberg::Vst::kAfterTouch, msg.getChannelPressureValue() / 127.0};
result.controllerNumber = -1;
return false;
return {};
} }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiEventList) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiEventList)


+ 21
- 4
source/modules/juce_audio_processors/format_types/juce_VST3Headers.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -100,6 +107,8 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-copy-dtor",
#include <public.sdk/source/common/memorystream.h> #include <public.sdk/source/common/memorystream.h>
#include <public.sdk/source/vst/vsteditcontroller.h> #include <public.sdk/source/vst/vsteditcontroller.h>
#include <public.sdk/source/vst/vstpresetfile.h> #include <public.sdk/source/vst/vstpresetfile.h>
#include "pslextensions/ipslviewembedding.h"
#else #else
// needed for VST_VERSION // needed for VST_VERSION
#include <pluginterfaces/vst/vsttypes.h> #include <pluginterfaces/vst/vsttypes.h>
@@ -150,6 +159,8 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-copy-dtor",
#include <public.sdk/source/vst/hosting/pluginterfacesupport.cpp> #include <public.sdk/source/vst/hosting/pluginterfacesupport.cpp>
#endif #endif
#include "pslextensions/ipslviewembedding.h"
//============================================================================== //==============================================================================
namespace Steinberg namespace Steinberg
{ {
@@ -172,6 +183,12 @@ namespace Steinberg
DEF_CLASS_IID (Linux::IEventHandler) DEF_CLASS_IID (Linux::IEventHandler)
#endif #endif
} }
namespace Presonus
{
DEF_CLASS_IID (IPlugInViewEmbedding)
}
#endif // JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY #endif // JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
JUCE_END_IGNORE_WARNINGS_MSVC JUCE_END_IGNORE_WARNINGS_MSVC


+ 175
- 23
source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -20,6 +27,18 @@
#include "juce_VST3Headers.h" #include "juce_VST3Headers.h"
#include "juce_VST3Common.h" #include "juce_VST3Common.h"
#include "juce_ARACommon.h"
#if JUCE_PLUGINHOST_ARA && (JUCE_MAC || JUCE_WINDOWS)
#include <ARA_API/ARAVST3.h>
namespace ARA
{
DEF_CLASS_IID (IMainFactory)
DEF_CLASS_IID (IPlugInEntryPoint)
DEF_CLASS_IID (IPlugInEntryPoint2)
}
#endif
namespace juce namespace juce
{ {
@@ -804,6 +823,20 @@ struct DescriptionFactory
auto numClasses = factory->countClasses(); auto numClasses = factory->countClasses();
// Every ARA::IMainFactory must have a matching Steinberg::IComponent.
// The match is determined by the two classes having the same name.
std::unordered_set<String> araMainFactoryClassNames;
#if JUCE_PLUGINHOST_ARA && (JUCE_MAC || JUCE_WINDOWS)
for (Steinberg::int32 i = 0; i < numClasses; ++i)
{
PClassInfo info;
factory->getClassInfo (i, &info);
if (std::strcmp (info.category, kARAMainFactoryClass) == 0)
araMainFactoryClassNames.insert (info.name);
}
#endif
for (Steinberg::int32 i = 0; i < numClasses; ++i) for (Steinberg::int32 i = 0; i < numClasses; ++i)
{ {
PClassInfo info; PClassInfo info;
@@ -867,6 +900,9 @@ struct DescriptionFactory
} }
} }
if (araMainFactoryClassNames.find (name) != araMainFactoryClassNames.end())
desc.hasARAExtension = true;
if (desc.uniqueId != 0) if (desc.uniqueId != 0)
result = performOnDescription (desc); result = performOnDescription (desc);
@@ -1330,6 +1366,72 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3ModuleHandle) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3ModuleHandle)
}; };
template <typename Type, size_t N>
static int compareWithString (Type (&charArray)[N], const String& str)
{
return std::strncmp (str.toRawUTF8(),
charArray,
std::min (str.getNumBytesAsUTF8(), (size_t) numElementsInArray (charArray)));
}
template <typename Callback>
static void forEachARAFactory (IPluginFactory* pluginFactory, Callback&& cb)
{
#if JUCE_PLUGINHOST_ARA && (JUCE_MAC || JUCE_WINDOWS)
const auto numClasses = pluginFactory->countClasses();
for (Steinberg::int32 i = 0; i < numClasses; ++i)
{
PClassInfo info;
pluginFactory->getClassInfo (i, &info);
if (std::strcmp (info.category, kARAMainFactoryClass) == 0)
{
const bool keepGoing = cb (info);
if (! keepGoing)
break;
}
}
#else
ignoreUnused (pluginFactory, cb);
#endif
}
static std::shared_ptr<const ARA::ARAFactory> getARAFactory (Steinberg::IPluginFactory* pluginFactory, const String& pluginName)
{
std::shared_ptr<const ARA::ARAFactory> factory;
#if JUCE_PLUGINHOST_ARA && (JUCE_MAC || JUCE_WINDOWS)
forEachARAFactory (pluginFactory,
[&pluginFactory, &pluginName, &factory] (const auto& pcClassInfo)
{
if (compareWithString (pcClassInfo.name, pluginName) == 0)
{
ARA::IMainFactory* source;
if (pluginFactory->createInstance (pcClassInfo.cid, ARA::IMainFactory::iid, (void**) &source)
== Steinberg::kResultOk)
{
factory = getOrCreateARAFactory (source->getFactory(),
[source] (const ARA::ARAFactory*) { source->release(); });
return false;
}
jassert (source == nullptr);
}
return true;
});
#else
ignoreUnused (pluginFactory, pluginName);
#endif
return factory;
}
static std::shared_ptr<const ARA::ARAFactory> getARAFactory (VST3ModuleHandle& module)
{
auto* pluginFactory = module.getPluginFactory();
return getARAFactory (pluginFactory, module.getName());
}
//============================================================================== //==============================================================================
struct VST3PluginWindow : public AudioProcessorEditor, struct VST3PluginWindow : public AudioProcessorEditor,
private ComponentMovementWatcher, private ComponentMovementWatcher,
@@ -1677,6 +1779,27 @@ private:
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) // warning about overriding deprecated methods JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996) // warning about overriding deprecated methods
//==============================================================================
static bool hasARAExtension (IPluginFactory* pluginFactory, const String& pluginClassName)
{
bool result = false;
forEachARAFactory (pluginFactory,
[&pluginClassName, &result] (const auto& pcClassInfo)
{
if (compareWithString (pcClassInfo.name, pluginClassName) == 0)
{
result = true;
return false;
}
return true;
});
return result;
}
//============================================================================== //==============================================================================
struct VST3ComponentHolder struct VST3ComponentHolder
{ {
@@ -1802,6 +1925,8 @@ struct VST3ComponentHolder
totalNumInputChannels, totalNumInputChannels,
totalNumOutputChannels); totalNumOutputChannels);
description.hasARAExtension = hasARAExtension (factory, description.name);
return; return;
} }
@@ -2082,18 +2207,6 @@ public:
void setValue (float newValue) override void setValue (float newValue) override
{ {
pluginInstance.cachedParamValues.set (vstParamIndex, newValue); pluginInstance.cachedParamValues.set (vstParamIndex, newValue);
pluginInstance.parameterDispatcher.push (vstParamIndex, newValue);
}
/* If the editor set the value, there's no need to notify it that the parameter
value changed. Instead, we set the cachedValue (which will be read by the
processor during the next processBlock) and notify listeners that the parameter
has changed.
*/
void setValueFromEditor (float newValue)
{
pluginInstance.cachedParamValues.set (vstParamIndex, newValue);
sendValueChangedMessageToListeners (newValue);
} }
/* If we're syncing the editor to the processor, the processor won't need to /* If we're syncing the editor to the processor, the processor won't need to
@@ -2292,7 +2405,8 @@ public:
void getExtensions (ExtensionsVisitor& visitor) const override void getExtensions (ExtensionsVisitor& visitor) const override
{ {
struct Extensions : public ExtensionsVisitor::VST3Client
struct Extensions : public ExtensionsVisitor::VST3Client,
public ExtensionsVisitor::ARAClient
{ {
explicit Extensions (const VST3PluginInstance* instanceIn) : instance (instanceIn) {} explicit Extensions (const VST3PluginInstance* instanceIn) : instance (instanceIn) {}
@@ -2305,10 +2419,21 @@ public:
return instance->setStateFromPresetFile (rawData); return instance->setStateFromPresetFile (rawData);
} }
void createARAFactoryAsync (std::function<void (ARAFactoryWrapper)> cb) const noexcept override
{
cb (ARAFactoryWrapper { ::juce::getARAFactory (*(instance->holder->module)) });
}
const VST3PluginInstance* instance = nullptr; const VST3PluginInstance* instance = nullptr;
}; };
visitor.visitVST3Client (Extensions { this });
Extensions extensions { this };
visitor.visitVST3Client (extensions);
if (::juce::getARAFactory (*(holder->module)))
{
visitor.visitARAClient (extensions);
}
} }
void* getPlatformSpecificData() override { return holder->component; } void* getPlatformSpecificData() override { return holder->component; }
@@ -2559,6 +2684,11 @@ public:
inputParameterChanges->set (cachedParamValues.getParamID (index), value); inputParameterChanges->set (cachedParamValues.getParamID (index), value);
}); });
inputParameterChanges->forEach ([&] (Steinberg::int32 index, float value)
{
parameterDispatcher.push (index, value);
});
processor->process (data); processor->process (data);
outputParameterChanges->forEach ([&] (Steinberg::int32 index, float value) outputParameterChanges->forEach ([&] (Steinberg::int32 index, float value)
@@ -3024,7 +3154,9 @@ private:
{ {
Steinberg::MemoryStream stream; Steinberg::MemoryStream stream;
if (object->getState (&stream) == kResultTrue)
const auto result = object->getState (&stream);
if (result == kResultTrue)
{ {
MemoryBlock info (stream.getData(), (size_t) stream.getSize()); MemoryBlock info (stream.getData(), (size_t) stream.getSize());
head.createNewChildElement (identifier)->addTextElement (info.toBase64Encoding()); head.createNewChildElement (identifier)->addTextElement (info.toBase64Encoding());
@@ -3112,7 +3244,7 @@ private:
if ((paramInfo.flags & Vst::ParameterInfo::kIsBypass) != 0) if ((paramInfo.flags & Vst::ParameterInfo::kIsBypass) != 0)
bypassParam = param; bypassParam = param;
std::function<AudioProcessorParameterGroup*(Vst::UnitID)> findOrCreateGroup;
std::function<AudioProcessorParameterGroup* (Vst::UnitID)> findOrCreateGroup;
findOrCreateGroup = [&groupMap, &infoMap, &findOrCreateGroup] (Vst::UnitID groupID) findOrCreateGroup = [&groupMap, &infoMap, &findOrCreateGroup] (Vst::UnitID groupID)
{ {
auto existingGroup = groupMap.find (groupID); auto existingGroup = groupMap.find (groupID);
@@ -3322,8 +3454,12 @@ private:
{ {
MidiEventList::hostToPluginEventList (*midiInputs, MidiEventList::hostToPluginEventList (*midiInputs,
midiBuffer, midiBuffer,
destination.inputParameterChanges,
storedMidiMapping);
storedMidiMapping,
[this] (const auto controlID, const auto paramValue)
{
if (auto* param = this->getParameterForID (controlID))
param->setValueNotifyingHost ((float) paramValue);
});
} }
destination.inputEvents = midiInputs; destination.inputEvents = midiInputs;
@@ -3468,7 +3604,7 @@ tresult VST3HostContext::performEdit (Vst::ParamID paramID, Vst::ParamValue valu
if (auto* param = plugin->getParameterForID (paramID)) if (auto* param = plugin->getParameterForID (paramID))
{ {
param->setValueFromEditor ((float) valueNormalised);
param->setValueNotifyingHost ((float) valueNormalised);
// did the plug-in already update the parameter internally // did the plug-in already update the parameter internally
if (plugin->editController->getParamNormalized (paramID) != (float) valueNormalised) if (plugin->editController->getParamNormalized (paramID) != (float) valueNormalised)
@@ -3670,6 +3806,22 @@ void VST3PluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& resul
} }
} }
void VST3PluginFormat::createARAFactoryAsync (const PluginDescription& description, ARAFactoryCreationCallback callback)
{
if (! description.hasARAExtension)
{
jassertfalse;
callback ({ {}, "The provided plugin does not support ARA features" });
}
File file (description.fileOrIdentifier);
VSTComSmartPtr<IPluginFactory> pluginFactory (
DLLHandleCache::getInstance()->findOrCreateHandle (file.getFullPathName()).getPluginFactory());
const auto* pluginName = description.name.toRawUTF8();
callback ({ ARAFactoryWrapper { ::juce::getARAFactory (pluginFactory, pluginName) }, {} });
}
void VST3PluginFormat::createPluginInstance (const PluginDescription& description, void VST3PluginFormat::createPluginInstance (const PluginDescription& description,
double, int, PluginCreationCallback callback) double, int, PluginCreationCallback callback)
{ {


+ 12
- 4
source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -61,6 +68,7 @@ public:
StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive, bool) override; StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive, bool) override;
bool doesPluginStillExist (const PluginDescription&) override; bool doesPluginStillExist (const PluginDescription&) override;
FileSearchPath getDefaultLocationsToSearch() override; FileSearchPath getDefaultLocationsToSearch() override;
void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) override;
private: private:
//============================================================================== //==============================================================================


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_VSTCommon.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 21
- 123
source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -1208,10 +1215,6 @@ struct VSTPluginInstance final : public AudioPluginInstance,
wantsMidiMessages = pluginCanDo ("receiveVstMidiEvent") > 0 || isSynthPlugin(); wantsMidiMessages = pluginCanDo ("receiveVstMidiEvent") > 0 || isSynthPlugin();
#if JUCE_MAC && JUCE_SUPPORT_CARBON
usesCocoaNSView = ((unsigned int) pluginCanDo ("hasCockosViewAsConfig") & 0xffff0000ul) == 0xbeef0000ul;
#endif
setLatencySamples (vstEffect->latency); setLatencySamples (vstEffect->latency);
} }
@@ -1949,7 +1952,6 @@ struct VSTPluginInstance final : public AudioPluginInstance,
ModuleHandle::Ptr vstModule; ModuleHandle::Ptr vstModule;
std::unique_ptr<VSTPluginFormat::ExtraFunctions> extraFunctions; std::unique_ptr<VSTPluginFormat::ExtraFunctions> extraFunctions;
bool usesCocoaNSView = false;
private: private:
//============================================================================== //==============================================================================
@@ -2719,18 +2721,8 @@ public:
#elif JUCE_MAC #elif JUCE_MAC
ignoreUnused (recursiveResize, pluginRefusesToResize, alreadyInside); ignoreUnused (recursiveResize, pluginRefusesToResize, alreadyInside);
#if JUCE_SUPPORT_CARBON
if (! plug.usesCocoaNSView)
{
carbonWrapper.reset (new CarbonWrapperComponent (*this));
addAndMakeVisible (carbonWrapper.get());
}
else
#endif
{
cocoaWrapper.reset (new NSViewComponentWithParent (plugin));
addAndMakeVisible (cocoaWrapper.get());
}
cocoaWrapper.reset (new NSViewComponentWithParent (plugin));
addAndMakeVisible (cocoaWrapper.get());
#endif #endif
activeVSTWindows.add (this); activeVSTWindows.add (this);
@@ -2756,9 +2748,6 @@ public:
closePluginWindow(); closePluginWindow();
#if JUCE_MAC #if JUCE_MAC
#if JUCE_SUPPORT_CARBON
carbonWrapper.reset();
#endif
cocoaWrapper.reset(); cocoaWrapper.reset();
#endif #endif
@@ -2787,11 +2776,6 @@ public:
setSize (correctedBounds.getWidth(), correctedBounds.getHeight()); setSize (correctedBounds.getWidth(), correctedBounds.getHeight());
#if JUCE_MAC #if JUCE_MAC
#if JUCE_SUPPORT_CARBON
if (carbonWrapper != nullptr)
carbonWrapper->setSize (correctedBounds.getWidth(), correctedBounds.getHeight());
#endif
if (cocoaWrapper != nullptr) if (cocoaWrapper != nullptr)
cocoaWrapper->setSize (correctedBounds.getWidth(), correctedBounds.getHeight()); cocoaWrapper->setSize (correctedBounds.getWidth(), correctedBounds.getHeight());
#endif #endif
@@ -2807,25 +2791,19 @@ public:
void visibilityChanged() override void visibilityChanged() override
{ {
if (cocoaWrapper != nullptr)
{
if (isShowing())
openPluginWindow ((NSView*) cocoaWrapper->getView());
else
closePluginWindow();
}
if (isShowing())
openPluginWindow ((NSView*) cocoaWrapper->getView());
else
closePluginWindow();
} }
void childBoundsChanged (Component*) override void childBoundsChanged (Component*) override
{ {
if (cocoaWrapper != nullptr)
{
auto w = cocoaWrapper->getWidth();
auto h = cocoaWrapper->getHeight();
auto w = cocoaWrapper->getWidth();
auto h = cocoaWrapper->getHeight();
if (w != getWidth() || h != getHeight())
setSize (w, h);
}
if (w != getWidth() || h != getHeight())
setSize (w, h);
} }
void parentHierarchyChanged() override { visibilityChanged(); } void parentHierarchyChanged() override { visibilityChanged(); }
@@ -3304,86 +3282,6 @@ private:
//============================================================================== //==============================================================================
#if JUCE_MAC #if JUCE_MAC
#if JUCE_SUPPORT_CARBON
struct CarbonWrapperComponent : public CarbonViewWrapperComponent
{
CarbonWrapperComponent (VSTPluginWindow& w) : owner (w)
{
keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow();
setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated());
}
~CarbonWrapperComponent()
{
deleteWindow();
}
HIViewRef attachView (WindowRef windowRef, HIViewRef /*rootView*/) override
{
owner.openPluginWindow (windowRef);
return {};
}
void removeView (HIViewRef) override
{
if (owner.isOpen)
{
owner.isOpen = false;
owner.dispatch (Vst2::plugInOpcodeCloseEditor, 0, 0, 0, 0);
owner.dispatch (Vst2::plugInOpcodeSleepEditor, 0, 0, 0, 0);
}
}
bool getEmbeddedViewSize (int& w, int& h) override
{
Vst2::VstEditorBounds* rect = nullptr;
owner.dispatch (Vst2::plugInOpcodeGetEditorBounds, 0, 0, &rect, 0);
w = rect->rightmost - rect->leftmost;
h = rect->lower - rect->upper;
return true;
}
void handleMouseDown (int x, int y) override
{
if (! alreadyInside)
{
alreadyInside = true;
getTopLevelComponent()->toFront (true);
owner.dispatch (Vst2::plugInOpcodeGetMouse, x, y, 0, 0);
alreadyInside = false;
}
else
{
PostEvent (::mouseDown, 0);
}
}
void handlePaint() override
{
if (auto* peer = getPeer())
{
auto pos = peer->globalToLocal (getScreenPosition());
Vst2::VstEditorBounds r;
r.leftmost = (int16) pos.getX();
r.upper = (int16) pos.getY();
r.rightmost = (int16) (r.leftmost + getWidth());
r.lower = (int16) (r.upper + getHeight());
owner.dispatch (Vst2::plugInOpcodeDrawEditor, 0, 0, &r, 0);
}
}
private:
VSTPluginWindow& owner;
bool alreadyInside = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CarbonWrapperComponent)
};
friend struct CarbonWrapperComponent;
std::unique_ptr<CarbonWrapperComponent> carbonWrapper;
#endif
std::unique_ptr<NSViewComponentWithParent> cocoaWrapper; std::unique_ptr<NSViewComponentWithParent> cocoaWrapper;
void resized() override void resized() override


+ 11
- 4
source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 190
- 0
source/modules/juce_audio_processors/format_types/pslextensions/ipslcontextinfo.h View File

@@ -0,0 +1,190 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : ipslcontextinfo.h
// Created by : PreSonus Software Ltd., 08/2013, last updated 11/2016
// Description : Context Information Interface
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _ipslcontextinfo_h
#define _ipslcontextinfo_h
#include "pluginterfaces/vst/vsttypes.h"
#include "pluginterfaces/base/falignpush.h"
namespace Presonus {
//************************************************************************************************
// IContextInfoProvider
/** Callback interface to access context information from the host. Implemented by the host
as extension of Steinberg::Vst::IComponentHandler.
The host might not be able to report all available attributes at all times. Please check the
return value of getContextInfoValue() and getContextInfoString(). It's not required to implement
IContextInfoHandler on the plug-in side, but we recommend to do so. The host will then call
notifyContextInfoChange() during initialization to inform the plug-in about the initial state of
the available attributes.
Usage Example:
IComponentHandler* handler;
FUnknownPtr<IContextInfoProvider> contextInfoProvider (handler);
void PLUGIN_API MyEditController::notifyContextInfoChange ()
{
int32 channelIndex = 0;
contextInfoProvider->getContextInfoValue (channelIndex, ContextInfo::kIndex);
TChar channelName[128] = {0};
contextInfoProvider->getContextInfoString (channelName, 128, ContextInfo::kName);
}
*/
//************************************************************************************************
struct IContextInfoProvider: Steinberg::FUnknown
{
/** Get context information by identifier. */
virtual Steinberg::tresult PLUGIN_API getContextInfoValue (Steinberg::int32& value, Steinberg::FIDString id) = 0;
/** Get context information by identifier. */
virtual Steinberg::tresult PLUGIN_API getContextInfoString (Steinberg::Vst::TChar* string, Steinberg::int32 maxCharCount, Steinberg::FIDString id) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IContextInfoProvider, 0x483e61ea, 0x17994494, 0x8199a35a, 0xebb35e3c)
//************************************************************************************************
// IContextInfoProvider2
/** Extension to IContextInfoProvider enabling the plug-in to modify host context information.
Values like volume or pan support both, numeric and string representation for get and set.*/
//************************************************************************************************
struct IContextInfoProvider2: IContextInfoProvider
{
using IContextInfoProvider::getContextInfoValue;
/** Get context information by identifier (floating-point). */
virtual Steinberg::tresult PLUGIN_API getContextInfoValue (double& value, Steinberg::FIDString id) = 0;
/** Set context information by identifier (floating-point). */
virtual Steinberg::tresult PLUGIN_API setContextInfoValue (Steinberg::FIDString id, double value) = 0;
/** Set context information by identifier (integer). */
virtual Steinberg::tresult PLUGIN_API setContextInfoValue (Steinberg::FIDString id, Steinberg::int32 value) = 0;
/** Set context information by identifier (string). */
virtual Steinberg::tresult PLUGIN_API setContextInfoString (Steinberg::FIDString id, Steinberg::Vst::TChar* string) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IContextInfoProvider2, 0x61e45968, 0x3d364f39, 0xb15e1733, 0x4944172b)
//************************************************************************************************
// IContextInfoHandler
/** Notification interface for context information changes. Implemented by the plug-in as extension of
Steinberg::Vst::IEditController. */
//************************************************************************************************
struct IContextInfoHandler: Steinberg::FUnknown
{
/** Called by the host if context information has changed. */
virtual void PLUGIN_API notifyContextInfoChange () = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IContextInfoHandler, 0xc3b17bc0, 0x2c174494, 0x80293402, 0xfbc4bbf8)
//************************************************************************************************
// IContextInfoHandler2
/** Replacement of IContextInfoHandler passing additional information about what changed on the host-side.
This interface will be preferred if implemented by the plug-in. It is required to
receive certain notifications like volume, pan, etc. */
//************************************************************************************************
struct IContextInfoHandler2: Steinberg::FUnknown
{
/** Called by the host if context information has changed.
The identifier (id) is empty for the inital update. */
virtual void PLUGIN_API notifyContextInfoChange (Steinberg::FIDString id) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IContextInfoHandler2, 0x31e29a7a, 0xe55043ad, 0x8b95b9b8, 0xda1fbe1e)
//************************************************************************************************
// Context Information Attributes
//************************************************************************************************
namespace ContextInfo
{
/** Channel types. */
enum ChannelType
{
kTrack = 0, ///< audio track
kBus, ///< audio bus
kFX, ///< FX channel
kSynth, ///< output of virtual instrument
kIn, ///< input from audio driver
kOut ///< output to audio driver (main or sub-out)
};
/** Channel index mode. */
enum ChannelIndexMode
{
kFlatIndex = 0, ///< channel indices are contiguous (example: track 1, track 2, bus 3, bus 4)
kPerTypeIndex ///< channel indices restarts at zero for each type (example: track 1, track 2, bus 1, bus 2)
};
// per instance
const Steinberg::FIDString kID = "id"; ///< (R) channel identifier, use to compare identity (string)
const Steinberg::FIDString kName = "name"; ///< (R/W) channel name, can be displayed to the user (string)
const Steinberg::FIDString kType = "type"; ///< (R) channel type (int32, see ChannelType enumeration)
const Steinberg::FIDString kMain = "main"; ///< (R) channel is main output (int32, 0: false, 1: true)
const Steinberg::FIDString kIndex = "index"; ///< (R) channel index (int32, starts at zero)
const Steinberg::FIDString kColor = "color"; ///< (R/W) channel color (int32: RGBA)
const Steinberg::FIDString kVisibility = "visibility"; ///< (R) channel visibility (int32, 0: false, 1: true)
const Steinberg::FIDString kSelected = "selected"; ///< (R/W) selection state, channel is selected exlusively and scrolled into view on write (int32, 0: false, 1: true)
const Steinberg::FIDString kMultiSelect = "multiselect"; ///< (W) select channel without unselecting others (int32, 0: false, 1: true)
const Steinberg::FIDString kFocused = "focused"; ///< (R) focus for user input when multiple channels are selected (int32, 0: false, 1: true)
const Steinberg::FIDString kRegionName = "regionName"; ///< (R) name of region/event for region/event-based effects (string)
const Steinberg::FIDString kRegionSelected = "regionSelected"; ///< (R) selection state of region/event for region/event-based effects (int32, 0: false, 1: true)
// per instance (requires IContextInfoHandler2 on plug-in side)
const Steinberg::FIDString kVolume = "volume"; ///< (R/W) volume factor [float, 0. = -oo dB, 1. = 0dB, etc.], also available as string
const Steinberg::FIDString kMaxVolume = "maxVolume"; ///< (R) maximum volume factor [float, 1. = 0dB], also available as string
const Steinberg::FIDString kPan = "pan"; ///< (R/W) stereo panning [float, < 0.5 = (L), 0.5 = (C), > 0.5 = (R)], also available as string
const Steinberg::FIDString kMute = "mute"; ///< (R/W) mute (int32, 0: false, 1: true)
const Steinberg::FIDString kSolo = "solo"; ///< (R/W) solo (int32, 0: false, 1: true)
const Steinberg::FIDString kSendCount = "sendcount"; ///< (R) send count [int]
const Steinberg::FIDString kSendLevel = "sendlevel"; ///< (R/W) send level factor, index is appended to id (e.g. "sendlevel0" for first), also available as string
const Steinberg::FIDString kMaxSendLevel = "maxSendlevel"; ///< (R) maximum send level factor, also available as string
// global
const Steinberg::FIDString kActiveDocumentID = "activeDocumentID"; ///< (R) active document identifier, use to get identity of the active document (string)
const Steinberg::FIDString kDocumentID = "documentID"; ///< (R) document identifier, use to compare identity (string)
const Steinberg::FIDString kDocumentName = "documentName"; ///< (R) document name, can be displayed to user (string)
const Steinberg::FIDString kDocumentFolder = "documentFolder"; ///< (R) document folder (string)
const Steinberg::FIDString kAudioFolder = "audioFolder"; ///< (R) folder for audio files (string)
const Steinberg::FIDString kIndexMode = "indexMode"; ///< (R) channel index mode (default is flat, see ChannelIndexMode enumeration)
}
} // namespace Presonus
#include "pluginterfaces/base/falignpop.h"
#endif // _ipslcontextinfo_h

+ 108
- 0
source/modules/juce_audio_processors/format_types/pslextensions/ipsleditcontroller.h View File

@@ -0,0 +1,108 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : ipsleditcontroller.h
// Created by : PreSonus Software Ltd., 02/2017, last updated 10/2017
// Description : Plug-in Edit Controller Extension Interface
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _ipsleditcontroller_h
#define _ipsleditcontroller_h
#include "pluginterfaces/vst/vsttypes.h"
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/falignpush.h"
namespace Steinberg {
namespace Vst {
class IEditController; }}
namespace Presonus {
/** Parameter extra flags. Used with IEditControllerExtra. */
enum ParamExtraFlags
{
kParamFlagMicroEdit = 1<<0 ///< parameter should be displayed in host micro view
};
/** Automation mode. Used with IEditControllerExtra. */
enum AutomationMode
{
kAutomationNone = 0, ///< no automation data available
kAutomationOff, ///< data available, but mode is set to off
kAutomationRead, ///< data + read mode
kAutomationTouch, ///< data + touch mode
kAutomationLatch, ///< data + latch mode
kAutomationWrite ///< data + write mode
};
/** Slave mode. Used with ISlaveControllerHandler. */
enum SlaveMode
{
kSlaveModeNormal, ///< plug-in used in different location following given master
kSlaveModeLowLatencyClone ///< plug-in used as hidden slave for low latency processing following given master
};
//************************************************************************************************
// IEditControllerExtra
/** Extension to Steinberg::Vst::IEditController with additonal flags and notifications
not available in the standard edit controller interface. */
//************************************************************************************************
struct IEditControllerExtra: Steinberg::FUnknown
{
/** Get extra flags for given parameter (see ParamExtraFlags). */
virtual Steinberg::int32 PLUGIN_API getParamExtraFlags (Steinberg::Vst::ParamID id) = 0;
/** Set automation mode for given parameter (see AutomationMode). */
virtual Steinberg::tresult PLUGIN_API setParamAutomationMode (Steinberg::Vst::ParamID id, Steinberg::int32 automationMode) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IEditControllerExtra, 0x50553fd9, 0x1d2c4c24, 0xb410f484, 0xc5fb9f3f)
//************************************************************************************************
// ISlaveControllerHandler
/** Extension to Steinberg::Vst::IEditController used to notify the plug-in about slave instances.
The host might decide to use "cloned" (slave) instances in various scenarios, e.g. to process
audio paths with different latencies simultaneously or to synchronize grouped plug-in instances
between multiple mixer channels - see SlaveMode. In this case multiple plug-in instances are active
at the same time even though it looks like one to the user, i.e. only the editor of the master
instance is visible and can be used to change parameters. The edit controller implementation has
to synchronize parameter changes between instances that aren't visible to the host internally.
*/
//************************************************************************************************
struct ISlaveControllerHandler: Steinberg::FUnknown
{
/** Add slave edit controller. Implementation must sync non-automatable parameters between
this instance (master) and given slave instance internally, i.e. when the master (this)
changes update all connected slaves.
*/
virtual Steinberg::tresult PLUGIN_API addSlave (Steinberg::Vst::IEditController* slave, Steinberg::int32 slaveMode) = 0;
/** Remove slave edit controller. */
virtual Steinberg::tresult PLUGIN_API removeSlave (Steinberg::Vst::IEditController* slave) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (ISlaveControllerHandler, 0xd93894bd, 0x67454c29, 0x977ae2f5, 0xdb380434)
} // namespace Presonus
#include "pluginterfaces/base/falignpop.h"
#endif // _ipsleditcontroller_h

+ 53
- 0
source/modules/juce_audio_processors/format_types/pslextensions/ipslgainreduction.h View File

@@ -0,0 +1,53 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : ipslgainreduction.h
// Created by : PreSonus Software Ltd., 03/2015
// Description : Plug-in Gain Reduction Interface
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _ipslgainreduction_h
#define _ipslgainreduction_h
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/falignpush.h"
namespace Presonus {
//************************************************************************************************
// IGainReductionInfo
/** Interface to report gain reduction imposed to the audio signal by the plug-in to the
host for display in the UI. Implemented by the VST3 edit controller class.
*/
//************************************************************************************************
struct IGainReductionInfo: Steinberg::FUnknown
{
/** Get current gain reduction for display. The returned value in dB is either 0.0 (no reduction)
or negative. The host calls this function periodically while the plug-in is active.
The value is used AS IS for UI display purposes, without imposing additional ballistics or
presentation latency compensation. Be sure to return zero if processing is bypassed internally.
For multiple reduction stages, please report the sum in dB here.
*/
virtual double PLUGIN_API getGainReductionValueInDb () = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IGainReductionInfo, 0x8e3c292c, 0x95924f9d, 0xb2590b1e, 0x100e4198)
} // namespace Presonus
#include "pluginterfaces/base/falignpop.h"
#endif // _ipslgainreduction_h

+ 121
- 0
source/modules/juce_audio_processors/format_types/pslextensions/ipslhostcommands.h View File

@@ -0,0 +1,121 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : ipslhostcommands.h
// Created by : PreSonus Software Ltd., 11/2009
// Description : Host Command Interface
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _ipslhostcommands_h
#define _ipslhostcommands_h
#include "pluginterfaces/vst/vsttypes.h"
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/falignpush.h"
namespace Steinberg {
class IPlugView; }
namespace Presonus {
struct ICommandList;
//************************************************************************************************
// IHostCommandHandler
/** Callback interface to access host-specific parameter commands to be integrated
into a context menu inside the plug-in editor. Implemented as extension of
Steinberg::Vst::IComponentHandler.
Please note that the intention of this set of interfaces is not to allow a generic menu
implementation. This is the responsibility of a GUI toolkit. It basically provides
a way to enumerate and execute commands anonymously, i.e. the plug-in does not have to
know the exact sematics of the commands and the host does not break the consistency of
the plug-in GUI.
Usage Example:
IComponentHandler* handler;
FUnknownPtr<IHostCommandHandler> commandHandler (handler);
if(commandHandler)
if(ICommandList* commandList = commandHandler->createParamCommands (kMyParamId))
{
FReleaser commandListReleaser (commandList);
commandHandler->popupCommandMenu (commandList, xPos, yPos);
}
*/
//************************************************************************************************
struct IHostCommandHandler: Steinberg::FUnknown
{
/** Create list of currently available host commands for given parameter.
The command list has a short lifecycle, it is recreated whenever
a context menu should appear. The returned pointer can be null, otherwise
it has to be released. */
virtual ICommandList* PLUGIN_API createParamCommands (Steinberg::Vst::ParamID tag) = 0;
/** Helper to popup a command menu at given position.
Coordinates are relative to view or in screen coordintes if view is null.
Can be used for testing purpose, if the plug-in does not have its own context menu implementation
or if it wants to use the look & feel of the host menu. This method is not supposed
to support command lists implemented by the plug-in. */
virtual Steinberg::tresult PLUGIN_API popupCommandMenu (ICommandList* commandList, Steinberg::int32 xPos, Steinberg::int32 yPos, Steinberg::IPlugView* view = 0) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IHostCommandHandler, 0xF92032CD, 0x7A84407C, 0xABE6F863, 0x058EA6C2)
//************************************************************************************************
// CommandInfo
/** Describes a single command. */
//************************************************************************************************
struct CommandInfo
{
Steinberg::Vst::String128 title; ///< command title (possibly localized into active host language)
Steinberg::int32 flags; ///< command flags
enum CommandFlags
{
kCanExecute = 1<<0, ///< used to display command enabled/disabled
kIsSeparator = 1<<1, ///< not a command, it's a separator
kIsChecked = 1<<2 ///< used to display command with a check mark
};
};
//************************************************************************************************
// ICommandList
/** Describes a list of commands. */
//************************************************************************************************
struct ICommandList: Steinberg::FUnknown
{
/** Returns the number of commands. */
virtual Steinberg::int32 PLUGIN_API getCommandCount () = 0;
/** Get command information for a given index. */
virtual Steinberg::tresult PLUGIN_API getCommandInfo (Steinberg::int32 index, CommandInfo& info) = 0;
/** Execute command at given index. */
virtual Steinberg::tresult PLUGIN_API executeCommand (Steinberg::int32 index) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (ICommandList, 0xC5A687DB, 0x82F344E9, 0xB378254A, 0x47C4D712)
} // namespace Presonus
#include "pluginterfaces/base/falignpop.h"
#endif // _ipslhostcommands_h

+ 53
- 0
source/modules/juce_audio_processors/format_types/pslextensions/ipslviewembedding.h View File

@@ -0,0 +1,53 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : ipslviewembedding.h
// Created by : PreSonus Software Ltd., 05/2012
// Description : Plug-in View Embedding Interface
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _ipslviewembedding_h
#define _ipslviewembedding_h
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/falignpush.h"
namespace Steinberg {
class IPlugView; }
namespace Presonus {
//************************************************************************************************
// IPlugInViewEmbedding
/** Support for plug-in view embedding, to be implemented by the VST3 controller class. */
//************************************************************************************************
class IPlugInViewEmbedding: public Steinberg::FUnknown
{
public:
/** Check if view embedding is supported. */
virtual Steinberg::TBool PLUGIN_API isViewEmbeddingSupported () = 0;
/** Inform plug-in that its view will be embedded. */
virtual Steinberg::tresult PLUGIN_API setViewIsEmbedded (Steinberg::IPlugView* view, Steinberg::TBool embedded) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IPlugInViewEmbedding, 0xda57e6d1, 0x1f3242d1, 0xad9c1a82, 0xfdb95695)
} // namespace Presonus
#include "pluginterfaces/base/falignpop.h"
#endif // _ipslviewembedding_h

+ 67
- 0
source/modules/juce_audio_processors/format_types/pslextensions/ipslviewscaling.h View File

@@ -0,0 +1,67 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : ipslviewscaling.h
// Created by : PreSonus Software Ltd., 03/2015
// Description : Plug-in View DPI Scaling Interface
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _ipslviewscaling_h
#define _ipslviewscaling_h
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/base/falignpush.h"
namespace Presonus {
//************************************************************************************************
// IPlugInViewScaling
/** Support for plug-in view content scaling, to be implemented by the VST3 IPlugView class.
On Windows, if a process is "DPI-aware" and the system DPI setting is different from the default
value of 96 DPI, the application is responsible to scale the contents of its windows accordingly,
including child windows provided by 3rd party plug-ins.
This interface is used by the host to inform the plug-in about the current scaling factor.
The scaling factor is used to convert user space coordinates aka DIPs (device-independent pixels)
to physical pixels on screen.
The plug-in has to be prepared to deal with the following scaling factors:
96 DPI = 100% scaling (factor = 1.0)
120 DPI = 125% scaling (factor = 1.25)
144 DPI = 150% scaling (factor = 1.5)
192 DPI = 200% scaling (factor = 2.0)
On Windows 8.1 or later DPI settings are per monitor. The scaling factor for a window can change
when it is moved between screens.
*/
//************************************************************************************************
struct IPlugInViewScaling: Steinberg::FUnknown
{
/** Inform the view about the current content scaling factor. The scaling factor can change
if the window is moved between screens.
*/
virtual Steinberg::tresult PLUGIN_API setContentScaleFactor (float factor) = 0;
static const Steinberg::FUID iid;
};
DECLARE_CLASS_IID (IPlugInViewScaling, 0x65ed9690, 0x8ac44525, 0x8aadef7a, 0x72ea703f)
} // namespace Presonus
#include "pluginterfaces/base/falignpop.h"
#endif // _ipslviewscaling_h

+ 57
- 0
source/modules/juce_audio_processors/format_types/pslextensions/pslauextensions.h View File

@@ -0,0 +1,57 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : pslauextensions.h
// Created by : PreSonus Software Ltd., 08/2017, last updated 10/2017
// Description : PreSonus-specific AU API Extensions
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _pslauextensions_h
#define _pslauextensions_h
#ifdef __cplusplus
namespace Presonus {
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////
// Property IDs
//////////////////////////////////////////////////////////////////////////////////////////////////
/** This AU property in the global scope is of type CFArrayRef and is writable by the host.
The elements of the array are of type CFDataRef which encapsulate SlaveMode structures.
For more details, please check the documentation of Presonus::ISlaveControllerHandler. */
static const AudioUnitPropertyID kSlaveEffectsPropID = 0x50534C01;
//////////////////////////////////////////////////////////////////////////////////////////////////
// Data types
//////////////////////////////////////////////////////////////////////////////////////////////////
enum SlaveMode
{
kSlaveModeNormal, ///< plug-in used in different location following given master
kSlaveModeLowLatencyClone ///< plug-in used as hidden slave for low latency processing following given master
};
//////////////////////////////////////////////////////////////////////////////////////////////////
struct SlaveEffect
{
AudioUnit unit; ///< Audio Unit reference
SInt32 mode; ///< SlaveMode
};
#ifdef __cplusplus
}
#endif
#endif // _pslauextensions_h

+ 111
- 0
source/modules/juce_audio_processors/format_types/pslextensions/pslvst2extensions.h View File

@@ -0,0 +1,111 @@
//************************************************************************************************
//
// PreSonus Plug-In Extensions
// Written and placed in the PUBLIC DOMAIN by PreSonus Software Ltd.
//
// Filename : pslvst2extensions.h
// Created by : PreSonus Software Ltd., 05/2012, last updated 08/2017
// Description : PreSonus-specific VST2 API Extensions
//
//************************************************************************************************
/*
DISCLAIMER:
The PreSonus Plug-In Extensions are host-specific extensions of existing proprietary technologies,
provided to the community on an AS IS basis. They are not part of any official 3rd party SDK and
PreSonus is not affiliated with the owner of the underlying technology in any way.
*/
//************************************************************************************************
#ifndef _pslvst2extensions_h
#define _pslvst2extensions_h
namespace Presonus {
//////////////////////////////////////////////////////////////////////////////////////////////////
// CanDo Strings
//////////////////////////////////////////////////////////////////////////////////////////////////
/** Identifiers to be passed to VST2's canDo() method. */
namespace PlugCanDos
{
/** Check if view can be resized by the host. */
static const char* canDoViewResize = "supportsViewResize";
/** Check if view can be embedded by the host. */
static const char* canDoViewEmbedding = "supportsViewEmbedding";
/** Check if view scaling for high-DPI is supported by the plug-in. */
static const char* canDoViewDpiScaling = "supportsViewDpiScaling";

/** Check if gain reduction reporting is supported by the plug-in. */
static const char* canDoGainReductionInfo = "supportsGainReductionInfo";

/** Check if slave effects are supported by plug-in. */
static const char* canDoSlaveEffects = "supportsSlaveEffects";
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// Opcodes
//////////////////////////////////////////////////////////////////////////////////////////////////
/** Vendor-specific opcodes a VST2 plug-in can implement to add non-standard features like
embedding its views as subview into the host, resizing from the host, high-DPI scaling, etc.
Embedding corresponds to the Presonus::IPlugInViewEmbedding VST3 extended interface.
Resizing works like VST3's checkSizeConstraint() and onSize() methods, VST3's canResize()
is defined via canDoViewResize.
For "DPI-aware" host applications on the Windows platform a similar mimic to the
Presonus::IPlugInViewScaling VST3 extended interface is defined here.
Gain reduction reporting corresponds to the Presonus::IGainReductionInfo VST3 interface.
Slave effect handling corresponds to the Presonus::ISlaveControllerHandler VST3 interface.
*/
enum Opcodes
{
/** PreSonus vendor ID - distinguishes our calls from other VST2 extensions.
Pass this vendor ID as "index" (aka "lArg1") parameter for vendor specific calls. */
kVendorID = 'PreS',
/** The host can suggest a new editor size, and the plug-in can modify the suggested
size to a suitable value if it cannot resize to the given values.
The ptrArg is a ERect* to the input/output rect. This differs from the ERect**
used by effEditGetRect, because here the rect is owned by the host, not the plug-in.
The result is 0 on failure, 1 on success. */
kEffEditCheckSizeConstraints = 'AeCc',
/** The host can set a new size after negotiating the size via the above
kEffEditCheckSizeConstraints, triggering the actual resizing.
The ptrArg is a ERect* to the input/output rect. This differs from the ERect**
used by effEditGetRect, because here the rect is owned by the host, not the plug-in.
The result is 0 on failure, 1 on success. */
kEffEditSetRect = 'AeSr',
/** When the view is embedded, it may need to adjust its UI, e.g. by suppressing
its built-in resizing facility because this is then controlled by the host.
The ptrArg is a VstInt32*, pointing to 0 to disable or to 1 to enable embedding.
Per default, embedding is disabled until the host calls this to indicate otherwise. */
kEffEditSetEmbedded = 'AeEm',
/** Inform the view about the current content scaling factor. The factor is passed in the opt argument.
For more details, please check the documentation of Presonus::IPlugInViewScaling. */
kEffEditSetContentScaleFactor = 'AeCs',
/** Get current gain reduction for display. The ptrArg is a float* to be set to the dB value.
For more details, please check the documentation of Presonus::IGainReductionInfo. */
kEffGetGainReductionValueInDb = 'GRdB',
/** Add slave effect. The ptrArg is a pointer to the slave AEffect, the 'opt' float transmits the mode (see enum SlaveMode).
For more details, please check the documentation of Presonus::ISlaveControllerHandler. */
kEffAddSlave = 'AdSl',
/** Remove slave effect. The ptrArg is a pointer to the slave AEffect.
For more details, please check the documentation of Presonus::ISlaveControllerHandler. */
kEffRemoveSlave = 'RmSl'
};
} // namespace Presonus
#endif // _pslvst2extensions_h

+ 35
- 19
source/modules/juce_audio_processors/juce_audio_processors.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -27,7 +34,9 @@
#define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#endif
#define JUCE_GUI_BASICS_INCLUDE_SCOPED_THREAD_DPI_AWARENESS_SETTER 1 #define JUCE_GUI_BASICS_INCLUDE_SCOPED_THREAD_DPI_AWARENESS_SETTER 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1 #define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1
@@ -36,14 +45,7 @@
#include <juce_core/containers/juce_Optional.h> #include <juce_core/containers/juce_Optional.h>
//============================================================================== //==============================================================================
#if JUCE_MAC
#if JUCE_SUPPORT_CARBON && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU)
#include <Carbon/Carbon.h>
#include <juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h>
#endif
#endif
#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && (JUCE_LINUX || JUCE_BSD)
#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && (JUCE_LINUX || JUCE_BSD) && ! JUCE_AUDIOPROCESSOR_NO_GUI
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <sys/utsname.h> #include <sys/utsname.h>
@@ -202,17 +204,23 @@ private:
#include "format_types/juce_LegacyAudioParameter.cpp" #include "format_types/juce_LegacyAudioParameter.cpp"
#include "processors/juce_AudioProcessor.cpp" #include "processors/juce_AudioProcessor.cpp"
#include "processors/juce_AudioPluginInstance.cpp" #include "processors/juce_AudioPluginInstance.cpp"
#include "processors/juce_AudioProcessorEditor.cpp"
#include "processors/juce_AudioProcessorGraph.cpp" #include "processors/juce_AudioProcessorGraph.cpp"
#include "processors/juce_GenericAudioProcessorEditor.cpp"
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#include "processors/juce_AudioProcessorEditor.cpp"
#include "processors/juce_GenericAudioProcessorEditor.cpp"
#endif
#include "processors/juce_PluginDescription.cpp" #include "processors/juce_PluginDescription.cpp"
#include "format_types/juce_ARACommon.cpp"
#include "format_types/juce_LADSPAPluginFormat.cpp" #include "format_types/juce_LADSPAPluginFormat.cpp"
#include "format_types/juce_VSTPluginFormat.cpp" #include "format_types/juce_VSTPluginFormat.cpp"
#include "format_types/juce_VST3PluginFormat.cpp" #include "format_types/juce_VST3PluginFormat.cpp"
#include "format_types/juce_AudioUnitPluginFormat.mm" #include "format_types/juce_AudioUnitPluginFormat.mm"
#include "scanning/juce_KnownPluginList.cpp"
#include "scanning/juce_PluginDirectoryScanner.cpp"
#include "scanning/juce_PluginListComponent.cpp"
#include "format_types/juce_ARAHosting.cpp"
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#include "scanning/juce_KnownPluginList.cpp"
#include "scanning/juce_PluginDirectoryScanner.cpp"
#include "scanning/juce_PluginListComponent.cpp"
#endif
#include "processors/juce_AudioProcessorParameterGroup.cpp" #include "processors/juce_AudioProcessorParameterGroup.cpp"
#include "utilities/juce_AudioProcessorParameterWithID.cpp" #include "utilities/juce_AudioProcessorParameterWithID.cpp"
#include "utilities/juce_RangedAudioParameter.cpp" #include "utilities/juce_RangedAudioParameter.cpp"
@@ -220,10 +228,13 @@ private:
#include "utilities/juce_AudioParameterInt.cpp" #include "utilities/juce_AudioParameterInt.cpp"
#include "utilities/juce_AudioParameterBool.cpp" #include "utilities/juce_AudioParameterBool.cpp"
#include "utilities/juce_AudioParameterChoice.cpp" #include "utilities/juce_AudioParameterChoice.cpp"
#include "utilities/juce_ParameterAttachments.cpp"
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#include "utilities/juce_ParameterAttachments.cpp"
#endif
#include "utilities/juce_AudioProcessorValueTreeState.cpp" #include "utilities/juce_AudioProcessorValueTreeState.cpp"
#include "utilities/juce_PluginHostType.cpp" #include "utilities/juce_PluginHostType.cpp"
#include "utilities/juce_NativeScaleFactorNotifier.cpp" #include "utilities/juce_NativeScaleFactorNotifier.cpp"
#include "utilities/ARA/juce_ARA_utils.cpp"
#include "format_types/juce_LV2PluginFormat.cpp" #include "format_types/juce_LV2PluginFormat.cpp"
@@ -231,3 +242,8 @@ private:
#include "format_types/juce_VST3PluginFormat_test.cpp" #include "format_types/juce_VST3PluginFormat_test.cpp"
#include "format_types/juce_LV2PluginFormat_test.cpp" #include "format_types/juce_LV2PluginFormat_test.cpp"
#endif #endif
#if JUCE_AUDIOPROCESSOR_NO_GUI
// commonly used classes in DSP code
namespace juce { Colour::Colour(juce::uint32) noexcept {} }
#endif

+ 44
- 12
source/modules/juce_audio_processors/juce_audio_processors.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -94,6 +101,17 @@
#define JUCE_PLUGINHOST_LV2 0 #define JUCE_PLUGINHOST_LV2 0
#endif #endif
/** Config: JUCE_PLUGINHOST_ARA
Enables the ARA plugin extension hosting classes. You will need to download the ARA SDK and specify the
path to it either in the Projucer, using juce_set_ara_sdk_path() in your CMake project file.
The directory can be obtained by recursively cloning https://github.com/Celemony/ARA_SDK and checking out
the tag releases/2.1.0.
*/
#ifndef JUCE_PLUGINHOST_ARA
#define JUCE_PLUGINHOST_ARA 0
#endif
/** Config: JUCE_CUSTOM_VST3_SDK /** Config: JUCE_CUSTOM_VST3_SDK
If enabled, the embedded VST3 SDK in JUCE will not be added to the project and instead you should If enabled, the embedded VST3 SDK in JUCE will not be added to the project and instead you should
add the path to your custom VST3 SDK to the project's header search paths. Most users shouldn't add the path to your custom VST3 SDK to the project's header search paths. Most users shouldn't
@@ -107,10 +125,6 @@
// #error "You need to set either the JUCE_PLUGINHOST_AU and/or JUCE_PLUGINHOST_VST and/or JUCE_PLUGINHOST_VST3 and/or JUCE_PLUGINHOST_LADSPA flags if you're using this module!" // #error "You need to set either the JUCE_PLUGINHOST_AU and/or JUCE_PLUGINHOST_VST and/or JUCE_PLUGINHOST_VST3 and/or JUCE_PLUGINHOST_LADSPA flags if you're using this module!"
#endif #endif
#if ! (defined (JUCE_SUPPORT_CARBON) || JUCE_64BIT || JUCE_IOS)
#define JUCE_SUPPORT_CARBON 1
#endif
#ifndef JUCE_SUPPORT_LEGACY_AUDIOPROCESSOR #ifndef JUCE_SUPPORT_LEGACY_AUDIOPROCESSOR
#define JUCE_SUPPORT_LEGACY_AUDIOPROCESSOR 1 #define JUCE_SUPPORT_LEGACY_AUDIOPROCESSOR 1
#endif #endif
@@ -119,18 +133,23 @@
#include "utilities/juce_VSTCallbackHandler.h" #include "utilities/juce_VSTCallbackHandler.h"
#include "utilities/juce_VST3ClientExtensions.h" #include "utilities/juce_VST3ClientExtensions.h"
#include "utilities/juce_NativeScaleFactorNotifier.h" #include "utilities/juce_NativeScaleFactorNotifier.h"
#include "format_types/juce_ARACommon.h"
#include "utilities/juce_ExtensionsVisitor.h" #include "utilities/juce_ExtensionsVisitor.h"
#include "processors/juce_AudioProcessorParameter.h" #include "processors/juce_AudioProcessorParameter.h"
#include "processors/juce_HostedAudioProcessorParameter.h" #include "processors/juce_HostedAudioProcessorParameter.h"
#include "processors/juce_AudioProcessorEditorHostContext.h" #include "processors/juce_AudioProcessorEditorHostContext.h"
#include "processors/juce_AudioProcessorEditor.h"
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#include "processors/juce_AudioProcessorEditor.h"
#endif
#include "processors/juce_AudioProcessorListener.h" #include "processors/juce_AudioProcessorListener.h"
#include "processors/juce_AudioProcessorParameterGroup.h" #include "processors/juce_AudioProcessorParameterGroup.h"
#include "processors/juce_AudioProcessor.h" #include "processors/juce_AudioProcessor.h"
#include "processors/juce_PluginDescription.h" #include "processors/juce_PluginDescription.h"
#include "processors/juce_AudioPluginInstance.h" #include "processors/juce_AudioPluginInstance.h"
#include "processors/juce_AudioProcessorGraph.h" #include "processors/juce_AudioProcessorGraph.h"
#include "processors/juce_GenericAudioProcessorEditor.h"
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#include "processors/juce_GenericAudioProcessorEditor.h"
#endif
#include "format/juce_AudioPluginFormat.h" #include "format/juce_AudioPluginFormat.h"
#include "format/juce_AudioPluginFormatManager.h" #include "format/juce_AudioPluginFormatManager.h"
#include "scanning/juce_KnownPluginList.h" #include "scanning/juce_KnownPluginList.h"
@@ -140,6 +159,7 @@
#include "format_types/juce_VST3PluginFormat.h" #include "format_types/juce_VST3PluginFormat.h"
#include "format_types/juce_VSTMidiEventList.h" #include "format_types/juce_VSTMidiEventList.h"
#include "format_types/juce_VSTPluginFormat.h" #include "format_types/juce_VSTPluginFormat.h"
#include "format_types/juce_ARAHosting.h"
#include "scanning/juce_PluginDirectoryScanner.h" #include "scanning/juce_PluginDirectoryScanner.h"
#include "scanning/juce_PluginListComponent.h" #include "scanning/juce_PluginListComponent.h"
#include "utilities/juce_AudioProcessorParameterWithID.h" #include "utilities/juce_AudioProcessorParameterWithID.h"
@@ -148,11 +168,23 @@
#include "utilities/juce_AudioParameterInt.h" #include "utilities/juce_AudioParameterInt.h"
#include "utilities/juce_AudioParameterBool.h" #include "utilities/juce_AudioParameterBool.h"
#include "utilities/juce_AudioParameterChoice.h" #include "utilities/juce_AudioParameterChoice.h"
#include "utilities/juce_ParameterAttachments.h"
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
#include "utilities/juce_ParameterAttachments.h"
#endif
#include "utilities/juce_AudioProcessorValueTreeState.h" #include "utilities/juce_AudioProcessorValueTreeState.h"
#include "utilities/juce_PluginHostType.h" #include "utilities/juce_PluginHostType.h"
#include "utilities/ARA/juce_ARA_utils.h"
//==============================================================================
// These declarations are here to avoid missing-prototype warnings in user code.
// This is here to avoid missing-prototype warnings in user code.
// If you're implementing a plugin, you should supply a body for // If you're implementing a plugin, you should supply a body for
// this function in your own code. // this function in your own code.
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter(); juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter();
// If you are implementing an ARA enabled plugin, you need to
// implement this function somewhere in the codebase by returning
// SubclassOfARADocumentControllerSpecialisation::createARAFactory<SubclassOfARADocumentControllerSpecialisation>();
#if JucePlugin_Enable_ARA
const ARA::ARAFactory* JUCE_CALLTYPE createARAFactory();
#endif

+ 40
- 0
source/modules/juce_audio_processors/juce_audio_processors_ara.cpp View File

@@ -0,0 +1,40 @@
/*
==============================================================================
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_core/system/juce_CompilerWarnings.h>
#include <juce_core/system/juce_TargetPlatform.h>
/* Having WIN32_LEAN_AND_MEAN defined at the point of including ARADebug.c will produce warnings.
To prevent such problems it's easiest to have it in its own translation unit.
*/
#if (JucePlugin_Enable_ARA || (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU))) && (JUCE_MAC || JUCE_WINDOWS)
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wgnu-zero-variadic-macro-arguments", "-Wmissing-prototypes")
#include <ARA_Library/Debug/ARADebug.c>
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#endif

+ 11
- 4
source/modules/juce_audio_processors/juce_audio_processors_lv2_libs.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 15
- 5
source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -43,12 +50,14 @@ AudioProcessor::AudioProcessor (const BusesProperties& ioConfig)
AudioProcessor::~AudioProcessor() AudioProcessor::~AudioProcessor()
{ {
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
{ {
const ScopedLock sl (activeEditorLock); const ScopedLock sl (activeEditorLock);
// ooh, nasty - the editor should have been deleted before its AudioProcessor. // ooh, nasty - the editor should have been deleted before its AudioProcessor.
jassert (activeEditor == nullptr); jassert (activeEditor == nullptr);
} }
#endif
#if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING
// This will fail if you've called beginParameterChangeGesture() for one // This will fail if you've called beginParameterChangeGesture() for one
@@ -867,6 +876,7 @@ void AudioProcessor::audioIOChanged (bool busNumberChanged, bool channelNumChang
processorLayoutsChanged(); processorLayoutsChanged();
} }
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
//============================================================================== //==============================================================================
void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept
{ {
@@ -903,6 +913,7 @@ AudioProcessorEditor* AudioProcessor::createEditorIfNeeded()
return ed; return ed;
} }
#endif
//============================================================================== //==============================================================================
void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData) void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData)
@@ -1241,7 +1252,6 @@ const char* AudioProcessor::getWrapperTypeDescription (AudioProcessor::WrapperTy
case AudioProcessor::wrapperType_VST3: return "VST3"; case AudioProcessor::wrapperType_VST3: return "VST3";
case AudioProcessor::wrapperType_AudioUnit: return "AU"; case AudioProcessor::wrapperType_AudioUnit: return "AU";
case AudioProcessor::wrapperType_AudioUnitv3: return "AUv3"; case AudioProcessor::wrapperType_AudioUnitv3: return "AUv3";
case AudioProcessor::wrapperType_RTAS: return "RTAS";
case AudioProcessor::wrapperType_AAX: return "AAX"; case AudioProcessor::wrapperType_AAX: return "AAX";
case AudioProcessor::wrapperType_Standalone: return "Standalone"; case AudioProcessor::wrapperType_Standalone: return "Standalone";
case AudioProcessor::wrapperType_Unity: return "Unity"; case AudioProcessor::wrapperType_Unity: return "Unity";


+ 41
- 6
source/modules/juce_audio_processors/processors/juce_AudioProcessor.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -24,7 +31,7 @@ namespace juce
Base class for audio processing classes or plugins. Base class for audio processing classes or plugins.
This is intended to act as a base class of audio processor that is general enough This is intended to act as a base class of audio processor that is general enough
to be wrapped as a VST, AU, RTAS, etc, or used internally.
to be wrapped as a VST, AU, AAX, etc, or used internally.
It is also used by the plugin hosting code as the wrapper around an instance It is also used by the plugin hosting code as the wrapper around an instance
of a loaded plugin. of a loaded plugin.
@@ -71,6 +78,12 @@ public:
doublePrecision doublePrecision
}; };
enum class Realtime
{
no,
yes
};
using ChangeDetails = AudioProcessorListener::ChangeDetails; using ChangeDetails = AudioProcessorListener::ChangeDetails;
//============================================================================== //==============================================================================
@@ -916,11 +929,27 @@ public:
*/ */
bool isNonRealtime() const noexcept { return nonRealtime; } bool isNonRealtime() const noexcept { return nonRealtime; }
/** Returns no if the processor is being run in an offline mode for rendering.
If the processor is being run live on realtime signals, this returns yes.
If the mode is unknown, this will assume it's realtime and return yes.
This value may be unreliable until the prepareToPlay() method has been called,
and could change each time prepareToPlay() is called.
@see setNonRealtime()
*/
Realtime isRealtime() const noexcept
{
return isNonRealtime() ? Realtime::no : Realtime::yes;
}
/** Called by the host to tell this processor whether it's being used in a non-realtime /** Called by the host to tell this processor whether it's being used in a non-realtime
capacity for offline rendering or bouncing. capacity for offline rendering or bouncing.
*/ */
virtual void setNonRealtime (bool isNonRealtime) noexcept; virtual void setNonRealtime (bool isNonRealtime) noexcept;
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
//============================================================================== //==============================================================================
/** Creates the processor's GUI. /** Creates the processor's GUI.
@@ -970,6 +999,7 @@ public:
This may call createEditor() internally to create the component. This may call createEditor() internally to create the component.
*/ */
AudioProcessorEditor* createEditorIfNeeded(); AudioProcessorEditor* createEditorIfNeeded();
#endif
//============================================================================== //==============================================================================
/** Returns the default number of steps for a parameter. /** Returns the default number of steps for a parameter.
@@ -1231,9 +1261,11 @@ public:
virtual CurveData getResponseCurve (CurveData::Type /*curveType*/) const { return {}; } virtual CurveData getResponseCurve (CurveData::Type /*curveType*/) const { return {}; }
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
//============================================================================== //==============================================================================
/** Not for public use - this is called before deleting an editor component. */ /** Not for public use - this is called before deleting an editor component. */
void editorBeingDeleted (AudioProcessorEditor*) noexcept; void editorBeingDeleted (AudioProcessorEditor*) noexcept;
#endif
/** Flags to indicate the type of plugin context in which a processor is being used. */ /** Flags to indicate the type of plugin context in which a processor is being used. */
enum WrapperType enum WrapperType
@@ -1243,7 +1275,6 @@ public:
wrapperType_VST3, wrapperType_VST3,
wrapperType_AudioUnit, wrapperType_AudioUnit,
wrapperType_AudioUnitv3, wrapperType_AudioUnitv3,
wrapperType_RTAS,
wrapperType_AAX, wrapperType_AAX,
wrapperType_Standalone, wrapperType_Standalone,
wrapperType_Unity, wrapperType_Unity,
@@ -1264,7 +1295,9 @@ public:
struct TrackProperties struct TrackProperties
{ {
String name; // The name of the track - this will be empty if the track name is not known String name; // The name of the track - this will be empty if the track name is not known
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
Colour colour; // The colour of the track - this will be transparentBlack if the colour is not known Colour colour; // The colour of the track - this will be transparentBlack if the colour is not known
#endif
// other properties may be added in the future // other properties may be added in the future
}; };
@@ -1513,7 +1546,9 @@ private:
//============================================================================== //==============================================================================
Array<AudioProcessorListener*> listeners; Array<AudioProcessorListener*> listeners;
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
Component::SafePointer<AudioProcessorEditor> activeEditor; Component::SafePointer<AudioProcessorEditor> activeEditor;
#endif
double currentSampleRate = 0; double currentSampleRate = 0;
int blockSize = 0, latencySamples = 0; int blockSize = 0, latencySamples = 0;
bool suspended = false; bool suspended = false;


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 13
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -1575,8 +1582,10 @@ bool AudioProcessorGraph::AudioGraphIOProcessor::producesMidi() const
bool AudioProcessorGraph::AudioGraphIOProcessor::isInput() const noexcept { return type == audioInputNode || type == midiInputNode; } bool AudioProcessorGraph::AudioGraphIOProcessor::isInput() const noexcept { return type == audioInputNode || type == midiInputNode; }
bool AudioProcessorGraph::AudioGraphIOProcessor::isOutput() const noexcept { return type == audioOutputNode || type == midiOutputNode; } bool AudioProcessorGraph::AudioGraphIOProcessor::isOutput() const noexcept { return type == audioOutputNode || type == midiOutputNode; }
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
bool AudioProcessorGraph::AudioGraphIOProcessor::hasEditor() const { return false; } bool AudioProcessorGraph::AudioGraphIOProcessor::hasEditor() const { return false; }
AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; } AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; }
#endif
int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; } int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() { return 0; }
int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; } int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; }


+ 15
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -357,8 +364,10 @@ public:
bool acceptsMidi() const override; bool acceptsMidi() const override;
bool producesMidi() const override; bool producesMidi() const override;
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
bool hasEditor() const override; bool hasEditor() const override;
AudioProcessorEditor* createEditor() override; AudioProcessorEditor* createEditor() override;
#endif
int getNumPrograms() override; int getNumPrograms() override;
int getCurrentProgram() override; int getCurrentProgram() override;
@@ -394,8 +403,10 @@ public:
bool acceptsMidi() const override; bool acceptsMidi() const override;
bool producesMidi() const override; bool producesMidi() const override;
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
bool hasEditor() const override { return false; } bool hasEditor() const override { return false; }
AudioProcessorEditor* createEditor() override { return nullptr; } AudioProcessorEditor* createEditor() override { return nullptr; }
#endif
int getNumPrograms() override { return 0; } int getNumPrograms() override { return 0; }
int getCurrentProgram() override { return 0; } int getCurrentProgram() override { return 0; }
void setCurrentProgram (int) override { } void setCurrentProgram (int) override { }


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/processors/juce_HostedAudioProcessorParameter.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 13
- 4
source/modules/juce_audio_processors/processors/juce_PluginDescription.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -72,6 +79,7 @@ std::unique_ptr<XmlElement> PluginDescription::createXml() const
e->setAttribute ("numInputs", numInputChannels); e->setAttribute ("numInputs", numInputChannels);
e->setAttribute ("numOutputs", numOutputChannels); e->setAttribute ("numOutputs", numOutputChannels);
e->setAttribute ("isShell", hasSharedContainer); e->setAttribute ("isShell", hasSharedContainer);
e->setAttribute ("hasARAExtension", hasARAExtension);
e->setAttribute ("uid", String::toHexString (deprecatedUid)); e->setAttribute ("uid", String::toHexString (deprecatedUid));
@@ -95,6 +103,7 @@ bool PluginDescription::loadFromXml (const XmlElement& xml)
numInputChannels = xml.getIntAttribute ("numInputs"); numInputChannels = xml.getIntAttribute ("numInputs");
numOutputChannels = xml.getIntAttribute ("numOutputs"); numOutputChannels = xml.getIntAttribute ("numOutputs");
hasSharedContainer = xml.getBoolAttribute ("isShell", false); hasSharedContainer = xml.getBoolAttribute ("isShell", false);
hasARAExtension = xml.getBoolAttribute ("hasARAExtension", false);
deprecatedUid = xml.getStringAttribute ("uid").getHexValue32(); deprecatedUid = xml.getStringAttribute ("uid").getHexValue32();
uniqueId = xml.getStringAttribute ("uniqueId", "0").getHexValue32(); uniqueId = xml.getStringAttribute ("uniqueId", "0").getHexValue32();


+ 14
- 4
source/modules/juce_audio_processors/processors/juce_PluginDescription.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -122,6 +129,9 @@ public:
/** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */ /** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */
bool hasSharedContainer = false; bool hasSharedContainer = false;
/** True if the plug-in is ARA enabled and can supply a valid ARAFactoryWrapper. */
bool hasARAExtension = false;
/** Returns true if the two descriptions refer to the same plug-in. /** Returns true if the two descriptions refer to the same plug-in.
This isn't quite as simple as them just having the same file (because of This isn't quite as simple as them just having the same file (because of


+ 11
- 4
source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/scanning/juce_KnownPluginList.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 971
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp View 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 += 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
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.h View 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. */
ARADocument* doCreateDocument();
/** Override to return a custom subclass instance of ARAMusicalContext. */
ARAMusicalContext* doCreateMusicalContext (ARADocument* document,
ARA::ARAMusicalContextHostRef hostRef);
/** Override to return a custom subclass instance of ARARegionSequence. */
ARARegionSequence* doCreateRegionSequence (ARADocument* document,
ARA::ARARegionSequenceHostRef hostRef);
/** Override to return a custom subclass instance of ARAAudioSource. */
ARAAudioSource* doCreateAudioSource (ARADocument* document,
ARA::ARAAudioSourceHostRef hostRef);
/** Override to return a custom subclass instance of ARAAudioModification. */
ARAAudioModification* doCreateAudioModification (ARAAudioSource* audioSource,
ARA::ARAAudioModificationHostRef hostRef,
const ARAAudioModification* optionalModificationToClone);
/** Override to return a custom subclass instance of ARAPlaybackRegion. */
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
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentControllerCommon.cpp View 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
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.cpp View 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
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARAModelObjects.h
File diff suppressed because it is too large
View File


+ 92
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.cpp View 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::CurrentPositionInfo& 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

+ 271
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARAPlugInInstanceRoles.h View File

@@ -0,0 +1,271 @@
/*
==============================================================================
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::CurrentPositionInfo& 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::CurrentPositionInfo& 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::CurrentPositionInfo& positionInfo) noexcept override
{
ignoreUnused (buffer, realtime, positionInfo);
return false;
}
// 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::CurrentPositionInfo& positionInfo) noexcept override
{
ignoreUnused (buffer, isNonRealtime, positionInfo);
return true;
}
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)
};
}

+ 32
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.cpp View File

@@ -0,0 +1,32 @@
/*
==============================================================================
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 "juce_ARADocumentControllerCommon.cpp"
#include "juce_ARADocumentController.cpp"
#include "juce_ARAModelObjects.cpp"
#include "juce_ARAPlugInInstanceRoles.cpp"
#include "juce_AudioProcessor_ARAExtensions.cpp"
#endif

+ 85
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_ARA_utils.h View 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

+ 156
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.cpp View File

@@ -0,0 +1,156 @@
/*
==============================================================================
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::CurrentPositionInfo& 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)
{
AudioPlayHead::CurrentPositionInfo positionInfo;
if (! isBoundToARA() || ! playhead || ! playhead->getCurrentPosition (positionInfo))
positionInfo.resetToDefault();
return processBlockForARA (buffer, realtime, 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
- 0
source/modules/juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.h View 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::CurrentPositionInfo& 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

+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 13
- 4
source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -466,6 +473,7 @@ void AudioProcessorValueTreeState::timerCallback()
} }
//============================================================================== //==============================================================================
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
template <typename Attachment, typename Control> template <typename Attachment, typename Control>
std::unique_ptr<Attachment> makeAttachment (const AudioProcessorValueTreeState& stateToUse, std::unique_ptr<Attachment> makeAttachment (const AudioProcessorValueTreeState& stateToUse,
const String& parameterID, const String& parameterID,
@@ -498,6 +506,7 @@ AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessor
: attachment (makeAttachment<ButtonParameterAttachment> (stateToUse, parameterID, button)) : attachment (makeAttachment<ButtonParameterAttachment> (stateToUse, parameterID, button))
{ {
} }
#endif
//============================================================================== //==============================================================================
//============================================================================== //==============================================================================


+ 13
- 4
source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -519,6 +526,7 @@ public:
friend class AudioProcessorValueTreeState::ParameterAdapter; friend class AudioProcessorValueTreeState::ParameterAdapter;
}; };
#if ! JUCE_AUDIOPROCESSOR_NO_GUI
//============================================================================== //==============================================================================
/** An object of this class maintains a connection between a Slider and a parameter /** An object of this class maintains a connection between a Slider and a parameter
in an AudioProcessorValueTreeState. in an AudioProcessorValueTreeState.
@@ -586,6 +594,7 @@ public:
std::unique_ptr<ButtonParameterAttachment> attachment; std::unique_ptr<ButtonParameterAttachment> attachment;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAttachment) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAttachment)
}; };
#endif
private: private:
//============================================================================== //==============================================================================


+ 22
- 5
source/modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
@@ -30,7 +37,7 @@ namespace Steinberg
#endif #endif
//============================================================================== //==============================================================================
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(AUDIOCOMPONENT_NOCARBONINSTANCES) && AUDIOCOMPONENT_NOCARBONINSTANCES)
#if TARGET_OS_IPHONE
struct OpaqueAudioComponentInstance; struct OpaqueAudioComponentInstance;
typedef struct OpaqueAudioComponentInstance* AudioComponentInstance; typedef struct OpaqueAudioComponentInstance* AudioComponentInstance;
#else #else
@@ -108,6 +115,13 @@ struct ExtensionsVisitor
virtual AEffect* getAEffectPtr() const noexcept = 0; 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;
};
virtual ~ExtensionsVisitor() = default; virtual ~ExtensionsVisitor() = default;
/** Will be called if there is no platform specific information available. */ /** Will be called if there is no platform specific information available. */
@@ -121,6 +135,9 @@ struct ExtensionsVisitor
/** Called with AU-specific information. */ /** Called with AU-specific information. */
virtual void visitAudioUnitClient (const AudioUnitClient&) {} virtual void visitAudioUnitClient (const AudioUnitClient&) {}
/** Called with ARA-specific information. */
virtual void visitARAClient (const ARAClient&) {}
}; };
} // namespace juce } // namespace juce

+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_FlagCache.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


+ 11
- 4
source/modules/juce_audio_processors/utilities/juce_ParameterAttachments.h View File

@@ -1,13 +1,20 @@
/* /*
============================================================================== ==============================================================================
This file is part of the JUCE 7 technical preview.
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited Copyright (c) 2022 - Raw Material Software Limited
You may use this code under the terms of the GPL v3
(see www.gnu.org/licenses).
JUCE is an open source library subject to commercial or open-source
licensing.
For the technical preview this file cannot be licensed commercially.
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 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save