Hi @devoh,
This is a good idea, and something I’ve been considering.
There’s a number of tools that could be ported/supported, and some commonality with slightly different inputs/names.
Much of the fastLED AP is fixed in 8 bit or 16 bit math, and as such has name variants (like beat8
and beat16
) and takes integer arguments and return integer values where they usually mean some ratio between 0.0 and 1.0.
I could add a strictly compatible API so that code could work as-is (with a few exceptions), which is what you are asking for, but I think this code has a different aesthetic that is directly tied to the implementation constraints, much of it linked to 8 bit micros. These days 32 bit CPUs and even single and double precision FPUs becoming more common so I’ve tried to make a design choices that don’t punt these to the animation author.
I’ve considered adding compatible concepts, such as beat
and beasin
use fractional values instead of 8 or 16 bit integer inputs.
For experienced microcontroller programmers there’s a bit of mental shift to go from “255 is 1.0” to “1.0 is 1.0” but I think it simplifies things in the long run, and is certainly simpler for new users.
In the meantime, I think some measure of compatibility could be done with an adapter layer in the pattern code, for example here are beat8 and beatsin8 adapters:
// beat8( BPM ) returns an 8-bit value that cycles 'BPM' times
// per minute, rising from 0 to 255, resetting to zero,
// rising up again, etc.. The output of this function
// is suitable for feeding directly into sin8, and cos8,
// triwave8, quadwave8, and cubicwave8.
function beat8(bpm) {
return 255 * time(0.91552734375/bpm)
}
// beatsin8( BPM, uint8_t low, uint8_t high) returns an 8-bit value that
// rises and falls in a sine wave, 'BPM' times per minute,
// between the values of 'low' and 'high'.
function beatsin8(bpm, low, high) {
return wave(time(0.91552734375/bpm)) * (high - low) + low
}
Of course these won’t truncate to 8 bits like their C code equivalents in fastLED since they are all using fixed point values, but for most cases it should work. If necessary, a floor()
here and there would do the trick.
The beat16 and beatsin16 won’t work without some porting work because PB variables have only 16 bits for the integer portion and use signed numbers, so they store up to 32,767, not 65,535 and would overflow.
Here is the slight adaptation that doesn’t scale to 255 or 65536, and uses fractional values. If I were to design fastLED around a real number type (like floats or 16.16 fixed point math) I would make an API like this:
// beat( BPM ) returns an value that cycles 'BPM' times
// per minute, rising from 0.0 to 1.0, resetting to zero,
// rising up again, etc.. The output of this function
// is suitable for feeding directly into wave, triangle, etc
function beat(bpm) {
return time(0.91552734375/bpm)
}
// beatsin( BPM, low, high) returns an value that
// rises and falls in a sine wave, 'BPM' times per minute,
// between the values of 'low' and 'high'.
function beatsin(bpm, low, high) {
return wave(time(0.91552734375/bpm)) * (high - low) + low
}
As you can see, these are very similar, but don’t assume 8 bit values, instead returning values between 0.0 and 1.0, which are compatible with the rest of the Pixelblaze API. Conceptually these are similar to fastLED APIs, and might help port patterns.
I would fully welcome and help with any efforts to create a JS language API compatibility layer that helps port fastLED patterns. Of course there are a ton of APIs, not just the math stuff, including color utilities and things like that to explore.
I hope that helps both give you a head start in porting, and also an idea of my thinking around the design of the animation APIs.