Line data Source code
1 0 : /*
2 : * Copyright (c) 2024 Titouan Christophe
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_AUDIO_MIDI_H_
8 : #define ZEPHYR_INCLUDE_AUDIO_MIDI_H_
9 :
10 : #ifdef __cplusplus
11 : extern "C" {
12 : #endif
13 :
14 : #include <stdint.h>
15 :
16 : /**
17 : * @brief Universal MIDI Packet definitions
18 : * @defgroup midi_ump MIDI2 Universal MIDI Packet definitions
19 : * @ingroup audio_interface
20 : * @since 4.1
21 : * @version 0.1.0
22 : * @see ump112: "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol"
23 : * Document version 1.1.2
24 : * @{
25 : */
26 :
27 : /**
28 : * @brief Universal MIDI Packet container
29 : */
30 1 : struct midi_ump {
31 1 : uint32_t data[4]; /**< Raw content, in the CPU native endianness */
32 : };
33 :
34 : /**
35 : * @defgroup midi_ump_mt Message types
36 : * @ingroup midi_ump
37 : * @see ump112: 2.1.4 Message Type (MT) Allocation
38 : * @{
39 : */
40 :
41 : /** Utility Messages */
42 1 : #define UMP_MT_UTILITY 0x00
43 : /** System Real Time and System Common Messages (except System Exclusive) */
44 1 : #define UMP_MT_SYS_RT_COMMON 0x01
45 : /** MIDI 1.0 Channel Voice Messages */
46 1 : #define UMP_MT_MIDI1_CHANNEL_VOICE 0x02
47 : /** 64 bits Data Messages (including System Exclusive) */
48 1 : #define UMP_MT_DATA_64 0x03
49 : /** MIDI 2.0 Channel Voice Messages */
50 1 : #define UMP_MT_MIDI2_CHANNEL_VOICE 0x04
51 : /** 128 bits Data Messages */
52 1 : #define UMP_MT_DATA_128 0x05
53 : /** Flex Data Messages */
54 1 : #define UMP_MT_FLEX_DATA 0x0d
55 : /** UMP Stream Message */
56 1 : #define UMP_MT_UMP_STREAM 0x0f
57 : /** @} */
58 :
59 : /**
60 : * @brief Message Type field of a Universal MIDI Packet
61 : * @param[in] ump Universal MIDI Packet
62 : */
63 1 : #define UMP_MT(ump) \
64 : ((ump).data[0] >> 28)
65 :
66 : /**
67 : * There are 16 UMP message types, each of which can be 1 to 4 uint32 long.
68 : * Hence this packed representation of 16x2b array as an uint32 lookup table
69 : */
70 1 : #define UMP_NUM_WORDS_LOOKUP_TABLE \
71 : ((0U << 0) | (0U << 2) | (0U << 4) | (1U << 6) | \
72 : (1U << 8) | (3U << 10) | (0U << 12) | (0U << 14) | \
73 : (1U << 16) | (1U << 18) | (1U << 20) | (2U << 22) | \
74 : (2U << 24) | (3U << 26) | (3U << 28) | (3U << 30))
75 :
76 : /**
77 : * @brief Size of a Universal MIDI Packet, in 32bit words
78 : * @param[in] ump Universal MIDI Packet
79 : * @see ump112: 2.1.4 Message Type (MT) Allocation
80 : */
81 1 : #define UMP_NUM_WORDS(ump) \
82 : (1 + ((UMP_NUM_WORDS_LOOKUP_TABLE >> (2 * UMP_MT(ump))) & 3))
83 :
84 : /**
85 : * @brief MIDI group field of a Universal MIDI Packet
86 : * @param[in] ump Universal MIDI Packet
87 : */
88 1 : #define UMP_GROUP(ump) \
89 : (((ump).data[0] >> 24) & 0x0f)
90 :
91 : /**
92 : * @brief Status byte of a MIDI channel voice or system message
93 : * @param[in] ump Universal MIDI Packet (containing a MIDI1 event)
94 : */
95 1 : #define UMP_MIDI_STATUS(ump) \
96 : (((ump).data[0] >> 16) & 0xff)
97 : /**
98 : * @brief Command of a MIDI channel voice message
99 : * @param[in] ump Universal MIDI Packet (containing a MIDI event)
100 : * @see midi_ump_cmd
101 : */
102 1 : #define UMP_MIDI_COMMAND(ump) \
103 : (UMP_MIDI_STATUS(ump) >> 4)
104 : /**
105 : * @brief Channel of a MIDI channel voice message
106 : * @param[in] ump Universal MIDI Packet (containing a MIDI event)
107 : */
108 1 : #define UMP_MIDI_CHANNEL(ump) \
109 : (UMP_MIDI_STATUS(ump) & 0x0f)
110 : /**
111 : * @brief First parameter of a MIDI1 channel voice or system message
112 : * @param[in] ump Universal MIDI Packet (containing a MIDI1 message)
113 : */
114 1 : #define UMP_MIDI1_P1(ump) \
115 : (((ump).data[0] >> 8) & 0x7f)
116 : /**
117 : * @brief Second parameter of a MIDI1 channel voice or system message
118 : * @param[in] ump Universal MIDI Packet (containing a MIDI1 message)
119 : */
120 1 : #define UMP_MIDI1_P2(ump) \
121 : ((ump).data[0] & 0x7f)
122 :
123 : /**
124 : * @brief Initialize a UMP with a MIDI1 channel voice message
125 : * @remark For messages that take a single parameter, p2 is ignored by the receiver.
126 : * @param group The UMP group
127 : * @param command The MIDI1 command
128 : * @param channel The MIDI1 channel number
129 : * @param p1 The 1st MIDI1 parameter
130 : * @param p2 The 2nd MIDI1 parameter
131 : */
132 1 : #define UMP_MIDI1_CHANNEL_VOICE(group, command, channel, p1, p2) \
133 : (struct midi_ump) {.data = { \
134 : (UMP_MT_MIDI1_CHANNEL_VOICE << 28) \
135 : | (((group) & 0x0f) << 24) \
136 : | (((command) & 0x0f) << 20) \
137 : | (((channel) & 0x0f) << 16) \
138 : | (((p1) & 0x7f) << 8) \
139 : | ((p2) & 0x7f) \
140 : }}
141 :
142 : /**
143 : * @defgroup midi_ump_cmd MIDI commands
144 : * @ingroup midi_ump
145 : * @see ump112: 7.3 MIDI 1.0 Channel Voice Messages
146 : *
147 : * When UMP_MT(x)=UMP_MT_MIDI1_CHANNEL_VOICE or UMP_MT_MIDI2_CHANNEL_VOICE, then
148 : * UMP_MIDI_COMMAND(x) may be one of:
149 : * @{
150 : */
151 1 : #define UMP_MIDI_NOTE_OFF 0x8 /**< Note Off (p1=note number, p2=velocity) */
152 1 : #define UMP_MIDI_NOTE_ON 0x9 /**< Note On (p1=note number, p2=velocity) */
153 1 : #define UMP_MIDI_AFTERTOUCH 0xa /**< Polyphonic aftertouch (p1=note number, p2=data) */
154 1 : #define UMP_MIDI_CONTROL_CHANGE 0xb /**< Control Change (p1=index, p2=data) */
155 1 : #define UMP_MIDI_PROGRAM_CHANGE 0xc /**< Control Change (p1=program) */
156 1 : #define UMP_MIDI_CHAN_AFTERTOUCH 0xd /**< Channel aftertouch (p1=data) */
157 1 : #define UMP_MIDI_PITCH_BEND 0xe /**< Pitch bend (p1=lsb, p2=msb) */
158 : /** @} */
159 :
160 : /**
161 : * @brief Initialize a UMP with a System Real Time and System Common Message
162 : * @remark For messages that take only one (or no) parameter, p2 (and p1)
163 : * are ignored by the receiver.
164 : * @param group The UMP group
165 : * @param status The status byte
166 : * @param p1 The 1st parameter
167 : * @param p2 The 2nd parameter
168 : */
169 1 : #define UMP_SYS_RT_COMMON(group, status, p1, p2) \
170 : (struct midi_ump) {.data = { \
171 : (UMP_MT_SYS_RT_COMMON << 28) \
172 : | (((group) & 0x0f) << 24) \
173 : | ((status) << 16) \
174 : | (((p1) & 0x7f) << 8) \
175 : | ((p2) & 0x7f) \
176 : }}
177 :
178 : /**
179 : * @defgroup midi_ump_sys System common and System Real Time message status
180 : * @ingroup midi_ump
181 : * @see ump112: 7.6 System Common and System Real Time Messages
182 : *
183 : * When UMP_MT(x)=UMP_MT_SYS_RT_COMMON, UMP_MIDI_STATUS(x) may be one of:
184 : * @{
185 : */
186 1 : #define UMP_SYS_MIDI_TIME_CODE 0xf1 /**< MIDI Time Code (no param) */
187 1 : #define UMP_SYS_SONG_POSITION 0xf2 /**< Song Position Pointer (p1=lsb, p2=msb) */
188 1 : #define UMP_SYS_SONG_SELECT 0xf3 /**< Song Select (p1=song number) */
189 1 : #define UMP_SYS_TUNE_REQUEST 0xf6 /**< Tune Request (no param) */
190 1 : #define UMP_SYS_TIMING_CLOCK 0xf8 /**< Timing Clock (no param) */
191 1 : #define UMP_SYS_START 0xfa /**< Start (no param) */
192 1 : #define UMP_SYS_CONTINUE 0xfb /**< Continue (no param) */
193 1 : #define UMP_SYS_STOP 0xfc /**< Stop (no param) */
194 1 : #define UMP_SYS_ACTIVE_SENSING 0xfe /**< Active sensing (no param) */
195 1 : #define UMP_SYS_RESET 0xff /**< Reset (no param) */
196 : /** @} */
197 :
198 : /** @} */
199 :
200 : #ifdef __cplusplus
201 : }
202 : #endif
203 :
204 : #endif
|