Best/fastest approach for sending periodic DMX data over a USB interface?

I’m working on a plugin which allows for control of DMX lighting within a DAW via a USB -> DXM interface.

At this point I have implemented all functionality I want in the plugin. I recently ran the plugin in Ableton for the first time. When the plugin is sending DMX data, and the plugin GUI is open, the Ableton interface slows way down. It’s almost unusable.

This is a relatively simple plugin that provides users with 512 channel parameters they can use to control a DMX universe. I want the plugin to send updated DMX packets (based on the processor’s current channel parameters) upwards of 40 times per second.

What is the best approach for sending periodic DMX data over a USB interface? I am new to threading and cannot figure out what I should do differently.

Here’s some additional info:

The Juce project source files (along with screenshots and release builds) are located in this Github repository.

I have a class, defined in UsbDmxPro.h that connects/communicates with a DMX Pro compatible device. This class inherits from the Juce Thread class. When the user hit’s connect, and a connection is successfully established, the class’s run() method sends a new DMX packet (based on the processor’s current parameter values) every 25ms.

 void run() override {
	while (!threadShouldExit() && connected) {
		wait(25);
		sendDmx(*blackout);
	}
}

Thank you,
Spenser

If your sendDmx method returns in short time, I would save the effort for an extra thread and simply call from a Timer callback. Inherit from Timer, override the void timerCallback() override to call sendDmx and call startTimerHz (40); in the constructor…

Don’t call wait, if that’s what you did… let the timer do the periodic callback, since in the meantime other things can be worked on.

Thanks for the idea Daniel :slight_smile:

I looked at the the time it takes to run sendDMX. It was averaging 27ms. I was able to cut it down to 7ms.

Then I used the Timer class as you describe above, calling startTimerHz(40). The lights run more smoothly, since DMX is being sent at roughly twice the freqency as before, but Ableton is still unusable. Even if I call startTimerHz(10), things are just as bad. I also tried the plugin in another DAW and things are even worse.

The weird thing is, the DAW works fine when the plugin is running, and even when it’s sending DMX. It only becomes unresponsive when the plugin is sending DMX and the GUI is open.

I’m going to try compiling to AU format to see if that changes anything.

EDIT: Oh wait, I can’t compile/run AU plugins on my PC… Nevermind.

I think what happens is, that you call in paint() the “determineConnectionStatus()”. If it is connected, you call connectUsbButton.setButtonText("Connected");, which will trigger a repaint…

Try commenting that out, and if that helps, make sure to set the text only when the status changed…

Good luck!

3 Likes

@daniel Oh my gosh you are right :sweat_smile: Thank you so, so much! I’m sorry you ended up debugging my code. I try and avoid forum posting for that reason… I truly thought this was an issue with the methods I was using.

That said.

Seriously man, a million thanks :star_struck: I was about ready to walk away from this project for a while. This is my first Juce project that I think is genuinely useful and unique and I have some cool ideas for it moving forward; Thanks to you I can!

-Spenser