fluid_midi.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:37k
源码类别:

midi

开发平台:

C/C++

  1. /* FluidSynth - A Software Synthesizer
  2.  *
  3.  * Copyright (C) 2003  Peter Hanappe and others.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public License
  7.  * as published by the Free Software Foundation; either version 2 of
  8.  * the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18.  * 02111-1307, USA
  19.  */
  20. #include "fluid_midi.h"
  21. #include "fluid_sys.h"
  22. #include "fluid_synth.h"
  23. #include "fluid_settings.h"
  24. static int fluid_midi_event_length(unsigned char event);
  25. /***************************************************************
  26.  *
  27.  *                      MIDIFILE
  28.  */
  29. /**
  30.  * Open a MIDI file and return a new MIDI file handle.
  31.  * @internal
  32.  * @param filename Path of file to open.
  33.  * @return New MIDI file handle or NULL on error.
  34.  */
  35. fluid_midi_file* new_fluid_midi_file(char* filename)
  36. {
  37. fluid_midi_file* mf;
  38. mf = FLUID_NEW(fluid_midi_file);
  39. if (mf == NULL) {
  40. FLUID_LOG(FLUID_ERR, "Out of memory");
  41. return NULL;
  42. }
  43. FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file));
  44. mf->c = -1;
  45. mf->running_status = -1;
  46. mf->fp = FLUID_FOPEN(filename, "rb");
  47. if (mf->fp == NULL) {
  48. FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file");
  49. FLUID_FREE(mf);
  50. return NULL;
  51. }
  52. if (fluid_midi_file_read_mthd(mf) != FLUID_OK) {
  53. FLUID_FREE(mf);
  54. return NULL;
  55. }
  56. return mf;
  57. }
  58. /**
  59.  * Delete a MIDI file handle.
  60.  * @internal
  61.  * @param mf MIDI file handle to close and free.
  62.  */
  63. void delete_fluid_midi_file(fluid_midi_file* mf)
  64. {
  65. if (mf == NULL) {
  66. return;
  67. }
  68. if (mf->fp != NULL) {
  69. FLUID_FCLOSE(mf->fp);
  70. }
  71. FLUID_FREE(mf);
  72. return;
  73. }
  74. /*
  75.  * Get the next byte in a MIDI file.
  76.  */
  77. int fluid_midi_file_getc(fluid_midi_file* mf)
  78. {
  79. unsigned char c;
  80. int n;
  81. if (mf->c >= 0) {
  82. c = mf->c;
  83. mf->c = -1;
  84. } else {
  85. n = FLUID_FREAD(&c, 1, 1, mf->fp);
  86. mf->trackpos++;
  87. }
  88. return (int) c;
  89. }
  90. /*
  91.  * fluid_midi_file_push
  92.  */
  93. int fluid_midi_file_push(fluid_midi_file* mf, int c)
  94. {
  95. mf->c = c;
  96. return FLUID_OK;
  97. }
  98. /*
  99.  * fluid_midi_file_read
  100.  */
  101. int fluid_midi_file_read(fluid_midi_file* mf, void* buf, int len)
  102. {
  103. int num = FLUID_FREAD(buf, 1, len, mf->fp);
  104. mf->trackpos += num;
  105. #if DEBUG
  106. if (num != len) {
  107. FLUID_LOG(FLUID_DBG, "Coulnd't read the requested number of bytes");
  108. }
  109. #endif
  110. return (num != len)? FLUID_FAILED : FLUID_OK;
  111. }
  112. /*
  113.  * fluid_midi_file_skip
  114.  */
  115. int fluid_midi_file_skip(fluid_midi_file* mf, int skip)
  116. {
  117. int err = FLUID_FSEEK(mf->fp, skip, SEEK_CUR);
  118. if (err) {
  119. FLUID_LOG(FLUID_ERR, "Failed to seek position in file");
  120. return FLUID_FAILED;
  121. }
  122. return FLUID_OK;
  123. }
  124. /*
  125.  * fluid_midi_file_read_mthd
  126.  */
  127. int fluid_midi_file_read_mthd(fluid_midi_file* mf)
  128. {
  129. char mthd[15];
  130. if (fluid_midi_file_read(mf, mthd, 14) != FLUID_OK) {
  131. return FLUID_FAILED;
  132. }
  133. if ((FLUID_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6) || (mthd[9] > 2)) {
  134. FLUID_LOG(FLUID_ERR, "Doesn't look like a MIDI file: invalid MThd header");
  135. return FLUID_FAILED;
  136. }
  137. mf->type = mthd[9];
  138. mf->ntracks = (unsigned) mthd[11];
  139. mf->ntracks += (unsigned int) (mthd[10]) << 16;
  140. if((mthd[12]) < 0){
  141. mf->uses_smpte = 1;
  142. mf->smpte_fps = -mthd[12];
  143. mf->smpte_res = (unsigned) mthd[13];
  144. FLUID_LOG(FLUID_ERR, "File uses SMPTE timing -- Not implemented yet");
  145. return FLUID_FAILED;
  146. } else {
  147. mf->uses_smpte = 0;
  148. mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
  149. FLUID_LOG(FLUID_DBG, "Division=%d", mf->division);
  150. }
  151. return FLUID_OK;
  152. }
  153. /*
  154.  * fluid_midi_file_load_tracks
  155.  */
  156. int fluid_midi_file_load_tracks(fluid_midi_file* mf, fluid_player_t* player)
  157. {
  158. int i;
  159. for (i = 0; i < mf->ntracks; i++) {
  160. if (fluid_midi_file_read_track(mf, player, i) != FLUID_OK) {
  161. return FLUID_FAILED;
  162. }
  163. }
  164. return FLUID_OK;
  165. }
  166. /*
  167.  * fluid_isasciistring
  168.  */
  169. int fluid_isasciistring(char* s)
  170. {
  171. int i;
  172. int len = (int) FLUID_STRLEN(s);
  173. for (i = 0; i < len; i++) {
  174. if (!fluid_isascii(s[i])) {
  175. return 0;
  176. }
  177. }
  178. return 1;
  179. }
  180. /*
  181.  * fluid_getlength
  182.  */
  183. long fluid_getlength(unsigned char *s)
  184. {
  185. long i = 0;
  186. i = s[3] | (s[2]<<8) | (s[1]<<16) | (s[0]<<24);
  187. return i;
  188. }
  189. /*
  190.  * fluid_midi_file_read_tracklen
  191.  */
  192. int fluid_midi_file_read_tracklen(fluid_midi_file* mf)
  193. {
  194. unsigned char length[5];
  195. if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
  196. return FLUID_FAILED;
  197. }
  198. mf->tracklen = fluid_getlength(length);
  199. mf->trackpos = 0;
  200. mf->eot = 0;
  201. return FLUID_OK;
  202. }
  203. /*
  204.  * fluid_midi_file_eot
  205.  */
  206. int fluid_midi_file_eot(fluid_midi_file* mf)
  207. {
  208. #if DEBUG
  209. if (mf->trackpos > mf->tracklen) {
  210. printf("track overrun: %d > %dn", mf->trackpos, mf->tracklen);
  211. }
  212. #endif
  213. return mf->eot || (mf->trackpos >= mf->tracklen);
  214. }
  215. /*
  216.  * fluid_midi_file_read_track
  217.  */
  218. int fluid_midi_file_read_track(fluid_midi_file* mf, fluid_player_t* player, int num)
  219. {
  220. fluid_track_t* track;
  221. unsigned char id[5], length[5];
  222. int found_track = 0;
  223. int skip;
  224. if (fluid_midi_file_read(mf, id, 4) != FLUID_OK) {
  225. return FLUID_FAILED;
  226. }
  227. id[4]='';
  228. mf->dtime = 0;
  229. while (!found_track){
  230. if (fluid_isasciistring((char*) id) == 0) {
  231. FLUID_LOG(FLUID_ERR, "An non-ascii track header found, corrupt file");
  232. return FLUID_FAILED;
  233. } else if (strcmp((char*) id, "MTrk") == 0) {
  234. found_track = 1;
  235. if (fluid_midi_file_read_tracklen(mf) != FLUID_OK) {
  236. return FLUID_FAILED;
  237. }
  238. track = new_fluid_track(num);
  239. if (track == NULL) {
  240. FLUID_LOG(FLUID_ERR, "Out of memory");
  241. return FLUID_FAILED;
  242. }
  243. while (!fluid_midi_file_eot(mf)) {
  244. if (fluid_midi_file_read_event(mf, track) != FLUID_OK) {
  245. return FLUID_FAILED;
  246. }
  247. }
  248. /* Skip remaining track data, if any */
  249. if (mf->trackpos < mf->tracklen)
  250. fluid_midi_file_skip (mf, mf->tracklen - mf->trackpos);
  251. fluid_player_add_track(player, track);
  252. } else {
  253. found_track = 0;
  254. if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
  255. return FLUID_FAILED;
  256. }
  257. skip = fluid_getlength(length);
  258. /*        fseek(mf->fp, skip, SEEK_CUR); */
  259. if (fluid_midi_file_skip(mf, skip) != FLUID_OK) {
  260. return FLUID_FAILED;
  261. }
  262. }
  263. }
  264. if (feof(mf->fp)) {
  265. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  266. return FLUID_FAILED;
  267. }
  268. return FLUID_OK;
  269. }
  270. /*
  271.  * fluid_midi_file_read_varlen
  272.  */
  273. int fluid_midi_file_read_varlen(fluid_midi_file* mf)
  274. {
  275. int i;
  276. int c;
  277. mf->varlen = 0;
  278. for (i = 0;;i++) {
  279. if (i == 4) {
  280. FLUID_LOG(FLUID_ERR, "Invalid variable length number");
  281. return FLUID_FAILED;
  282. }
  283. c = fluid_midi_file_getc(mf);
  284. if (c < 0) {
  285. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  286. return FLUID_FAILED;
  287. }
  288. if (c & 0x80){
  289. mf->varlen |= (int) (c & 0x7F);
  290. mf->varlen <<= 7;
  291. } else {
  292. mf->varlen += c;
  293. break;
  294. }
  295. }
  296. return FLUID_OK;
  297. }
  298. /*
  299.  * fluid_midi_file_read_event
  300.  */
  301. int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
  302. {
  303. int status;
  304. int type;
  305. int tempo;
  306. unsigned char* metadata = NULL;
  307. unsigned char* dyn_buf = NULL;
  308. unsigned char static_buf[256];
  309. int nominator, denominator, clocks, notes, sf, mi;
  310. fluid_midi_event_t* evt;
  311. int channel = 0;
  312. int param1 = 0;
  313. int param2 = 0;
  314. int size;
  315. /* read the delta-time of the event */
  316. if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
  317. return FLUID_FAILED;
  318. }
  319. mf->dtime += mf->varlen;
  320. /* read the status byte */
  321. status = fluid_midi_file_getc(mf);
  322. if (status < 0) {
  323. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  324. return FLUID_FAILED;
  325. }
  326. /* not a valid status byte: use the running status instead */
  327. if ((status & 0x80) == 0) {
  328. if ((mf->running_status & 0x80) == 0) {
  329. FLUID_LOG(FLUID_ERR, "Undefined status and invalid running status");
  330. return FLUID_FAILED;
  331. }
  332. fluid_midi_file_push(mf, status);
  333. status = mf->running_status;
  334. }
  335. /* check what message we have */
  336. mf->running_status = status;
  337. if ((status == MIDI_SYSEX)) {     /* system exclusif */
  338. /* read the length of the message */
  339. if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
  340. return FLUID_FAILED;
  341. }
  342. if (mf->varlen) {
  343. FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
  344. metadata = FLUID_MALLOC(mf->varlen + 1);
  345. if (metadata == NULL) {
  346. FLUID_LOG(FLUID_PANIC, "Out of memory");
  347. return FLUID_FAILED;
  348. }
  349. /* read the data of the message */
  350. if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
  351. FLUID_FREE (metadata);
  352. return FLUID_FAILED;
  353. }
  354. evt = new_fluid_midi_event();
  355. if (evt == NULL) {
  356. FLUID_LOG(FLUID_ERR, "Out of memory");
  357. FLUID_FREE (metadata);
  358. return FLUID_FAILED;
  359. }
  360. evt->dtime = mf->dtime;
  361. size = mf->varlen;
  362. if (metadata[mf->varlen - 1] == MIDI_EOX)
  363. size--;
  364. /* Add SYSEX event and indicate that its dynamically allocated and should be freed with event */
  365. fluid_midi_event_set_sysex (evt, metadata, size, TRUE);
  366. fluid_track_add_event (track, evt);
  367. mf->dtime = 0;
  368. }
  369. return FLUID_OK;
  370. } else if (status == MIDI_META_EVENT) {             /* meta events */
  371. int result = FLUID_OK;
  372. /* get the type of the meta message */
  373. type = fluid_midi_file_getc(mf);
  374. if (type < 0) {
  375. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  376. return FLUID_FAILED;
  377. }
  378. /* get the length of the data part */
  379. if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
  380. return FLUID_FAILED;
  381. }
  382. if (mf->varlen < 255) {
  383. metadata = &static_buf[0];
  384. } else {
  385. FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
  386. dyn_buf = FLUID_MALLOC(mf->varlen + 1);
  387. if (dyn_buf == NULL) {
  388. FLUID_LOG(FLUID_PANIC, "Out of memory");
  389. return FLUID_FAILED;
  390. }
  391. metadata = dyn_buf;
  392. }
  393. /* read the data */
  394. if (mf->varlen)
  395. {
  396. if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
  397. if (dyn_buf) {
  398. FLUID_FREE(dyn_buf);
  399. }
  400. return FLUID_FAILED;
  401. }
  402. }
  403. /* handle meta data */
  404. switch (type) {
  405. case MIDI_COPYRIGHT:
  406. metadata[mf->varlen] = 0;
  407. break;
  408. case MIDI_TRACK_NAME:
  409. metadata[mf->varlen] = 0;
  410. fluid_track_set_name(track, (char*) metadata);
  411. break;
  412. case MIDI_INST_NAME:
  413. metadata[mf->varlen] = 0;
  414. break;
  415. case MIDI_LYRIC:
  416. break;
  417. case MIDI_MARKER:
  418. break;
  419. case MIDI_CUE_POINT:
  420. break; /* don't care much for text events */
  421. case MIDI_EOT:
  422. if (mf->varlen != 0) {
  423. FLUID_LOG(FLUID_ERR, "Invalid length for EndOfTrack event");
  424. result = FLUID_FAILED;
  425. break;
  426. }
  427. mf->eot = 1;
  428. break;
  429. case MIDI_SET_TEMPO:
  430. if (mf->varlen != 3) {
  431. FLUID_LOG(FLUID_ERR, "Invalid length for SetTempo meta event");
  432. result = FLUID_FAILED;
  433. break;
  434. }
  435. tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
  436. evt = new_fluid_midi_event();
  437. if (evt == NULL) {
  438. FLUID_LOG(FLUID_ERR, "Out of memory");
  439. result = FLUID_FAILED;
  440. break;
  441. }
  442. evt->dtime = mf->dtime;
  443. evt->type = MIDI_SET_TEMPO;
  444. evt->channel = 0;
  445. evt->param1 = tempo;
  446. evt->param2 = 0;
  447. fluid_track_add_event(track, evt);
  448. mf->dtime = 0;
  449. break;
  450. case MIDI_SMPTE_OFFSET:
  451. if (mf->varlen != 5) {
  452. FLUID_LOG(FLUID_ERR, "Invalid length for SMPTE Offset meta event");
  453. result = FLUID_FAILED;
  454. break;
  455. }
  456. break; /* we don't use smtp */
  457. case MIDI_TIME_SIGNATURE:
  458. if (mf->varlen != 4) {
  459. FLUID_LOG(FLUID_ERR, "Invalid length for TimeSignature meta event");
  460. result = FLUID_FAILED;
  461. break;
  462. }
  463. nominator = metadata[0];
  464. denominator = pow(2.0, (double) metadata[1]);
  465. clocks = metadata[2];
  466. notes = metadata[3];
  467. FLUID_LOG(FLUID_DBG, "signature=%d/%d, metronome=%d, 32nd-notes=%d",
  468.   nominator, denominator, clocks, notes);
  469. break;
  470. case MIDI_KEY_SIGNATURE:
  471. if (mf->varlen != 2) {
  472. FLUID_LOG(FLUID_ERR, "Invalid length for KeySignature meta event");
  473. result = FLUID_FAILED;
  474. break;
  475. }
  476. sf = metadata[0];
  477. mi = metadata[1];
  478. break;
  479. case MIDI_SEQUENCER_EVENT:
  480. break;
  481. default:
  482. break;
  483. }
  484. if (dyn_buf) {
  485. FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__);
  486. FLUID_FREE(dyn_buf);
  487. }
  488. return result;
  489. } else {                /* channel messages */
  490. type = status & 0xf0;
  491. channel = status & 0x0f;
  492. /* all channel message have at least 1 byte of associated data */
  493. if ((param1 = fluid_midi_file_getc(mf)) < 0) {
  494. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  495. return FLUID_FAILED;
  496. }
  497. switch (type) {
  498. case NOTE_ON:
  499. if ((param2 = fluid_midi_file_getc(mf)) < 0) {
  500. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  501. return FLUID_FAILED;
  502. }
  503. break;
  504. case NOTE_OFF:
  505. if ((param2 = fluid_midi_file_getc(mf)) < 0) {
  506. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  507. return FLUID_FAILED;
  508. }
  509. break;
  510. case KEY_PRESSURE:
  511. if ((param2 = fluid_midi_file_getc(mf)) < 0) {
  512. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  513. return FLUID_FAILED;
  514. }
  515. break;
  516. case CONTROL_CHANGE:
  517. if ((param2 = fluid_midi_file_getc(mf)) < 0) {
  518. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  519. return FLUID_FAILED;
  520. }
  521. break;
  522. case PROGRAM_CHANGE:
  523. break;
  524. case CHANNEL_PRESSURE:
  525. break;
  526. case PITCH_BEND:
  527. if ((param2 = fluid_midi_file_getc(mf)) < 0) {
  528. FLUID_LOG(FLUID_ERR, "Unexpected end of file");
  529. return FLUID_FAILED;
  530. }
  531. param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
  532. param2 = 0;
  533. break;
  534. default:
  535. /* Can't possibly happen !? */
  536. FLUID_LOG(FLUID_ERR, "Unrecognized MIDI event");
  537. return FLUID_FAILED;
  538. }
  539. evt = new_fluid_midi_event();
  540. if (evt == NULL) {
  541. FLUID_LOG(FLUID_ERR, "Out of memory");
  542. return FLUID_FAILED;
  543. }
  544. evt->dtime = mf->dtime;
  545. evt->type = type;
  546. evt->channel = channel;
  547. evt->param1 = param1;
  548. evt->param2 = param2;
  549. fluid_track_add_event(track, evt);
  550. mf->dtime = 0;
  551. }
  552. return FLUID_OK;
  553. }
  554. /*
  555.  * fluid_midi_file_get_division
  556.  */
  557. int fluid_midi_file_get_division(fluid_midi_file* midifile)
  558. {
  559. return midifile->division;
  560. }
  561. /******************************************************
  562.  *
  563.  *     fluid_track_t
  564.  */
  565. /**
  566.  * Create a MIDI event structure.
  567.  * @return New MIDI event structure or NULL when out of memory.
  568.  */
  569. fluid_midi_event_t* new_fluid_midi_event()
  570. {
  571. fluid_midi_event_t* evt;
  572. evt = FLUID_NEW(fluid_midi_event_t);
  573. if (evt == NULL) {
  574. FLUID_LOG(FLUID_ERR, "Out of memory");
  575. return NULL;
  576. }
  577. evt->dtime = 0;
  578. evt->type = 0;
  579. evt->channel = 0;
  580. evt->param1 = 0;
  581. evt->param2 = 0;
  582. evt->next = NULL;
  583. evt->paramptr = NULL;
  584. return evt;
  585. }
  586. /**
  587.  * Delete MIDI event structure.
  588.  * @param evt MIDI event structure
  589.  * @return Always returns #FLUID_OK
  590.  */
  591. int delete_fluid_midi_event(fluid_midi_event_t* evt)
  592. {
  593. fluid_midi_event_t *temp;
  594. while (evt)
  595. {
  596. temp = evt->next;
  597. /* Dynamic SYSEX event? - free (param2 indicates if dynamic) */
  598. if (evt->type == MIDI_SYSEX && evt->paramptr && evt->param2)
  599. FLUID_FREE (evt->paramptr);
  600. FLUID_FREE(evt);
  601. evt = temp;
  602. }
  603. return FLUID_OK;
  604. }
  605. /**
  606.  * Get the event type field of a MIDI event structure.
  607.  * @param evt MIDI event structure
  608.  * @return Event type field (MIDI status byte without channel)
  609.  */
  610. int fluid_midi_event_get_type(fluid_midi_event_t* evt)
  611. {
  612. return evt->type;
  613. }
  614. /**
  615.  * Set the event type field of a MIDI event structure.
  616.  * @param evt MIDI event structure
  617.  * @param type Event type field (MIDI status byte without channel)
  618.  * @return Always returns #FLUID_OK
  619.  */
  620. int fluid_midi_event_set_type(fluid_midi_event_t* evt, int type)
  621. {
  622. evt->type = type;
  623. return FLUID_OK;
  624. }
  625. /**
  626.  * Get the channel field of a MIDI event structure.
  627.  * @param evt MIDI event structure
  628.  * @return Channel field
  629.  */
  630. int fluid_midi_event_get_channel(fluid_midi_event_t* evt)
  631. {
  632. return evt->channel;
  633. }
  634. /**
  635.  * Set the channel field of a MIDI event structure.
  636.  * @param evt MIDI event structure
  637.  * @param chan MIDI channel field
  638.  * @return Always returns #FLUID_OK
  639.  */
  640. int fluid_midi_event_set_channel(fluid_midi_event_t* evt, int chan)
  641. {
  642. evt->channel = chan;
  643. return FLUID_OK;
  644. }
  645. /**
  646.  * Get the key field of a MIDI event structure.
  647.  * @param evt MIDI event structure
  648.  * @return MIDI note number (0-127)
  649.  */
  650. int fluid_midi_event_get_key(fluid_midi_event_t* evt)
  651. {
  652. return evt->param1;
  653. }
  654. /**
  655.  * Set the key field of a MIDI event structure.
  656.  * @param evt MIDI event structure
  657.  * @param v MIDI note number (0-127)
  658.  * @return Always returns #FLUID_OK
  659.  */
  660. int fluid_midi_event_set_key(fluid_midi_event_t* evt, int v)
  661. {
  662. evt->param1 = v;
  663. return FLUID_OK;
  664. }
  665. /**
  666.  * Get the velocity field of a MIDI event structure.
  667.  * @param evt MIDI event structure
  668.  * @return MIDI velocity number (0-127)
  669.  */
  670. int fluid_midi_event_get_velocity(fluid_midi_event_t* evt)
  671. {
  672. return evt->param2;
  673. }
  674. /**
  675.  * Set the velocity field of a MIDI event structure.
  676.  * @param evt MIDI event structure
  677.  * @param v MIDI velocity value
  678.  * @return Always returns #FLUID_OK
  679.  */
  680. int fluid_midi_event_set_velocity(fluid_midi_event_t* evt, int v)
  681. {
  682. evt->param2 = v;
  683. return FLUID_OK;
  684. }
  685. /**
  686.  * Get the control number of a MIDI event structure.
  687.  * @param evt MIDI event structure
  688.  * @return MIDI control number
  689.  */
  690. int fluid_midi_event_get_control(fluid_midi_event_t* evt)
  691. {
  692. return evt->param1;
  693. }
  694. /**
  695.  * Set the control field of a MIDI event structure.
  696.  * @param evt MIDI event structure
  697.  * @param v MIDI control number
  698.  * @return Always returns #FLUID_OK
  699.  */
  700. int fluid_midi_event_set_control(fluid_midi_event_t* evt, int v)
  701. {
  702. evt->param1 = v;
  703. return FLUID_OK;
  704. }
  705. /**
  706.  * Get the value field from a MIDI event structure.
  707.  * @param evt MIDI event structure
  708.  * @return Value field
  709.  */
  710. int fluid_midi_event_get_value(fluid_midi_event_t* evt)
  711. {
  712. return evt->param2;
  713. }
  714. /**
  715.  * Set the value field of a MIDI event structure.
  716.  * @param evt MIDI event structure
  717.  * @param v Value to assign
  718.  * @return Always returns #FLUID_OK
  719.  */
  720. int fluid_midi_event_set_value(fluid_midi_event_t* evt, int v)
  721. {
  722. evt->param2 = v;
  723. return FLUID_OK;
  724. }
  725. /**
  726.  * Get the program field of a MIDI event structure.
  727.  * @param evt MIDI event structure
  728.  * @return MIDI program number (0-127)
  729.  */
  730. int fluid_midi_event_get_program(fluid_midi_event_t* evt)
  731. {
  732. return evt->param1;
  733. }
  734. /**
  735.  * Set the program field of a MIDI event structure.
  736.  * @param evt MIDI event structure
  737.  * @param val MIDI program number (0-127)
  738.  * @return Always returns #FLUID_OK
  739.  */
  740. int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val)
  741. {
  742. evt->param1 = val;
  743. return FLUID_OK;
  744. }
  745. /**
  746.  * Get the pitch field of a MIDI event structure.
  747.  * @param evt MIDI event structure
  748.  * @return Pitch value (14 bit value, 0-16383, 8192 is center)
  749.  */
  750. int fluid_midi_event_get_pitch(fluid_midi_event_t* evt)
  751. {
  752. return evt->param1;
  753. }
  754. /**
  755.  * Set the pitch field of a MIDI event structure.
  756.  * @param evt MIDI event structure
  757.  * @param val Pitch value (14 bit value, 0-16383, 8192 is center)
  758.  * @return Always returns FLUID_OK
  759.  */
  760. int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val)
  761. {
  762. evt->param1 = val;
  763. return FLUID_OK;
  764. }
  765. /**
  766.  * Assign sysex data to a MIDI event structure.
  767.  * @param evt MIDI event structure
  768.  * @param data Pointer to SYSEX data
  769.  * @param size Size of SYSEX data
  770.  * @param dynamic TRUE if the SYSEX data has been dynamically allocated and
  771.  *   should be freed when the event is freed (only applies if event gets destroyed
  772.  *   with delete_fluid_midi_event())
  773.  * @return Always returns #FLUID_OK
  774.  *
  775.  * NOTE: Unlike the other event assignment functions, this one sets evt->type.
  776.  */
  777. int
  778. fluid_midi_event_set_sysex(fluid_midi_event_t* evt, void *data, int size, int dynamic)
  779. {
  780. evt->type = MIDI_SYSEX;
  781. evt->paramptr = data;
  782. evt->param1 = size;
  783. evt->param2 = dynamic;
  784. return FLUID_OK;
  785. }
  786. /******************************************************
  787.  *
  788.  *     fluid_track_t
  789.  */
  790. /*
  791.  * new_fluid_track
  792.  */
  793. fluid_track_t* new_fluid_track(int num)
  794. {
  795. fluid_track_t* track;
  796. track = FLUID_NEW(fluid_track_t);
  797. if (track == NULL) {
  798. return NULL;
  799. }
  800. track->name = NULL;
  801. track->num = num;
  802. track->first = NULL;
  803. track->cur = NULL;
  804. track->last = NULL;
  805. track->ticks = 0;
  806. return track;
  807. }
  808. /*
  809.  * delete_fluid_track
  810.  */
  811. int delete_fluid_track(fluid_track_t* track)
  812. {
  813. if (track->name != NULL) {
  814. FLUID_FREE(track->name);
  815. }
  816. if (track->first != NULL) {
  817. delete_fluid_midi_event(track->first);
  818. }
  819. FLUID_FREE(track);
  820. return FLUID_OK;
  821. }
  822. /*
  823.  * fluid_track_set_name
  824.  */
  825. int fluid_track_set_name(fluid_track_t* track, char* name)
  826. {
  827. int len;
  828. if (track->name != NULL) {
  829. FLUID_FREE(track->name);
  830. }
  831. if (name == NULL) {
  832. track->name = NULL;
  833. return FLUID_OK;
  834. }
  835. len = FLUID_STRLEN(name);
  836. track->name = FLUID_MALLOC(len + 1);
  837. if (track->name == NULL) {
  838. FLUID_LOG(FLUID_ERR, "Out of memory");
  839. return FLUID_FAILED;
  840. }
  841. FLUID_STRCPY(track->name, name);
  842. return FLUID_OK;
  843. }
  844. /*
  845.  * fluid_track_get_name
  846.  */
  847. char* fluid_track_get_name(fluid_track_t* track)
  848. {
  849. return track->name;
  850. }
  851. /*
  852.  * fluid_track_get_duration
  853.  */
  854. int fluid_track_get_duration(fluid_track_t* track)
  855. {
  856. int time = 0;
  857. fluid_midi_event_t* evt = track->first;
  858. while (evt != NULL) {
  859. time += evt->dtime;
  860. evt = evt->next;
  861. }
  862. return time;
  863. }
  864. /*
  865.  * fluid_track_count_events
  866.  */
  867. int fluid_track_count_events(fluid_track_t* track, int* on, int* off)
  868. {
  869. fluid_midi_event_t* evt = track->first;
  870. while (evt != NULL) {
  871. if (evt->type == NOTE_ON) {
  872. (*on)++;
  873. } else if (evt->type == NOTE_OFF) {
  874. (*off)++;
  875. }
  876. evt = evt->next;
  877. }
  878. return FLUID_OK;
  879. }
  880. /*
  881.  * fluid_track_add_event
  882.  */
  883. int fluid_track_add_event(fluid_track_t* track, fluid_midi_event_t* evt)
  884. {
  885. evt->next = NULL;
  886. if (track->first == NULL) {
  887. track->first = evt;
  888. track->cur = evt;
  889. track->last = evt;
  890. } else {
  891. track->last->next = evt;
  892. track->last = evt;
  893. }
  894. return FLUID_OK;
  895. }
  896. /*
  897.  * fluid_track_first_event
  898.  */
  899. fluid_midi_event_t* fluid_track_first_event(fluid_track_t* track)
  900. {
  901. track->cur = track->first;
  902. return track->cur;
  903. }
  904. /*
  905.  * fluid_track_next_event
  906.  */
  907. fluid_midi_event_t* fluid_track_next_event(fluid_track_t* track)
  908. {
  909. if (track->cur != NULL) {
  910. track->cur = track->cur->next;
  911. }
  912. return track->cur;
  913. }
  914. /*
  915.  * fluid_track_reset
  916.  */
  917. int
  918. fluid_track_reset(fluid_track_t* track)
  919. {
  920. track->ticks = 0;
  921. track->cur = track->first;
  922. return FLUID_OK;
  923. }
  924. /*
  925.  * fluid_track_send_events
  926.  */
  927. int
  928. fluid_track_send_events(fluid_track_t* track,
  929. fluid_synth_t* synth,
  930. fluid_player_t* player,
  931. unsigned int ticks)
  932. {
  933. int status = FLUID_OK;
  934. fluid_midi_event_t* event;
  935. while (1) {
  936. event = track->cur;
  937. if (event == NULL) {
  938. return status;
  939. }
  940. /*  printf("track=%02dtticks=%05uttrack=%05utdtime=%05utnext=%05un", */
  941. /*         track->num, */
  942. /*         ticks, */
  943. /*         track->ticks, */
  944. /*         event->dtime, */
  945. /*         track->ticks + event->dtime); */
  946. if (track->ticks + event->dtime > ticks) {
  947. return status;
  948. }
  949. track->ticks += event->dtime;
  950. if (event->type != MIDI_SET_TEMPO)
  951. fluid_synth_handle_midi_event (synth, event);
  952. else if (player) fluid_player_set_midi_tempo (player, event->param1);
  953. fluid_track_next_event(track);
  954. }
  955. return status;
  956. }
  957. /******************************************************
  958.  *
  959.  *     fluid_player
  960.  */
  961. /**
  962.  * Create a new MIDI player.
  963.  * @param synth Fluid synthesizer instance to create player for
  964.  * @return New MIDI player instance or NULL on error (out of memory)
  965.  */
  966. fluid_player_t* new_fluid_player(fluid_synth_t* synth)
  967. {
  968. int i;
  969. fluid_player_t* player;
  970. player = FLUID_NEW(fluid_player_t);
  971. if (player == NULL) {
  972. FLUID_LOG(FLUID_ERR, "Out of memory");
  973. return NULL;
  974. }
  975. player->status = FLUID_PLAYER_READY;
  976. player->loop = 1;
  977. player->ntracks = 0;
  978. for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
  979. player->track[i] = NULL;
  980. }
  981. player->synth = synth;
  982. player->system_timer = NULL;
  983. player->sample_timer = NULL;
  984. player->playlist = NULL;
  985. player->currentfile = NULL;
  986. player->division = 0;
  987. player->send_program_change = 1;
  988. player->miditempo = 480000;
  989. player->deltatime = 4.0;
  990. player->use_system_timer = 
  991. fluid_settings_str_equal(synth->settings, "player.timing-source", "system");
  992. fluid_settings_getint (synth->settings, "player.reset-synth", &i);
  993. player->reset_synth_between_songs = i;
  994. return player;
  995. }
  996. /**
  997.  * Delete a MIDI player instance.
  998.  * @param player MIDI player instance
  999.  * @return Always returns #FLUID_OK
  1000.  */
  1001. int delete_fluid_player(fluid_player_t* player)
  1002. {
  1003. fluid_list_t* q;
  1004. if (player == NULL) {
  1005. return FLUID_OK;
  1006. }
  1007. fluid_player_stop(player);
  1008. fluid_player_reset(player);
  1009. while (player->playlist != NULL) {
  1010. q = player->playlist->next;
  1011. FLUID_FREE(player->playlist->data);
  1012. delete1_fluid_list(player->playlist);
  1013. player->playlist = q;
  1014. }
  1015. FLUID_FREE(player);
  1016. return FLUID_OK;
  1017. }
  1018. /**
  1019.  * Registers settings related to the MIDI player
  1020.  */
  1021. void fluid_player_settings(fluid_settings_t* settings)
  1022. {
  1023. /* player.timing-source can be either "system" (use system timer) 
  1024. or "sample" (use timer based on number of written samples) */
  1025. fluid_settings_register_str(settings, "player.timing-source", "sample", 0, NULL, NULL);
  1026. fluid_settings_add_option(settings, "player.timing-source", "sample");
  1027. fluid_settings_add_option(settings, "player.timing-source", "system");
  1028. /* Selects whether the player should reset the synth between songs, or not. */
  1029. fluid_settings_register_int(settings, "player.reset-synth", 1, 0, 1,
  1030.                                     FLUID_HINT_TOGGLED, NULL, NULL);
  1031. }
  1032. int fluid_player_reset(fluid_player_t* player)
  1033. {
  1034. int i;
  1035. for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
  1036. if (player->track[i] != NULL) {
  1037. delete_fluid_track(player->track[i]);
  1038. player->track[i] = NULL;
  1039. }
  1040. }
  1041. /* player->current_file = NULL; */
  1042. /* player->status = FLUID_PLAYER_READY; */
  1043. /* player->loop = 1; */
  1044. player->ntracks = 0;
  1045. player->division = 0;
  1046. player->send_program_change = 1;
  1047. player->miditempo = 480000;
  1048. player->deltatime = 4.0;
  1049. return 0;
  1050. }
  1051. /*
  1052.  * fluid_player_add_track
  1053.  */
  1054. int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track)
  1055. {
  1056. if (player->ntracks < MAX_NUMBER_OF_TRACKS) {
  1057. player->track[player->ntracks++] = track;
  1058. return FLUID_OK;
  1059. } else {
  1060. return FLUID_FAILED;
  1061. }
  1062. }
  1063. /*
  1064.  * fluid_player_count_tracks
  1065.  */
  1066. int fluid_player_count_tracks(fluid_player_t* player)
  1067. {
  1068. return player->ntracks;
  1069. }
  1070. /*
  1071.  * fluid_player_get_track
  1072.  */
  1073. fluid_track_t* fluid_player_get_track(fluid_player_t* player, int i)
  1074. {
  1075. if ((i >= 0) && (i < MAX_NUMBER_OF_TRACKS)) {
  1076. return player->track[i];
  1077. } else {
  1078. return NULL;
  1079. }
  1080. }
  1081. /**
  1082.  * Add a MIDI file to a player queue.
  1083.  * @param player MIDI player instance
  1084.  * @param midifile File name of the MIDI file to add
  1085.  * @return #FLUID_OK
  1086.  */
  1087. int
  1088. fluid_player_add(fluid_player_t* player, const char* midifile)
  1089. {
  1090. char *s = FLUID_STRDUP(midifile);
  1091. player->playlist = fluid_list_append(player->playlist, s);
  1092. return FLUID_OK;
  1093. }
  1094. /*
  1095.  * fluid_player_load
  1096.  */
  1097. int fluid_player_load(fluid_player_t* player, char *filename)
  1098. {
  1099. fluid_midi_file* midifile;
  1100. midifile = new_fluid_midi_file(filename);
  1101. if (midifile == NULL) {
  1102. return FLUID_FAILED;
  1103. }
  1104. player->division = fluid_midi_file_get_division(midifile);
  1105. fluid_player_set_midi_tempo(player, player->miditempo); // Update deltatime
  1106. /*FLUID_LOG(FLUID_DBG, "quarter note division=%dn", player->division); */
  1107. if (fluid_midi_file_load_tracks(midifile, player) != FLUID_OK){
  1108. return FLUID_FAILED;
  1109. }
  1110. delete_fluid_midi_file(midifile);
  1111. return FLUID_OK;
  1112. }
  1113. void fluid_player_advancefile(fluid_player_t* player)
  1114. {
  1115. if (player->playlist == NULL) {
  1116. return; /* No files to play */
  1117. }
  1118. if (player->currentfile != NULL) {
  1119. player->currentfile = fluid_list_next(player->currentfile);
  1120. }
  1121. if (player->currentfile == NULL) {
  1122. if (player->loop == 0) {
  1123. return; /* We're done playing */ 
  1124. }
  1125. if (player->loop > 0) {
  1126. player->loop--;
  1127. player->currentfile = player->playlist;
  1128. }
  1129. void fluid_player_playlist_load(fluid_player_t* player, unsigned int msec)
  1130. {
  1131. char* current_filename;
  1132. int i;
  1133. do {
  1134. fluid_player_advancefile(player);
  1135. if (player->currentfile == NULL) { 
  1136. /* Failed to find next song, probably since we're finished */
  1137. player->status = FLUID_PLAYER_DONE;
  1138. return;
  1139. }
  1140. fluid_player_reset(player);
  1141. current_filename = (char*) player->currentfile->data;
  1142. FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile %s", __FILE__, __LINE__, current_filename);
  1143. } while (fluid_player_load(player, current_filename) != FLUID_OK);
  1144. /* Successfully loaded midi file */
  1145. player->begin_msec = msec;
  1146. player->start_msec = msec;
  1147. player->start_ticks = 0;
  1148. player->cur_ticks = 0;
  1149. if (player->reset_synth_between_songs) {
  1150. fluid_synth_system_reset(player->synth);
  1151. }
  1152. for (i = 0; i < player->ntracks; i++) {
  1153. if (player->track[i] != NULL) {
  1154. fluid_track_reset(player->track[i]);
  1155. }
  1156. }
  1157. }
  1158. /*
  1159.  * fluid_player_callback
  1160.  */
  1161. int fluid_player_callback(void* data, unsigned int msec)
  1162. {
  1163. int i;
  1164. int loadnextfile;
  1165. int status = FLUID_PLAYER_DONE;
  1166. fluid_player_t* player;
  1167. fluid_synth_t* synth;
  1168. player = (fluid_player_t*) data;
  1169. synth = player->synth;
  1170. loadnextfile = player->currentfile == NULL ? 1 : 0; 
  1171. do {
  1172. if (loadnextfile) {
  1173. loadnextfile = 0;
  1174. fluid_player_playlist_load(player, msec);
  1175. if (player->currentfile == NULL) {
  1176. return 0;
  1177. }
  1178. }
  1179. player->cur_msec = msec;
  1180. player->cur_ticks = (player->start_ticks +
  1181. (int) ((double) (player->cur_msec - player->start_msec) / player->deltatime));
  1182. for (i = 0; i < player->ntracks; i++) {
  1183. if (!fluid_track_eot(player->track[i])) {
  1184. status = FLUID_PLAYER_PLAYING;
  1185. if (fluid_track_send_events(player->track[i], synth, player, player->cur_ticks) != FLUID_OK) {
  1186. /* */
  1187. }
  1188. }
  1189. }
  1190. if (status == FLUID_PLAYER_DONE) {
  1191. FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec",
  1192.   __FILE__, __LINE__, (msec - player->begin_msec) / 1000.0);
  1193. loadnextfile = 1;
  1194. }
  1195. } while (loadnextfile);
  1196. player->status = status;
  1197. return 1;
  1198. }
  1199. /**
  1200.  * Activates play mode for a MIDI player if not already playing.
  1201.  * @param player MIDI player instance
  1202.  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
  1203.  */
  1204. int fluid_player_play(fluid_player_t* player)
  1205. {
  1206. if (player->status == FLUID_PLAYER_PLAYING) {
  1207. return FLUID_OK;
  1208. }
  1209. if (player->playlist == NULL) {
  1210. return FLUID_OK;
  1211. }
  1212. player->status = FLUID_PLAYER_PLAYING;
  1213. if (player->use_system_timer) {
  1214. player->system_timer = new_fluid_timer((int) player->deltatime, fluid_player_callback,
  1215. (void*) player, TRUE, FALSE, TRUE);
  1216. if (player->system_timer == NULL) {
  1217. return FLUID_FAILED;
  1218. }
  1219. } else {
  1220. player->sample_timer = new_fluid_sample_timer(player->synth, fluid_player_callback,
  1221. (void*) player);
  1222. if (player->sample_timer == NULL) {
  1223. return FLUID_FAILED;
  1224. }
  1225. }
  1226. return FLUID_OK;
  1227. }
  1228. /**
  1229.  * Stops a MIDI player.
  1230.  * @param player MIDI player instance
  1231.  * @return Always returns #FLUID_OK
  1232.  */
  1233. int fluid_player_stop(fluid_player_t* player)
  1234. {
  1235. if (player->system_timer != NULL) {
  1236. delete_fluid_timer(player->system_timer);
  1237. }
  1238. if (player->sample_timer != NULL) {
  1239. delete_fluid_sample_timer(player->synth, player->sample_timer);
  1240. }
  1241. player->status = FLUID_PLAYER_DONE;
  1242. player->sample_timer = NULL;
  1243. player->system_timer = NULL;
  1244. return FLUID_OK;
  1245. }
  1246. /**
  1247.  * Get MIDI player status.
  1248.  * @param player MIDI player instance
  1249.  * @return Player status (#fluid_player_status)
  1250.  * @since 1.1.0
  1251.  */
  1252. int
  1253. fluid_player_get_status(fluid_player_t* player)
  1254. {
  1255. return player->status;
  1256. }
  1257. /**
  1258.  * Enable looping of a MIDI player 
  1259.  * @param player MIDI player instance
  1260.  * @param loop Times left to loop the playlist. -1 means loop infinitely.
  1261.  * @return Always returns #FLUID_OK
  1262.  * @since 1.1.0
  1263.  *
  1264.  * For example, if you want to loop the playlist twice, set loop to 2 
  1265.  * and call this function before you start the player.
  1266.  */
  1267. int fluid_player_set_loop(fluid_player_t* player, int loop)
  1268. {
  1269. player->loop = loop;
  1270. return FLUID_OK;
  1271. }
  1272. /**
  1273.  * Set the tempo of a MIDI player.
  1274.  * @param player MIDI player instance
  1275.  * @param tempo Tempo to set playback speed to (in microseconds per quarter note, as per MIDI file spec)
  1276.  * @return Always returns #FLUID_OK
  1277.  */
  1278. int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo)
  1279. {
  1280. player->miditempo = tempo;
  1281. player->deltatime = (double) tempo / player->division / 1000.0; /* in milliseconds */
  1282. player->start_msec = player->cur_msec;
  1283. player->start_ticks = player->cur_ticks;
  1284. FLUID_LOG(FLUID_DBG,"tempo=%d, tick time=%f msec, cur time=%d msec, cur tick=%d",
  1285.   tempo, player->deltatime, player->cur_msec, player->cur_ticks);
  1286. return FLUID_OK;
  1287. }
  1288. /**
  1289.  * Set the tempo of a MIDI player in beats per minute.
  1290.  * @param player MIDI player instance
  1291.  * @param bpm Tempo in beats per minute
  1292.  * @return Always returns #FLUID_OK
  1293.  */
  1294. int fluid_player_set_bpm(fluid_player_t* player, int bpm)
  1295. {
  1296. return fluid_player_set_midi_tempo(player, (int)((double) 60 * 1e6 / bpm));
  1297. }
  1298. /**
  1299.  * Wait for a MIDI player to terminate (when done playing).
  1300.  * @param player MIDI player instance
  1301.  * @return #FLUID_OK on success, #FLUID_FAILED otherwise
  1302.  */
  1303. int fluid_player_join(fluid_player_t* player)
  1304. {
  1305. if (player->system_timer) {
  1306. return fluid_timer_join(player->system_timer);
  1307. } else if (player->sample_timer) {
  1308. /* Busy-wait loop, since there's no thread to wait for... */
  1309. while (player->status == FLUID_PLAYER_PLAYING) {
  1310. #if defined(WIN32)
  1311. Sleep(10);
  1312. #else
  1313. usleep(10000);
  1314. #endif
  1315. }
  1316. }
  1317. return FLUID_OK;
  1318. }
  1319. /************************************************************************
  1320.  *       MIDI PARSER
  1321.  *
  1322.  */
  1323. /*
  1324.  * new_fluid_midi_parser
  1325.  */
  1326. fluid_midi_parser_t* new_fluid_midi_parser()
  1327. {
  1328. fluid_midi_parser_t* parser;
  1329. parser = FLUID_NEW(fluid_midi_parser_t);
  1330. if (parser == NULL) {
  1331. FLUID_LOG(FLUID_ERR, "Out of memory");
  1332. return NULL;
  1333. }
  1334. parser->status = 0; /* As long as the status is 0, the parser won't do anything -> no need to initialize all the fields. */
  1335. return parser;
  1336. }
  1337. /*
  1338.  * delete_fluid_midi_parser
  1339.  */
  1340. int delete_fluid_midi_parser(fluid_midi_parser_t* parser)
  1341. {
  1342. FLUID_FREE(parser);
  1343. return FLUID_OK;
  1344. }
  1345. /**
  1346.  * Parse a MIDI stream one character at a time.
  1347.  * @param parser Parser instance
  1348.  * @param c Next character in MIDI stream
  1349.  * @return A parsed MIDI event or NULL if none.  Event is internal and should
  1350.  *   not be modified or freed and is only valid until next call to this function.
  1351.  */
  1352. fluid_midi_event_t *
  1353. fluid_midi_parser_parse(fluid_midi_parser_t* parser, unsigned char c)
  1354. {
  1355.   fluid_midi_event_t *event;
  1356.   /* Real-time messages (0xF8-0xFF) can occur anywhere, even in the middle
  1357.    * of another message. */
  1358.   if (c >= 0xF8)
  1359.   {
  1360.     if (c == MIDI_SYSTEM_RESET)
  1361.     {
  1362.       parser->event.type = c;
  1363.       parser->status = 0;       /* clear the status */
  1364.       return &parser->event;
  1365.     }
  1366.     return NULL;
  1367.   }
  1368.   /* Status byte? - If previous message not yet complete, it is discarded (re-sync). */
  1369.   if (c & 0x80)
  1370.   {
  1371.     /* Any status byte terminates SYSEX messages (not just 0xF7) */
  1372.     if (parser->status == MIDI_SYSEX && parser->nr_bytes > 0)
  1373.     {
  1374.       event = &parser->event;
  1375.       fluid_midi_event_set_sysex (event, parser->data, parser->nr_bytes, FALSE);
  1376.     }
  1377.     else event = NULL;
  1378.     if (c < 0xF0)       /* Voice category message? */
  1379.     {
  1380.       parser->channel = c & 0x0F;
  1381.       parser->status = c & 0xF0;
  1382.       /* The event consumes x bytes of data... (subtract 1 for the status byte) */
  1383.       parser->nr_bytes_total = fluid_midi_event_length (parser->status) - 1;
  1384.       parser->nr_bytes = 0;     /* 0  bytes read so far */
  1385.     }
  1386.     else if (c == MIDI_SYSEX)
  1387.     {
  1388.       parser->status = MIDI_SYSEX;
  1389.       parser->nr_bytes = 0;
  1390.     }
  1391.     else parser->status = 0;    /* Discard other system messages (0xF1-0xF7) */
  1392.     return event;       /* Return SYSEX event or NULL */
  1393.   }
  1394.   /* Data/parameter byte */
  1395.   /* Discard data bytes for events we don't care about */
  1396.   if (parser->status == 0)
  1397.     return NULL;
  1398.   /* Max data size exceeded? (SYSEX messages only really) */
  1399.   if (parser->nr_bytes == FLUID_MIDI_PARSER_MAX_DATA_SIZE)
  1400.   {
  1401.     parser->status = 0;         /* Discard the rest of the message */
  1402.     return NULL;
  1403.   }
  1404.   /* Store next byte */
  1405.   parser->data[parser->nr_bytes++] = c;
  1406.   /* Do we still need more data to get this event complete? */
  1407.   if (parser->nr_bytes < parser->nr_bytes_total)
  1408.     return NULL;
  1409.   /* Event is complete, return it.
  1410.    * Running status byte MIDI feature is also handled here. */
  1411.   parser->event.type = parser->status;
  1412.   parser->event.channel = parser->channel;
  1413.   parser->nr_bytes = 0;         /* Reset data size, in case there are additional running status messages */
  1414.   switch (parser->status)
  1415.   {
  1416.     case NOTE_OFF:
  1417.     case NOTE_ON:
  1418.     case KEY_PRESSURE:
  1419.     case CONTROL_CHANGE:
  1420.     case PROGRAM_CHANGE:
  1421.     case CHANNEL_PRESSURE:
  1422.       parser->event.param1 = parser->data[0]; /* For example key number */
  1423.       parser->event.param2 = parser->data[1]; /* For example velocity */
  1424.       break;
  1425.     case PITCH_BEND:
  1426.       /* Pitch-bend is transmitted with 14-bit precision. */
  1427.       parser->event.param1 = (parser->data[1] << 7) | parser->data[0];
  1428.       break;
  1429.     default: /* Unlikely */
  1430.       return NULL;
  1431.   }
  1432.   return &parser->event;
  1433. }
  1434. /* Purpose:
  1435.  * Returns the length of a MIDI message. */
  1436. static int
  1437. fluid_midi_event_length(unsigned char event)
  1438. {
  1439. switch (event & 0xF0) {
  1440. case NOTE_OFF: 
  1441. case NOTE_ON:
  1442. case KEY_PRESSURE:
  1443. case CONTROL_CHANGE:
  1444. case PITCH_BEND: 
  1445. return 3;
  1446. case PROGRAM_CHANGE:
  1447. case CHANNEL_PRESSURE: 
  1448. return 2;
  1449. }
  1450. switch (event) {
  1451. case MIDI_TIME_CODE:
  1452. case MIDI_SONG_SELECT:
  1453. case 0xF4:
  1454. case 0xF5:
  1455. return 2;
  1456. case MIDI_TUNE_REQUEST:
  1457. return 1;
  1458. case MIDI_SONG_POSITION:
  1459. return 3;
  1460. }
  1461. return 1;
  1462. }