libcm is a C development framework with an emphasis on audio signal processing applications.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

cmMidi.h 5.3KB

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