![]() |
#1 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
So I have spent the past week or so trying to minimally/generically patch JUCE so that an upstream patch can be landed with support for REAPER's VST3 interfaces -- particularly interested in TCP FX embedding.
(Have spoken briefly w/ JUCE devs about this, there is some interest/receptiveness on their side depending on implementation) To get the base REAPER SDK working (IReaperApplication->getReaperApi()) with a "reaper.ShowConsoleMsg()" was very few changes. --- However I wanted to ask two quick questions, as trying to get IReaperUIEmbedInterface functional did not work based on what I assumed.
Here's the code for:
Would be grateful for any advise/feedback from folks who have a better clue about what they're doing than me. Getting this working and publishing it for others would be stellar! JUCE patches made: ![]() ![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 04-29-2021 at 07:20 PM. |
![]() |
![]() |
![]() |
#2 |
Human being with feelings
Join Date: Nov 2020
Posts: 277
|
![]()
I've never looked at these REAPER VST3 extensions, but did you add IReaperUIEmbedInterface to your edit controller's query interface?
|
![]() |
![]() |
![]() |
#3 | |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]() Quote:
https://github.com/GavinRay97/JUCE-r....cpp#L602-L667 PHP Code:
https://github.com/juce-framework/JU...T3Common.h#L49 PHP Code:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 04-30-2021 at 12:49 PM. |
|
![]() |
![]() |
![]() |
#4 | |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]() Quote:
|
|
![]() |
![]() |
![]() |
#5 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]() |
![]() |
![]() |
![]() |
#6 | |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]() Quote:
Will keep doing my part to keep convo going with JUCE folks and see if we can get an acceptable generic implementation merged upstream, so that all JUCE projects have optional out-of-the-box functionality for REAPER UI embedding + SDK hosting in both VST2 + VST3 ![]() <3
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
|
![]() |
![]() |
![]() |
#7 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
Haven't had time to test thoroughly, but the greyed-out "Show/Embed FX in TCP" option is now clickable in my plugin FX slot in 6.30 dev, and after enabling it and trying to expand the track the plugin crashed.
Which is good! It means I fucked up, but that that REAPER let me fuck up. So it sounds like this is going to be a fun and productive weekend =) Will continue dev efforts after brief sleep. Once again, really appreciate you folks
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#8 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
I'm going to go off topic from original post here if that's alright
--- I'd like to ask for some basic C++ code-review/help from anyone here experienced and willing to spare it. I have been working with JUCE devs on allowing users to implement REAPER's VST3 interfaces for TCP/MCP FX embedding and access to it's C++ API. (So that we can get it merged upstream and all JUCE VST2/VST3 plugins can optionally choose to be REAPER-capable by default) Got a rough version working but it was hacky (see below), then after talking to one of the JUCE dev's have been swapping it out for his implementation idea. Problem is, I'm hitting the limits of my knowledge trying to debug why this isn't working. ![]()
PHP Code:
PHP Code:
PHP Code:
PHP Code:
Here's the problem:
Wtf is going on, how do I debug this? =/ ![]() ![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 05-03-2021 at 07:43 AM. |
![]() |
![]() |
![]() |
#9 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]()
If you want to post a link to a test copy of your plugin, we can let you know what it looks like from REAPER's side.
|
![]() |
![]() |
![]() |
#10 | |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]() Quote:
This is what the code looks like from REAPER's side. if queryInterface() is being called for IReaperUIEmbedInterface and returning properly, embed_message() should be called immediately. Code:
IReaperUIEmbedInterface *embed_ui=NULL; if (m_vst3->m_controller->queryInterface(IReaperUIEmbedInterface::iid,(void **)&embed_ui) == kResultTrue && embed_ui) { if (embed_ui->embed_message(0,0,0)) // 0=REAPER_FXEMBED_WM_IS_SUPPORTED { m_vst3->m_embed_ui = embed_ui; } else { embed_ui->release(); } } If your code is receiving the interface query from REAPER, as your screenshot/breakpoint suggests, my guess is that it's actually working properly, but you're not seeing the debug message in embed_message() for some reason. I suppose another possibility is that your interface registration code is returning the IReaperUIEmbedInterface interface for the wrong query. You could dump the actual IID there to make sure. Last edited by schwa; 05-03-2021 at 08:15 AM. |
|
![]() |
![]() |
![]() |
#11 | |||
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
Really appreciate you responding here and the offer to give a glimpse from REAPER's end.
Let me push current work up to github repo, then will post here =) I touched C++ first time maybe 6 weeks ago (to add some popular single-header C++ imgui components to ReaImgui & learn REAPER's native API) and that was my "hello world" then it was onto this, this language is kicking my butt. Not an easy one to learn! Quote:
The code you see from the first post, where I had hackily #ifdef'ed the subclassing/extension of IReaperUIEmbedInterface onto JUCE's actual JuceVST3EditController did work! Right after the v6.28+dev0430 patch (thank you again) Quote:
Quote:
So I had added this statement inside of queryInterface(): PHP Code:
PHP Code:
To provide an instance of it, I wasn't really sure what to do so I just did the below -- and it might be some weirdness with me using the same class IID for my implementation class as the IReaperUIEmbedInterface. The reason I first noticed this was very broken was when I changed case REAPER_FXEMBED_WM_IS_SUPPORTED: to return 0 and it still gave me the option in context-menu to embed in TCP, then just drew a black square. PHP Code:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 05-03-2021 at 10:27 AM. |
|||
![]() |
![]() |
![]() |
#12 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
Pushed the current implementation to branch "reuk-impl-idea":
https://github.com/GavinRay97/JUCE-r...reuk-impl-idea There's a 7zip'ed copy of the debug VST along with the pdb and everything else in the root of the repo called "VST3-MSVC-x86-64.7z" To compile this (if you want), you should just need to have cloned recursively, and the patch the "juce_VST3_Wrapper.cpp" Code:
cp ./patches/JUCE/juce_VST3_Wrapper.cpp ./JUCE/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp I uploaded a patch to see the slight alterations made to the JUCE VST3 wrapper here: https://github.com/GavinRay97/JUCE-r...mpl_idea.patch And finally, here's the file with the REAPER implementation: https://github.com/GavinRay97/JUCE-r...Controller.hpp
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#13 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]()
Do you mind posting a binary that doesn't depend on the debug runtime?
|
![]() |
![]() |
![]() |
#14 | |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]() Quote:
That would be the non-"D" versions here of VCRUNTIME140D and MSVCP140D right? (Should just be a build in "RelWithDbgInfo" mode I think) ![]() --- Edit: Okay, built. New dependencies: https://github.com/GavinRay97/JUCE-r...WithDebInfo.7z ![]() Compressing and pushing now
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 05-03-2021 at 11:41 AM. |
|
![]() |
![]() |
![]() |
#15 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
So I annotated every single method (ctor, dtor, addRef, release, queryInterface, and embed_message) with logging.
And I faked a call to embed_message() right before I return pointer to the object and it works, the call gets logged. PHP Code:
PHP Code:
Does calling casts like dynamic_cast<T> and static_cast<T> on pointers that get sent to other functions change runtime behavior? That's the only difference I can think of -- the pointer object is not casted before being returned whereas "TEST_FOR_AND_RETURN_IF_VALID" does a cast to the class type. PHP Code:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 05-03-2021 at 12:35 PM. |
![]() |
![]() |
![]() |
#16 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]()
Thanks for posting the binary. REAPER is calling your embed_message(). If you're not receiving the call on your side, it may be because ReaperVST3EditController needs to implement the public interface of IReaperUIEmbedInterface, so the embed_message() REAPER thinks it's calling is the same one that IReaperUIEmbedInterface is implementing.
Also, since you're implementing add_ref and release yourself, you don't need to inherit from FObject. I think it will be helpful for you to make your class a standalone object that only inherits pure-virtual interface classes, with no state anywhere other than itself. |
![]() |
![]() |
![]() |
#17 | |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]() Quote:
I'll strip the FObject out and try to rewrite the class again. I'm certain I can get this working in the next day or two now that I know it's on the right track! Code:
═✿✿✿═════✿✿═════✿✿═════✿✿✿═ ════════════ ('\../') ═════════════ ════════════ (◕.◕) ═════════════ ════════════ (,,)(,,) ═════════════ .▀█▀.█▄█.█▀█.█▄.█.█▄▀ █▄█.█▀█.█─█ ─.█.─█▀█.█▀█.█.▀█.█▀▄ ─█.─█▄█.█▄█ PHP Code:
LOL ![]() PHP Code:
![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
|
![]() |
![]() |
![]() |
#18 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,954
|
![]()
It's crashing because you're returning an object on the stack. That would work fine (modulo other errors heh) if your ReaperUIEmbedImpl was on the heap. It's not "dirty" at all.
In fact the only reason you need any additional complication is that the ReaperUIEmbedImpl needs to have some connection to the actual plugin controller state. If you stored a pointer to the JUCE edit controller in ReaperUIEmbedImpl, you'd probably be most of the way to where you need to be. |
![]() |
![]() |
![]() |
#19 | |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]() Quote:
Then he said that the userland implementation of this function, on the JUCE AudioProcessor class, should take a "Location" variable -- which is the name/instance of the JUCE class holding the VST3 interface to install itself in. PHP Code:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
|
![]() |
![]() |
![]() |
#20 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
WE'RE IN BUSINESS!
![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#21 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
For anyone that might be following this, here's a status update if you're curious:
Also I'm figuring things out (making things up?) as I go along wrt. C++ so there's that too lol
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#22 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
Welp, it's Sunday night, and it took most of the weekend but I've got a generic solution (mostly) working.
There's a problem though: which is that I am using a scope-global variable in the JUCE VST3 wrapper file to share a reference between two classes. (Would really appreciate any advice on a better way to do this, if the order of construction is definitive and one will always come first) PHP Code:
PHP Code:
![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#23 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
Okay, a fellow named Ben Vining on the JUCE Discord helped me out with making the file global var thing less hacky using "static" + thread-local variables.
I think it's pretty much ready to submit now =) PHP Code:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#24 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#25 |
Human being with feelings
Join Date: May 2019
Posts: 444
|
![]()
For your work on this. It would be great to embed all of my plugins into a super-channel strip. Looking forward to the fruits of your efforts!
|
![]() |
![]() |
![]() |
Thread Tools | |
|
|