midi device: add cable-aware stream read (tud_midi_n_demux_stream_read)#3514
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements a cable-aware stream read function tud_midi_n_demux_stream_read() for USB-MIDI devices, addressing issue #1838. The existing tud_midi_n_stream_read() function ignores its cable_num parameter and mixes data from all virtual cables, making it impossible to build multi-port MIDI devices where each cable maps to a separate physical MIDI port.
Changes:
- Added
tud_midi_n_demux_stream_read()that returns the cable number of data actually read - Added single-interface convenience wrapper
tud_midi_demux_stream_read() - Function peeks at USB-MIDI packet headers to stop when the next packet belongs to a different cable
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/class/midi/midi_device.h | Added function declarations and inline wrapper for cable-demultiplexing stream read |
| src/class/midi/midi_device.c | Implemented cable-aware stream read using peek-before-consume pattern similar to host-side implementation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The existing tud_midi_n_stream_read() accepts a cable_num parameter but ignores it — all cables share a single FIFO and stream parser state, so data from different virtual cables is silently mixed together. Add tud_midi_n_demux_stream_read() which returns the cable number of the data that was actually read. It peeks at each USB-MIDI event packet header before consuming it and stops when the next packet belongs to a different cable, allowing callers to dispatch per-cable without losing data. Implementation details: - Mirrors the host-side tuh_midi_stream_read() approach: tu_edpt_stream_peek for cable inspection, CIN-based byte count (USB MIDI 1.0 Table 4-1), leftover handling via existing midi_driver_stream_t - *p_cable_num initialized to 0xff sentinel so callers can detect "no data" even when return value is 0 - Cable-change check (total_read > 0 guard) covers both leftover-originated reads and freshly consumed packets - TU_VERIFY uses explicit != NULL comparisons, consistent with codebase style - Note: shares stream->buffer with tud_midi_n_stream_read(); do not mix calls on the same interface - Adds single-interface convenience wrapper tud_midi_demux_stream_read() Closes hathach#1838
9a08c74 to
4d40219
Compare
Size Difference ReportBecause TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds. Note: If there is no change, only one value is shown. Changes >1% in sizeNo entries. Changes <1% in sizeNo entries. No changes
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks @HiFiPhile for the merge! Deleting the branch on my end. |
Summary
Implements the
tud_midi_n_demux_stream_read()function proposed in #1838 — a cable-aware variant oftud_midi_n_stream_read()that returns the cable number of the data actually read.The existing
tud_midi_n_stream_read()accepts acable_numparameter but ignores it ((void) cable_num), silently mixing data from all virtual cables into a single stream. This makes it impossible to build multi-port MIDI devices where each cable maps to a separate DIN jack or logical MIDI port.New API
Reads MIDI byte-stream data from the RX FIFO. Peeks at each USB-MIDI event packet header before consuming it and stops when the next packet belongs to a different cable, allowing callers to dispatch per-cable without losing data. Sets
*p_cable_numto the cable number of the returned data.Usage example
Implementation details
tuh_midi_stream_read(): usestu_edpt_stream_peek()for cable inspection before consuming packetsmidi_driver_stream_tFiles changed
src/class/midi/midi_device.c— newtud_midi_n_demux_stream_read()functionsrc/class/midi/midi_device.h— declaration + single-interface wrapperCloses #1838