Open nofishonfriday opened 1 year ago
So I was looking at this for surge also. I haven't written the code yet but let me jot notes here (especially if you are interested in taking a shot at it).
the answer is "yes" but we just need to plumb it through.
The extension is something you can just get with HostProxy::getExtension
(https://github.com/free-audio/clap-helpers/blob/4d4e297947382d2a9d00a469af61e43332463ebf/include/clap/helpers/host-proxy.hh#L24) so the question is how do you get from your AudioProcessor to a HostProxy instance. Basically we want your AudioProcessor to be able to do something like (clap-juce-extensions-somewhere)->getHost()->getExtension(&reaper_info, "cokocs.reaper-info")
or what not.
The way to do this, I think (and how I would do it) is
in include/clap-juce-extensions/clap-juce-extensions.h
capabilities
class in the private section add a new function which is probably something like
std::function<bool(void *, const char*)> extensionGet{nullptr}
In the public section add
{ auto res = extensionGet((void *)&t, id);
}
else return false; }```
so this will give you, if you implement the extensions, the ability to do `reaper_info_t info; if (getExtension(info, "cokocs.reaper-thingy")) ... ` in your juce class
So the only thing left then is to set that lambda to something in the startup path. In src/wrapper/clap-juce-wrapper.cpp
you can see this code
if (processorAsClapExtensions != nullptr)
{
processorAsClapExtensions->parameterChangeHandler =
[this](const clap_event_param_value *paramEvent) {
handleParameterChangeEvent(paramEvent);
};
processorAsClapExtensions->lookupParamByID = [this](clap_id param_id) {
return findVariantByParamId(param_id);
};
};
soo to that you should be able to do something like set the extensionGet to [this](a, b) {host->extensioNGet(a,b);}
anyway that's shorthand. If you think you want to take a swing at it would be happy to review, and if not, can def get to it after thanksgiving or earlier if its pressing.
Thanks for the quick and thorough reply. It's definitely not pressing (hadn't planned to do anything specific with it currently). I may give it a shot (aka PR), but if you get round to it earlier that's also fine (and much appreciated). Thanks again.
Yeah we’ve kinda used surge to highlight the things which are possible so I kinda want to do something. The only thing is I don’t know reaper well enough to know what a cool feature would be with this api!! All ears for ideas
Admittedly I don't come up spontaneously with something too. But in general all Reaper's API functions should be accessible with it. Not sure if the host functions/context available for VST are available for CLAP also. Anyway I'll post back if I come up with something which I think that could be cool. :)
Yeah, this seems like a cool thing to have! And it makes sense that the same approach could be used for other DAWs with host-specific APIs. I think Paul's sketch of the implementation seems about right. I think it would also be nice to have an example plugin in this repo that does something simple: I'm thinking a drop-down menu that changes the colour of the track the plugin is on? I should have time for some hacking on this over the Thanksgiving holiday.
@jatinchowdhury18 did you have the chance to make any progress on this?
I'm totally new to CLAP but I would certainly digg into it if the interoperability with Reaper API and its host methods was confirmed.
@giohappy I did not... but I spent 5-10 minutes on it just now. I've pushed my work to a branch in case you (or anyone else) wants to take a look: https://github.com/free-audio/clap-juce-extensions/compare/main...jatinchowdhury18:clap-juce-extensions:reaper-ext
We can query Reaper for the extension, and Reaper gives us back something that is not nullptr
, so that seems promising! I haven't yet tried to cast it to a reaper_plugin_info_t
and then actually try to do anything useful with it, but that seems like it would be the logical next step.
Another few minutes of hacking today... muting a track through the Reaper API works!
@jatinchowdhury18 great! Thanks for sharing it, I will test it ASAP.
@jatinchowdhury18 I was able to run it. Thanks!
I'm not an expert in C++. Is there any difference between this (your code):
MediaTrack *(*getTrackFunc)(ReaProject *, int);
*((void **)&getTrackFunc) = reaperPluginExtension->GetFunc("GetTrack");
auto *track0 = (*getTrackFunc)(nullptr, 0);
and this (what I would have done)?:
void *(*getTrackFunc)(ReaProject *, int);
getTrackFunc = reinterpret_cast<void *(*)(ReaProject *, int)>(reaperPluginExtension->GetFunc("GetTrack"));
auto *track0 = reinterpret_cast<MediaTrack *>((*getTrackFunc)(nullptr, 0));
And are you going to open a PR to have getExtension
/extensionGet
added to clap-juce-exntesions
?
No problem!
Those code snippets look equivalent to me. I was using this example from the Reaper SDK as a reference.
You might be able to simply your version a little bit if you define the function pointer return type, since then you shouldn't need the second reinterpret_cast
.
MediaTrack *(*getTrackFunc)(ReaProject *, int);
getTrackFunc = reinterpret_cast<MediaTrack *(*)(ReaProject *, int)>(reaperPluginExtension->GetFunc("GetTrack"));
auto *track0 = (*getTrackFunc)(nullptr, 0);
There's probably some ways to clean it up further with using
declarations as well.
I do plan to open a PR for the extension-related changes, but there's a couple things I'd like to do first:
getExtension()
in its constructor, since it hasn't been initialized yet. I'd like to see if there's a way to re-order some things which could make that possible.Having some fun with track colours:
getExtension()
available and add this new example plugin.
Hi,
Cockos has just added support for CLAP plugins being able to access the REAPER API in their pre-release versions ( link to changelog) . Curious (as I'm still a beginner with the clap-juce-extensions), can we use/access this out of the box with the current version or would it need a code modification? And if the latter, would it be something considerable for the future?
Thanks.