Skip to content

Add amy_config.midi_thru: echo MIDI in to MIDI out (#738)#739

Open
bwhitman wants to merge 1 commit into
mainfrom
claude/midi-thru
Open

Add amy_config.midi_thru: echo MIDI in to MIDI out (#738)#739
bwhitman wants to merge 1 commit into
mainfrom
claude/midi-thru

Conversation

@bwhitman

Copy link
Copy Markdown
Collaborator

Closes #738.

What

Adds an amy_config_t.midi_thru flag. When set, AMY echoes every incoming MIDI byte straight to MIDI out, in addition to processing it normally. Off by default.

amy_config_t c = amy_default_config();
c.midi_thru = 1;          // enable at startup
amy_start(c);
// ...or toggle at runtime:
amy_global.config.midi_thru = 1;

How

Forwarding is done byte-by-byte at the top of convert_midi_bytes_to_messages() — the single function that all MIDI inputs (UART via esp_poll_midi/on_pico_uart_rx, USB via check_tusb_midi) funnel through.

Forwarding inside the parse loop (rather than blasting the whole input buffer) keeps USB correct: USB MIDI always delivers fixed 3-byte groups, padded with junk for <3-byte messages. The existing if(usb) i = len+1 early-exits stop the loop before those padding bytes, so only the real MIDI bytes of a USB message are passed through. UART input has no padding and forwards in full.

Notes

  • No new symbols added to amy_midi.c (only the body of an existing function changed), so no Godot platform-stub updates are needed.
  • On Tulip this is exposed to Python as tulip.amy_midi_thru(True/False) (companion tulipcc PR).
  • Web targets are out of scope for now; the field is platform-agnostic and stays off unless explicitly enabled.

Test

  • make test — all 94 tests pass (midi_thru is off by default; no behavior change to existing paths).
  • Verified amyboard (ESP32-S3) firmware compiles with the change.

Docs updated: docs/api.md (config table) and docs/midi.md (new "MIDI Thru" section).

When amy_config.midi_thru is set, every incoming MIDI byte is echoed
straight to MIDI out, in addition to being processed normally. Off by
default.

Forwarding happens byte-by-byte inside convert_midi_bytes_to_messages,
which all MIDI inputs (UART, USB) funnel through. Forwarding inside the
parse loop (rather than blasting the whole input buffer) means USB MIDI
packet padding is naturally skipped: USB always delivers fixed 3-byte
groups, and the existing `if(usb) i = len+1` early-exits stop the loop
before the padding bytes of <3-byte messages. UART input has no padding
and forwards in full.

Closes #738

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MIDI thru

1 participant