mfmidi.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. * Read a Standard MIDI File. Externally-assigned function pointers are
  3. * called upon recognizing things in the file. See midifile(3).
  4. */
  5. /*****************************************************************************
  6. * Change Log
  7. * Date | who : Change
  8. *-----------+-----------------------------------------------------------------
  9. * 2-Mar-92 | GWL : created changelog; MIDIFILE_ERROR to satisfy compiler
  10. *****************************************************************************/
  11. #include "stdio.h"
  12. #include "mfmidi.h"
  13. #include "string.h"
  14. #define MIDIFILE_ERROR -1
  15. /* public stuff */
  16. extern int abort_flag;
  17. void Midifile_reader::midifile()
  18. {
  19. int ntrks;
  20. midifile_error = 0;
  21. ntrks = readheader();
  22. if (midifile_error) return;
  23. if (ntrks <= 0) {
  24. mferror("No tracks!");
  25. /* no need to return since midifile_error is set */
  26. }
  27. while (ntrks-- > 0 && !midifile_error) readtrack();
  28. }
  29. int Midifile_reader::readmt(const char *s, int skip)
  30. /* read through the "MThd" or "MTrk" header string */
  31. /* if skip == 1, we attempt to skip initial garbage. */
  32. {
  33. int nread = 0;
  34. char b[4];
  35. char buff[32];
  36. int c;
  37. const char *errmsg = "expecting ";
  38. retry:
  39. while ( nread<4 ) {
  40. c = Mf_getc();
  41. if ( c == EOF ) {
  42. errmsg = "EOF while expecting ";
  43. goto err;
  44. }
  45. b[nread++] = c;
  46. }
  47. /* See if we found the 4 characters we're looking for */
  48. if ( s[0]==b[0] && s[1]==b[1] && s[2]==b[2] && s[3]==b[3] )
  49. return(0);
  50. if ( skip ) {
  51. /* If we are supposed to skip initial garbage, */
  52. /* try again with the next character. */
  53. b[0]=b[1];
  54. b[1]=b[2];
  55. b[2]=b[3];
  56. nread = 3;
  57. goto retry;
  58. }
  59. err:
  60. (void) strcpy(buff,errmsg);
  61. (void) strcat(buff,s);
  62. mferror(buff);
  63. return(0);
  64. }
  65. int Midifile_reader::egetc()
  66. /* read a single character and abort on EOF */
  67. {
  68. int c = Mf_getc();
  69. if ( c == EOF ) {
  70. mferror("premature EOF");
  71. return EOF;
  72. }
  73. Mf_toberead--;
  74. return(c);
  75. }
  76. int Midifile_reader::readheader()
  77. /* read a header chunk */
  78. {
  79. int format, ntrks, division;
  80. if ( readmt("MThd",Mf_skipinit) == EOF )
  81. return(0);
  82. Mf_toberead = read32bit();
  83. if (midifile_error) return MIDIFILE_ERROR;
  84. format = read16bit();
  85. if (midifile_error) return MIDIFILE_ERROR;
  86. ntrks = read16bit();
  87. if (midifile_error) return MIDIFILE_ERROR;
  88. division = read16bit();
  89. if (midifile_error) return MIDIFILE_ERROR;
  90. Mf_header(format,ntrks,division);
  91. /* flush any extra stuff, in case the length of header is not 6 */
  92. while ( Mf_toberead > 0 && !midifile_error)
  93. (void) egetc();
  94. return(ntrks);
  95. }
  96. void Midifile_reader::readtrack()
  97. /* read a track chunk */
  98. {
  99. /* This array is indexed by the high half of a status byte. It's */
  100. /* value is either the number of bytes needed (1 or 2) for a channel */
  101. /* message, or 0 (meaning it's not a channel message). */
  102. static int chantype[] = {
  103. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 through 0x70 */
  104. 2, 2, 2, 2, 1, 1, 2, 0 /* 0x80 through 0xf0 */
  105. };
  106. long lookfor, lng;
  107. int c, c1, type;
  108. int sysexcontinue = 0; /* 1 if last message was an unfinished sysex */
  109. int running = 0; /* 1 when running status used */
  110. int status = 0; /* (possibly running) status byte */
  111. int needed;
  112. if ( readmt("MTrk",0) == EOF )
  113. return;
  114. Mf_toberead = read32bit();
  115. if (midifile_error) return;
  116. Mf_currtime = 0L;
  117. Mf_starttrack();
  118. while ( Mf_toberead > 0 ) {
  119. Mf_currtime += readvarinum(); /* delta time */
  120. if (midifile_error) return;
  121. c = egetc();
  122. if (midifile_error) return;
  123. if ( sysexcontinue && c != 0xf7 ) {
  124. mferror("didn't find expected continuation of a sysex");
  125. return;
  126. }
  127. if ( (c & 0x80) == 0 ) { /* running status? */
  128. if ( status == 0 ) {
  129. mferror("unexpected running status");
  130. return;
  131. }
  132. running = 1;
  133. } else {
  134. status = c;
  135. running = 0;
  136. }
  137. needed = chantype[ (status>>4) & 0xf ];
  138. if ( needed ) { /* ie. is it a channel message? */
  139. if ( running )
  140. c1 = c;
  141. else {
  142. c1 = egetc();
  143. if (midifile_error) return;
  144. }
  145. chanmessage( status, c1, (needed>1) ? egetc() : 0 );
  146. if (midifile_error) return;
  147. continue;;
  148. }
  149. switch ( c ) {
  150. case 0xff: /* meta event */
  151. type = egetc();
  152. if (midifile_error) return;
  153. /* watch out - Don't combine the next 2 statements */
  154. lng = readvarinum();
  155. if (midifile_error) return;
  156. lookfor = Mf_toberead - lng;
  157. msginit();
  158. while ( Mf_toberead > lookfor ) {
  159. char c = egetc();
  160. if (midifile_error) return;
  161. msgadd(c);
  162. }
  163. metaevent(type);
  164. break;
  165. case 0xf0: /* start of system exclusive */
  166. /* watch out - Don't combine the next 2 statements */
  167. lng = readvarinum();
  168. if (midifile_error) return;
  169. lookfor = Mf_toberead - lng;
  170. msginit();
  171. msgadd(0xf0);
  172. while ( Mf_toberead > lookfor ) {
  173. c = egetc();
  174. if (midifile_error) return;
  175. msgadd(c);
  176. }
  177. if ( c==0xf7 || Mf_nomerge==0 )
  178. sysex();
  179. else
  180. sysexcontinue = 1; /* merge into next msg */
  181. break;
  182. case 0xf7: /* sysex continuation or arbitrary stuff */
  183. /* watch out - Don't combine the next 2 statements */
  184. lng = readvarinum();
  185. if (midifile_error) return;
  186. lookfor = Mf_toberead - lng;
  187. if ( ! sysexcontinue )
  188. msginit();
  189. while ( Mf_toberead > lookfor ) {
  190. c = egetc();
  191. if (midifile_error) return;
  192. msgadd(c);
  193. }
  194. if ( ! sysexcontinue ) {
  195. Mf_arbitrary(msgleng(), msg());
  196. }
  197. else if ( c == 0xf7 ) {
  198. sysex();
  199. sysexcontinue = 0;
  200. }
  201. break;
  202. default:
  203. badbyte(c);
  204. break;
  205. }
  206. }
  207. Mf_endtrack();
  208. return;
  209. }
  210. void Midifile_reader::badbyte(int c)
  211. {
  212. char buff[32];
  213. (void) sprintf(buff,"unexpected byte: 0x%02x",c);
  214. mferror(buff);
  215. }
  216. void Midifile_reader::metaevent(int type)
  217. {
  218. int leng = msgleng();
  219. char *m = msg();
  220. switch ( type ) {
  221. case 0x00:
  222. Mf_seqnum(to16bit(m[0],m[1]));
  223. break;
  224. case 0x01: /* Text event */
  225. case 0x02: /* Copyright notice */
  226. case 0x03: /* Sequence/Track name */
  227. case 0x04: /* Instrument name */
  228. case 0x05: /* Lyric */
  229. case 0x06: /* Marker */
  230. case 0x07: /* Cue point */
  231. case 0x08:
  232. case 0x09:
  233. case 0x0a:
  234. case 0x0b:
  235. case 0x0c:
  236. case 0x0d:
  237. case 0x0e:
  238. case 0x0f:
  239. /* These are all text events */
  240. Mf_text(type,leng,m);
  241. break;
  242. case 0x20:
  243. Mf_chanprefix(m[0]);
  244. break;
  245. case 0x21:
  246. Mf_portprefix(m[0]);
  247. break;
  248. case 0x2f: /* End of Track */
  249. Mf_eot();
  250. break;
  251. case 0x51: /* Set tempo */
  252. Mf_tempo(to32bit(0,m[0],m[1],m[2]));
  253. break;
  254. case 0x54:
  255. Mf_smpte(m[0],m[1],m[2],m[3],m[4]);
  256. break;
  257. case 0x58:
  258. Mf_timesig(m[0],m[1],m[2],m[3]);
  259. break;
  260. case 0x59:
  261. Mf_keysig(m[0],m[1]);
  262. break;
  263. case 0x7f:
  264. Mf_sqspecific(leng,m);
  265. break;
  266. default:
  267. Mf_metamisc(type,leng,m);
  268. }
  269. }
  270. void Midifile_reader::sysex()
  271. {
  272. Mf_sysex(msgleng(), msg());
  273. }
  274. void Midifile_reader::chanmessage(int status, int c1, int c2)
  275. {
  276. int chan = status & 0xf;
  277. switch ( status & 0xf0 ) {
  278. case NOTEOFF:
  279. Mf_off(chan,c1,c2);
  280. break;
  281. case NOTEON:
  282. Mf_on(chan,c1,c2);
  283. break;
  284. case PRESSURE:
  285. Mf_pressure(chan,c1,c2);
  286. break;
  287. case CONTROLLER:
  288. Mf_controller(chan,c1,c2);
  289. break;
  290. case PITCHBEND:
  291. Mf_pitchbend(chan,c1,c2);
  292. break;
  293. case PROGRAM:
  294. Mf_program(chan,c1);
  295. break;
  296. case CHANPRESSURE:
  297. Mf_chanpressure(chan,c1);
  298. break;
  299. }
  300. }
  301. /* readvarinum - read a varying-length number, and return the */
  302. /* number of characters it took. */
  303. long Midifile_reader::readvarinum()
  304. {
  305. long value;
  306. int c;
  307. c = egetc();
  308. if (midifile_error) return 0;
  309. value = (long) c;
  310. if ( c & 0x80 ) {
  311. value &= 0x7f;
  312. do {
  313. c = egetc();
  314. if (midifile_error) return 0;
  315. value = (value << 7) + (c & 0x7f);
  316. } while (c & 0x80);
  317. }
  318. return (value);
  319. }
  320. long Midifile_reader::to32bit(int c1, int c2, int c3, int c4)
  321. {
  322. long value = 0L;
  323. value = (c1 & 0xff);
  324. value = (value<<8) + (c2 & 0xff);
  325. value = (value<<8) + (c3 & 0xff);
  326. value = (value<<8) + (c4 & 0xff);
  327. return (value);
  328. }
  329. int Midifile_reader::to16bit(int c1, int c2)
  330. {
  331. return ((c1 & 0xff ) << 8) + (c2 & 0xff);
  332. }
  333. long Midifile_reader::read32bit()
  334. {
  335. int c1, c2, c3, c4;
  336. c1 = egetc(); if (midifile_error) return 0;
  337. c2 = egetc(); if (midifile_error) return 0;
  338. c3 = egetc(); if (midifile_error) return 0;
  339. c4 = egetc(); if (midifile_error) return 0;
  340. return to32bit(c1,c2,c3,c4);
  341. }
  342. int Midifile_reader::read16bit()
  343. {
  344. int c1, c2;
  345. c1 = egetc(); if (midifile_error) return 0;
  346. c2 = egetc(); if (midifile_error) return 0;
  347. return to16bit(c1,c2);
  348. }
  349. void Midifile_reader::mferror(const char *s)
  350. {
  351. Mf_error(s);
  352. midifile_error = 1;
  353. }
  354. /* The code below allows collection of a system exclusive message of */
  355. /* arbitrary length. The Msgbuff is expanded as necessary. The only */
  356. /* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */
  357. #define MSGINCREMENT 128
  358. Midifile_reader::Midifile_reader()
  359. {
  360. Mf_nomerge = 0;
  361. Mf_currtime = 0L;
  362. Mf_skipinit = 0;
  363. Mf_toberead = 0;
  364. Msgbuff = 0; /* message buffer */
  365. Msgsize = 0; /* Size of currently allocated Msg */
  366. Msgindex = 0; /* index of next available location in Msg */
  367. }
  368. void Midifile_reader::finalize()
  369. {
  370. if (Msgbuff) Mf_free(Msgbuff, Msgsize);
  371. Msgbuff = NULL;
  372. }
  373. void Midifile_reader::msginit()
  374. {
  375. Msgindex = 0;
  376. }
  377. char *Midifile_reader::msg()
  378. {
  379. return(Msgbuff);
  380. }
  381. int Midifile_reader::msgleng()
  382. {
  383. return(Msgindex);
  384. }
  385. void Midifile_reader::msgadd(int c)
  386. {
  387. /* If necessary, allocate larger message buffer. */
  388. if ( Msgindex >= Msgsize )
  389. msgenlarge();
  390. Msgbuff[Msgindex++] = c;
  391. }
  392. void Midifile_reader::msgenlarge()
  393. {
  394. char *newmess;
  395. char *oldmess = Msgbuff;
  396. int oldleng = Msgsize;
  397. Msgsize += MSGINCREMENT;
  398. newmess = (char *) Mf_malloc((sizeof(char) * Msgsize) );
  399. /* copy old message into larger new one */
  400. if ( oldmess != 0 ) {
  401. register char *p = newmess;
  402. register char *q = oldmess;
  403. register char *endq = &oldmess[oldleng];
  404. for ( ; q!=endq ; p++,q++ )
  405. *p = *q;
  406. Mf_free(oldmess, oldleng);
  407. }
  408. Msgbuff = newmess;
  409. }