Reaper and effEditClose

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Just as an aside the Reaper related WDL code returns 0 for effEditOpen! I must admit there is so much inconsistency in the VST world. Looking at sample code some code returns 1 some does not, one even returns the rectangle in response to effEditGetRect

Post

Curious, why are you implementing the opcode dispatcher? Isn't it in the SDK already?

Sorry if I'm a little hazy on the lower levels of this, I use VSTGUI. You might want to use VSTGUI as a reference. (Or just use VSTGUI.)

In answer to your question about suspend and resume, is that editor::suspend and editor::resume? If so, you don't need to do anything there, it's just giving you a chance to do something in your editor if it's appropriate there. (Say, show the "bypassed" state).

Post

Windows beep? Only in Reaper or in general?

If this is on windows, and you're writing native Win32, then there are WM_KEYDOWN, WM_KEYUP and WM_CHAR messages. IIRC DefWindowProc() sends them all to the parent window if you don't handle them yourself. You will normally get both WM_KEYDOWN and WM_CHAR for pressed keys, then WM_KEYUP for release. If you're using just one of WM_KEYDOWN / WM_CHAR, then the other could be sent to Reaper, which might think "bad key" and beep (which sounds retarded thing to do in an audio application, but you never know). If that's the case, just add a dummy handler(s) that return 0 instead of calling DefWindowProc().

If your on some other operating system, it's likely that the logic is still quite similar; some applications care about keys, and some care about characters, and once you add multiple keyboard layouts and "input methods" and what not, the logical thing to do is separate the two message types..

Post

Hi, thanks for the replies. I use my own editor which is why I handle opcodes.

I have to own up to doing a few 'dodgy hacks'. Firstly I wanted to avoid the limited accuracy of WM_TIMER messages so I create my GUI in another thread. The plugin is very GUI intensive doing Direct3D 3D rendering. Secondly I handle raw keyboard data to avoid issues with key repeat delays using WM_INPUT.

While non-standard this approach does work well on all hosts bar Reaper. I have discovered if I put a sleep in the code before returning from effEditOpen it works ok which of course suggests a threading issue.

The beep on keypress I tried to solve by trapping the messages you mention but with no luck.

Post

My experiment with D3D vs plugin editors wasn't pretty (in the end I went with OpenGL instead), so hopefully you're either prepared, or running the graphics in a separate top-level window.

Also, WM_TIMER is quite accurate in practice (about 1ms as long as you've got beginPeriod(1) active, but you probably need it anyway), except when the GUI thread spends gets stuck somewhere (which would be a valid reason to use a separate render thread if you do fancy live visualization or something), or your have a heave CPU load. In both cases though, any other method of timing would be just as inaccurate anyway.

Also, personally (in non-plugin projects where I use D3D, since I like it more than OGL) I generally just offload rendering into a separate thread, while running everything else (well, except a few other things like audio and what not where applicable, but you get the point) in the main thread. This works fine even for D3D9 (as long as you do device init and resets in the main thread and don't try to touch the device from two threads at the same time) and might save you from some trouble, if you're doing it all just to maintain stable framerates.

Post

Hi, thanks, that is useful. The D3D rendering is in a topmost window and that part appears to work fine. However I am currently using my new thread for the whole of the GUI and not just the D3D part so your post has given me the idea of maybe separating them. I think I will need to do a few big changes and try it a few ways. Easiest way to start is to not create a new thread and trap WM_TIMER. I will try that first and see what happens

Post

Hi, after hours of work I have finally got a solution that works in Cubase, Live and Reaper so I thought I would post again in case anyone else faces this kind of issue.

Firstly the problem with opening the editor and Reaper sending me multiple open messages. I tried lots of workarounds with the most effective being a dummy window in the GUI thread feeding my own thread however I could never get it to work 100% of the time, it was almost there but not quite. In the end I abandoned the idea of my own GUI thread. It was a bit ambitious to think I could keep my own thread synchronised with the host's GUI thread. It was a pain though as it worked so smoothly in Live and Cubase and just failed in Reaper. I suspect, and would love to know for sure, that Reaper does some window checking after calling open rather than relying on my return code.

Anyway I reverted to just creating my window when asked in the callers thread and then using WM_TIMER messages to drive the rendering. I still had issues because I needed to make my window topmost and different hosts seem to handle window positioning differently. Reaper has this annoying button bar at the top of the wrapper window that needs taking into account. Anyway after a lot fo struggle I got this working 100% of the time in all hosts - phew.

The other issue with the key presses was not so easily solved and I ended up using a hack. Irrespective of using WM_KEYDOWN or Raw Input I would always either grab complete control of the keyboard preventing host commands or I would pass through my key presses causing issues. It seems plugins are not really set up to handle key presses and work nicely with the host. If I used RIDEV_NOLEGACY when setting up raw input I could prevent keydown messages going to the host however I then needed a way to pass through keys I did not handle and that is a very complex process to convert raw input data into keydown data so I abandoned that. In the end I got it working with a smelly hack that I am not too proud of and may revisit when I get a chance. What I do is check if the mouse is over my window. If it is I turn on raw input. When the mouse leaves the window I turn off raw input. I thought this might be slow but it seems to work.

So it has been a learning experience for sure!

Post

I also ran into the problem that REAPER played a beep/system sound when keys were pressed in my plugin. The solution in my case was to add the following message handling to the corresponding WndProc:

Code: Select all

case WM_GETDLGCODE:
{
    return DLGC_WANTALLKEYS;
}
This seems to prevent the propagation of key events to the parent window because we tell the framework that we want to handle all keys. Another side effect is that WM_CHAR messages are now generated for my WndProc.

P.S.: I am aware that this is quite some necro. However, I think the solution might be interesting for others because I also hoped to find it in this thread some hours ago. :) Relevant XKCD:
Image
Passed 303 posts. Next stop: 808.

Post Reply

Return to “DSP and Plugin Development”