libcm is a C development framework with an emphasis on audio signal processing applications.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

cmMidi.h 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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 = 0x40,
  64. kPortamentoCtlMdId = 0x41,
  65. kSostenutoCtlMdId = 0x42,
  66. kSoftPedalCtlMdId = 0x43,
  67. kLegatoCtlMdId = 0x44
  68. };
  69. typedef unsigned char cmMidiByte_t;
  70. //===============================================================================================
  71. // Utility Functions
  72. //
  73. #define cmMidiIsStatus( s ) (kNoteOffMdId <= (s) /*&& ((unsigned)(s)) <= kSysRtResetMdId*/ )
  74. #define cmMidiIsChStatus( s ) (kNoteOffMdId <= (s) && (s) < kSysExMdId)
  75. #define cmMidiIsNoteOn( s ) ( kNoteOnMdId <= (s) && (s) <= (kNoteOnMdId + kMidiChCnt) )
  76. #define cmMidiIsNoteOff( s, d1 ) ( cmMidiIsNoteOn(s) && (d1)==0 || kNoteOffMdId <= (s) && (s) <= (kNoteOffMdId + kMidiChCnt) )
  77. #define cmMidiIsCtl( s ) ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) )
  78. #define cmMidiIsSustainPedal( s, d0 ) ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) && (d0)== kSustainCtlMdId )
  79. #define cmMidiIsSustainPedalDown( s, d0, d1) ( cmMidiIsSustainPedal(s,d0) && (d1)>=64 )
  80. #define cmMidiIsSustainPedalUp( s, d0, d1) ( cmMidiIsSustainPedal(s,d0) && (d1)<64 )
  81. #define cmMidiIsPedal( s, d0 ) ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) && (d0)>=kSustainCtlMdId && (d0)<=kLegatoCtlMdId )
  82. #define cmMidiIsPedalDown( s, d0, d1 ) ( cmMidiIsPedal(s,d0) && (d1)>=64 )
  83. #define cmMidiIsPedalUp( s, d0, d1 ) ( cmMidiIsPedal(s,d0) && (d1)<64 )
  84. const char* cmMidiStatusToLabel( cmMidiByte_t status );
  85. const char* cmMidiMetaStatusToLabel( cmMidiByte_t metaStatus );
  86. const char* cmMidiPedalLabel( cmMidiByte_t d0 );
  87. // Returns kInvalidMidiByte if status is not a valid status byte
  88. cmMidiByte_t cmMidiStatusToByteCount( cmMidiByte_t status );
  89. unsigned cmMidiTo14Bits( cmMidiByte_t d0, cmMidiByte_t d1 );
  90. void cmMidiSplit14Bits( unsigned v, cmMidiByte_t* d0Ref, cmMidiByte_t* d1Ref );
  91. int cmMidiToPbend( cmMidiByte_t d0, cmMidiByte_t d1 );
  92. void cmMidiSplitPbend( int v, cmMidiByte_t* d0Ref, cmMidiByte_t* d1Ref );
  93. //===============================================================================================
  94. // MIDI Communication data types
  95. //
  96. typedef struct
  97. {
  98. //unsigned deltaUs; // time since last MIDI msg in microseconds
  99. cmTimeSpec_t timeStamp;
  100. cmMidiByte_t status; // midi status byte
  101. cmMidiByte_t d0; // midi data byte 0
  102. cmMidiByte_t d1; // midi data byte 1
  103. cmMidiByte_t pad;
  104. } cmMidiMsg;
  105. typedef struct
  106. {
  107. void* cbDataPtr; // application supplied reference value from mdParserCreate()
  108. unsigned devIdx; // the device the msg originated from
  109. unsigned portIdx; // the port index on the source device
  110. cmMidiMsg* msgArray; // pointer to an array of 'msgCnt' mdMsg records or NULL if sysExMsg is non-NULL
  111. cmMidiByte_t* sysExMsg; // pointer to a sys-ex msg or NULL if msgArray is non-NULL (see note below)
  112. unsigned msgCnt; // count of mdMsg records or sys-ex bytes
  113. } cmMidiPacket_t;
  114. // Notes: If the sys-ex message can be contained in a single msg then
  115. // then the first msg byte is kSysExMdId and the last is kSysComEoxMdId.
  116. // If the sys-ex message is broken into multiple pieces then only the
  117. // first will begin with kSysExMdId and the last will end with kSysComEoxMdId.
  118. // If label is NULL or labelCharCnt==0 then a pointer to an internal static
  119. // buffer is returned. If label[] is given the it
  120. // should have at least 5 (kMidiPitchCharCnt) char's (including the terminating zero).
  121. // If 'pitch' is outside of the range 0-127 then a blank string is returned.
  122. const char* cmMidiToSciPitch( cmMidiByte_t pitch, char* label, unsigned labelCharCnt );
  123. // Scientific pitch string: [A-Ga-g][#b][#] where # may be -1 to 9.
  124. // Return kInvalidMidiPitch if sciPtichStr does not contain a valid
  125. // scientific pitch string. This function will convert C-1 to G9 to
  126. // valid MIDI pitch values 0 to 127. Scientific pitch strings outside
  127. // of this range will be returned as kInvalidMidiPitch.
  128. cmMidiByte_t cmSciPitchToMidi( const char* sciPitchStr );
  129. #ifdef __cplusplus
  130. }
  131. #endif
  132. #endif