OpenShot Library | libopenshot-audio  0.1.9
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 
27 namespace juce
28 {
29 
30 //==============================================================================
31 /**
32  Encapsulates a MIDI message.
33 
34  @see MidiMessageSequence, MidiOutput, MidiInput
35 
36  @tags{Audio}
37 */
39 {
40 public:
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  */
113  MidiMessage() noexcept;
114 
115  /** Creates a copy of another midi message. */
116  MidiMessage (const MidiMessage&);
117 
118  /** Creates a copy of another midi message, with a different timestamp. */
119  MidiMessage (const MidiMessage&, double newTimeStamp);
120 
121  /** Destructor. */
122  ~MidiMessage() noexcept;
123 
124  /** Copies this message from another one. */
125  MidiMessage& operator= (const MidiMessage& other);
126 
127  /** Move constructor */
128  MidiMessage (MidiMessage&&) noexcept;
129 
130  /** Move assignment operator */
131  MidiMessage& operator= (MidiMessage&&) noexcept;
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  */
167  double getTimeStamp() const noexcept { return timeStamp; }
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,
433  int aftertouchAmount) noexcept;
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  */
615  static MidiMessage tempoMetaEvent (int microsecondsPerQuarterNote) noexcept;
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,
869  int& numBytesUsed) noexcept;
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,
895  bool includeOctaveNumber,
896  int octaveNumForMiddleC);
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,
935  float pitchbendRangeInSemitones) noexcept;
936 
937 private:
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 /** @}*/
#define JUCE_API
This macro is added to all JUCE public class declarations.
void setTimeStamp(double newTimestamp) noexcept
Changes the message&#39;s associated timestamp.
Encapsulates a MIDI message.
A simple class for holding temporary references to a string literal or String.
int getRawDataSize() const noexcept
Returns the number of bytes of data in the message.
The JUCE String class!
Definition: juce_String.h:42
void addToTimeStamp(double delta) noexcept
Adds a value to the message&#39;s timestamp.
MidiMessage(int byte1, int byte2, int byte3, Data... otherBytes)
Creates a midi message from a list of bytes.
MidiMachineControlCommand
Types of MMC command.
SmpteTimecodeType
SMPTE timecode types.
const uint8 * getRawData() const noexcept
Returns a pointer to the raw midi data.
double getTimeStamp() const noexcept
Returns the timestamp associated with this message.