midi lane
midiLane · sourcesMIDI LANE — a per-channel "instrument bus" demux for a hardware MIDI sequencer (Reliq, Cre8audio Programm, Empress ZOIA, or any class-compliant USB-MIDI device). DAW-style workflow: assign each track of your sequencer to its own MIDI channel, then drop one MIDI LANE per instrument and point each at that track's channel — multi-timbral = several lanes, like several MIDI-CV-BUDDYs but channel-aware and richer. Each lane demuxes its channel into the CV/gate the rack speaks: pitch_cv (V/oct, 0V = C4 = MIDI 60, pitch-bend summed at ±2 st), gate (HIGH while any key on the lane is held; with RETRIG, dips one audio block on each new note-on so a downstream ADSR re-fires), velocity_cv (0..1), plus TWO learn-assignable CC taps (cc_a / cc_b → 0..1 CV — hit LEARN, wiggle a CC, done; these subsume the per-track CC-modulation lane and can drive audio params OR video params via the cross-domain bridge), plus ONE by-note-number drum gate (note_gate fires on a card-selected MIDI note, default GM kick = 36 — the Programm/Reliq ch10 drum-router pattern generalized via configuration, not 8 fixed ports). MONO mode is monophonic with three voice-priority modes (LAST / LOW / HIGH); POLY mode adds a 10-channel polyPitchGate output (poly) so a chord on the lane plays a polyphonic synth (cartesian / dx7). The SAME outputs drive VIDEO modules for free: a gate or cv handle cabled into ACIDWARP.scene_cv / DOOM.cv_pN fires visuals with no synth voice — the engine's cross-domain CV/gate→video bridge needs no special "video gate" port. Uses the browser's built-in Web MIDI API (no third-party library, no native bridge); click "Connect MIDI…" once per origin to grant access. Main-thread plumbing (ConstantSource-per-output, 2 ms scheduling lookahead) identical to MIDI-CV-BUDDY, whose note logic it reuses verbatim. v1 surfaces a single-channel-or-ALL selector on the card (the engine supports a multi-channel Set under the hood for a future multi-select). End-to-end Web MIDI latency is the honest ~5-10 ms main-thread path.
the faceplate
outputs
| id | cable | what it does |
|---|---|---|
pitch_cv | cv | The winning held note as pitch CV in volts-per-octave (0V = C4 = MIDI 60), with pitch-bend summed in. Driven only when the card's mode is 'mono' (it follows the voice-priority winner of the held stack and latches the last note); in 'poly' mode it stays quiet and you use the POLY output instead. control voltage (CV) |
gate | gate | High while any key on this lane's channel(s) is held, with a brief retrigger dip so downstream envelopes re-fire. Driven only in 'mono' mode (it sits low in 'poly' mode). Patch it into an envelope or VCA gate. gate / trigger; gate — acts while the level is high (reacts to both edges) |
velocity_cv | cv | How hard the most recent note was struck, as 0..1 CV (MIDI velocity / 127), latched between events. Route it to a VCA level or filter cutoff for velocity dynamics. control voltage (CV) |
cc_a | cv | Learn-assignable Continuous-Controller tap A, output as 0..1 CV: it follows whatever MIDI CC number the card has assigned to slot A (e.g. a mod wheel or a track's automation lane on this channel). Wire it to an audio param — or, via the cross-domain bridge, a video param — for hands-on modulation from the external gear. control voltage (CV) |
cc_b | cv | Learn-assignable Continuous-Controller tap B, a second independent 0..1 CV tap following its own card-assigned CC number — a second modulation lane alongside cc_a. control voltage (CV) |
note_gate | gate | A gate that fires when the SPECIFIC MIDI note number selected on the card arrives on this lane's channel(s) (defaults to GM kick, MIDI 36). It generalizes the per-device drum-router pattern (e.g. the Programm's ch10 by-note triggers) through one configurable port — patch it into a drum voice's strike or any trigger input. gate / trigger; trigger — fires once per rising edge |
poly | polyPitchGate | A polyphonic pitch+gate bus (up to 10 voices) that ALWAYS carries the full held chord, in both 'mono' and 'poly' modes. Wire it to a poly-aware voice — DX7, CUBE, or a module with a poly input — and the chord plays straight away with no mode toggle. This is the real polyphonic source chain: MIDI LANE.poly → poly synth produces audible chords (it does not need the mono outputs). poly pitch+gate bus; 10-channel poly bus (5 pitch + 5 gate lanes) |
controls
| control | what it does |
|---|---|
| Midi lane channel {n} | Which MIDI channel this lane listens to — the setting the whole module is built around. The intended workflow is DAW-style 'one channel = one instrument': assign each track of the external sequencer to its own channel, drop one lane per track, and set each lane's channel to match. Channels are shown 1..16 the way the hardware labels them, while the wire format counts from zero; ALL collects every channel into this one lane, which is what you want for a single-track device and what you do not want the moment two tracks are playing. Changing it clears any held notes so a channel switch cannot strand a gate high. |
| Midi lane clear a {n} | Unassigns CC tap A, so no controller number drives it and the CC A jack holds its last value instead of following anything. Use it to free a tap you bound by accident, or to park a lane's modulation before re-learning it to a different control. It does not change the CC A jack's current level, and it does not touch tap B. |
| Midi lane clear b {n} | Unassigns CC tap B, leaving the CC B jack holding its last value with nothing driving it. The mirror of CLEAR A, and independent of it — clearing one tap never disturbs the other's binding. |
| Midi lane connect {n} | The one-time-per-origin permission gesture, and the first thing to press on a lane that has never been used. Web MIDI needs the browser's consent before any device is even visible, so until it is granted this module has no stream to demux and all seven jacks sit at rest — it is not optional and it is not a setting. Once access is granted the device strip at the top of the dock faceplate lists the inputs that were found and remembers the one you pick, so a reloaded patch re-attaches without another press. The grant is per origin, not per lane: drop a second MIDI LANE afterwards and it is already connected. |
| Midi lane learn a {n} | Arms CC tap A to bind itself to the next controller number that arrives on this lane's channel(s). Press it, then move the control you want on the device — a mod wheel, a fader, a track's automation lane — and tap A follows that CC number from then on, emitting it as 0..1 CV on the CC A jack. This is how a tap gets bound: there is no list of controller numbers to hunt through, because which physical control sends which number is a property of the device rather than of this module. The binding is saved with the patch. Only one tap arms at a time, so arming A disarms B. |
| Midi lane learn b {n} | Arms CC tap B, the second independent modulation tap, exactly as LEARN A arms the first — press it and move a control on the device to bind the next controller number that arrives. Two taps is what lets one track carry two hands' worth of modulation: a wheel into a filter and a pedal into a delay send, say, from the same channel. Arming B disarms A, since only one tap can be listening for the next number. |
| Midi lane mode {n} | Whether the MONO jacks speak. In MONO the held stack collapses to one winning note (see PRIORITY) and drives PITCH and GATE; in POLY those two jacks stay quiet and the chord goes out of the POLY jack instead. The thing worth knowing is that POLY is not a mode you have to find: the POLY jack carries the full held chord in BOTH settings, so wiring it to a poly-aware voice plays straight away and this control only decides whether the mono pair is ALSO live. Switching clears held notes so the bank you just left cannot leave a voice sounding. |
| Midi lane note {n} | Which single MIDI note fires the NOTE jack — the by-note drum tap. When a note-on with exactly this number arrives on the lane's channel(s), NOTE emits a short one-shot pulse suitable for a drum voice's strike or any trigger input; every other note is ignored by this jack and still flows through PITCH/GATE/POLY as usual. It generalizes the per-device drum-router pattern (a Programm or Reliq sending its kit on channel 10 by note number) through one configurable port rather than eight fixed ones, so a rack with six drum voices is six lanes on one channel with six different notes here. Type either a note name (c2, f#3) or a bare MIDI number (0..127); the default 36 is the General MIDI kick. A value outside 0..127 is refused rather than rounded to the nearest legal one. |
| Midi lane priority {n} | Which held note wins when several are down and the lane is in MONO. LAST follows the most recently pressed key, which is what feels like playing; LOW holds the bottom of the chord, the classic bass-line behaviour that lets you play over a held root; HIGH holds the top, so a melody survives notes added underneath it. It has no effect at all in POLY, where every held note gets its own voice on the POLY jack. |
| Midi lane retrig {n} | Whether a new note while another is already held re-fires downstream envelopes. ON drops the GATE jack for a single audio block and raises it again, which an ADSR reads as a fresh note-on, so legato playing articulates every note. OFF leaves the gate high through the change, so the envelope sustains and only the pitch moves — the legato behaviour you want for a slide or a portamento line. MONO only; it has no bearing on the POLY jack, where each voice has its own gate. |
source
midi-lane.ts on GitHub.