libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #ifndef cmMidi_h
  2. #define cmMidi_h
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. enum
  7. {
  8. kMidiChCnt = 16,
  9. kInvalidMidiByte = 128,
  10. kMidiNoteCnt = kInvalidMidiByte,
  11. kMidiCtlCnt = kInvalidMidiByte,
  12. kMidiPgmCnt = kInvalidMidiByte,
  13. kInvalidMidiPitch = kInvalidMidiByte,
  14. kInvalidMidiVelocity = kInvalidMidiByte,
  15. kInvalidMidiCtl = kInvalidMidiByte,
  16. kInvalidMidiPgm = kInvalidMidiByte,
  17. kMidiSciPitchCharCnt = 5 // A#-1
  18. };
  19. // MIDI status bytes
  20. enum
  21. {
  22. kInvalidStatusMdId = 0x00,
  23. kNoteOffMdId = 0x80,
  24. kNoteOnMdId = 0x90,
  25. kPolyPresMdId = 0xa0,
  26. kCtlMdId = 0xb0,
  27. kPgmMdId = 0xc0,
  28. kChPresMdId = 0xd0,
  29. kPbendMdId = 0xe0,
  30. kSysExMdId = 0xf0,
  31. kSysComMtcMdId = 0xf1,
  32. kSysComSppMdId = 0xf2,
  33. kSysComSelMdId = 0xf3,
  34. kSysComUndef0MdId = 0xf4,
  35. kSysComUndef1MdId = 0xf5,
  36. kSysComTuneMdId = 0xf6,
  37. kSysComEoxMdId = 0xf7,
  38. kSysRtClockMdId = 0xf8,
  39. kSysRtUndef0MdId = 0xf9,
  40. kSysRtStartMdId = 0xfa,
  41. kSysRtContMdId = 0xfb,
  42. kSysRtStopMdId = 0xfc,
  43. kSysRtUndef1MdId = 0xfd,
  44. kSysRtSenseMdId = 0xfe,
  45. kSysRtResetMdId = 0xff,
  46. kMetaStId = 0xff,
  47. kSeqNumbMdId = 0x00,
  48. kTextMdId = 0x01,
  49. kCopyMdId = 0x02,
  50. kTrkNameMdId = 0x03,
  51. kInstrNameMdId = 0x04,
  52. kLyricsMdId = 0x05,
  53. kMarkerMdId = 0x06,
  54. kCuePointMdId = 0x07,
  55. kMidiChMdId = 0x20,
  56. kEndOfTrkMdId = 0x2f,
  57. kTempoMdId = 0x51,
  58. kSmpteMdId = 0x54,
  59. kTimeSigMdId = 0x58,
  60. kKeySigMdId = 0x59,
  61. kSeqSpecMdId = 0x7f,
  62. kInvalidMetaMdId = 0x80,
  63. kSustainCtlMdId = 64
  64. };
  65. typedef unsigned char cmMidiByte_t;
  66. //===============================================================================================
  67. // Utility Functions
  68. //
  69. #define cmMidiIsStatus( s ) (kNoteOffMdId <= (s) /*&& ((unsigned)(s)) <= kSysRtResetMdId*/ )
  70. #define cmMidiIsChStatus( s ) (kNoteOffMdId <= (s) && (s) < kSysExMdId)
  71. const char* cmMidiStatusToLabel( cmMidiByte_t status );
  72. const char* cmMidiMetaStatusToLabel( cmMidiByte_t metaStatus );
  73. // Returns kInvalidMidiByte if status is not a valid status byte
  74. cmMidiByte_t cmMidiStatusToByteCount( cmMidiByte_t status );
  75. //===============================================================================================
  76. // MIDI Communication data types
  77. //
  78. typedef struct
  79. {
  80. unsigned deltaUs; // time since last MIDI msg in microseconds
  81. cmMidiByte_t status; // midi status byte
  82. cmMidiByte_t d0; // midi data byte 0
  83. cmMidiByte_t d1; // midi data byte 1
  84. cmMidiByte_t pad;
  85. } cmMidiMsg;
  86. typedef struct
  87. {
  88. void* cbDataPtr; // application supplied reference value from mdParserCreate()
  89. unsigned devIdx; // the device the msg originated from
  90. unsigned portIdx; // the port index on the source device
  91. cmMidiMsg* msgArray; // pointer to an array of 'msgCnt' mdMsg records or NULL if sysExMsg is non-NULL
  92. cmMidiByte_t* sysExMsg; // pointer to a sys-ex msg or NULL if msgArray is non-NULL (see note below)
  93. unsigned msgCnt; // count of mdMsg records or sys-ex bytes
  94. } cmMidiPacket_t;
  95. // Notes: If the sys-ex message can be contained in a single msg then
  96. // then the first msg byte is kSysExMdId and the last is kSysComEoxMdId.
  97. // If the sys-ex message is broken into multiple pieces then only the
  98. // first will begin with kSysExMdId and the last will end with kSysComEoxMdId.
  99. // If label is NULL or labelCharCnt==0 then a pointer to an internal static
  100. // buffer is returned. If label[] is given the it
  101. // should have at least 5 (kMidiPitchCharCnt) char's (including the terminating zero).
  102. // If 'pitch' is outside of the range 0-127 then a blank string is returned.
  103. const char* cmMidiToSciPitch( cmMidiByte_t pitch, char* label, unsigned labelCharCnt );
  104. // Scientific pitch string: [A-Ga-g][#b][#] where # may be -1 to 9.
  105. // Return kInvalidMidiPitch if sciPtichStr does not contain a valid
  106. // scientific pitch string. This function will convert C-1 to G9 to
  107. // valid MIDI pitch values 0 to 127. Scientific pitch strings outside
  108. // of this range will be returned as kInvalidMidiPitch.
  109. cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr );
  110. #ifdef __cplusplus
  111. }
  112. #endif
  113. #endif