Sound Byte Libs 0.5.1-121-g3358a44
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
midi.hpp
Go to the documentation of this file.
1#ifndef SBL_USB_MIDI_HPP_
2#define SBL_USB_MIDI_HPP_
3
4/**
5 * @file midi.hpp
6 * @brief USB MIDI device interface
7 *
8 * Provides bidirectional USB MIDI 1.0 via TinyUSB's MIDI device class.
9 * Operates on cable 0 (single virtual cable).
10 *
11 * RX path: tud_midi_stream_read() → raw MIDI bytes → feed to sbl::midi::Parser
12 * TX path: MidiEvent → raw MIDI bytes → tud_midi_stream_write()
13 *
14 * Output ports. A USB device has one cable, so hardware targets have one
15 * output port and `port` is always 0. A target that offers more says so
16 * through out_port_count(): the workbench gives an app several, which is what
17 * a multi-voice sequencer sends into (FDP-078).
18 *
19 * Requires CFG_TUD_MIDI=1 in tusb_config.h and the composite CDC+MIDI
20 * descriptor in usb_descriptors.c.
21 *
22 * Usage:
23 * // RX: poll in main loop (or use sbl::midi::poll_usb())
24 * uint8_t buf[64];
25 * uint32_t n = sbl::usb::MidiPort::read(buf, sizeof(buf));
26 * parser.push(buf, n);
27 *
28 * // TX: send events
29 * sbl::usb::MidiPort::send(event);
30 */
31
32#include <cstdint>
34
35namespace sbl::usb {
36
37/**
38 * @brief USB MIDI device port (static class)
39 *
40 * All methods are safe to call from main loop context.
41 * Not ISR-safe — TinyUSB device stack is not reentrant.
42 */
43class MidiPort {
44public:
45 /**
46 * @brief Check if USB MIDI interface is mounted by host
47 * @return true if host has enumerated and configured the MIDI interface
48 */
49 static bool connected();
50
51 /**
52 * @brief Read decoded MIDI bytes from USB (RX)
53 *
54 * TinyUSB unpacks 4-byte USB MIDI Event Packets into standard MIDI
55 * byte stream. Feed the output directly to sbl::midi::Parser::push().
56 *
57 * @param buf Buffer to receive MIDI bytes
58 * @param max_len Maximum bytes to read
59 * @return Number of bytes read (0 if nothing available)
60 */
61 static uint32_t read(uint8_t* buf, uint32_t max_len);
62
63 /**
64 * @brief Send a MidiEvent over USB MIDI (TX)
65 *
66 * Converts the event to standard MIDI bytes and writes them via
67 * tud_midi_stream_write(), which handles USB packet framing.
68 *
69 * @param event The MIDI event to send
70 * @param port Output port, 0 to out_port_count() - 1
71 * @return true if all bytes were written, false if the buffer is full or
72 * the port does not exist
73 */
74 static bool send(const sbl::midi::MidiEvent& event, uint8_t port = 0);
75
76 /**
77 * @brief Write raw MIDI bytes to USB MIDI (TX)
78 *
79 * TinyUSB packs bytes into 4-byte USB MIDI Event Packets.
80 *
81 * @param data Raw MIDI bytes to send
82 * @param len Number of bytes
83 * @param port Output port, 0 to out_port_count() - 1
84 * @return Number of bytes written (0 if the port does not exist)
85 */
86 static uint32_t write(const uint8_t* data, uint32_t len, uint8_t port = 0);
87
88 /**
89 * @brief How many output ports this target has
90 *
91 * One on a USB device. A port existing does not mean anything is
92 * listening to it.
93 */
94 static uint8_t out_port_count();
95};
96
97} // namespace sbl::usb
98
99#endif // SBL_USB_MIDI_HPP_
USB MIDI device port (static class)
Definition midi.hpp:43
static bool connected()
Check if USB MIDI interface is mounted by host.
Definition midi.cpp:24
static uint32_t write(const uint8_t *data, uint32_t len, uint8_t port=0)
Write raw MIDI bytes to USB MIDI (TX)
Definition midi.cpp:43
static uint8_t out_port_count()
How many output ports this target has.
Definition midi.cpp:48
static uint32_t read(uint8_t *buf, uint32_t max_len)
Read decoded MIDI bytes from USB (RX)
Definition midi.cpp:28
static bool send(const sbl::midi::MidiEvent &event, uint8_t port=0)
Send a MidiEvent over USB MIDI (TX)
Definition midi.cpp:33
USB device classes.
Definition cdc.cpp:24
MIDI message types.