Closed dschiller closed 1 month ago
Hi @dschiller!
AUv3 support is not tested at the moment - the documentation does not explicitly list AUv3 anywhere (although the usage of the generic "Audio Unit" name may suggest that all Audio Units are supported). The JUCE framework that Pedalboard is built on does have support for hosting AUv3 plugins, so enabling support may just be a matter of adding a test plugin to the test suite and changing the code in AudioUnitParser.mm
to properly support opening AUv3 bundles.
Hey Peter, it looks like that the AU Parser already is aware of .appex
AUv3 Apple App Extension format at https://github.com/spotify/pedalboard/blob/master/pedalboard/AudioUnitParser.mm#L81
I created a feature branch and try to build pedalboard locally
git clone https://github.com/spotify/pedalboard.git .
git checkout -b feature/add-auv3
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r test-requirements.txt
I needed to download and install JUCE via
curl -LJO https://github.com/juce-framework/JUCE/releases/download/7.0.11/juce-7.0.11-osx.zip
tar -xf juce-7.0.11-osx.zip -o JUCE
rm juce-7.0.11-osx.zip
Other dependencies like Flac also missing:
rm -rf build; python setup.py develop
...
In file included from /Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/pedalboard/juce_overrides/juce_PatchedFLACAudioFormat.cpp:139:
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/pedalboard/juce_overrides/../../JUCE/modules/juce_audio_formats/codecs/flac/libFLAC/format.c:57:45: error: use of undeclared identifier 'PACKAGE_VERSION'
FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION;
^
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/pedalboard/juce_overrides/../../JUCE/modules/juce_audio_formats/codecs/flac/libFLAC/format.c:58:64: error: expected ';' after top level declarator
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20230623";
^
;
In file included from /Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/pedalboard/juce_overrides/juce_PatchedFLACAudioFormat.cpp:147:
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/pedalboard/juce_overrides/../../vendors/libFLAC/metadata_object.c:41:10: fatal error: '../../JUCE/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h' file not found
#include "../../JUCE/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 errors generated.
error: command '/usr/bin/clang' failed with exit code 1
How do you install the necessary dependencies ?
I checked the .github/workflows/all.yml
file but couldn't find anything that installs Flac for example.
Possibly i am using the wrong JUCE version as there is no metadata.h
header file in JUCE 7.0.11:
git submodule
did the trick.
rm -rf JUCE
git submodule init
git submodule update
Submodule path 'JUCE': checked out 'ddaa09110392a4419fecbb6d3022bede89b7e841'
Submodule path 'vendors/lame': checked out '1f5cc9487284d5950343aa5d4f70de433468070a'
Submodule path 'vendors/libgsm': checked out '98f1708fb5e06a0dfebd58a3b40d610823db9715'
Submodule path 'vendors/pybind11': checked out '19a6b9f4efb569129c878b7f8db09132248fbaa1'
Submodule path 'vendors/rubberband': checked out '2be46b0dffb13273a67396c77bc9278736bb03d2'
In pedalboard/ExternalPlugin.h
it seems typesFound
stays empty when using .appex
AUv3 with JUCE's findAllTypesForFile()
:
...
#if JUCE_PLUGINHOST_AU && JUCE_MAC
if constexpr (std::is_same<ExternalPluginType,
juce::AudioUnitPluginFormat>::value) {
auto identifiers = getAudioUnitIdentifiersFromFile(pluginFileStripped);
// For each plugin in the identified bundle, scan using its AU identifier:
for (int i = 0; i < identifiers.size(); i++) {
std::cout << identifiers[i] << std::endl;
format.findAllTypesForFile(typesFound, identifiers[i]);
}
} else {
std::cout << pluginFileStripped << std::endl;
format.findAllTypesForFile(typesFound, pluginFileStripped);
}
#else
std::cout << pluginFileStripped << std::endl;
std::cout << typesFound << std::endl;
format.findAllTypesForFile(typesFound, pluginFileStripped);
std::cout << typesFound << std::endl;
#endif
if (!typesFound.isEmpty()) {
if (typesFound.size() == 1) {
foundPluginDescription = *typesFound[0];
} else if (typesFound.size() > 1) {
std::string errorMessage =
"Plugin file " + pathToPluginFile.toStdString() + " contains " +
std::to_string(typesFound.size()) + " plugins";
// Use the provided plugin name to disambiguate:
if (pluginName) {
for (int i = 0; i < typesFound.size(); i++) {
if (typesFound[i]->name.toStdString() == *pluginName) {
foundPluginDescription = *typesFound[i];
break;
}
}
if (foundPluginDescription.name.isEmpty()) {
errorMessage += ", and the provided plugin_name \"" + *pluginName +
"\" matched no plugins. ";
}
} else {
errorMessage += ". ";
}
if (foundPluginDescription.name.isEmpty()) {
juce::StringArray pluginNames;
for (int i = 0; i < typesFound.size(); i++) {
pluginNames.add(typesFound[i]->name);
}
errorMessage +=
("To open a specific plugin within this file, pass a "
"\"plugin_name\" parameter with one of the following "
"values:\n\t\"" +
pluginNames.joinIntoString("\"\n\t\"").toStdString() + "\"");
throw std::domain_error(errorMessage);
}
}
reinstantiatePlugin();
} else {
std::string errorMessage = "Unable to load plugin " +
pathToPluginFile.toStdString() +
": unsupported plugin format or load failure.";
...
Do i need to use pluginkit
in order to register my AUv3 Plug-In for macOS in order to load it via Pedalboard ?
pluginkit -a /Library/Audio/Plug-Ins/Components/auv3.appex
pluginkit -mv | grep -i modal
F com.Native.ModalTests.ModalTestsAUv3(0.0.1) 00E61720-45F1-4929-9C98-D5D49D6BF989 2024-05-01 12:47:30 +0000 /Volumes/K2TB/Work/Coding/JUCE/ModalTests/Builds/ModalTests_artefacts/Release/Standalone/ModalTests.app/Contents/PlugIns/ModalTests.appex
Tried that but still typesFound
is empty.
Also added tests at tests/test_external_plugins.py
:
...
@pytest.mark.parametrize("plugin_filename", ONE_AVAILABLE_TEST_PLUGIN)
def test_get_plugin_name_from_regular_plugin(plugin_filename: str):
plugin_path = find_plugin_path(plugin_filename)
if ".vst3" in plugin_filename:
names = pedalboard.VST3Plugin.get_plugin_names_for_file(plugin_path)
elif ".component" in plugin_filename:
names = pedalboard.AudioUnitPlugin.get_plugin_names_for_file(plugin_path)
elif ".appex" in plugin_filename:
names = pedalboard.AudioUnitPlugin.get_plugin_names_for_file(plugin_path)
else:
raise ValueError("Plugin does not seem to be a .vst3, .component or .appex.")
assert len(names) == 1
assert load_test_plugin(plugin_filename).name == names[0]
@pytest.mark.skipif(
not AVAILABLE_CONTAINER_EFFECT_PLUGINS_IN_TEST_ENVIRONMENT,
reason="No plugin containers installed in test environment!",
)
@pytest.mark.parametrize("plugin_filename", AVAILABLE_CONTAINER_EFFECT_PLUGINS_IN_TEST_ENVIRONMENT)
def test_get_plugin_names_from_container(plugin_filename: str):
plugin_path = find_plugin_path(plugin_filename)
if ".vst3" in plugin_filename:
names = pedalboard.VST3Plugin.get_plugin_names_for_file(plugin_path)
elif ".component" in plugin_filename:
names = pedalboard.AudioUnitPlugin.get_plugin_names_for_file(plugin_path)
elif ".appex" in plugin_filename:
names = pedalboard.AudioUnitPlugin.get_plugin_names_for_file(plugin_path)
else:
raise ValueError("Plugin does not seem to be a .vst3, .component or .appex.")
assert len(names) > 1
...
Of course AUv3 Plug-Ins need to be added to tests/plugins/effect/Darwin
and tests/plugins/instrument/Darwin
. -> Done
As expected those tests fail now:
pytest tests/test_external_plugins.py
================================================================= test session starts =================================================================
platform darwin -- Python 3.12.2, pytest-8.2.0, pluggy-1.5.0
rootdir: /Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3
configfile: tox.ini
plugins: cov-5.0.0, mock-3.14.0
collected 0 items / 1 error
======================================================================= ERRORS ========================================================================
___________________________________________________ ERROR collecting tests/test_external_plugins.py ___________________________________________________
ImportError while importing test module '/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/test_external_plugins.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/opt/homebrew/Cellar/python@3.12/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/__init__.py:90: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_external_plugins.py:334: in <module>
for parameter in [k for k, v in get_parameters(path).items() if v.type == float]
tests/test_external_plugins.py:126: in get_parameters
return load_test_plugin(plugin_filename).parameters
tests/test_external_plugins.py:182: in load_test_plugin
raise exception
tests/test_external_plugins.py:176: in load_test_plugin
plugin = pedalboard.load_plugin(plugin_path, *args, **kwargs)
pedalboard/_pedalboard.py:823: in load_plugin
raise ImportError(
E ImportError: Failed to load plugin as VST3Plugin or AudioUnitPlugin. Errors were:
E VST3Plugin: Unable to load plugin /Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex: unsupported plugin format or load failure.
E AudioUnitPlugin: Unable to load plugin /Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex: unsupported plugin format or load failure. macOS requires plugin files to be moved to /Library/Audio/Plug-Ins/Components/ or ~/Library/Audio/Plug-Ins/Components/ before loading.
------------------------------------------------------------------- Captured stdout -------------------------------------------------------------------
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex
/Volumes/K2TB/Work/Coding/Python/Pedalboard/feature.add-auv3/tests/plugins/effect/Darwin/ModalTests.appex
=============================================================== short test summary info ===============================================================
ERROR tests/test_external_plugins.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================== 1 error in 10.50s ==================================================================
Thank you, Peter, for the fix! When do you regularly create releases?
Dear Pedalboard Team, is there a possibility to load AUv3 Plug-Ins with Pedalboard ?
I am getting this error message:
Also tried to copy the AUv3 Plug-In to the suggested folder, but same issue:
Maybe AUv3 is not supported yet, but cannot find any explicit information in your documentation.