Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CLAP libs and support preset-load extension #141

Merged
merged 11 commits into from
Jan 22, 2024
2 changes: 1 addition & 1 deletion clap-libs/clap
Submodule clap updated 50 files
+10 −1 .github/workflows/cmake.yml
+11 −0 CMakeLists.txt
+30 −0 CMakePresets.json
+92 −1 ChangeLog.md
+35 −18 README.md
+32 −0 conventions/extension-id.md
+12 −0 include/clap/all.h
+12 −19 include/clap/clap.h
+75 −7 include/clap/entry.h
+57 −9 include/clap/events.h
+22 −14 include/clap/ext/ambisonic.h
+12 −3 include/clap/ext/audio-ports-activation.h
+13 −5 include/clap/ext/audio-ports-config.h
+4 −4 include/clap/ext/audio-ports.h
+23 −18 include/clap/ext/configurable-audio-ports.h
+13 −4 include/clap/ext/context-menu.h
+0 −32 include/clap/ext/draft/check-for-update.h
+0 −44 include/clap/ext/draft/cv.h
+1 −1 include/clap/ext/draft/extensible-audio-ports.h
+0 −40 include/clap/ext/draft/midi-mappings.h
+2 −2 include/clap/ext/draft/resource-directory.h
+1 −1 include/clap/ext/draft/transport-control.h
+1 −2 include/clap/ext/draft/triggers.h
+2 −1 include/clap/ext/draft/tuning.h
+1 −1 include/clap/ext/event-registry.h
+21 −25 include/clap/ext/gui.h
+2 −3 include/clap/ext/latency.h
+3 −2 include/clap/ext/note-ports.h
+7 −3 include/clap/ext/param-indication.h
+16 −6 include/clap/ext/params.h
+3 −0 include/clap/ext/posix-fd-support.h
+7 −3 include/clap/ext/preset-load.h
+8 −3 include/clap/ext/remote-controls.h
+16 −8 include/clap/ext/state-context.h
+4 −0 include/clap/ext/state.h
+14 −10 include/clap/ext/surround.h
+2 −0 include/clap/ext/timer-support.h
+9 −4 include/clap/ext/track-info.h
+1 −1 include/clap/ext/voice-info.h
+1 −1 include/clap/factory/draft/plugin-invalidation.h
+99 −0 include/clap/factory/draft/plugin-state-converter.h
+24 −37 include/clap/factory/preset-discovery.h
+12 −8 include/clap/plugin.h
+9 −3 include/clap/private/macros.h
+11 −0 include/clap/timestamp.h
+26 −0 include/clap/universal-plugin-id.h
+2 −2 include/clap/version.h
+1 −1 src/main.c
+13 −1 src/main.cc
+77 −4 src/plugin-template.c
32 changes: 29 additions & 3 deletions include/clap-juce-extensions/clap-juce-extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const clap_plugin *clap_create_plugin(const struct clap_plugin_factory *, const
const char *);
}


/** Forward declarations for any JUCE classes we might need. */
namespace juce
{
Expand Down Expand Up @@ -216,13 +215,13 @@ struct clap_juce_audio_processor_capabilities
* If your plugin supports custom note names, then this method should be overriden
* to return how the number of note names that your plugin has.
*/
virtual int noteNameCount() noexcept { return 0; }
virtual uint32_t noteNameCount() noexcept { return 0; }

/**
* The host will call this method to retrieve the note name for a given index
* in the range [0, noteNameCount()).
*/
virtual bool noteNameGet(int /*index*/, clap_note_name * /*noteName*/) noexcept
virtual bool noteNameGet(uint32_t /*index*/, clap_note_name * /*noteName*/) noexcept
{
return false;
}
Expand Down Expand Up @@ -267,6 +266,30 @@ struct clap_juce_audio_processor_capabilities
suggestRemoteControlsPageSignal(pageID);
}

/** If your plugin supports preset load, then override this method to return true. */
virtual bool supportsPresetLoad() const noexcept { return false; }

/**
* The plugin should override this method to attempt to load a preset from a location,
* and return true if the load occurred successfully.
*/
virtual bool presetLoadFromLocation(uint32_t /*location_kind*/, const char * /*location*/,
const char * /*load_key*/) noexcept
{
return false;
}

/**
* The plugin should call this from within presetLoadFromLocation() to report an error when
* trying to load the preset, and then return false from presetLoadFromLocation().
*/
void reportPresetLoadError(uint32_t location_kind, const char *location, const char *load_key,
int32_t os_error, const juce::String &message)
{
if (onPresetLoadError != nullptr)
onPresetLoadError(location_kind, location, load_key, os_error, message);
}

