- protocol.yaml: SSoT for the binary framing protocol (12 record types) - codegen/gen.mjs: generates C header/source and Node ESM from protocol.yaml - c-backend: ALSA sequencer with drift-free clock_nanosleep tick thread, pattern store (hierarchical sub-patterns), Unix socket server - node-server: Express 5 web app — REST API, SSE for real-time beat events, step-sequencer frontend with pending-edit / explicit-save flow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
148 lines
3.7 KiB
YAML
148 lines
3.7 KiB
YAML
version: 1
|
||
description: Binary protocol between Node sequencer and C ALSA MIDI backend
|
||
|
||
# Frame format: [record_type: uint8][payload_length: uint16le][payload: bytes...]
|
||
# Header size: 3 bytes
|
||
# High bit set (0x80+) means C → Node direction
|
||
|
||
frame:
|
||
- name: record_type
|
||
type: uint8
|
||
- name: payload_length
|
||
type: uint16
|
||
|
||
# Type mapping used by codegen
|
||
types:
|
||
uint8: { c_type: uint8_t, c_put: put_u8, c_get: get_u8, node_write: writeUInt8, node_read: readUInt8, size: 1 }
|
||
uint16: { c_type: uint16_t, c_put: put_u16, c_get: get_u16, node_write: writeUInt16LE, node_read: readUInt16LE, size: 2 }
|
||
|
||
records:
|
||
HELLO:
|
||
id: 0x01
|
||
direction: node_to_c
|
||
description: Protocol version handshake
|
||
fields:
|
||
- name: version
|
||
type: uint8
|
||
|
||
DEFINE_PATTERN:
|
||
id: 0x02
|
||
direction: node_to_c
|
||
description: Define or redefine a pattern (clears existing data)
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|
||
- name: steps
|
||
type: uint8
|
||
note: Total step count e.g. 16 for a one-bar pattern at 16th-note resolution
|
||
- name: channel
|
||
type: uint8
|
||
note: MIDI channel 0-15
|
||
|
||
CLEAR_PATTERN:
|
||
id: 0x03
|
||
direction: node_to_c
|
||
description: Remove all notes and sub-pattern references from a pattern
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|
||
|
||
ADD_NOTE:
|
||
id: 0x04
|
||
direction: node_to_c
|
||
description: Add a note event to a pattern at a specific step
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|
||
- name: step
|
||
type: uint8
|
||
note: 0-based step index within the pattern
|
||
- name: note
|
||
type: uint8
|
||
note: MIDI note number 0-127 (middle C = 60)
|
||
- name: velocity
|
||
type: uint8
|
||
note: 0-127
|
||
- name: duration_steps
|
||
type: uint8
|
||
note: Duration in steps (1 = one step)
|
||
|
||
ADD_SUB_PATTERN:
|
||
id: 0x05
|
||
direction: node_to_c
|
||
description: Schedule a sub-pattern to start at a given step within a parent pattern
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|
||
note: Parent pattern ID
|
||
- name: step
|
||
type: uint8
|
||
note: Step within parent at which the sub-pattern begins playing
|
||
- name: sub_pattern_id
|
||
type: uint16
|
||
|
||
PLAY:
|
||
id: 0x06
|
||
direction: node_to_c
|
||
description: Start playing a pattern from step 0
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|
||
|
||
STOP:
|
||
id: 0x07
|
||
direction: node_to_c
|
||
description: Stop all playback and send MIDI all-notes-off
|
||
fields: []
|
||
|
||
SET_TEMPO:
|
||
id: 0x08
|
||
direction: node_to_c
|
||
description: Set global tempo (applies immediately, even mid-sequence)
|
||
fields:
|
||
- name: bpm_x10
|
||
type: uint16
|
||
note: "BPM × 10 for 0.1 BPM resolution — e.g. 1200 = 120.0 BPM"
|
||
|
||
ACK:
|
||
id: 0x81
|
||
direction: c_to_node
|
||
description: Acknowledge a received command
|
||
fields:
|
||
- name: acked_type
|
||
type: uint8
|
||
note: Record type being acknowledged
|
||
|
||
ERROR:
|
||
id: 0x82
|
||
direction: c_to_node
|
||
description: Report an error condition
|
||
fields:
|
||
- name: code
|
||
type: uint8
|
||
- name: context_type
|
||
type: uint8
|
||
note: Record type that triggered this error
|
||
|
||
BEAT_TICK:
|
||
id: 0x83
|
||
direction: c_to_node
|
||
description: Timing notification sent on every sequencer step
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|
||
- name: step
|
||
type: uint8
|
||
note: Current step within the pattern (0-based)
|
||
- name: beat
|
||
type: uint8
|
||
note: Current beat number within the current cycle (wraps at 255)
|
||
|
||
PATTERN_END:
|
||
id: 0x84
|
||
direction: c_to_node
|
||
description: Notification that a pattern has completed one full cycle
|
||
fields:
|
||
- name: pattern_id
|
||
type: uint16
|