_MIDI.H 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. Copyright (C) 1994-1995 Apogee Software, Ltd.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. /**********************************************************************
  16. module: _MIDI.H
  17. author: James R. Dose
  18. date: May 25, 1994
  19. Private header for MIDI.C. Midi song file playback routines.
  20. (c) Copyright 1994 James R. Dose. All Rights Reserved.
  21. **********************************************************************/
  22. #ifndef ___MIDI_H
  23. #define ___MIDI_H
  24. #define RELATIVE_BEAT( measure, beat, tick ) \
  25. ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
  26. //Bobby Prince thinks this may be 100
  27. //#define GENMIDI_DefaultVolume 100
  28. #define GENMIDI_DefaultVolume 90
  29. #define MAX_FORMAT 1
  30. #define NUM_MIDI_CHANNELS 16
  31. #define TIME_PRECISION 16
  32. #define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd"
  33. #define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk"
  34. #define MIDI_VOLUME 7
  35. #define MIDI_PAN 10
  36. #define MIDI_DETUNE 94
  37. #define MIDI_RHYTHM_CHANNEL 9
  38. #define MIDI_RPN_MSB 100
  39. #define MIDI_RPN_LSB 101
  40. #define MIDI_DATAENTRY_MSB 6
  41. #define MIDI_DATAENTRY_LSB 38
  42. #define MIDI_PITCHBEND_MSB 0
  43. #define MIDI_PITCHBEND_LSB 0
  44. #define MIDI_RUNNING_STATUS 0x80
  45. #define MIDI_NOTE_OFF 0x8
  46. #define MIDI_NOTE_ON 0x9
  47. #define MIDI_POLY_AFTER_TCH 0xA
  48. #define MIDI_CONTROL_CHANGE 0xB
  49. #define MIDI_PROGRAM_CHANGE 0xC
  50. #define MIDI_AFTER_TOUCH 0xD
  51. #define MIDI_PITCH_BEND 0xE
  52. #define MIDI_SPECIAL 0xF
  53. #define MIDI_SYSEX 0xF0
  54. #define MIDI_SYSEX_CONTINUE 0xF7
  55. #define MIDI_META_EVENT 0xFF
  56. #define MIDI_END_OF_TRACK 0x2F
  57. #define MIDI_TEMPO_CHANGE 0x51
  58. #define MIDI_TIME_SIGNATURE 0x58
  59. #define MIDI_RESET_ALL_CONTROLLERS 0x79
  60. #define MIDI_ALL_NOTES_OFF 0x7b
  61. #define MIDI_MONO_MODE_ON 0x7E
  62. #define MIDI_SYSTEM_RESET 0xFF
  63. #define GET_NEXT_EVENT( track, data ) \
  64. ( data ) = *( track )->pos; \
  65. ( track )->pos += 1
  66. #define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf )
  67. #define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 )
  68. #define EMIDI_INFINITE -1
  69. #define EMIDI_END_LOOP_VALUE 127
  70. #define EMIDI_ALL_CARDS 127
  71. #define EMIDI_INCLUDE_TRACK 110
  72. #define EMIDI_EXCLUDE_TRACK 111
  73. #define EMIDI_PROGRAM_CHANGE 112
  74. #define EMIDI_VOLUME_CHANGE 113
  75. #define EMIDI_CONTEXT_START 114
  76. #define EMIDI_CONTEXT_END 115
  77. #define EMIDI_LOOP_START 116
  78. #define EMIDI_LOOP_END 117
  79. #define EMIDI_SONG_LOOP_START 118
  80. #define EMIDI_SONG_LOOP_END 119
  81. #define EMIDI_GeneralMIDI 0
  82. #define EMIDI_SoundCanvas 1
  83. #define EMIDI_AWE32 2
  84. #define EMIDI_WaveBlaster 3
  85. #define EMIDI_SoundBlaster 4
  86. #define EMIDI_ProAudio 5
  87. #define EMIDI_SoundMan16 6
  88. #define EMIDI_Adlib 7
  89. #define EMIDI_Soundscape 8
  90. #define EMIDI_Ultrasound 9
  91. #define EMIDI_AffectsCurrentCard( c, type ) \
  92. ( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
  93. #define EMIDI_NUM_CONTEXTS 7
  94. typedef struct
  95. {
  96. unsigned char *pos;
  97. unsigned char *loopstart;
  98. short loopcount;
  99. short RunningStatus;
  100. unsigned time;
  101. long FPSecondsPerTick;
  102. short tick;
  103. short beat;
  104. short measure;
  105. short BeatsPerMeasure;
  106. short TicksPerBeat;
  107. short TimeBase;
  108. long delay;
  109. short active;
  110. } songcontext;
  111. typedef struct
  112. {
  113. unsigned char *start;
  114. unsigned char *pos;
  115. long delay;
  116. short active;
  117. short RunningStatus;
  118. short currentcontext;
  119. songcontext context[ EMIDI_NUM_CONTEXTS ];
  120. char EMIDI_IncludeTrack;
  121. char EMIDI_ProgramChange;
  122. char EMIDI_VolumeChange;
  123. } track;
  124. static long _MIDI_ReadNumber( void *from, size_t size );
  125. static long _MIDI_ReadDelta( track *ptr );
  126. static void _MIDI_ResetTracks( void );
  127. static void _MIDI_AdvanceTick( void );
  128. static void _MIDI_MetaEvent( track *Track );
  129. static void _MIDI_SysEx( track *Track );
  130. static int _MIDI_InterpretControllerInfo( track *Track, int TimeSet,
  131. int channel, int c1, int c2 );
  132. //static
  133. void _MIDI_ServiceRoutine( task *Task );
  134. static int _MIDI_SendControlChange( int channel, int c1, int c2 );
  135. static void _MIDI_SetChannelVolume( int channel, int volume );
  136. static void _MIDI_SendChannelVolumes( void );
  137. static int _MIDI_ProcessNextTick( void );
  138. static void _MIDI_InitEMIDI( void );
  139. /*
  140. if ( c1 == EMIDI_LOOP_START )
  141. {
  142. if ( c2 == 0 )
  143. {
  144. Track->context[ 0 ].loopcount = EMIDI_INFINITE;
  145. }
  146. else
  147. {
  148. Track->context[ 0 ].loopcount = c2;
  149. }
  150. Track->context[ 0 ].pos = Track->pos;
  151. Track->context[ 0 ].loopstart = Track->pos;
  152. Track->context[ 0 ].RunningStatus = Track->RunningStatus;
  153. Track->context[ 0 ].time = _MIDI_Time;
  154. Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
  155. Track->context[ 0 ].tick = _MIDI_Tick;
  156. Track->context[ 0 ].beat = _MIDI_Beat;
  157. Track->context[ 0 ].measure = _MIDI_Measure;
  158. Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
  159. Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat;
  160. Track->context[ 0 ].TimeBase = _MIDI_TimeBase;
  161. break;
  162. }
  163. if ( ( c1 == EMIDI_LOOP_END ) &&
  164. ( c2 == EMIDI_END_LOOP_VALUE ) )
  165. {
  166. if ( ( Track->context[ 0 ].loopstart != NULL ) &&
  167. ( Track->context[ 0 ].loopcount != 0 ) )
  168. {
  169. if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE )
  170. {
  171. Track->context[ 0 ].loopcount--;
  172. }
  173. Track->pos = Track->context[ 0 ].loopstart;
  174. Track->RunningStatus = Track->context[ 0 ].RunningStatus;
  175. if ( !TimeSet )
  176. {
  177. _MIDI_Time = Track->context[ 0 ].time;
  178. _MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick;
  179. _MIDI_Tick = Track->context[ 0 ].tick;
  180. _MIDI_Beat = Track->context[ 0 ].beat;
  181. _MIDI_Measure = Track->context[ 0 ].measure;
  182. _MIDI_BeatsPerMeasure = Track->context[ 0 ].BeatsPerMeasure;
  183. _MIDI_TicksPerBeat = Track->context[ 0 ].TicksPerBeat;
  184. _MIDI_TimeBase = Track->context[ 0 ].TimeBase;
  185. TimeSet = TRUE;
  186. }
  187. }
  188. break;
  189. }
  190. if ( c1 == MIDI_MONO_MODE_ON )
  191. {
  192. Track->pos++;
  193. }
  194. if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) )
  195. {
  196. _MIDI_SetChannelVolume( channel, c2 );
  197. break;
  198. }
  199. else if ( ( c1 == EMIDI_VOLUME_CHANGE ) &&
  200. ( Track->EMIDI_VolumeChange ) )
  201. {
  202. _MIDI_SetChannelVolume( channel, c2 );
  203. break;
  204. }
  205. if ( ( c1 == EMIDI_PROGRAM_CHANGE ) &&
  206. ( Track->EMIDI_ProgramChange ) )
  207. {
  208. _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
  209. break;
  210. }
  211. if ( c1 == EMIDI_CONTEXT_START )
  212. {
  213. break;
  214. }
  215. if ( c1 == EMIDI_CONTEXT_END )
  216. {
  217. if ( ( Track->currentcontext != _MIDI_Context ) ||
  218. ( Track->context[ _MIDI_Context ].pos == NULL )
  219. {
  220. break;
  221. }
  222. Track->currentcontext = _MIDI_Context;
  223. Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
  224. Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
  225. Track->pos = Track->context[ _MIDI_Context ].pos;
  226. Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
  227. if ( TimeSet )
  228. {
  229. break;
  230. }
  231. _MIDI_Time = Track->context[ _MIDI_Context ].time;
  232. _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
  233. _MIDI_Tick = Track->context[ _MIDI_Context ].tick;
  234. _MIDI_Beat = Track->context[ _MIDI_Context ].beat;
  235. _MIDI_Measure = Track->context[ _MIDI_Context ].measure;
  236. _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure;
  237. _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat;
  238. _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase;
  239. TimeSet = TRUE;
  240. break;
  241. }
  242. if ( _MIDI_Funcs->ControlChange )
  243. {
  244. _MIDI_Funcs->ControlChange( channel, c1, c2 );
  245. }
  246. */
  247. #endif