/*
* If you are working with a host that chooses to not implement cookies you will
* need to look up parameters by param_id. Use this method to do so.
Expand Down Expand Up @@ -294,6 +317,9 @@ struct clap_juce_audio_processor_capabilities
std::function<void()> noteNamesChangedSignal = nullptr;
std::function<void()> remoteControlsChangedSignal = nullptr;
std::function<void(uint32_t)> suggestRemoteControlsPageSignal = nullptr;
std::function<void(uint32_t location_kind, const char *location, const char *load_key,
int32_t os_error, const juce::String &msg)>
onPresetLoadError = nullptr;
std::function<const void *(const char *)> extensionGet = nullptr;

friend const clap_plugin *ClapAdapter::clap_create_plugin(const struct clap_plugin_factory *,
Expand Down
55 changes: 43 additions & 12 deletions src/wrapper/clap-juce-wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ JUCE_BEGIN_IGNORE_WARNINGS_MSVC(4100 4127 4244)
#include <clap/helpers/host-proxy.hxx>
#include <clap/helpers/plugin.hh>
#include <clap/helpers/plugin.hxx>

#if CLAP_VERSION_LT(1,2,0)
static_assert(false, "CLAP juce wrapper requires at least clap 1.2.0");
#endif

JUCE_END_IGNORE_WARNINGS_MSVC
JUCE_END_IGNORE_WARNINGS_GCC_LIKE

Expand Down Expand Up @@ -68,7 +73,7 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}

#if CLAP_SUPPORTS_CUSTOM_FACTORY
extern void *clapJuceExtensionCustomFactory(const char *);
extern const void *JUCE_CALLTYPE clapJuceExtensionCustomFactory(const char *);
#endif

#if !JUCE_MAC
Expand Down Expand Up @@ -173,19 +178,19 @@ class EditorContextMenu : public juce::HostProvidedContextMenu

juce::PopupMenu getEquivalentPopupMenu() const override
{
host.contextMenuPopulate(host.host(), &menuTarget, builder.builder());
host.contextMenuPopulate(&menuTarget, builder.builder());

jassert(builder.menuStack.size() == 1); // one of the sub-menus has not been closed?
return builder.menuStack.front();
}

void showNativeMenu(Point<int> pos) const override
{
if (!host.contextMenuCanPopup(host.host()))
if (!host.contextMenuCanPopup())
return;

// TODO: figure out screen index?
host.contextMenuPopup(host.host(), &menuTarget, 0, pos.x, pos.y);
host.contextMenuPopup(&menuTarget, 0, pos.x, pos.y);
}

clap_context_menu_target menuTarget{};
Expand Down Expand Up @@ -230,9 +235,7 @@ class EditorContextMenu : public juce::HostProvidedContextMenu
item.text = juce::CharPointer_UTF8(entry->label);
item.isEnabled = entry->is_enabled;
item.action = [&host = this->host, target = *this->menuTarget,
id = entry->action_id] {
host.contextMenuPerform(host.host(), &target, id);
};
id = entry->action_id] { host.contextMenuPerform(&target, id); };

currentMenu.addItem(item);
}
Expand All @@ -246,9 +249,7 @@ class EditorContextMenu : public juce::HostProvidedContextMenu
item.isEnabled = entry->is_enabled;
item.isTicked = entry->is_checked;
item.action = [&host = this->host, target = *this->menuTarget,
id = entry->action_id] {
host.contextMenuPerform(host.host(), &target, id);
};
id = entry->action_id] { host.contextMenuPerform(&target, id); };

currentMenu.addItem(item);
}
Expand Down Expand Up @@ -434,6 +435,13 @@ class ClapJuceWrapper : public clap::helpers::Plugin<
_host.remoteControlsSuggestPage(pageID);
});
};
processorAsClapExtensions->onPresetLoadError =
[this](uint32_t location_kind, const char *location, const char *load_key,
int32_t os_error, const juce::String &msg) {
if (_host.canUsePresetLoad())
_host.presetLoadOnError(location_kind, location, load_key, os_error,
msg.toRawUTF8());
};
processorAsClapExtensions->extensionGet = [this](const char *name) {
return _host.host()->get_extension(_host.host(), name);
};
Expand Down Expand Up @@ -1018,14 +1026,14 @@ class ClapJuceWrapper : public clap::helpers::Plugin<
return false;
}

int noteNameCount() noexcept override
uint32_t noteNameCount() noexcept override
{
if (processorAsClapExtensions)
return processorAsClapExtensions->noteNameCount();
return 0;
}

bool noteNameGet(int index, clap_note_name *noteName) noexcept override
bool noteNameGet(uint32_t index, clap_note_name *noteName) noexcept override
{
if (processorAsClapExtensions)
return processorAsClapExtensions->noteNameGet(index, noteName);
Expand Down Expand Up @@ -1080,6 +1088,29 @@ class ClapJuceWrapper : public clap::helpers::Plugin<
return false;
}

bool implementsPresetLoad() const noexcept override
{
if (processorAsClapExtensions)
return processorAsClapExtensions->supportsPresetLoad();
return false;
}

bool presetLoadFromLocation(uint32_t location_kind, const char *location,
const char *load_key) noexcept override
{
if (processorAsClapExtensions)
{
if (processorAsClapExtensions->presetLoadFromLocation(location_kind, location,
load_key))
{
if (_host.canUsePresetLoad())
_host.presetLoadLoaded(location_kind, location, load_key);
return true;
}
}
return false;
}

public:
bool implementsParams() const noexcept override { return true; }
bool isValidParamId(clap_id paramId) const noexcept override
Expand Down
Loading