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
  • lcxl3_language.py
Find file
BlameHistoryPermalink
  • PLN (Algolia)'s avatar
    feat(lcxl3): the rings breathe at the tempo when a control is engaged · 0824a277
    Motion on the board now means one thing: THIS IS MAKING SOUND. It used to mean
    only "a DJF sits at its zero mark", because animated() hard-returned False for
    every role but family_filter.
    
    Three laws, all at bar rate (the slow breath, not the beat one):
    
      fx / fx2, every orbit   breathe whenever the knob is off zero
      level, d9-d12 only      breathe whenever the level is not off. Only those
                              four, because d1-d8 levels live on row D and FADERS
                              HAVE NO LEDS — painting them was already called a
                              no-op lie in paint_cell, and asking for it here would
                              have been the same lie one layer up
      boolean cells           dark until 127, breathing at 127
    
    That last law needs to know what a control IS, so parse_kinds() reads it off
    the track: a cc reached through `# effect (... "^NN" ...)` is a dial, a cc
    reached through midiOn/midiOff is a switch. Tidal applies midiOn's function
    while the CC reads high, so such a control is boolean however many steps the
    hardware sends — and a ring fading up across a range the music ignores is a
    ring that lies about the sound. When one cc is used both ways, continuous wins:
    the value demonstrably matters somewhere, so fading is the honest paint.
    
    The breath's CEILING is the value (_breathe_to): the brightest instant equals
    _lightness(value) and never exceeds it, so "lightness carries VALUE" still
    holds while motion carries engagement. A knob at 30% breathes dim.
    
    Levels stay honest. Ardour owns cc 13-16 and has not told us their values, so
    ring_colour(value_known=False) keeps the flat rest colour rather than breathing
    on a guess — the oldest rule here is that the LEDs do not lie. The feedback
    feed that fills ardour_seen comes next; until it does, those four rings look
    exactly as they did.
    
    Also folds two defaults that had drifted: paint used 0 for an unseen control
    and the glow tick used 64. value_of() settles it — an unseen DJF is at its
    centre detent, because that is where the knob physically rests; anything else
    unseen is OFF, because engagement we have never observed must not be claimed.
    
    Checked against rose_rouge: B8+C8 (d8's stacks, the ones asked about) classify
    bool; A6/A7/A8's delay and squiz knobs classify cont; breath peak equals the
    static value at every level; DJF behaviour unchanged; unmapped still black.
    PLN (Algolia) authored Sep 06, 2026
    0824a277
lcxl3_language.py 19.1 KB
EditWeb IDE
×

Replace lcxl3_language.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.