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