# Multi‑Channel & Bind Feature The looper supports up to 16 independent channels (numbered 0–15). Channel 0 is always present and connected to the `looper:input` / `looper:output` audio ports. Additional channels can be created and removed dynamically using MIDI commands. ## MIDI Ports - **`looper:control`** – receives MIDI note‑on events for channel management and state toggling. - **`looper:clock`** – receives MIDI clock messages (0xFA, 0xFC, 0xFB) that affect channel 0 only. ## Control‑Key Modifier Hold the **control key** (MIDI note 64) pressed *before* sending another note to put the looper in “command mode”. While control‑key is active, the next note‑on (with velocity > 0) performs a special action instead of its direct mapping. The control key is released either by sending note‑off (note 64 or any note) or by sending a note‑on while control‑key is already active (the action is performed and control‑key is cleared). ## Available Commands (under control key) | Note | Action | |------|----------------------------------------------------------------------------------------------| | 0–15 | **Bind** the next `control+62` toggle to the channel with that index. | | 60 | **Add** a new dynamic channel (creates `channelX_input` / `channelX_output` ports). | | 61 | **Remove** the highest‑numbered active channel (excluding channel 0). | | 62 | **Toggle** the current bound channel through its state machine: | | | IDLE → RECORD → LOOPING → PAUSED → LOOPING → … (each press advances one step). | > **Notes:** > - The default bound channel is **0**. If you never send a bind command, `control+62` controls channel 0. > - To bind a different channel, send `control + note <16>` (e.g., control + note 5 binds channel 5). > - Bind is sticky – it stays until overwritten by another bind command. > - There is **no unbind** command; you can rebind to channel 0 if needed. ## Direct Mapping (without control key) For backward compatibility, the following notes work **without** the control‑key modifier: | Note | Action | |------|----------------------------------------------------------------------------------------------| | 1 | Toggle channel 0 state (IDLE→RECORD→LOOPING→PAUSED→LOOPING…). | | 60 | Add a dynamic channel (same as `control+60`). | | 61 | Remove the highest‑numbered active channel (same as `control+61`). | ## Example Usage 1. **Record a loop on channel 0 (using direct note 1)** - Send note‑on, note 1, velocity 127 → channel 0 enters RECORD. - Play some audio into `looper:input`. - Send note‑on, note 1, velocity 127 again → channel 0 enters LOOPING. - The recorded audio repeats indefinitely. 2. **Use the control‑key to toggle channel 0** - Send `note‑on, note 64` (control key). - Then send `note‑on, note 62` → toggles channel 0 (IDLE→RECORD). - Send `note‑on, note 64` again, then `note‑on, note 62` again → RECORD→LOOPING. 3. **Add a new channel and bind it** - Send `note‑on, note 64` + `note‑on, note 60` → creates channel 1. - Send `note‑on, note 64` + `note‑on, note 1` → binds channel 1. - Now `control+62` toggles channel 1 instead of channel 0. - Record audio on channel 1 by sending `control+62` twice. 4. **Remove a dynamic channel** - Send `note‑on, note 64` + `note‑on, note 61` → removes the highest‑numbered active channel (e.g., channel 1). ## Notes - The looper must be connected to a running JACK server. - Channel buffers hold up to 5 seconds of audio at 48 kHz. - After removal, the channel’s audio ports are unregistered on the next main‑loop cycle (deferred to avoid race conditions). - The bind index is stored as an integer (0–15); values outside 0–15 are ignored (the note is processed as a command rather than a bind).