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
types.hpp
Go to the documentation of this file.
1// sbl/protocol/midi/types.hpp — MIDI message types
2//
3// Core types for MIDI protocol handling. All values follow the MIDI 1.0 spec.
4
5#ifndef SBL_PROTOCOL_MIDI_TYPES_HPP_
6#define SBL_PROTOCOL_MIDI_TYPES_HPP_
7
8#include <cstdint>
9
10namespace sbl::midi {
11
12enum class MessageType : uint8_t {
13 NoteOff = 0x80,
14 NoteOn = 0x90,
15 PolyPressure = 0xA0,
16 ControlChange = 0xB0,
17 ProgramChange = 0xC0,
18 ChannelPressure = 0xD0,
19 PitchBend = 0xE0,
20
21 // System Real-Time (no channel, no data bytes)
22 Clock = 0xF8,
23 Start = 0xFA,
24 Continue = 0xFB,
25 Stop = 0xFC,
26 ActiveSensing = 0xFE,
27 SystemReset = 0xFF,
28
29 // System Common
30 SysEx = 0xF0,
31 SysExEnd = 0xF7,
32 TimeCode = 0xF1,
33 SongPosition = 0xF2,
34 SongSelect = 0xF3,
35 TuneRequest = 0xF6,
36
37 None = 0x00,
38};
39
40struct MidiEvent {
42 uint8_t channel = 0; ///< 0-15 for channel messages, 0 for system
43 uint8_t data1 = 0; ///< Note number, CC number, program, etc.
44 uint8_t data2 = 0; ///< Velocity, CC value, etc.
45
46 /** @brief Note number (alias for data1) */
47 uint8_t note() const { return data1; }
48
49 /** @brief Velocity (alias for data2) */
50 uint8_t velocity() const { return data2; }
51
52 /** @brief CC number (alias for data1) */
53 uint8_t cc_number() const { return data1; }
54
55 /** @brief CC value (alias for data2) */
56 uint8_t cc_value() const { return data2; }
57
58 /**
59 * @brief 14-bit pitch bend value, centered at 8192
60 *
61 * Range: 0 (max down) to 16383 (max up), 8192 = center.
62 */
63 int16_t pitch_bend_value() const {
64 return static_cast<int16_t>((static_cast<uint16_t>(data2) << 7) | data1) - 8192;
65 }
66
67 /** @brief Raw 14-bit pitch bend (0-16383) */
68 uint16_t pitch_bend_raw() const {
69 return (static_cast<uint16_t>(data2) << 7) | data1;
70 }
71
72 /**
73 * @brief Encode this event as raw MIDI bytes
74 * @param out Buffer for MIDI bytes (must be at least 3 bytes)
75 * @return Number of bytes written (0 if unsupported message type)
76 */
77 uint8_t to_bytes(uint8_t* out) const {
78 switch (type) {
79 // 3-byte channel messages
81 out[0] = 0x90 | (channel & 0x0F);
82 out[1] = data1 & 0x7F;
83 out[2] = data2 & 0x7F;
84 return 3;
86 out[0] = 0x80 | (channel & 0x0F);
87 out[1] = data1 & 0x7F;
88 out[2] = data2 & 0x7F;
89 return 3;
91 out[0] = 0xB0 | (channel & 0x0F);
92 out[1] = data1 & 0x7F;
93 out[2] = data2 & 0x7F;
94 return 3;
96 out[0] = 0xE0 | (channel & 0x0F);
97 out[1] = data1 & 0x7F; // LSB
98 out[2] = data2 & 0x7F; // MSB
99 return 3;
101 out[0] = 0xA0 | (channel & 0x0F);
102 out[1] = data1 & 0x7F;
103 out[2] = data2 & 0x7F;
104 return 3;
105
106 // 2-byte channel messages
108 out[0] = 0xC0 | (channel & 0x0F);
109 out[1] = data1 & 0x7F;
110 return 2;
112 out[0] = 0xD0 | (channel & 0x0F);
113 out[1] = data1 & 0x7F;
114 return 2;
115
116 // System Real-Time (1 byte, no data)
117 case MessageType::Clock: out[0] = 0xF8; return 1;
118 case MessageType::Start: out[0] = 0xFA; return 1;
119 case MessageType::Continue: out[0] = 0xFB; return 1;
120 case MessageType::Stop: out[0] = 0xFC; return 1;
121 case MessageType::ActiveSensing: out[0] = 0xFE; return 1;
122 case MessageType::SystemReset: out[0] = 0xFF; return 1;
123
124 // System Common
126 out[0] = 0xF2;
127 out[1] = data1 & 0x7F;
128 out[2] = data2 & 0x7F;
129 return 3;
131 out[0] = 0xF3;
132 out[1] = data1 & 0x7F;
133 return 2;
135 out[0] = 0xF6;
136 return 1;
137
138 default:
139 return 0; // Unsupported (SysEx, None, etc.)
140 }
141 }
142};
143
144/// Callback type for parsed MIDI events
145using MidiCallback = void(*)(const MidiEvent& event);
146
147/// Number of data bytes expected for a channel message status byte
148inline uint8_t expected_data_bytes(uint8_t status) {
149 switch (status & 0xF0) {
150 case 0xC0: return 1; // Program Change
151 case 0xD0: return 1; // Channel Pressure
152 default: return 2; // Note On/Off, CC, Poly AT, Pitch Bend
153 }
154}
155
156} // namespace sbl::midi
157
158#endif // SBL_PROTOCOL_MIDI_TYPES_HPP_
MIDI parser, encoder, SMF and sequencer.
Definition input.hpp:18
uint8_t expected_data_bytes(uint8_t status)
Number of data bytes expected for a channel message status byte.
Definition types.hpp:148
void(*)(const MidiEvent &event) MidiCallback
Callback type for parsed MIDI events.
Definition types.hpp:145
uint8_t cc_value() const
CC value (alias for data2)
Definition types.hpp:56
int16_t pitch_bend_value() const
14-bit pitch bend value, centered at 8192
Definition types.hpp:63
uint8_t cc_number() const
CC number (alias for data1)
Definition types.hpp:53
uint8_t data2
Velocity, CC value, etc.
Definition types.hpp:44
uint16_t pitch_bend_raw() const
Raw 14-bit pitch bend (0-16383)
Definition types.hpp:68
uint8_t note() const
Note number (alias for data1)
Definition types.hpp:47
uint8_t channel
0-15 for channel messages, 0 for system
Definition types.hpp:42
uint8_t to_bytes(uint8_t *out) const
Encode this event as raw MIDI bytes.
Definition types.hpp:77
uint8_t data1
Note number, CC number, program, etc.
Definition types.hpp:43
MessageType type
Definition types.hpp:41
uint8_t velocity() const
Velocity (alias for data2)
Definition types.hpp:50