Laserphile/JS-Telecortex-2-Server

View on GitHub
src/protocols/sk9822.js

Summary

Maintainability
A
0 mins
Test Coverage
import { flatten, mapValues } from 'lodash';
import { createGammaTable } from './gamma';

const uint8Max = 0x100;

// Constant prefix in first byte of sk9822 frame
const sk9822Prefix = 0xe0;
// Mask for brightness bitfield in first byte of sk9822 frame
const sk9822BrightnessMask = 0x1f;
// header bytes in sk9822 protocol
const sk9822ResetFrame = [0x00, 0x00, 0x00, 0x00];
// order of colours in sk9822 frame
const sk9822ColourOrder = ['b', 'g', 'r'];

export const SK9822_GAMMA = createGammaTable(uint8Max, 2.8);

export const sk9822GammaCorrect = colour =>
  mapValues(colour, colorVal => SK9822_GAMMA[Math.round(colorVal)]);

/**
 * Given a colorsys RGB objects and a float brightness value from 0 to 1,
 * @return {number[]} the sk9822 frame for this pixel
 */
export const rgb2sk9822 = (colour, brightness = 0.5) => {
  // first byte is a constant 0xE0 + 5 bit brightness value
  const correctedColour = sk9822GammaCorrect(colour);
  return [sk9822Prefix + Math.round(brightness * sk9822BrightnessMask)].concat(
    sk9822ColourOrder.map(key => correctedColour[key] % uint8Max)
  );
};

/**
 * Given a list of colosys RGB objects, and a float brightness value from 0 to 1,
 * @return {number[]} a complete sk9822 message for the strip
 */
export const colours2sk9822 = (colours, brightness) =>
  Array.from(sk9822ResetFrame).concat(
    flatten(colours.map(colour => rgb2sk9822(colour, brightness)))
  );