OpenShot Library | libopenshot-audio 0.2.0
juce_MidiMessage.h
1
2/** @weakgroup juce_audio_basics-midi
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 Encapsulates a MIDI message.
33
34 @see MidiMessageSequence, MidiOutput, MidiInput
35
36 @tags{Audio}
37*/
39{
40public:
41 //==============================================================================
42 /** Creates a 3-byte short midi message.
43
44 @param byte1 message byte 1
45 @param byte2 message byte 2
46 @param byte3 message byte 3
47 @param timeStamp the time to give the midi message - this value doesn't
48 use any particular units, so will be application-specific
49 */
50 MidiMessage (int byte1, int byte2, int byte3, double timeStamp = 0) noexcept;
51
52 /** Creates a 2-byte short midi message.
53
54 @param byte1 message byte 1
55 @param byte2 message byte 2
56 @param timeStamp the time to give the midi message - this value doesn't
57 use any particular units, so will be application-specific
58 */
59 MidiMessage (int byte1, int byte2, double timeStamp = 0) noexcept;
60
61 /** Creates a 1-byte short midi message.
62
63 @param byte1 message byte 1
64 @param timeStamp the time to give the midi message - this value doesn't
65 use any particular units, so will be application-specific
66 */
67 MidiMessage (int byte1, double timeStamp = 0) noexcept;
68
69 /** Creates a midi message from a list of bytes. */
70 template <typename... Data>
71 MidiMessage (int byte1, int byte2, int byte3, Data... otherBytes) : size (3 + sizeof... (otherBytes))
72 {
73 // this checks that the length matches the data..
74 jassert (size > 3 || byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == size);
75
76 const uint8 data[] = { (uint8) byte1, (uint8) byte2, (uint8) byte3, static_cast<uint8> (otherBytes)... };
77 memcpy (allocateSpace (size), data, (size_t) size);
78 }
79
80
81 /** Creates a midi message from a block of data. */
82 MidiMessage (const void* data, int numBytes, double timeStamp = 0);
83
84 /** Reads the next midi message from some data.
85
86 This will read as many bytes from a data stream as it needs to make a
87 complete message, and will return the number of bytes it used. This lets
88 you read a sequence of midi messages from a file or stream.
89
90 @param data the data to read from
91 @param maxBytesToUse the maximum number of bytes it's allowed to read
92 @param numBytesUsed returns the number of bytes that were actually needed
93 @param lastStatusByte in a sequence of midi messages, the initial byte
94 can be dropped from a message if it's the same as the
95 first byte of the previous message, so this lets you
96 supply the byte to use if the first byte of the message
97 has in fact been dropped.
98 @param timeStamp the time to give the midi message - this value doesn't
99 use any particular units, so will be application-specific
100 @param sysexHasEmbeddedLength when reading sysexes, this flag indicates whether
101 to expect the data to begin with a variable-length
102 field indicating its size
103 */
104 MidiMessage (const void* data, int maxBytesToUse,
105 int& numBytesUsed, uint8 lastStatusByte,
106 double timeStamp = 0,
107 bool sysexHasEmbeddedLength = true);
108
109 /** Creates an active-sense message.
110 Since the MidiMessage has to contain a valid message, this default constructor
111 just initialises it with an empty sysex message.
112 */
114
115 /** Creates a copy of another midi message. */
117
118 /** Creates a copy of another midi message, with a different timestamp. */
120
121 /** Destructor. */
123
124 /** Copies this message from another one. */
126
127 /** Move constructor */
129
130 /** Move assignment operator */
132
133 //==============================================================================
134 /** Returns a pointer to the raw midi data.
135 @see getRawDataSize
136 */
137 const uint8* getRawData() const noexcept { return getData(); }
138
139 /** Returns the number of bytes of data in the message.
140 @see getRawData
141 */
142 int getRawDataSize() const noexcept { return size; }
143
144 //==============================================================================
145 /** Returns a human-readable description of the midi message as a string,
146 for example "Note On C#3 Velocity 120 Channel 1".
147 */
148 String getDescription() const;
149
150 //==============================================================================
151 /** Returns the timestamp associated with this message.
152
153 The exact meaning of this time and its units will vary, as messages are used in
154 a variety of different contexts.
155
156 If you're getting the message from a midi file, this could be a time in seconds, or
157 a number of ticks - see MidiFile::convertTimestampTicksToSeconds().
158
159 If the message is being used in a MidiBuffer, it might indicate the number of
160 audio samples from the start of the buffer.
161
162 If the message was created by a MidiInput, see MidiInputCallback::handleIncomingMidiMessage()
163 for details of the way that it initialises this value.
164
165 @see setTimeStamp, addToTimeStamp
166 */
168
169 /** Changes the message's associated timestamp.
170 The units for the timestamp will be application-specific - see the notes for getTimeStamp().
171 @see addToTimeStamp, getTimeStamp
172 */
173 void setTimeStamp (double newTimestamp) noexcept { timeStamp = newTimestamp; }
174
175 /** Adds a value to the message's timestamp.
176 The units for the timestamp will be application-specific.
177 */
178 void addToTimeStamp (double delta) noexcept { timeStamp += delta; }
179
180 /** Return a copy of this message with a new timestamp.
181 The units for the timestamp will be application-specific - see the notes for getTimeStamp().
182 */
183 MidiMessage withTimeStamp (double newTimestamp) const;
184
185 //==============================================================================
186 /** Returns the midi channel associated with the message.
187
188 @returns a value 1 to 16 if the message has a channel, or 0 if it hasn't (e.g.
189 if it's a sysex)
190 @see isForChannel, setChannel
191 */
192 int getChannel() const noexcept;
193
194 /** Returns true if the message applies to the given midi channel.
195
196 @param channelNumber the channel number to look for, in the range 1 to 16
197 @see getChannel, setChannel
198 */
199 bool isForChannel (int channelNumber) const noexcept;
200
201 /** Changes the message's midi channel.
202 This won't do anything for non-channel messages like sysexes.
203 @param newChannelNumber the channel number to change it to, in the range 1 to 16
204 */
205 void setChannel (int newChannelNumber) noexcept;
206
207 //==============================================================================
208 /** Returns true if this is a system-exclusive message.
209 */
210 bool isSysEx() const noexcept;
211
212 /** Returns a pointer to the sysex data inside the message.
213 If this event isn't a sysex event, it'll return 0.
214 @see getSysExDataSize
215 */
216 const uint8* getSysExData() const noexcept;
217
218 /** Returns the size of the sysex data.
219 This value excludes the 0xf0 header byte and the 0xf7 at the end.
220 @see getSysExData
221 */
222 int getSysExDataSize() const noexcept;
223
224 //==============================================================================
225 /** Returns true if this message is a 'key-down' event.
226
227 @param returnTrueForVelocity0 if true, then if this event is a note-on with
228 velocity 0, it will still be considered to be a note-on and the
229 method will return true. If returnTrueForVelocity0 is false, then
230 if this is a note-on event with velocity 0, it'll be regarded as
231 a note-off, and the method will return false
232
233 @see isNoteOff, getNoteNumber, getVelocity, noteOn
234 */
235 bool isNoteOn (bool returnTrueForVelocity0 = false) const noexcept;
236
237 /** Creates a key-down message (using a floating-point velocity).
238
239 @param channel the midi channel, in the range 1 to 16
240 @param noteNumber the key number, 0 to 127
241 @param velocity in the range 0 to 1.0
242 @see isNoteOn
243 */
244 static MidiMessage noteOn (int channel, int noteNumber, float velocity) noexcept;
245
246 /** Creates a key-down message (using an integer velocity).
247
248 @param channel the midi channel, in the range 1 to 16
249 @param noteNumber the key number, 0 to 127
250 @param velocity in the range 0 to 127
251 @see isNoteOn
252 */
253 static MidiMessage noteOn (int channel, int noteNumber, uint8 velocity) noexcept;
254
255 /** Returns true if this message is a 'key-up' event.
256
257 If returnTrueForNoteOnVelocity0 is true, then his will also return true
258 for a note-on event with a velocity of 0.
259
260 @see isNoteOn, getNoteNumber, getVelocity, noteOff
261 */
262 bool isNoteOff (bool returnTrueForNoteOnVelocity0 = true) const noexcept;
263
264 /** Creates a key-up message.
265
266 @param channel the midi channel, in the range 1 to 16
267 @param noteNumber the key number, 0 to 127
268 @param velocity in the range 0 to 1.0
269 @see isNoteOff
270 */
271 static MidiMessage noteOff (int channel, int noteNumber, float velocity) noexcept;
272
273 /** Creates a key-up message.
274
275 @param channel the midi channel, in the range 1 to 16
276 @param noteNumber the key number, 0 to 127
277 @param velocity in the range 0 to 127
278 @see isNoteOff
279 */
280 static MidiMessage noteOff (int channel, int noteNumber, uint8 velocity) noexcept;
281
282 /** Creates a key-up message.
283
284 @param channel the midi channel, in the range 1 to 16
285 @param noteNumber the key number, 0 to 127
286 @see isNoteOff
287 */
288 static MidiMessage noteOff (int channel, int noteNumber) noexcept;
289
290 /** Returns true if this message is a 'key-down' or 'key-up' event.
291
292 @see isNoteOn, isNoteOff
293 */
294 bool isNoteOnOrOff() const noexcept;
295
296 /** Returns the midi note number for note-on and note-off messages.
297 If the message isn't a note-on or off, the value returned is undefined.
298 @see isNoteOff, getMidiNoteName, getMidiNoteInHertz, setNoteNumber
299 */
300 int getNoteNumber() const noexcept;
301
302 /** Changes the midi note number of a note-on or note-off message.
303 If the message isn't a note on or off, this will do nothing.
304 */
305 void setNoteNumber (int newNoteNumber) noexcept;
306
307 //==============================================================================
308 /** Returns the velocity of a note-on or note-off message.
309
310 The value returned will be in the range 0 to 127.
311 If the message isn't a note-on or off event, it will return 0.
312
313 @see getFloatVelocity
314 */
315 uint8 getVelocity() const noexcept;
316
317 /** Returns the velocity of a note-on or note-off message.
318
319 The value returned will be in the range 0 to 1.0
320 If the message isn't a note-on or off event, it will return 0.
321
322 @see getVelocity, setVelocity
323 */
324 float getFloatVelocity() const noexcept;
325
326 /** Changes the velocity of a note-on or note-off message.
327
328 If the message isn't a note on or off, this will do nothing.
329
330 @param newVelocity the new velocity, in the range 0 to 1.0
331 @see getFloatVelocity, multiplyVelocity
332 */
333 void setVelocity (float newVelocity) noexcept;
334
335 /** Multiplies the velocity of a note-on or note-off message by a given amount.
336
337 If the message isn't a note on or off, this will do nothing.
338
339 @param scaleFactor the value by which to multiply the velocity
340 @see setVelocity
341 */
342 void multiplyVelocity (float scaleFactor) noexcept;
343
344 //==============================================================================
345 /** Returns true if this message is a 'sustain pedal down' controller message. */
346 bool isSustainPedalOn() const noexcept;
347 /** Returns true if this message is a 'sustain pedal up' controller message. */
348 bool isSustainPedalOff() const noexcept;
349
350 /** Returns true if this message is a 'sostenuto pedal down' controller message. */
351 bool isSostenutoPedalOn() const noexcept;
352 /** Returns true if this message is a 'sostenuto pedal up' controller message. */
353 bool isSostenutoPedalOff() const noexcept;
354
355 /** Returns true if this message is a 'soft pedal down' controller message. */
356 bool isSoftPedalOn() const noexcept;
357 /** Returns true if this message is a 'soft pedal up' controller message. */
358 bool isSoftPedalOff() const noexcept;
359
360 //==============================================================================
361 /** Returns true if the message is a program (patch) change message.
362 @see getProgramChangeNumber, getGMInstrumentName
363 */
364 bool isProgramChange() const noexcept;
365
366 /** Returns the new program number of a program change message.
367 If the message isn't a program change, the value returned is undefined.
368 @see isProgramChange, getGMInstrumentName
369 */
370 int getProgramChangeNumber() const noexcept;
371
372 /** Creates a program-change message.
373
374 @param channel the midi channel, in the range 1 to 16
375 @param programNumber the midi program number, 0 to 127
376 @see isProgramChange, getGMInstrumentName
377 */
378 static MidiMessage programChange (int channel, int programNumber) noexcept;
379
380 //==============================================================================
381 /** Returns true if the message is a pitch-wheel move.
382 @see getPitchWheelValue, pitchWheel
383 */
384 bool isPitchWheel() const noexcept;
385
386 /** Returns the pitch wheel position from a pitch-wheel move message.
387
388 The value returned is a 14-bit number from 0 to 0x3fff, indicating the wheel position.
389 If called for messages which aren't pitch wheel events, the number returned will be
390 nonsense.
391
392 @see isPitchWheel
393 */
394 int getPitchWheelValue() const noexcept;
395
396 /** Creates a pitch-wheel move message.
397
398 @param channel the midi channel, in the range 1 to 16
399 @param position the wheel position, in the range 0 to 16383
400 @see isPitchWheel
401 */
402 static MidiMessage pitchWheel (int channel, int position) noexcept;
403
404 //==============================================================================
405 /** Returns true if the message is an aftertouch event.
406
407 For aftertouch events, use the getNoteNumber() method to find out the key
408 that it applies to, and getAftertouchValue() to find out the amount. Use
409 getChannel() to find out the channel.
410
411 @see getAftertouchValue, getNoteNumber
412 */
413 bool isAftertouch() const noexcept;
414
415 /** Returns the amount of aftertouch from an aftertouch messages.
416
417 The value returned is in the range 0 to 127, and will be nonsense for messages
418 other than aftertouch messages.
419
420 @see isAftertouch
421 */
422 int getAfterTouchValue() const noexcept;
423
424 /** Creates an aftertouch message.
425
426 @param channel the midi channel, in the range 1 to 16
427 @param noteNumber the key number, 0 to 127
428 @param aftertouchAmount the amount of aftertouch, 0 to 127
429 @see isAftertouch
430 */
431 static MidiMessage aftertouchChange (int channel,
432 int noteNumber,
434
435 /** Returns true if the message is a channel-pressure change event.
436
437 This is like aftertouch, but common to the whole channel rather than a specific
438 note. Use getChannelPressureValue() to find out the pressure, and getChannel()
439 to find out the channel.
440
441 @see channelPressureChange
442 */
443 bool isChannelPressure() const noexcept;
444
445 /** Returns the pressure from a channel pressure change message.
446
447 @returns the pressure, in the range 0 to 127
448 @see isChannelPressure, channelPressureChange
449 */
450 int getChannelPressureValue() const noexcept;
451
452 /** Creates a channel-pressure change event.
453
454 @param channel the midi channel: 1 to 16
455 @param pressure the pressure, 0 to 127
456 @see isChannelPressure
457 */
458 static MidiMessage channelPressureChange (int channel, int pressure) noexcept;
459
460 //==============================================================================
461 /** Returns true if this is a midi controller message.
462
463 @see getControllerNumber, getControllerValue, controllerEvent
464 */
465 bool isController() const noexcept;
466
467 /** Returns the controller number of a controller message.
468
469 The name of the controller can be looked up using the getControllerName() method.
470 Note that the value returned is invalid for messages that aren't controller changes.
471
472 @see isController, getControllerName, getControllerValue
473 */
474 int getControllerNumber() const noexcept;
475
476 /** Returns the controller value from a controller message.
477
478 A value 0 to 127 is returned to indicate the new controller position.
479 Note that the value returned is invalid for messages that aren't controller changes.
480
481 @see isController, getControllerNumber
482 */
483 int getControllerValue() const noexcept;
484
485 /** Returns true if this message is a controller message and if it has the specified
486 controller type.
487 */
488 bool isControllerOfType (int controllerType) const noexcept;
489
490 /** Creates a controller message.
491 @param channel the midi channel, in the range 1 to 16
492 @param controllerType the type of controller
493 @param value the controller value
494 @see isController
495 */
496 static MidiMessage controllerEvent (int channel,
497 int controllerType,
498 int value) noexcept;
499
500 /** Checks whether this message is an all-notes-off message.
501 @see allNotesOff
502 */
503 bool isAllNotesOff() const noexcept;
504
505 /** Checks whether this message is an all-sound-off message.
506 @see allSoundOff
507 */
508 bool isAllSoundOff() const noexcept;
509
510 /** Checks whether this message is a reset all controllers message.
511 @see allControllerOff
512 */
513 bool isResetAllControllers() const noexcept;
514
515 /** Creates an all-notes-off message.
516 @param channel the midi channel, in the range 1 to 16
517 @see isAllNotesOff
518 */
519 static MidiMessage allNotesOff (int channel) noexcept;
520
521 /** Creates an all-sound-off message.
522 @param channel the midi channel, in the range 1 to 16
523 @see isAllSoundOff
524 */
525 static MidiMessage allSoundOff (int channel) noexcept;
526
527 /** Creates an all-controllers-off message.
528 @param channel the midi channel, in the range 1 to 16
529 */
530 static MidiMessage allControllersOff (int channel) noexcept;
531
532 //==============================================================================
533 /** Returns true if this event is a meta-event.
534
535 Meta-events are things like tempo changes, track names, etc.
536
537 @see getMetaEventType, isTrackMetaEvent, isEndOfTrackMetaEvent,
538 isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent,
539 isKeySignatureMetaEvent, isMidiChannelMetaEvent
540 */
541 bool isMetaEvent() const noexcept;
542
543 /** Returns a meta-event's type number.
544
545 If the message isn't a meta-event, this will return -1.
546
547 @see isMetaEvent, isTrackMetaEvent, isEndOfTrackMetaEvent,
548 isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent,
549 isKeySignatureMetaEvent, isMidiChannelMetaEvent
550 */
551 int getMetaEventType() const noexcept;
552
553 /** Returns a pointer to the data in a meta-event.
554 @see isMetaEvent, getMetaEventLength
555 */
556 const uint8* getMetaEventData() const noexcept;
557
558 /** Returns the length of the data for a meta-event.
559 @see isMetaEvent, getMetaEventData
560 */
561 int getMetaEventLength() const noexcept;
562
563 //==============================================================================
564 /** Returns true if this is a 'track' meta-event. */
565 bool isTrackMetaEvent() const noexcept;
566
567 /** Returns true if this is an 'end-of-track' meta-event. */
568 bool isEndOfTrackMetaEvent() const noexcept;
569
570 /** Creates an end-of-track meta-event.
571 @see isEndOfTrackMetaEvent
572 */
573 static MidiMessage endOfTrack() noexcept;
574
575 /** Returns true if this is an 'track name' meta-event.
576 You can use the getTextFromTextMetaEvent() method to get the track's name.
577 */
578 bool isTrackNameEvent() const noexcept;
579
580 /** Returns true if this is a 'text' meta-event.
581 @see getTextFromTextMetaEvent
582 */
583 bool isTextMetaEvent() const noexcept;
584
585 /** Returns the text from a text meta-event.
586 @see isTextMetaEvent
587 */
588 String getTextFromTextMetaEvent() const;
589
590 /** Creates a text meta-event. */
591 static MidiMessage textMetaEvent (int type, StringRef text);
592
593 //==============================================================================
594 /** Returns true if this is a 'tempo' meta-event.
595 @see getTempoMetaEventTickLength, getTempoSecondsPerQuarterNote
596 */
597 bool isTempoMetaEvent() const noexcept;
598
599 /** Returns the tick length from a tempo meta-event.
600
601 @param timeFormat the 16-bit time format value from the midi file's header.
602 @returns the tick length (in seconds).
603 @see isTempoMetaEvent
604 */
605 double getTempoMetaEventTickLength (short timeFormat) const noexcept;
606
607 /** Calculates the seconds-per-quarter-note from a tempo meta-event.
608 @see isTempoMetaEvent, getTempoMetaEventTickLength
609 */
610 double getTempoSecondsPerQuarterNote() const noexcept;
611
612 /** Creates a tempo meta-event.
613 @see isTempoMetaEvent
614 */
616
617 //==============================================================================
618 /** Returns true if this is a 'time-signature' meta-event.
619 @see getTimeSignatureInfo
620 */
621 bool isTimeSignatureMetaEvent() const noexcept;
622
623 /** Returns the time-signature values from a time-signature meta-event.
624 @see isTimeSignatureMetaEvent
625 */
626 void getTimeSignatureInfo (int& numerator, int& denominator) const noexcept;
627
628 /** Creates a time-signature meta-event.
629 @see isTimeSignatureMetaEvent
630 */
631 static MidiMessage timeSignatureMetaEvent (int numerator, int denominator);
632
633 //==============================================================================
634 /** Returns true if this is a 'key-signature' meta-event.
635 @see getKeySignatureNumberOfSharpsOrFlats, isKeySignatureMajorKey
636 */
637 bool isKeySignatureMetaEvent() const noexcept;
638
639 /** Returns the key from a key-signature meta-event.
640 This method must only be called if isKeySignatureMetaEvent() is true.
641 A positive number here indicates the number of sharps in the key signature,
642 and a negative number indicates a number of flats. So e.g. 3 = F# + C# + G#,
643 -2 = Bb + Eb
644 @see isKeySignatureMetaEvent, isKeySignatureMajorKey
645 */
646 int getKeySignatureNumberOfSharpsOrFlats() const noexcept;
647
648 /** Returns true if this key-signature event is major, or false if it's minor.
649 This method must only be called if isKeySignatureMetaEvent() is true.
650 */
651 bool isKeySignatureMajorKey() const noexcept;
652
653 /** Creates a key-signature meta-event.
654 @param numberOfSharpsOrFlats if positive, this indicates the number of sharps
655 in the key; if negative, the number of flats
656 @param isMinorKey if true, the key is minor; if false, it is major
657 @see isKeySignatureMetaEvent
658 */
659 static MidiMessage keySignatureMetaEvent (int numberOfSharpsOrFlats, bool isMinorKey);
660
661 //==============================================================================
662 /** Returns true if this is a 'channel' meta-event.
663
664 A channel meta-event specifies the midi channel that should be used
665 for subsequent meta-events.
666
667 @see getMidiChannelMetaEventChannel
668 */
669 bool isMidiChannelMetaEvent() const noexcept;
670
671 /** Returns the channel number from a channel meta-event.
672
673 @returns the channel, in the range 1 to 16.
674 @see isMidiChannelMetaEvent
675 */
676 int getMidiChannelMetaEventChannel() const noexcept;
677
678 /** Creates a midi channel meta-event.
679
680 @param channel the midi channel, in the range 1 to 16
681 @see isMidiChannelMetaEvent
682 */
683 static MidiMessage midiChannelMetaEvent (int channel) noexcept;
684
685 //==============================================================================
686 /** Returns true if this is an active-sense message. */
687 bool isActiveSense() const noexcept;
688
689 //==============================================================================
690 /** Returns true if this is a midi start event.
691 @see midiStart
692 */
693 bool isMidiStart() const noexcept;
694
695 /** Creates a midi start event. */
696 static MidiMessage midiStart() noexcept;
697
698 /** Returns true if this is a midi continue event.
699 @see midiContinue
700 */
701 bool isMidiContinue() const noexcept;
702
703 /** Creates a midi continue event. */
704 static MidiMessage midiContinue() noexcept;
705
706 /** Returns true if this is a midi stop event.
707 @see midiStop
708 */
709 bool isMidiStop() const noexcept;
710
711 /** Creates a midi stop event. */
712 static MidiMessage midiStop() noexcept;
713
714 /** Returns true if this is a midi clock event.
715 @see midiClock, songPositionPointer
716 */
717 bool isMidiClock() const noexcept;
718
719 /** Creates a midi clock event. */
720 static MidiMessage midiClock() noexcept;
721
722 /** Returns true if this is a song-position-pointer message.
723 @see getSongPositionPointerMidiBeat, songPositionPointer
724 */
725 bool isSongPositionPointer() const noexcept;
726
727 /** Returns the midi beat-number of a song-position-pointer message.
728 @see isSongPositionPointer, songPositionPointer
729 */
730 int getSongPositionPointerMidiBeat() const noexcept;
731
732 /** Creates a song-position-pointer message.
733
734 The position is a number of midi beats from the start of the song, where 1 midi
735 beat is 6 midi clocks, and there are 24 midi clocks in a quarter-note. So there
736 are 4 midi beats in a quarter-note.
737
738 @see isSongPositionPointer, getSongPositionPointerMidiBeat
739 */
740 static MidiMessage songPositionPointer (int positionInMidiBeats) noexcept;
741
742 //==============================================================================
743 /** Returns true if this is a quarter-frame midi timecode message.
744 @see quarterFrame, getQuarterFrameSequenceNumber, getQuarterFrameValue
745 */
746 bool isQuarterFrame() const noexcept;
747
748 /** Returns the sequence number of a quarter-frame midi timecode message.
749 This will be a value between 0 and 7.
750 @see isQuarterFrame, getQuarterFrameValue, quarterFrame
751 */
752 int getQuarterFrameSequenceNumber() const noexcept;
753
754 /** Returns the value from a quarter-frame message.
755 This will be the lower nybble of the message's data-byte, a value between 0 and 15
756 */
757 int getQuarterFrameValue() const noexcept;
758
759 /** Creates a quarter-frame MTC message.
760
761 @param sequenceNumber a value 0 to 7 for the upper nybble of the message's data byte
762 @param value a value 0 to 15 for the lower nybble of the message's data byte
763 */
764 static MidiMessage quarterFrame (int sequenceNumber, int value) noexcept;
765
766 /** SMPTE timecode types.
767 Used by the getFullFrameParameters() and fullFrame() methods.
768 */
770 {
771 fps24 = 0,
772 fps25 = 1,
773 fps30drop = 2,
774 fps30 = 3
775 };
776
777 /** Returns true if this is a full-frame midi timecode message. */
778 bool isFullFrame() const noexcept;
779
780 /** Extracts the timecode information from a full-frame midi timecode message.
781
782 You should only call this on messages where you've used isFullFrame() to
783 check that they're the right kind.
784 */
785 void getFullFrameParameters (int& hours,
786 int& minutes,
787 int& seconds,
788 int& frames,
789 SmpteTimecodeType& timecodeType) const noexcept;
790
791 /** Creates a full-frame MTC message. */
792 static MidiMessage fullFrame (int hours,
793 int minutes,
794 int seconds,
795 int frames,
796 SmpteTimecodeType timecodeType);
797
798 //==============================================================================
799 /** Types of MMC command.
800
801 @see isMidiMachineControlMessage, getMidiMachineControlCommand, midiMachineControlCommand
802 */
804 {
805 mmc_stop = 1,
806 mmc_play = 2,
807 mmc_deferredplay = 3,
808 mmc_fastforward = 4,
809 mmc_rewind = 5,
810 mmc_recordStart = 6,
811 mmc_recordStop = 7,
812 mmc_pause = 9
813 };
814
815 /** Checks whether this is an MMC message.
816 If it is, you can use the getMidiMachineControlCommand() to find out its type.
817 */
818 bool isMidiMachineControlMessage() const noexcept;
819
820 /** For an MMC message, this returns its type.
821
822 Make sure it's actually an MMC message with isMidiMachineControlMessage() before
823 calling this method.
824 */
825 MidiMachineControlCommand getMidiMachineControlCommand() const noexcept;
826
827 /** Creates an MMC message. */
828 static MidiMessage midiMachineControlCommand (MidiMachineControlCommand command);
829
830 /** Checks whether this is an MMC "goto" message.
831 If it is, the parameters passed-in are set to the time that the message contains.
832 @see midiMachineControlGoto
833 */
834 bool isMidiMachineControlGoto (int& hours,
835 int& minutes,
836 int& seconds,
837 int& frames) const noexcept;
838
839 /** Creates an MMC "goto" message.
840 This messages tells the device to go to a specific frame.
841 @see isMidiMachineControlGoto
842 */
843 static MidiMessage midiMachineControlGoto (int hours,
844 int minutes,
845 int seconds,
846 int frames);
847
848 //==============================================================================
849 /** Creates a master-volume change message.
850 @param volume the volume, 0 to 1.0
851 */
852 static MidiMessage masterVolume (float volume);
853
854 //==============================================================================
855 /** Creates a system-exclusive message.
856 The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7.
857 */
858 static MidiMessage createSysExMessage (const void* sysexData,
859 int dataSize);
860
861
862 //==============================================================================
863 /** Reads a midi variable-length integer.
864
865 @param data the data to read the number from
866 @param numBytesUsed on return, this will be set to the number of bytes that were read
867 */
868 static int readVariableLengthVal (const uint8* data,
870
871 /** Based on the first byte of a short midi message, this uses a lookup table
872 to return the message length (either 1, 2, or 3 bytes).
873
874 The value passed in must be 0x80 or higher.
875 */
876 static int getMessageLengthFromFirstByte (uint8 firstByte) noexcept;
877
878 //==============================================================================
879 /** Returns the name of a midi note number.
880
881 E.g "C", "D#", etc.
882
883 @param noteNumber the midi note number, 0 to 127
884 @param useSharps if true, sharpened notes are used, e.g. "C#", otherwise
885 they'll be flattened, e.g. "Db"
886 @param includeOctaveNumber if true, the octave number will be appended to the string,
887 e.g. "C#4"
888 @param octaveNumForMiddleC if an octave number is being appended, this indicates the
889 number that will be used for middle C's octave
890
891 @see getMidiNoteInHertz
892 */
893 static String getMidiNoteName (int noteNumber,
894 bool useSharps,
897
898 /** Returns the frequency of a midi note number.
899
900 The frequencyOfA parameter is an optional frequency for 'A', normally 440-444Hz for concert pitch.
901 @see getMidiNoteName
902 */
903 static double getMidiNoteInHertz (int noteNumber, double frequencyOfA = 440.0) noexcept;
904
905 /** Returns true if the given midi note number is a black key. */
906 static bool isMidiNoteBlack (int noteNumber) noexcept;
907
908 /** Returns the standard name of a GM instrument, or nullptr if unknown for this index.
909
910 @param midiInstrumentNumber the program number 0 to 127
911 @see getProgramChangeNumber
912 */
913 static const char* getGMInstrumentName (int midiInstrumentNumber);
914
915 /** Returns the name of a bank of GM instruments, or nullptr if unknown for this bank number.
916 @param midiBankNumber the bank, 0 to 15
917 */
918 static const char* getGMInstrumentBankName (int midiBankNumber);
919
920 /** Returns the standard name of a channel 10 percussion sound, or nullptr if unknown for this note number.
921 @param midiNoteNumber the key number, 35 to 81
922 */
923 static const char* getRhythmInstrumentName (int midiNoteNumber);
924
925 /** Returns the name of a controller type number, or nullptr if unknown for this controller number.
926 @see getControllerNumber
927 */
928 static const char* getControllerName (int controllerNumber);
929
930 /** Converts a floating-point value between 0 and 1 to a MIDI 7-bit value between 0 and 127. */
931 static uint8 floatValueToMidiByte (float valueBetween0and1) noexcept;
932
933 /** Converts a pitchbend value in semitones to a MIDI 14-bit pitchwheel position value. */
934 static uint16 pitchbendToPitchwheelPos (float pitchbendInSemitones,
936
937private:
938 //==============================================================================
939 #ifndef DOXYGEN
940 union PackedData
941 {
942 uint8* allocatedData;
943 uint8 asBytes[sizeof (uint8*)];
944 };
945
946 PackedData packedData;
947 double timeStamp = 0;
948 int size;
949 #endif
950
951 inline bool isHeapAllocated() const noexcept { return size > (int) sizeof (packedData); }
952 inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; }
953 uint8* allocateSpace (int);
954};
955
956} // namespace juce
957
958/** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:60
Encapsulates a MIDI message.
MidiMessage(int byte1, int byte2, int byte3, Data... otherBytes)
Creates a midi message from a list of bytes.
double getTimeStamp() const noexcept
Returns the timestamp associated with this message.
MidiMachineControlCommand
Types of MMC command.
void addToTimeStamp(double delta) noexcept
Adds a value to the message's timestamp.
void setTimeStamp(double newTimestamp) noexcept
Changes the message's associated timestamp.
SmpteTimecodeType
SMPTE timecode types.
int getRawDataSize() const noexcept
Returns the number of bytes of data in the message.
A simple class for holding temporary references to a string literal or String.
The JUCE String class!
Definition juce_String.h:43
#define JUCE_API
This macro is added to all JUCE public class declarations.