Strange mouse movement and repaint problems in AU


#1

I want to port my JUCE-based plugin to AU, but got hell of bad experiences in the last day. (JUCE-based VST version on Windows works very well and always did).

In Logic 8 and also in AU Lab, Mouse Movement Events seem not to be send to the plugin directly when the mouse is not dragging. That’s why the JUCE AU wrapper just polls the mouse position every 20 seconds and creates internal mouse movement messages (a very hacky approach).

The weird thing is, that in AU Lab, the mouseEnter() and mouseLeave() functions get called more or less randomly, or at least the painting of the controls is.

When I open several instances of the plugin, sometimes the mouseEnter or mouseLeave functions don’t seem to get called, or the buttons flash up for some milliseconds and then are grayed again.

Also some beta testers told me, that after a while of using the plugin in Logic 8, no repainting was occuring anymore for the knobs/buttons or level meters. Clicking on them had still some effect (one does hear it), but no visual update would be made.

Even worse: After closing the project and opening again (even after closing Logic 8 ), this would still be the case: no visual updates anymore. Only solution: start the plugin again.

All this problems occured in Logic 8. In Logic 7 or Ableton 7, it seems to be no problem. In AU Lab there are also those “highlighting” problems with mouseEnter() or mouseExit(). Since Logic 8 and AU Lab are, as far as I know, Cocoa based, and JUCE Carbon based, I think that the problem lies in there. But I don’t know what it is, since I am a 99% Windows coder. I guess Logic 7 and Ableton 7 are Carbon based, not Cocoa based.

So if anyone had this experiences, and knows what’s the problem, please let me know if you have any valuable information.

PS: Same “highlighting” problems with the JUCE Demo AU in AU Lab or Logic 8


#2

Sounds like just one little problem that’s underlying it, and it does relate to the way the host controls the window. I’ve not got logic 8, but will try it in AU lab and see if I can find any clues…


#3

Seems like the mouse position is sometimes not taken relative to the plugin window itself, but just absolutely, and so the knobs highlight when I hover the mouse over the screen, even if the mouse pointer is not over the plugin’s window.

This bug can be seen very well in AU Lab with the JUCE-based AU plugin Hypercyclic from MuCoder, because it has a relatively big surface compared to my own plugin, and does also do highlighting of the knobs, combo boxes,… when the mouse is over.


#4

I remember there were some very odd aspects to the way HIViews map their co-ordinates onto the window that they’re inside, and it’d sometimes come up with weird effects like this. I never figured out if it was there was a bug in my code, in apple’s code, or if they just hadn’t explained how to use their functions properly.


#5

Does the bug also occur on your Apple in AU Lab with Juce Demo AU or HyperCyclic?


#6

Haven’t got my mac to hand right now to try it out…


#7

When you’ve got one, when testing make sure NOT to click in the plugin’s window and then go over the screen with the mouse. Here the components will repond to the mouse even if the pointer is not over the components themselves (absolute mouse position is taken).

When I comment out the 2 lines that contain startTimer(20) in juce_AudioUnitWrapper.cpp,
then everything’s fine (mouse positions are then correctly interpreted, always relative to the plugin window), except that I have to click once on the plugin’s surface before mouseEnter() and mouseExit() are called (or the components repainted? at least the highlighting only occurs after a first click on the plugin surface).

Don’t know why the first mouseClick is needed, but that’s the way it is.

Perhaps this now helps?


#8

Yes, this sounds like the problems I had when I first did it - I think it was something bizarre like the HIView not having the correct origin until you actually click on it.


#9

So, meanwhile, I could just remove the 2 startTimer(20) lines and forget about the mouseEnter() mouseExit() stuff and then it would at least work (with no highlighting ofcourse) ?


#10

Yes, if that works for you, go for it.


#11

The repaint problem, did the 2 beta-testers tell me, still is there. I could never recreate that problem on my computer: after a while, the knobs and VU meters will just not repaint anymore (but the knobs still actually work internally).

I will ask the beta-testers if this problems also occurs with other JUCE-based plugins.

I’ve seen other AU plugins that just would not repaint in AU Lab or Logic 8, but those wouldn’t repaint from the start, not after a certain time.


#12

I’ve been chasing that repaint() bug for weeks and just can’t find it. What could possibly block the painting? I guess the thread that is responsible for painting just somehow gets stuck? what thread is this and is it only responsible for painting or also for other things? note that the controls still correctly call setParameter() but you just wont’ see it.


#13

I remember some issue we had in our custom UI toolkit.
It seemed that if you send too much repaint event to OSX, some was skipped.

Try changing the priority in juce_postMessageToSystemQueue from kEventPriorityStandard to kEventPriorityLow

in juce_mac_messaging.cpp line 293

HTH


#14

Did your GUI controls stop painting forever or just sometimes skipped painting? Mine stop painting forever. It seems that this always happens when Logic or even Ableton users load a saved project that contained my plugin. It never happens when opening the plugin from scratch (if there is no other instance of it that already stopped repainting).


#15

only skipped painting


#16

Ok. I finally found out where the problem is, but it’s not solved, it’s a JUCE or OS X problem.

I have a project in Ableton that consumes much CPU (around 50% DSP). When I open it, all Timers in my JUCE-based plugin stop working. My controls did actually not repaint, because I use a mechanism that calls repaint() based on a Timer. I absolutely need a Timer in my AU for the level meters.

Here’s how I found out:

First, I thought there was some bug in my code, but then I modified the Juce AU Demo to show a label that is updated via a Timer every 20 ms, and which displays 1 2 3 4 an so on. So I added the Juce Demo AU to the buggy project, and the Label was updated every 20ms.
BUT after closing Ableton and loading the same project again, the Label would not be updated in the modified Juce AU Demo, which means the Timer is not working anymore!!!

So something happens when there’s heavy CPU load which just keeps the Timers from working.

I’m really happy to at least have found out what it is, but I have no idea why this bug occurs.

N.B. In the same project there is a Sonalksis plugin (they are JUCE based I think?) and this plugin’s level meters actually do work!

N.B. 2: If I close the Juce AU Demo in the project and open it again, the Timer works again, until I save the project and open it again.

Jules, have you got the slightest idea what this could be? The bug must be somewhere in juce_Timer.cpp?


#17

I just modified juce_Timer.cpp and now my AudioUnit plugin works 100%!

Even the automation bug (automation recording would be jumpy, inconsistent , not recorded or out of time) & the controls-not-highlighting-bug (one had to first press onto the plugin surface before controls would start highlighting) in Logic just all dissapeared. ** Unbelievable! ** So many bugs caused by just one C++ file.

What I did is this: I rewrote the Timer class to use the Carbon Timer API instead of using some Thread as you did (why did you do that? For performance reasons?).

I will send you the sourcecode via email, so you can adapt Juce to something similar.

You will also not need your AudioUnit wrapper to install a Timer anymore to check the mouse position… :slight_smile:


#18

Hmm. That’s certainly interesting, but there’s wrong with the Timer class in principle - having a thread and callbacks is a perfectly good way of doing it, and I’d prefer to run the same mechanism on all platforms rather than using platform-specific code which will probably behave slightly differently and have different callback patterns.

The bug sounds like the timer class is stopping when the message thread is blocked too long, but that’s odd because it’s something I fixed a long time ago - you can see the code I added at line 212.

But I will have a go myself and dig around, as there’s obviously something going on here that I’d like to understand better!


#19

BTW your timer code in the AUWrapper still needs to be there. Wrote a mistake before.


#20

And now that everything works, here’s what the plugin looks like ^^