libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cmMidi.h 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifndef cmMidi_h
  4. #define cmMidi_h
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. //( { file_desc:"MIDI utility constants and functions." kw:[midi]}
  9. enum
  10. {
  11. kMidiChCnt = 16,
  12. kInvalidMidiByte = 128,
  13. kMidiNoteCnt = kInvalidMidiByte,
  14. kMidiCtlCnt = kInvalidMidiByte,
  15. kMidiPgmCnt = kInvalidMidiByte,
  16. kInvalidMidiPitch = kInvalidMidiByte,
  17. kInvalidMidiVelocity = kInvalidMidiByte,
  18. kInvalidMidiCtl = kInvalidMidiByte,
  19. kInvalidMidiPgm = kInvalidMidiByte,
  20. kMidiSciPitchCharCnt = 5 // A#-1
  21. };
  22. // MIDI status bytes
  23. enum
  24. {
  25. kInvalidStatusMdId = 0x00,
  26. kNoteOffMdId = 0x80,
  27. kNoteOnMdId = 0x90,
  28. kPolyPresMdId = 0xa0,
  29. kCtlMdId = 0xb0,
  30. kPgmMdId = 0xc0,
  31. kChPresMdId = 0xd0,
  32. kPbendMdId = 0xe0,
  33. kSysExMdId = 0xf0,
  34. kSysComMtcMdId = 0xf1,
  35. kSysComSppMdId = 0xf2,
  36. kSysComSelMdId = 0xf3,
  37. kSysComUndef0MdId = 0xf4,
  38. kSysComUndef1MdId = 0xf5,
  39. kSysComTuneMdId = 0xf6,
  40. kSysComEoxMdId = 0xf7,
  41. kSysRtClockMdId = 0xf8,
  42. kSysRtUndef0MdId = 0xf9,
  43. kSysRtStartMdId = 0xfa,
  44. kSysRtContMdId = 0xfb,
  45. kSysRtStopMdId = 0xfc,
  46. kSysRtUndef1MdId = 0xfd,
  47. kSysRtSenseMdId = 0xfe,
  48. kSysRtResetMdId = 0xff,
  49. kMetaStId = 0xff,
  50. kSeqNumbMdId = 0x00,
  51. kTextMdId = 0x01,
  52. kCopyMdId = 0x02,
  53. kTrkNameMdId = 0x03,
  54. kInstrNameMdId = 0x04,
  55. kLyricsMdId = 0x05,
  56. kMarkerMdId = 0x06,
  57. kCuePointMdId = 0x07,
  58. kMidiChMdId = 0x20,
  59. kEndOfTrkMdId = 0x2f,
  60. kTempoMdId = 0x51,
  61. kSmpteMdId = 0x54,
  62. kTimeSigMdId = 0x58,
  63. kKeySigMdId = 0x59,
  64. kSeqSpecMdId = 0x7f,
  65. kInvalidMetaMdId = 0x80,
  66. kSustainCtlMdId = 0x40,
  67. kPortamentoCtlMdId = 0x41,
  68. kSostenutoCtlMdId = 0x42,
  69. kSoftPedalCtlMdId = 0x43,
  70. kLegatoCtlMdId = 0x44
  71. };
  72. typedef unsigned char cmMidiByte_t;
  73. //===============================================================================================
  74. // Utility Functions
  75. //
  76. #define cmMidiIsStatus( s ) (kNoteOffMdId <= (s) /*&& ((unsigned)(s)) <= kSysRtResetMdId*/ )
  77. #define cmMidiIsChStatus( s ) (kNoteOffMdId <= (s) && (s) < kSysExMdId)
  78. #define cmMidiIsNoteOn( s ) ( kNoteOnMdId <= (s) && (s) < (kNoteOnMdId + kMidiChCnt) )
  79. #define cmMidiIsNoteOff( s, d1 ) ( (cmMidiIsNoteOn(s) && (d1)==0) || (kNoteOffMdId <= (s) && (s) < (kNoteOffMdId + kMidiChCnt)) )
  80. #define cmMidiIsCtl( s ) ( kCtlMdId <= (s) && (s) < (kCtlMdId + kMidiChCnt) )
  81. #define cmMidiIsSustainPedal( s, d0 ) ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) && (d0)== kSustainCtlMdId )
  82. #define cmMidiIsSustainPedalDown( s, d0, d1) ( cmMidiIsSustainPedal(s,d0) && (d1)>=64 )
  83. #define cmMidiIsSustainPedalUp( s, d0, d1) ( cmMidiIsSustainPedal(s,d0) && (d1)<64 )
  84. #define cmMidiIsSostenutoPedal( s, d0 ) ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) && (d0)== kSostenutoCtlMdId )
  85. #define cmMidiIsSostenutoPedalDown( s, d0, d1) ( cmMidiIsSostenutoPedal(s,d0) && (d1)>=64 )
  86. #define cmMidiIsSostenutoPedalUp( s, d0, d1) ( cmMidiIsSostenutoPedal(s,d0) && (d1)<64 )
  87. #define cmMidiIsPedal( s, d0 ) ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) && (d0)>=kSustainCtlMdId && (d0)<=kLegatoCtlMdId )
  88. #define cmMidiIsPedalDown( s, d0, d1 ) ( cmMidiIsPedal(s,d0) && (d1)>=64 )
  89. #define cmMidiIsPedalUp( s, d0, d1 ) ( cmMidiIsPedal(s,d0) && (d1)<64 )
  90. const char* cmMidiStatusToLabel( cmMidiByte_t status );
  91. const char* cmMidiMetaStatusToLabel( cmMidiByte_t metaStatus );
  92. const char* cmMidiPedalLabel( cmMidiByte_t d0 );
  93. // Returns kInvalidMidiByte if status is not a valid status byte
  94. cmMidiByte_t cmMidiStatusToByteCount( cmMidiByte_t status );
  95. unsigned cmMidiTo14Bits( cmMidiByte_t d0, cmMidiByte_t d1 );
  96. void cmMidiSplit14Bits( unsigned v, cmMidiByte_t* d0Ref, cmMidiByte_t* d1Ref );
  97. int cmMidiToPbend( cmMidiByte_t d0, cmMidiByte_t d1 );
  98. void cmMidiSplitPbend( int v, cmMidiByte_t* d0Ref, cmMidiByte_t* d1Ref );
  99. //===============================================================================================
  100. // MIDI Communication data types
  101. //
  102. typedef struct
  103. {
  104. //unsigned deltaUs; // time since last MIDI msg in microseconds
  105. cmTimeSpec_t timeStamp;
  106. cmMidiByte_t status; // midi status byte
  107. cmMidiByte_t d0; // midi data byte 0
  108. cmMidiByte_t d1; // midi data byte 1
  109. cmMidiByte_t pad;
  110. } cmMidiMsg;
  111. typedef struct
  112. {
  113. void* cbDataPtr; // application supplied reference value from mdParserCreate()
  114. unsigned devIdx; // the device the msg originated from
  115. unsigned portIdx; // the port index on the source device
  116. cmMidiMsg* msgArray; // pointer to an array of 'msgCnt' mdMsg records or NULL if sysExMsg is non-NULL
  117. cmMidiByte_t* sysExMsg; // pointer to a sys-ex msg or NULL if msgArray is non-NULL (see note below)
  118. unsigned msgCnt; // count of mdMsg records or sys-ex bytes
  119. } cmMidiPacket_t;
  120. // Notes: If the sys-ex message can be contained in a single msg then
  121. // then the first msg byte is kSysExMdId and the last is kSysComEoxMdId.
  122. // If the sys-ex message is broken into multiple pieces then only the
  123. // first will begin with kSysExMdId and the last will end with kSysComEoxMdId.
  124. // If label is NULL or labelCharCnt==0 then a pointer to an internal static
  125. // buffer is returned. If label[] is given the it
  126. // should have at least 5 (kMidiPitchCharCnt) char's (including the terminating zero).
  127. // If 'pitch' is outside of the range 0-127 then a blank string is returned.
  128. const char* cmMidiToSciPitch( cmMidiByte_t pitch, char* label, unsigned labelCharCnt );
  129. // Convert a scientific pitch to MIDI pitch. acc == 1 == sharp, acc == -1 == flat.
  130. // The pitch character must be in the range 'A' to 'G'. Upper or lower case is valid.
  131. // Return kInvalidMidiPitch if the arguments are not valid.
  132. cmMidiByte_t cmSciPitchToMidiPitch( cmChar_t pitch, int acc, int octave );
  133. // Scientific pitch string: [A-Ga-g][#b][#] where # may be -1 to 9.
  134. // Return kInvalidMidiPitch if sciPtichStr does not contain a valid
  135. // scientific pitch string. This function will convert C-1 to G9 to
  136. // valid MIDI pitch values 0 to 127. Scientific pitch strings outside
  137. // of this range will be returned as kInvalidMidiPitch.
  138. cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr );
  139. //)
  140. #ifdef __cplusplus
  141. }
  142. #endif
  143. #endif