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.

cmMidi.h 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. unsigned cmMidiTo14Bits( cmMidiByte_t d0, cmMidiByte_t d1 );
  76. void cmMidiSplit14Bits( unsigned v, cmMidiByte_t* d0Ref, cmMidiByte_t* d1Ref );
  77. int cmMidiToPbend( cmMidiByte_t d0, cmMidiByte_t d1 );
  78. void cmMidiSplitPbend( int v, cmMidiByte_t* d0Ref, cmMidiByte_t* d1Ref );
  79. //===============================================================================================
  80. // MIDI Communication data types
  81. //
  82. typedef struct
  83. {
  84. unsigned deltaUs; // time since last MIDI msg in microseconds
  85. cmMidiByte_t status; // midi status byte
  86. cmMidiByte_t d0; // midi data byte 0
  87. cmMidiByte_t d1; // midi data byte 1
  88. cmMidiByte_t pad;
  89. } cmMidiMsg;
  90. typedef struct
  91. {
  92. void* cbDataPtr; // application supplied reference value from mdParserCreate()
  93. unsigned devIdx; // the device the msg originated from
  94. unsigned portIdx; // the port index on the source device
  95. cmMidiMsg* msgArray; // pointer to an array of 'msgCnt' mdMsg records or NULL if sysExMsg is non-NULL
  96. cmMidiByte_t* sysExMsg; // pointer to a sys-ex msg or NULL if msgArray is non-NULL (see note below)
  97. unsigned msgCnt; // count of mdMsg records or sys-ex bytes
  98. } cmMidiPacket_t;
  99. // Notes: If the sys-ex message can be contained in a single msg then
  100. // then the first msg byte is kSysExMdId and the last is kSysComEoxMdId.
  101. // If the sys-ex message is broken into multiple pieces then only the
  102. // first will begin with kSysExMdId and the last will end with kSysComEoxMdId.
  103. // If label is NULL or labelCharCnt==0 then a pointer to an internal static
  104. // buffer is returned. If label[] is given the it
  105. // should have at least 5 (kMidiPitchCharCnt) char's (including the terminating zero).
  106. // If 'pitch' is outside of the range 0-127 then a blank string is returned.
  107. const char* cmMidiToSciPitch( cmMidiByte_t pitch, char* label, unsigned labelCharCnt );
  108. // Scientific pitch string: [A-Ga-g][#b][#] where # may be -1 to 9.
  109. // Return kInvalidMidiPitch if sciPtichStr does not contain a valid
  110. // scientific pitch string. This function will convert C-1 to G9 to
  111. // valid MIDI pitch values 0 to 127. Scientific pitch strings outside
  112. // of this range will be returned as kInvalidMidiPitch.
  113. cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr );
  114. #ifdef __cplusplus
  115. }
  116. #endif
  117. #endif