OpenShot Audio Library | OpenShotAudio 0.4.0
Loading...
Searching...
No Matches
juce_UMPFactory.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23#ifndef DOXYGEN
24
25namespace juce::universal_midi_packets
26{
27
34struct Factory
35{
37 struct Detail
38 {
39 static PacketX1 makeSystem() { return PacketX1{}.withMessageType (1); }
40 static PacketX1 makeV1() { return PacketX1{}.withMessageType (2); }
41 static PacketX2 makeV2() { return PacketX2{}.withMessageType (4); }
42
43 static PacketX2 makeSysEx (uint8_t group,
44 uint8_t status,
45 uint8_t numBytes,
46 const std::byte* data)
47 {
48 jassert (numBytes <= 6);
49
50 std::array<uint8_t, 8> bytes{{}};
51 bytes[0] = (0x3 << 0x4) | group;
52 bytes[1] = (uint8_t) (status << 0x4) | numBytes;
53
54 std::memcpy (bytes.data() + 2, data, numBytes);
55
56 std::array<uint32_t, 2> words;
57
58 for (const auto [index, word] : enumerate (words))
59 word = ByteOrder::bigEndianInt (bytes.data() + 4 * index);
60
61 return PacketX2 { words };
62 }
63
64 static PacketX4 makeSysEx8 (uint8_t group,
65 uint8_t status,
66 uint8_t numBytes,
67 uint8_t dataStart,
68 const uint8_t* data)
69 {
70 jassert (numBytes <= 16 - dataStart);
71
72 std::array<uint8_t, 16> bytes{{}};
73 bytes[0] = (0x5 << 0x4) | group;
74 bytes[1] = (uint8_t) (status << 0x4) | numBytes;
75
76 std::memcpy (bytes.data() + dataStart, data, numBytes);
77
78 std::array<uint32_t, 4> words;
79
80 for (const auto [index, word] : enumerate (words))
81 word = ByteOrder::bigEndianInt (bytes.data() + 4 * index);
82
83 return PacketX4 { words };
84 }
85 };
86
87 static PacketX1 makeNoop (uint8_t group)
88 {
89 return PacketX1{}.withGroup (group);
90 }
91
92 static PacketX1 makeJRClock (uint8_t group, uint16_t time)
93 {
94 return PacketX1 { time }.withStatus (1).withGroup (group);
95 }
96
97 static PacketX1 makeJRTimestamp (uint8_t group, uint16_t time)
98 {
99 return PacketX1 { time }.withStatus (2).withGroup (group);
100 }
101
102 static PacketX1 makeTimeCode (uint8_t group, uint8_t code)
103 {
104 return Detail::makeSystem().withGroup (group)
105 .withU8<1> (0xf1)
106 .withU8<2> (code & 0x7f);
107 }
108
109 static PacketX1 makeSongPositionPointer (uint8_t group, uint16_t pos)
110 {
111 return Detail::makeSystem().withGroup (group)
112 .withU8<1> (0xf2)
113 .withU8<2> (pos & 0x7f)
114 .withU8<3> ((pos >> 7) & 0x7f);
115 }
116
117 static PacketX1 makeSongSelect (uint8_t group, uint8_t song)
118 {
119 return Detail::makeSystem().withGroup (group)
120 .withU8<1> (0xf3)
121 .withU8<2> (song & 0x7f);
122 }
123
124 static PacketX1 makeTuneRequest (uint8_t group)
125 {
126 return Detail::makeSystem().withGroup (group)
127 .withU8<1> (0xf6);
128 }
129
130 static PacketX1 makeTimingClock (uint8_t group)
131 {
132 return Detail::makeSystem().withGroup (group)
133 .withU8<1> (0xf8);
134 }
135
136 static PacketX1 makeStart (uint8_t group)
137 {
138 return Detail::makeSystem().withGroup (group)
139 .withU8<1> (0xfa);
140 }
141
142 static PacketX1 makeContinue (uint8_t group)
143 {
144 return Detail::makeSystem().withGroup (group)
145 .withU8<1> (0xfb);
146 }
147
148 static PacketX1 makeStop (uint8_t group)
149 {
150 return Detail::makeSystem().withGroup (group)
151 .withU8<1> (0xfc);
152 }
153
154 static PacketX1 makeActiveSensing (uint8_t group)
155 {
156 return Detail::makeSystem().withGroup (group)
157 .withU8<1> (0xfe);
158 }
159
160 static PacketX1 makeReset (uint8_t group)
161 {
162 return Detail::makeSystem().withGroup (group)
163 .withU8<1> (0xff);
164 }
165
166 static PacketX1 makeNoteOffV1 (uint8_t group,
167 uint8_t channel,
168 uint8_t note,
169 uint8_t velocity)
170 {
171 return Detail::makeV1().withGroup (group)
172 .withStatus (0x8)
173 .withChannel (channel)
174 .withU8<2> (note & 0x7f)
175 .withU8<3> (velocity & 0x7f);
176 }
177
178 static PacketX1 makeNoteOnV1 (uint8_t group,
179 uint8_t channel,
180 uint8_t note,
181 uint8_t velocity)
182 {
183 return Detail::makeV1().withGroup (group)
184 .withStatus (0x9)
185 .withChannel (channel)
186 .withU8<2> (note & 0x7f)
187 .withU8<3> (velocity & 0x7f);
188 }
189
190 static PacketX1 makePolyPressureV1 (uint8_t group,
191 uint8_t channel,
192 uint8_t note,
193 uint8_t pressure)
194 {
195 return Detail::makeV1().withGroup (group)
196 .withStatus (0xa)
197 .withChannel (channel)
198 .withU8<2> (note & 0x7f)
199 .withU8<3> (pressure & 0x7f);
200 }
201
202 static PacketX1 makeControlChangeV1 (uint8_t group,
203 uint8_t channel,
204 uint8_t controller,
205 uint8_t value)
206 {
207 return Detail::makeV1().withGroup (group)
208 .withStatus (0xb)
209 .withChannel (channel)
210 .withU8<2> (controller & 0x7f)
211 .withU8<3> (value & 0x7f);
212 }
213
214 static PacketX1 makeProgramChangeV1 (uint8_t group,
215 uint8_t channel,
216 uint8_t program)
217 {
218 return Detail::makeV1().withGroup (group)
219 .withStatus (0xc)
220 .withChannel (channel)
221 .withU8<2> (program & 0x7f);
222 }
223
224 static PacketX1 makeChannelPressureV1 (uint8_t group,
225 uint8_t channel,
226 uint8_t pressure)
227 {
228 return Detail::makeV1().withGroup (group)
229 .withStatus (0xd)
230 .withChannel (channel)
231 .withU8<2> (pressure & 0x7f);
232 }
233
234 static PacketX1 makePitchBend (uint8_t group,
235 uint8_t channel,
236 uint16_t pitchbend)
237 {
238 return Detail::makeV1().withGroup (group)
239 .withStatus (0xe)
240 .withChannel (channel)
241 .withU8<2> (pitchbend & 0x7f)
242 .withU8<3> ((pitchbend >> 7) & 0x7f);
243 }
244
245 static PacketX2 makeSysExIn1Packet (uint8_t group,
246 uint8_t numBytes,
247 const std::byte* data)
248 {
249 return Detail::makeSysEx (group, 0x0, numBytes, data);
250 }
251
252 static PacketX2 makeSysExStart (uint8_t group,
253 uint8_t numBytes,
254 const std::byte* data)
255 {
256 return Detail::makeSysEx (group, 0x1, numBytes, data);
257 }
258
259 static PacketX2 makeSysExContinue (uint8_t group,
260 uint8_t numBytes,
261 const std::byte* data)
262 {
263 return Detail::makeSysEx (group, 0x2, numBytes, data);
264 }
265
266 static PacketX2 makeSysExEnd (uint8_t group,
267 uint8_t numBytes,
268 const std::byte* data)
269 {
270 return Detail::makeSysEx (group, 0x3, numBytes, data);
271 }
272
273 static PacketX2 makeRegisteredPerNoteControllerV2 (uint8_t group,
274 uint8_t channel,
275 uint8_t note,
276 uint8_t controller,
277 uint32_t data)
278 {
279 return Detail::makeV2().withGroup (group)
280 .withStatus (0x0)
281 .withChannel (channel)
282 .withU8<2> (note & 0x7f)
283 .withU8<3> (controller & 0x7f)
284 .withU32<1> (data);
285 }
286
287 static PacketX2 makeAssignablePerNoteControllerV2 (uint8_t group,
288 uint8_t channel,
289 uint8_t note,
290 uint8_t controller,
291 uint32_t data)
292 {
293 return Detail::makeV2().withGroup (group)
294 .withStatus (0x1)
295 .withChannel (channel)
296 .withU8<2> (note & 0x7f)
297 .withU8<3> (controller & 0x7f)
298 .withU32<1> (data);
299 }
300
301 static PacketX2 makeRegisteredControllerV2 (uint8_t group,
302 uint8_t channel,
303 uint8_t bank,
304 uint8_t index,
305 uint32_t data)
306 {
307 return Detail::makeV2().withGroup (group)
308 .withStatus (0x2)
309 .withChannel (channel)
310 .withU8<2> (bank & 0x7f)
311 .withU8<3> (index & 0x7f)
312 .withU32<1> (data);
313 }
314
315 static PacketX2 makeAssignableControllerV2 (uint8_t group,
316 uint8_t channel,
317 uint8_t bank,
318 uint8_t index,
319 uint32_t data)
320 {
321 return Detail::makeV2().withGroup (group)
322 .withStatus (0x3)
323 .withChannel (channel)
324 .withU8<2> (bank & 0x7f)
325 .withU8<3> (index & 0x7f)
326 .withU32<1> (data);
327 }
328
329 static PacketX2 makeRelativeRegisteredControllerV2 (uint8_t group,
330 uint8_t channel,
331 uint8_t bank,
332 uint8_t index,
333 uint32_t data)
334 {
335 return Detail::makeV2().withGroup (group)
336 .withStatus (0x4)
337 .withChannel (channel)
338 .withU8<2> (bank & 0x7f)
339 .withU8<3> (index & 0x7f)
340 .withU32<1> (data);
341 }
342
343 static PacketX2 makeRelativeAssignableControllerV2 (uint8_t group,
344 uint8_t channel,
345 uint8_t bank,
346 uint8_t index,
347 uint32_t data)
348 {
349 return Detail::makeV2().withGroup (group)
350 .withStatus (0x5)
351 .withChannel (channel)
352 .withU8<2> (bank & 0x7f)
353 .withU8<3> (index & 0x7f)
354 .withU32<1> (data);
355 }
356
357 static PacketX2 makePerNotePitchBendV2 (uint8_t group,
358 uint8_t channel,
359 uint8_t note,
360 uint32_t data)
361 {
362 return Detail::makeV2().withGroup (group)
363 .withStatus (0x6)
364 .withChannel (channel)
365 .withU8<2> (note & 0x7f)
366 .withU32<1> (data);
367 }
368
369 enum class NoteAttributeKind : uint8_t
370 {
371 none = 0x00,
372 manufacturer = 0x01,
373 profile = 0x02,
374 pitch7_9 = 0x03
375 };
376
377 static PacketX2 makeNoteOffV2 (uint8_t group,
378 uint8_t channel,
379 uint8_t note,
380 NoteAttributeKind attribute,
381 uint16_t velocity,
382 uint16_t attributeValue)
383 {
384 return Detail::makeV2().withGroup (group)
385 .withStatus (0x8)
386 .withChannel (channel)
387 .withU8<2> (note & 0x7f)
388 .withU8<3> ((uint8_t) attribute)
389 .withU16<2> (velocity)
390 .withU16<3> (attributeValue);
391 }
392
393 static PacketX2 makeNoteOnV2 (uint8_t group,
394 uint8_t channel,
395 uint8_t note,
396 NoteAttributeKind attribute,
397 uint16_t velocity,
398 uint16_t attributeValue)
399 {
400 return Detail::makeV2().withGroup (group)
401 .withStatus (0x9)
402 .withChannel (channel)
403 .withU8<2> (note & 0x7f)
404 .withU8<3> ((uint8_t) attribute)
405 .withU16<2> (velocity)
406 .withU16<3> (attributeValue);
407 }
408
409 static PacketX2 makePolyPressureV2 (uint8_t group,
410 uint8_t channel,
411 uint8_t note,
412 uint32_t data)
413 {
414 return Detail::makeV2().withGroup (group)
415 .withStatus (0xa)
416 .withChannel (channel)
417 .withU8<2> (note & 0x7f)
418 .withU32<1> (data);
419 }
420
421 static PacketX2 makeControlChangeV2 (uint8_t group,
422 uint8_t channel,
423 uint8_t controller,
424 uint32_t data)
425 {
426 return Detail::makeV2().withGroup (group)
427 .withStatus (0xb)
428 .withChannel (channel)
429 .withU8<2> (controller & 0x7f)
430 .withU32<1> (data);
431 }
432
433 static PacketX2 makeProgramChangeV2 (uint8_t group,
434 uint8_t channel,
435 uint8_t optionFlags,
436 uint8_t program,
437 uint8_t bankMsb,
438 uint8_t bankLsb)
439 {
440 return Detail::makeV2().withGroup (group)
441 .withStatus (0xc)
442 .withChannel (channel)
443 .withU8<3> (optionFlags)
444 .withU8<4> (program)
445 .withU8<6> (bankMsb)
446 .withU8<7> (bankLsb);
447 }
448
449 static PacketX2 makeChannelPressureV2 (uint8_t group,
450 uint8_t channel,
451 uint32_t data)
452 {
453 return Detail::makeV2().withGroup (group)
454 .withStatus (0xd)
455 .withChannel (channel)
456 .withU32<1> (data);
457 }
458
459 static PacketX2 makePitchBendV2 (uint8_t group,
460 uint8_t channel,
461 uint32_t data)
462 {
463 return Detail::makeV2().withGroup (group)
464 .withStatus (0xe)
465 .withChannel (channel)
466 .withU32<1> (data);
467 }
468
469 static PacketX2 makePerNoteManagementV2 (uint8_t group,
470 uint8_t channel,
471 uint8_t note,
472 uint8_t optionFlags)
473 {
474 return Detail::makeV2().withGroup (group)
475 .withStatus (0xf)
476 .withChannel (channel)
477 .withU8<2> (note)
478 .withU8<3> (optionFlags);
479 }
480
481
482 static PacketX4 makeSysEx8in1Packet (uint8_t group,
483 uint8_t numBytes,
484 uint8_t streamId,
485 const uint8_t* data)
486 {
487 return Detail::makeSysEx8 (group, 0x0, numBytes, 3, data).withU8<2> (streamId);
488 }
489
490 static PacketX4 makeSysEx8Start (uint8_t group,
491 uint8_t numBytes,
492 uint8_t streamId,
493 const uint8_t* data)
494 {
495 return Detail::makeSysEx8 (group, 0x1, numBytes, 3, data).withU8<2> (streamId);
496 }
497
498 static PacketX4 makeSysEx8Continue (uint8_t group,
499 uint8_t numBytes,
500 uint8_t streamId,
501 const uint8_t* data)
502 {
503 return Detail::makeSysEx8 (group, 0x2, numBytes, 3, data).withU8<2> (streamId);
504 }
505
506 static PacketX4 makeSysEx8End (uint8_t group,
507 uint8_t numBytes,
508 uint8_t streamId,
509 const uint8_t* data)
510 {
511 return Detail::makeSysEx8 (group, 0x3, numBytes, 3, data).withU8<2> (streamId);
512 }
513
514 static PacketX4 makeMixedDataSetHeader (uint8_t group,
515 uint8_t dataSetId,
516 const uint8_t* data)
517 {
518 return Detail::makeSysEx8 (group, 0x8, 14, 2, data).withChannel (dataSetId);
519 }
520
521 static PacketX4 makeDataSetPayload (uint8_t group,
522 uint8_t dataSetId,
523 const uint8_t* data)
524 {
525 return Detail::makeSysEx8 (group, 0x9, 14, 2, data).withChannel (dataSetId);
526 }
527};
528
529} // namespace juce::universal_midi_packets
530
531#endif
static constexpr uint32 bigEndianInt(const void *bytes) noexcept