Varibright failover for legacy devices?

I got pretty excited to try out Block Party, but my bubble totally burst when none of my LEDs lit up. Alas, Rodrigo programmed it specifically for varibright, and I’m on a grayscale 128.

The core issue here is that libmonome (and in turn, serialosc) just NOPs for the /level OSC messages, rather than degrading gracefully.

So, I’ve opened up a pull request with a proof of concept implementation.

For the thoughtful non-C-coders in the bunch, there are a couple of design/approach issues that should probably still be hammered out. Particularly, where do we put a threshold for falling back?

In this implementation, any LED whose level is set to 8 or higher is turned on, and anything 7 or lower is turned off. This matches up somewhat with the legacy 4-level varibright, in that “low” intensity maps to off, and “medium” and “high” intensities both map to on.

Is this something that should be configurable? Should only the “high” intensity map to on, with “medium” mapping to off?

I was also thinking that it might be a worthwhile experiment to add a timer and an LED state buffer to libmonome for legacy devices and have it attempt to PWM the brightness. There might be downsides to this (code bloat in libmonome, for example), but since we already have the higher-level OSC API, and since people are using it to build apps, it seems like a reasonably good idea to try to emulate as much as possible, at as low of a level as possible in order for older devices to keep up with the times.


I was planning on putting the code conversion stuff from TPV1 into TPV2, but didn’t think to put it in BP. The downsampling (internally) would be much easier as I use /monome/grid/led/level/row exclusively in BP(/TPV2).

The threshold thing is tricky though, as I pretty solidly use the whole range of brightness, with something as dim as 3 being used in the alt menu to show the available tilt choices as well showing what setting/mode is engaged by having an LED brighter (which wouldn’t show up if everything is clipped).

I remember ages ago someone (don’t remember which app) was using PWM for a faux-brightness thing. I don’t remember it being super granular, so it was probably just off/dim/on.

Yeah, this dormant memory is, I think, what inspired the thought of moving that functionality over to libmonome. I remember it being a complete pain in the ass, and slower than a camel in quicksand, to implement the PWMing in Max. At least if it were handled in libmonome it would be more efficient.

I’ll need to do some experiments to see how much usable granularity I can get with doing the intensity fully in software, but I’m guessing that the most appropriate way to do that would be to have libmonome just send hardware LED_FRAME messages at some specified refresh rate, so when you send something like /grid/led/set 5 5 1, it would set the appropriate bit in an internal buffer rather than passing the message directly onto the device. Then the LED would be lit up appropriately on the next refresh.

I’m not at the point of trying to implement this yet, but, these are the design thoughts anyways…

That would definitely be better than just metro-banging the shit out of oodles of LEDs to fake the PWM over serialosc.

I would think that keeping just a ‘dim’ state would be enough for compatibility, so there could be two definable thresholds for off->dim and dim->on, then people could program around that.

this has been discussed and somehow inexplicably deferred for too long-- it’s an easy fix and makes sense. i think the issue has been collectively deciding on the most rational behavior.

it makes sense to be to split on/off at the midpoint. obviously some applications won’t look right. if an app author is ambitious/kind enough to support old devices, there will simply need to be a separate LED update function (i did this in the modules). but in reality we should be pushing forward with vari-bright as it is such a higher level experience.

i do not want to add any timer/pwm based emulation into libmonome or serialosc. flickery lights are a nightmare and i’m certain the apps wouldn’t translate well. it’s much better to hand-customize a mono-brightness experience, and drop features where things don’t make sense.

so yes-- excellent-- i’ll check out the pull request. thanks!


What about slow blinking for the lowest values on mono bright models? Or would that look funny…

i merged in @rknLA’s pull request, and i’m happy to merge in fallback code for the 40h as well.

i am very reluctant to add or merge any code in for fallback-by-blinking. separate entirely to the question about whether it even looks good as is usable (and i personally don’t think it looks good, though it could potentially be useful) is the complexity it would add to libmonome, which is currently little more than a 1:1 translation layer between C API calls and serial messages.

libmonome would need to start caching the state of all the LEDs and then would need a mechanism for notifying client code that it needs to blink LEDs, and since libmonome isn’t designed to drive its own event loop, that pushes complexity out into serialosc as well.

1 Like

Maybe this has been answered before, but I have a grayscale 64 and had the strange idea of having the LEDs pulse when selected. I was wondering if the individual LEDs could do that, or if I had to just deal with doing it over the entire grid.

Maybe it would look like a giant mess, but humor me.

I suspect the state of affairs with a varibright hack in libmonome is about the same now as it was ~5 years ago. It’s probably better to do this in the application layer (despite it inevitably being “not great”, and the refresh rate not being high enough to really make it look like a dimmed LED instead of a blinking one)

Personally, I’m waiting patiently for the Vb_driver - a variable brightness upgrade for older grids to update my 40h and gs128.

1 Like