Closed faroit closed 8 years ago
An interesting idea, actually, to have kind of a "raw mode". We didn't implement it because there was no need for it: we never turn off the features that influence the resulting RGB PWM, like global brightness, white balance, color and brightness calibration, LED animation and power management.
Btw., you could simulate an RGB mode as follows: Assign each RGB LED a number in range 0...127 (there are only 94 of them). Set the color index of each of the RGB LEDs to this number (by sending CC/note-on). Now you can send the sysex to set the color palette entry for the respective color index, which effectively sets the RGB of the LED with this number. Make sure the white palette value is unchanged.
Ah, cool, that is the approach I will take then, since I rely on being able to set individual LEDs to arbitrary RGB values, to match the colors being generated for my light shows (and which I became accustomed to doing using the SysEx message which achieved that on the original Push). :grinning:
I was so excited to learn about this documentation this morning! For the past month I have been implementing support for the Novation Launchpad line in despair at ever being able to do with Push 2 the wonderful things I had accomplished with Push 1. But now I can! I have ordered one, and expect to be busy starting on it this weekend.
Now you can send the sysex to set the color palette entry for the respective color index, which effectively sets the RGB of the LED with this number.
I am curious how efficient it is to update the color palette that often. Imagine a fancy all-pad rainbow animation where you want it transition as smooth as possible...
That is an interesting question. We will have to try it and see. I imagine it will look fine. I am already (on my original Push interface) batching LED updates into frames which run at a configurable number of updates per second (I believe I am defaulting to 15 FPS at the moment while the light show itself runs at the maximum DMX speed of 40 FPS), and I keep track of the previous frame, and only send changes. I could do the same thing for the palette.
So I agree, for my application a raw RGB setting mode would be preferable, but I should be able to cope with this workaround until and unless a firmware update which provides that becomes available.
Just did a test writing whole "screens" of 64 pads using sysex. I get a little more than 20 FPS. When setting the colors the traditional way (sending note-on messages with color indices) I get 125 FPS.
Also, the asynchronous update after a palette change takes up to 80 ms. This can be solved by "pushing the colors through" by sending note-ons/CCs for each LED after the sysex. Interesting enough this speeds up the 64 pads update to 24 FPS.
Thanks, that is helpful information. I will take the “push the colors through” approach then, while hoping for an eventual raw option. Given that between most frames, most of the LEDs will have unchanged colors for me, and I am sending only changes, this should work fine for Afterglow.
Having read through the LED color section, I can see how a raw color command might not fit well with that model, so I shall not hold my breath for one. However, if you do decide to support such a feature, it would be nice if you could also investigate the ability to set more than one LED in the same SysEx message, to increase throughput and reduce redundant MIDI command byte overhead. Some MIDI grid controllers do that by accepting variable length arguments, allowing you to send additional RGB values which get applied to the next LEDs in some specified scan order, up to a maximum supported command length, which will depend on your buffer sizes.
OK, I have my light cue grid RGB colors being properly displayed and animated on the 8x8 pad grid now (after a brief digression to implement and release an open-source Java library to make it easy to draw on the Push 2 graphic display). I have a new question though:
It appears that I have to set the palette for the white LEDs for a given velocity at the same time as setting the palette for the RGB LEDs for that velocity. I would rather leave the white LEDs alone. Can anyone give me a complete list of what the default white LED palette entries are supposed to be for each velocity, or better, a formula?
Hmm, while writing this I thought of a different problem, and perhaps the best solution to both:
What is Live going to do if I have it running at the same time, and mess with a bunch of the LED color palettes while I am in User mode? Does it restore its own palettes when leaving User mode?
If not, what I should probably do is just query and record all the palette values when I start up my Push 2 mapping, and restore them whenever I shut it down, or whenever I leave User mode. Then I could look at that table of stored values for what the default white palette entry is for each velocity, and preserve that when I am setting my RGB values.
Yes, please query the palettes and restore them afterwards. Putting the RGB and white palettes into one sysex is something I'd not do again, but it's not bad enough to modify the interface, IMHO.
Concerning the sysex speed, I found an easy-to-fix bottleneck. The fix gives us 55 FPS instead of 24 when writing 64 palette entries incl. pushing the colors through with note-ons. Will be contained in one of the upcoming firmware updates.
Great, that is excellent news!
I will take the approach of querying and restoring the palettes, that will not be much effort, and I definitely want to cooperate seamlessly with Live for people who are running light shows while also performing music within Live. I hope that someday Link will be documented as well as the Push 2 now is, so I can support it as one of my synchronization mechanisms. (When I looked at the beta Link SDK agreement, it was very iOS focused, and incompatible with open-source projects.)
And I agree that, although in hindsight it would make sense to use separate sysex messages for the RGB and white palette updates, it is not worth an incompatible interface change today. One potential backwards-compatible tweak would be allowing you to omit the white bytes at the end of the sysex data of the set palette command, and when that happens, leave the white palette entry alone. But it really is not going to be hard for me to look at the saved palette entry and re-send the original values.
All right, I have my palette saving code working. I noticed some things while fine-tuning it that may be of interest to you.
In my first attempt, I just blasted all 128 palette requests at the Push 2, and gathered the responses. Then if any entries were missing, I tried requesting all the missing ones (again at maximum USB speed), and then repeated that a third time. It was purely a guess that I coded a maximum of three attempts in my loop, but that turns out to be exactly how many it took.
It seems the Push 2 got overwhelmed by that volume of palette requests; my first batch ended up receiving about 80 responses. The second batch, about 30 more, and the final batch got the remainder.
I changed my request loop to sleep for 5ms after every 20 requests, and now I am getting all the palette entries on the first try.
The reason of the lost responses is that you were probably not receiving replies in between commands, so buffers overflow. It's always recommended to wait for the reply after each command. There is no significant performance penalty. For the foreseeable future the palette is not dynamically changed by Live, so probably it is totally sufficient to retrieve it ones after startup.
I've added a hint to the manual.
PS. This an interesting moment: publishing the interface manual means people will use the Push 2 in new ways, which might discover unknown bugs or deficiencies. I'm happy it was not the case this time.
Thanks, that makes perfect sense; I had not previously been using any commands with responses, other than the device identification query when initially setting up the connection, so I had not run across this problem before. Since everything is operating asynchronously, it was easier to just send out all the queries and gather the responses as they happened, but I can change my code to query the next palette entry in response to the preceding response, and add a timeout check.
And this is an interesting moment indeed. I was doing all of these things with the original Push, but I did not have documented interfaces to support them, nor any avenue to communicate with the firmware authors. This is much nicer! :grinning:
Thank you also for validating my strategy of only saving the palette once, at initial startup, and restoring it whenever I suspend my interface.
does that mean it is not possible to light up LEDs by sending three 8 bit color values but instead having to change the color palette permanently?
Allowing this would make many hacks more convenient. On a competitors device for instance you can send
to light up a pad using a custom color. Is there a specific reason not to enable this?