Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
  • This project
    • Loading...
  • Sign in / Register
T
Tidal
  • Overview
    • Overview
    • Details
    • Activity
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 0
    • Issues 0
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Charts
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • PLN
  • Tidal
  • Repository

Switch branch/tag
  • Tidal
  • tools
  • at
  • tests
  • __init__.py
Find file
HistoryPermalink
  • PLN (Algolia)'s avatar
    feat(lcxl): a virtual LaunchControl XL, and PLN's six-step colour ramp · 80b732b0
    The LED work had a hole in the middle of it. `lcxl-leds.py --watch` was
    written, wired into the boot sequence and into gig-up.sh, and validated only
    against a FAKE aseqdump stream — nobody, human or machine, had ever seen it
    light a single LED. PLN kept reporting "still seeing static colors" and I had
    no way to check my own work, because I cannot look at the device.
    
    mock-lcxl decodes the same SysEx the real surface receives and renders it in
    the terminal, so the convention can be designed, reviewed and regression-tested
    without hardware. The only thing still needing PLN's eyes is whether the
    physical LEDs match the picture.
    
    It answered the "static yellow" complaint on its first run. Painting
    claude.tidal lights knobC 1-3 BRIGHT AMBER (63) — which is exactly
    filter_colour(64), the DJ filters resting at centre. Our code is working as
    designed; the design is the problem. Bright amber at rest is visually
    indistinguishable from the factory yellow PLN is trying to get away from, so
    "correct" and "looks broken" are the same picture. Second finding, same run:
    control_colour returns hue["full"] for every value from 8 to 119, so a touched
    knob is one flat bright colour across its whole travel. Touch changes it once
    and then it never moves again — which is precisely what he has been describing.
    
    So value_ramp() implements his spec verbatim — "from dim red nothing through
    bright red dim orange bright orange dim green bright green at max". That is
    six steps, and six is not a coincidence: the LCXL is bicolor (2 bits red x 2
    bits green = 16 states) and only about six read reliably on a dim stage. The
    ramp uses the entire usable budget and spends nothing on shades nobody can
    tell apart. `mock-lcxl.py --palette` shows the whole budget; --ramp shows the
    convention resolving across 0..127.
    
    The DJ filters deliberately keep filter_colour and do NOT get the ramp: they
    are bipolar, centre 64 is bypass, and a monotonic red->green ramp would paint
    bypass as mid-orange and the two opposite musical extremes as the same colour.
    
    8 regression tests covering the ramp order, monotonicity, "a mapped control at
    zero is dim, never off" (a control you cannot see is one you forget exists),
    "a filter is never dark", and a SysEx round-trip through the mock surface.
    PLN (Algolia) authored Jul 28, 2026
    80b732b0
__init__.py 0 Bytes
EditWeb IDE
×

Replace __init__.py

Attach a file by drag & drop or click to upload


Cancel
A new branch will be created in your fork and a new merge request will be started.