1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
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.
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.
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 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "fluid_midi.h"
22 #include "fluid_sys.h"
23 #include "fluid_synth.h"
24 #include "fluid_settings.h"
27 static int fluid_midi_event_length(unsigned char event);
29 /* Read the entire contents of a file into memory, allocating enough memory
30 * for the file, and returning the length and the buffer.
31 * Note: This rewinds the file to the start before reading.
32 * Returns NULL if there was an error reading or allocating memory.
34 static char* fluid_file_read_full(fluid_file fp, size_t* length);
35 #define READ_FULL_INITIAL_BUFLEN 1024
37 #if 0 // disable file I/O with Ardour
38 /***************************************************************
44 * Return a new MIDI file handle for parsing an already-loaded MIDI file.
46 * @param buffer Pointer to full contents of MIDI file (borrows the pointer).
47 * The caller must not free buffer until after the fluid_midi_file is deleted.
48 * @param length Size of the buffer in bytes.
49 * @return New MIDI file handle or NULL on error.
52 new_fluid_midi_file(const char* buffer, size_t length)
56 mf = FLUID_NEW(fluid_midi_file);
58 FLUID_LOG(FLUID_ERR, "Out of memory");
61 FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file));
64 mf->running_status = -1;
71 if (fluid_midi_file_read_mthd(mf) != FLUID_OK) {
79 fluid_file_read_full(fluid_file fp, size_t* length)
84 /* Work out the length of the file in advance */
85 if (FLUID_FSEEK(fp, 0, SEEK_END) != 0)
87 FLUID_LOG(FLUID_ERR, "File load: Could not seek within file");
91 if (FLUID_FSEEK(fp, 0, SEEK_SET) != 0)
93 FLUID_LOG(FLUID_ERR, "File load: Could not seek within file");
96 FLUID_LOG(FLUID_DBG, "File load: Allocating %d bytes", buflen);
97 buffer = FLUID_MALLOC(buflen);
99 FLUID_LOG(FLUID_PANIC, "Out of memory");
102 n = FLUID_FREAD(buffer, 1, buflen, fp);
104 FLUID_LOG(FLUID_ERR, "Only read %d bytes; expected %d", n,
114 * Delete a MIDI file handle.
116 * @param mf MIDI file handle to close and free.
119 delete_fluid_midi_file (fluid_midi_file *mf)
129 * Gets the next byte in a MIDI file, taking into account previous running status.
131 * returns FLUID_FAILED if EOF or read error
134 fluid_midi_file_getc (fluid_midi_file *mf)
141 if (mf->buf_pos >= mf->buf_len) {
145 c = mf->buffer[mf->buf_pos++];
152 * Saves a byte to be returned the next time fluid_midi_file_getc() is called,
153 * when it is necessary according to running status.
156 fluid_midi_file_push(fluid_midi_file *mf, int c)
163 * fluid_midi_file_read
166 fluid_midi_file_read(fluid_midi_file *mf, void *buf, int len)
168 int num = len < mf->buf_len - mf->buf_pos
169 ? len : mf->buf_len - mf->buf_pos;
176 /* Note: Read bytes, even if there aren't enough, but only increment
177 * trackpos if successful (emulates old behaviour of fluid_midi_file_read)
179 FLUID_MEMCPY(buf, mf->buffer+mf->buf_pos, num);
185 FLUID_LOG(FLUID_DBG, "Could not read the requested number of bytes");
187 return (num != len) ? FLUID_FAILED : FLUID_OK;
191 * fluid_midi_file_skip
194 fluid_midi_file_skip (fluid_midi_file *mf, int skip)
196 int new_pos = mf->buf_pos + skip;
197 /* Mimic the behaviour of fseek: Error to seek past the start of file, but
198 * OK to seek past end (this just puts it into the EOF state). */
200 FLUID_LOG(FLUID_ERR, "Failed to seek position in file");
203 /* Clear the EOF flag, even if moved past the end of the file (this is
204 * consistent with the behaviour of fseek). */
206 mf->buf_pos = new_pos;
211 * fluid_midi_file_eof
213 int fluid_midi_file_eof(fluid_midi_file* mf)
215 /* Note: This does not simply test whether the file read pointer is past
216 * the end of the file. It mimics the behaviour of feof by actually
217 * testing the stateful EOF condition, which is set to TRUE if getc or
218 * fread have attempted to read past the end (but not if they have
219 * precisely reached the end), but reset to FALSE upon a successful seek.
225 * fluid_midi_file_read_mthd
228 fluid_midi_file_read_mthd(fluid_midi_file *mf)
231 if (fluid_midi_file_read(mf, mthd, 14) != FLUID_OK) {
234 if ((FLUID_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6)
237 "Doesn't look like a MIDI file: invalid MThd header");
241 mf->ntracks = (unsigned) mthd[11];
242 mf->ntracks += (unsigned int) (mthd[10]) << 16;
243 if ((mthd[12]) < 0) {
245 mf->smpte_fps = -mthd[12];
246 mf->smpte_res = (unsigned) mthd[13];
247 FLUID_LOG(FLUID_ERR, "File uses SMPTE timing -- Not implemented yet");
251 mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
252 FLUID_LOG(FLUID_DBG, "Division=%d", mf->division);
258 * fluid_midi_file_load_tracks
261 fluid_midi_file_load_tracks(fluid_midi_file *mf, fluid_player_t *player)
264 for (i = 0; i < mf->ntracks; i++) {
265 if (fluid_midi_file_read_track(mf, player, i) != FLUID_OK) {
273 * fluid_isasciistring
276 fluid_isasciistring(char *s)
279 int len = (int) FLUID_STRLEN(s);
280 for (i = 0; i < len; i++) {
281 if (!fluid_isascii(s[i])) {
292 fluid_getlength(unsigned char *s)
295 i = s[3] | (s[2] << 8) | (s[1] << 16) | (s[0] << 24);
300 * fluid_midi_file_read_tracklen
303 fluid_midi_file_read_tracklen(fluid_midi_file *mf)
305 unsigned char length[5];
306 if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
309 mf->tracklen = fluid_getlength(length);
316 * fluid_midi_file_eot
319 fluid_midi_file_eot(fluid_midi_file *mf)
322 if (mf->trackpos > mf->tracklen) {
323 printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen);
326 return mf->eot || (mf->trackpos >= mf->tracklen);
330 * fluid_midi_file_read_track
333 fluid_midi_file_read_track(fluid_midi_file *mf, fluid_player_t *player, int num)
335 fluid_track_t *track;
336 unsigned char id[5], length[5];
340 if (fluid_midi_file_read(mf, id, 4) != FLUID_OK) {
346 while (!found_track) {
348 if (fluid_isasciistring((char *) id) == 0) {
350 "An non-ascii track header found, corrupt file");
353 } else if (strcmp((char *) id, "MTrk") == 0) {
357 if (fluid_midi_file_read_tracklen(mf) != FLUID_OK) {
361 track = new_fluid_track(num);
363 FLUID_LOG(FLUID_ERR, "Out of memory");
367 while (!fluid_midi_file_eot(mf)) {
368 if (fluid_midi_file_read_event(mf, track) != FLUID_OK) {
369 delete_fluid_track(track);
374 /* Skip remaining track data, if any */
375 if (mf->trackpos < mf->tracklen) {
376 if (fluid_midi_file_skip(mf, mf->tracklen - mf->trackpos) != FLUID_OK) {
377 delete_fluid_track(track);
382 if (fluid_player_add_track(player, track) != FLUID_OK) {
383 delete_fluid_track(track);
389 if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
392 skip = fluid_getlength(length);
393 /* fseek(mf->fp, skip, SEEK_CUR); */
394 if (fluid_midi_file_skip(mf, skip) != FLUID_OK) {
399 if (fluid_midi_file_eof(mf)) {
400 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
407 * fluid_midi_file_read_varlen
410 fluid_midi_file_read_varlen(fluid_midi_file *mf)
417 FLUID_LOG(FLUID_ERR, "Invalid variable length number");
420 c = fluid_midi_file_getc(mf);
422 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
426 mf->varlen |= (int) (c & 0x7F);
437 * fluid_midi_file_read_event
440 fluid_midi_file_read_event(fluid_midi_file *mf, fluid_track_t *track)
445 unsigned char *metadata = NULL;
446 unsigned char *dyn_buf = NULL;
447 unsigned char static_buf[256];
448 int nominator, denominator, clocks, notes;
449 fluid_midi_event_t *evt;
455 /* read the delta-time of the event */
456 if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
459 mf->dtime += mf->varlen;
461 /* read the status byte */
462 status = fluid_midi_file_getc(mf);
464 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
468 /* not a valid status byte: use the running status instead */
469 if ((status & 0x80) == 0) {
470 if ((mf->running_status & 0x80) == 0) {
471 FLUID_LOG(FLUID_ERR, "Undefined status and invalid running status");
474 fluid_midi_file_push(mf, status);
475 status = mf->running_status;
478 /* check what message we have */
480 mf->running_status = status;
482 if ((status == MIDI_SYSEX)) { /* system exclusif */
483 /* read the length of the message */
484 if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
489 FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__,
490 __LINE__, mf->varlen);
491 metadata = FLUID_MALLOC(mf->varlen + 1);
493 if (metadata == NULL) {
494 FLUID_LOG(FLUID_PANIC, "Out of memory");
498 /* read the data of the message */
499 if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
500 FLUID_FREE (metadata);
504 evt = new_fluid_midi_event();
506 FLUID_LOG(FLUID_ERR, "Out of memory");
507 FLUID_FREE (metadata);
511 evt->dtime = mf->dtime;
514 if (metadata[mf->varlen - 1] == MIDI_EOX)
517 /* Add SYSEX event and indicate that its dynamically allocated and should be freed with event */
518 fluid_midi_event_set_sysex(evt, metadata, size, TRUE);
519 fluid_track_add_event(track, evt);
525 } else if (status == MIDI_META_EVENT) { /* meta events */
527 int result = FLUID_OK;
529 /* get the type of the meta message */
530 type = fluid_midi_file_getc(mf);
532 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
536 /* get the length of the data part */
537 if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
541 if (mf->varlen < 255) {
542 metadata = &static_buf[0];
544 FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__,
545 __LINE__, mf->varlen);
546 dyn_buf = FLUID_MALLOC(mf->varlen + 1);
547 if (dyn_buf == NULL) {
548 FLUID_LOG(FLUID_PANIC, "Out of memory");
556 if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
564 /* handle meta data */
568 metadata[mf->varlen] = 0;
571 case MIDI_TRACK_NAME:
572 metadata[mf->varlen] = 0;
573 fluid_track_set_name(track, (char *) metadata);
577 metadata[mf->varlen] = 0;
587 break; /* don't care much for text events */
590 if (mf->varlen != 0) {
591 FLUID_LOG(FLUID_ERR, "Invalid length for EndOfTrack event");
592 result = FLUID_FAILED;
596 evt = new_fluid_midi_event();
598 FLUID_LOG(FLUID_ERR, "Out of memory");
599 result = FLUID_FAILED;
602 evt->dtime = mf->dtime;
603 evt->type = MIDI_EOT;
604 fluid_track_add_event(track, evt);
609 if (mf->varlen != 3) {
611 "Invalid length for SetTempo meta event");
612 result = FLUID_FAILED;
615 tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
616 evt = new_fluid_midi_event();
618 FLUID_LOG(FLUID_ERR, "Out of memory");
619 result = FLUID_FAILED;
622 evt->dtime = mf->dtime;
623 evt->type = MIDI_SET_TEMPO;
627 fluid_track_add_event(track, evt);
631 case MIDI_SMPTE_OFFSET:
632 if (mf->varlen != 5) {
634 "Invalid length for SMPTE Offset meta event");
635 result = FLUID_FAILED;
638 break; /* we don't use smtp */
640 case MIDI_TIME_SIGNATURE:
641 if (mf->varlen != 4) {
643 "Invalid length for TimeSignature meta event");
644 result = FLUID_FAILED;
647 nominator = metadata[0];
648 denominator = pow(2.0, (double) metadata[1]);
649 clocks = metadata[2];
653 "signature=%d/%d, metronome=%d, 32nd-notes=%d",
654 nominator, denominator, clocks, notes);
658 case MIDI_KEY_SIGNATURE:
659 if (mf->varlen != 2) {
661 "Invalid length for KeySignature meta event");
662 result = FLUID_FAILED;
665 /* We don't care about key signatures anyway */
670 case MIDI_SEQUENCER_EVENT:
678 FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__);
684 } else { /* channel messages */
686 type = status & 0xf0;
687 channel = status & 0x0f;
689 /* all channel message have at least 1 byte of associated data */
690 if ((param1 = fluid_midi_file_getc(mf)) < 0) {
691 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
698 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
699 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
705 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
706 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
712 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
713 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
719 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
720 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
728 case CHANNEL_PRESSURE:
732 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
733 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
737 param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
742 /* Can't possibly happen !? */
743 FLUID_LOG(FLUID_ERR, "Unrecognized MIDI event");
746 evt = new_fluid_midi_event();
748 FLUID_LOG(FLUID_ERR, "Out of memory");
751 evt->dtime = mf->dtime;
753 evt->channel = channel;
754 evt->param1 = param1;
755 evt->param2 = param2;
756 fluid_track_add_event(track, evt);
763 * fluid_midi_file_get_division
766 fluid_midi_file_get_division(fluid_midi_file *midifile)
768 return midifile->division;
772 /******************************************************
778 * Create a MIDI event structure.
779 * @return New MIDI event structure or NULL when out of memory.
782 new_fluid_midi_event ()
784 fluid_midi_event_t* evt;
785 evt = FLUID_NEW(fluid_midi_event_t);
787 FLUID_LOG(FLUID_ERR, "Out of memory");
796 evt->paramptr = NULL;
801 * Delete MIDI event structure.
802 * @param evt MIDI event structure
803 * @return Always returns #FLUID_OK
806 delete_fluid_midi_event(fluid_midi_event_t *evt)
808 fluid_midi_event_t *temp;
813 /* Dynamic SYSEX event? - free (param2 indicates if dynamic) */
814 if (evt->type == MIDI_SYSEX && evt->paramptr && evt->param2)
815 FLUID_FREE (evt->paramptr);
824 * Get the event type field of a MIDI event structure.
825 * @param evt MIDI event structure
826 * @return Event type field (MIDI status byte without channel)
829 fluid_midi_event_get_type(fluid_midi_event_t *evt)
835 * Set the event type field of a MIDI event structure.
836 * @param evt MIDI event structure
837 * @param type Event type field (MIDI status byte without channel)
838 * @return Always returns #FLUID_OK
841 fluid_midi_event_set_type(fluid_midi_event_t *evt, int type)
848 * Get the channel field of a MIDI event structure.
849 * @param evt MIDI event structure
850 * @return Channel field
853 fluid_midi_event_get_channel(fluid_midi_event_t *evt)
859 * Set the channel field of a MIDI event structure.
860 * @param evt MIDI event structure
861 * @param chan MIDI channel field
862 * @return Always returns #FLUID_OK
865 fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan)
872 * Get the key field of a MIDI event structure.
873 * @param evt MIDI event structure
874 * @return MIDI note number (0-127)
877 fluid_midi_event_get_key(fluid_midi_event_t *evt)
883 * Set the key field of a MIDI event structure.
884 * @param evt MIDI event structure
885 * @param v MIDI note number (0-127)
886 * @return Always returns #FLUID_OK
889 fluid_midi_event_set_key(fluid_midi_event_t *evt, int v)
896 * Get the velocity field of a MIDI event structure.
897 * @param evt MIDI event structure
898 * @return MIDI velocity number (0-127)
901 fluid_midi_event_get_velocity(fluid_midi_event_t *evt)
907 * Set the velocity field of a MIDI event structure.
908 * @param evt MIDI event structure
909 * @param v MIDI velocity value
910 * @return Always returns #FLUID_OK
913 fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int v)
920 * Get the control number of a MIDI event structure.
921 * @param evt MIDI event structure
922 * @return MIDI control number
925 fluid_midi_event_get_control(fluid_midi_event_t *evt)
931 * Set the control field of a MIDI event structure.
932 * @param evt MIDI event structure
933 * @param v MIDI control number
934 * @return Always returns #FLUID_OK
937 fluid_midi_event_set_control(fluid_midi_event_t *evt, int v)
944 * Get the value field from a MIDI event structure.
945 * @param evt MIDI event structure
946 * @return Value field
949 fluid_midi_event_get_value(fluid_midi_event_t *evt)
955 * Set the value field of a MIDI event structure.
956 * @param evt MIDI event structure
957 * @param v Value to assign
958 * @return Always returns #FLUID_OK
961 fluid_midi_event_set_value(fluid_midi_event_t *evt, int v)
968 * Get the program field of a MIDI event structure.
969 * @param evt MIDI event structure
970 * @return MIDI program number (0-127)
973 fluid_midi_event_get_program(fluid_midi_event_t *evt)
979 * Set the program field of a MIDI event structure.
980 * @param evt MIDI event structure
981 * @param val MIDI program number (0-127)
982 * @return Always returns #FLUID_OK
985 fluid_midi_event_set_program(fluid_midi_event_t *evt, int val)
992 * Get the pitch field of a MIDI event structure.
993 * @param evt MIDI event structure
994 * @return Pitch value (14 bit value, 0-16383, 8192 is center)
997 fluid_midi_event_get_pitch(fluid_midi_event_t *evt)
1003 * Set the pitch field of a MIDI event structure.
1004 * @param evt MIDI event structure
1005 * @param val Pitch value (14 bit value, 0-16383, 8192 is center)
1006 * @return Always returns FLUID_OK
1009 fluid_midi_event_set_pitch(fluid_midi_event_t *evt, int val)
1016 * Assign sysex data to a MIDI event structure.
1017 * @param evt MIDI event structure
1018 * @param data Pointer to SYSEX data
1019 * @param size Size of SYSEX data
1020 * @param dynamic TRUE if the SYSEX data has been dynamically allocated and
1021 * should be freed when the event is freed (only applies if event gets destroyed
1022 * with delete_fluid_midi_event())
1023 * @return Always returns #FLUID_OK
1025 * NOTE: Unlike the other event assignment functions, this one sets evt->type.
1028 fluid_midi_event_set_sysex(fluid_midi_event_t *evt, void *data, int size, int dynamic)
1030 evt->type = MIDI_SYSEX;
1031 evt->paramptr = data;
1033 evt->param2 = dynamic;
1037 /******************************************************
1041 #if 0 // disable fluid file player in Ardour
1046 new_fluid_track(int num)
1048 fluid_track_t *track;
1049 track = FLUID_NEW(fluid_track_t);
1050 if (track == NULL) {
1055 track->first = NULL;
1063 * delete_fluid_track
1066 delete_fluid_track(fluid_track_t *track)
1068 if (track->name != NULL) {
1069 FLUID_FREE(track->name);
1071 if (track->first != NULL) {
1072 delete_fluid_midi_event(track->first);
1079 * fluid_track_set_name
1082 fluid_track_set_name(fluid_track_t *track, char *name)
1085 if (track->name != NULL) {
1086 FLUID_FREE(track->name);
1092 len = FLUID_STRLEN(name);
1093 track->name = FLUID_MALLOC(len + 1);
1094 if (track->name == NULL) {
1095 FLUID_LOG(FLUID_ERR, "Out of memory");
1096 return FLUID_FAILED;
1098 FLUID_STRCPY(track->name, name);
1103 * fluid_track_get_name
1106 fluid_track_get_name(fluid_track_t *track)
1112 * fluid_track_get_duration
1115 fluid_track_get_duration(fluid_track_t *track)
1118 fluid_midi_event_t *evt = track->first;
1119 while (evt != NULL) {
1127 * fluid_track_count_events
1130 fluid_track_count_events(fluid_track_t *track, int *on, int *off)
1132 fluid_midi_event_t *evt = track->first;
1133 while (evt != NULL) {
1134 if (evt->type == NOTE_ON) {
1136 } else if (evt->type == NOTE_OFF) {
1145 * fluid_track_add_event
1148 fluid_track_add_event(fluid_track_t *track, fluid_midi_event_t *evt)
1151 if (track->first == NULL) {
1156 track->last->next = evt;
1163 * fluid_track_first_event
1165 fluid_midi_event_t *
1166 fluid_track_first_event(fluid_track_t *track)
1168 track->cur = track->first;
1173 * fluid_track_next_event
1175 fluid_midi_event_t *
1176 fluid_track_next_event(fluid_track_t *track)
1178 if (track->cur != NULL) {
1179 track->cur = track->cur->next;
1188 fluid_track_reset(fluid_track_t *track)
1191 track->cur = track->first;
1196 * fluid_track_send_events
1199 fluid_track_send_events(fluid_track_t *track,
1200 fluid_synth_t *synth,
1201 fluid_player_t *player,
1204 int status = FLUID_OK;
1205 fluid_midi_event_t *event;
1210 if (event == NULL) {
1214 /* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */
1219 /* track->ticks + event->dtime); */
1221 if (track->ticks + event->dtime > ticks) {
1225 track->ticks += event->dtime;
1227 if (!player || event->type == MIDI_EOT) {
1229 else if (event->type == MIDI_SET_TEMPO) {
1230 fluid_player_set_midi_tempo(player, event->param1);
1233 if (player->playback_callback)
1234 player->playback_callback(player->playback_userdata, event);
1237 fluid_track_next_event(track);
1243 /******************************************************
1249 * Create a new MIDI player.
1250 * @param synth Fluid synthesizer instance to create player for
1251 * @return New MIDI player instance or NULL on error (out of memory)
1254 new_fluid_player(fluid_synth_t *synth)
1257 fluid_player_t *player;
1258 player = FLUID_NEW(fluid_player_t);
1259 if (player == NULL) {
1260 FLUID_LOG(FLUID_ERR, "Out of memory");
1263 player->status = FLUID_PLAYER_READY;
1265 player->ntracks = 0;
1266 for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
1267 player->track[i] = NULL;
1269 player->synth = synth;
1270 player->system_timer = NULL;
1271 player->sample_timer = NULL;
1272 player->playlist = NULL;
1273 player->currentfile = NULL;
1274 player->division = 0;
1275 player->send_program_change = 1;
1276 player->miditempo = 480000;
1277 player->deltatime = 4.0;
1278 player->cur_msec = 0;
1279 player->cur_ticks = 0;
1280 fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth);
1282 player->use_system_timer = fluid_settings_str_equal(synth->settings,
1283 "player.timing-source", "system");
1285 fluid_settings_getint(synth->settings, "player.reset-synth", &i);
1286 player->reset_synth_between_songs = i;
1292 * Delete a MIDI player instance.
1293 * @param player MIDI player instance
1294 * @return Always returns #FLUID_OK
1297 delete_fluid_player(fluid_player_t *player)
1300 fluid_playlist_item* pi;
1302 if (player == NULL) {
1305 fluid_player_stop(player);
1306 fluid_player_reset(player);
1308 while (player->playlist != NULL) {
1309 q = player->playlist->next;
1310 pi = (fluid_playlist_item*) player->playlist->data;
1311 FLUID_FREE(pi->filename);
1312 FLUID_FREE(pi->buffer);
1314 delete1_fluid_list(player->playlist);
1315 player->playlist = q;
1323 * Registers settings related to the MIDI player
1326 fluid_player_settings(fluid_settings_t *settings)
1328 /* player.timing-source can be either "system" (use system timer)
1329 or "sample" (use timer based on number of written samples) */
1330 fluid_settings_register_str(settings, "player.timing-source", "sample", 0,
1332 fluid_settings_add_option(settings, "player.timing-source", "sample");
1333 fluid_settings_add_option(settings, "player.timing-source", "system");
1335 /* Selects whether the player should reset the synth between songs, or not. */
1336 fluid_settings_register_int(settings, "player.reset-synth", 1, 0, 1,
1337 FLUID_HINT_TOGGLED, NULL, NULL);
1342 fluid_player_reset(fluid_player_t *player)
1346 for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
1347 if (player->track[i] != NULL) {
1348 delete_fluid_track(player->track[i]);
1349 player->track[i] = NULL;
1352 /* player->current_file = NULL; */
1353 /* player->status = FLUID_PLAYER_READY; */
1354 /* player->loop = 1; */
1355 player->ntracks = 0;
1356 player->division = 0;
1357 player->send_program_change = 1;
1358 player->miditempo = 480000;
1359 player->deltatime = 4.0;
1364 * fluid_player_add_track
1367 fluid_player_add_track(fluid_player_t *player, fluid_track_t *track)
1369 if (player->ntracks < MAX_NUMBER_OF_TRACKS) {
1370 player->track[player->ntracks++] = track;
1373 return FLUID_FAILED;
1378 * fluid_player_count_tracks
1381 fluid_player_count_tracks(fluid_player_t *player)
1383 return player->ntracks;
1387 * fluid_player_get_track
1390 fluid_player_get_track(fluid_player_t *player, int i)
1392 if ((i >= 0) && (i < MAX_NUMBER_OF_TRACKS)) {
1393 return player->track[i];
1400 * Change the MIDI callback function. This is usually set to
1401 * fluid_synth_handle_midi_event, but can optionally be changed
1402 * to a user-defined function instead, for intercepting all MIDI
1403 * messages sent to the synth. You can also use a midi router as
1404 * the callback function to modify the MIDI messages before sending
1405 * them to the synth.
1406 * @param player MIDI player instance
1407 * @param handler Pointer to callback function
1408 * @param handler_data Parameter sent to the callback function
1413 fluid_player_set_playback_callback(fluid_player_t* player,
1414 handle_midi_event_func_t handler, void* handler_data)
1416 player->playback_callback = handler;
1417 player->playback_userdata = handler_data;
1422 * Add a MIDI file to a player queue.
1423 * @param player MIDI player instance
1424 * @param midifile File name of the MIDI file to add
1425 * @return #FLUID_OK or #FLUID_FAILED
1428 fluid_player_add(fluid_player_t *player, const char *midifile)
1430 fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item));
1431 char* f = FLUID_STRDUP(midifile);
1435 FLUID_LOG(FLUID_PANIC, "Out of memory");
1436 return FLUID_FAILED;
1442 player->playlist = fluid_list_append(player->playlist, pi);
1447 * Add a MIDI file to a player queue, from a buffer in memory.
1448 * @param player MIDI player instance
1449 * @param buffer Pointer to memory containing the bytes of a complete MIDI
1450 * file. The data is copied, so the caller may free or modify it immediately
1451 * without affecting the playlist.
1452 * @param len Length of the buffer, in bytes.
1453 * @return #FLUID_OK or #FLUID_FAILED
1456 fluid_player_add_mem(fluid_player_t* player, const void *buffer, size_t len)
1458 /* Take a copy of the buffer, so the caller can free immediately. */
1459 fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item));
1460 void *buf_copy = FLUID_MALLOC(len);
1461 if (!pi || !buf_copy) {
1463 FLUID_FREE(buf_copy);
1464 FLUID_LOG(FLUID_PANIC, "Out of memory");
1465 return FLUID_FAILED;
1468 FLUID_MEMCPY(buf_copy, buffer, len);
1469 pi->filename = NULL;
1470 pi->buffer = buf_copy;
1471 pi->buffer_len = len;
1472 player->playlist = fluid_list_append(player->playlist, pi);
1480 fluid_player_load(fluid_player_t *player, fluid_playlist_item *item)
1482 fluid_midi_file *midifile;
1484 size_t buffer_length;
1487 if (item->filename != NULL)
1490 /* This file is specified by filename; load the file from disk */
1491 FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile %s", __FILE__, __LINE__,
1493 /* Read the entire contents of the file into the buffer */
1494 fp = FLUID_FOPEN(item->filename, "rb");
1496 FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file");
1497 return FLUID_FAILED;
1499 buffer = fluid_file_read_full(fp, &buffer_length);
1503 return FLUID_FAILED;
1510 /* This file is specified by a pre-loaded buffer; load from memory */
1511 FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile from memory (%p)",
1512 __FILE__, __LINE__, item->buffer);
1513 buffer = (char *) item->buffer;
1514 buffer_length = item->buffer_len;
1515 /* Do not free the buffer (it is owned by the playlist) */
1519 midifile = new_fluid_midi_file(buffer, buffer_length);
1520 if (midifile == NULL) {
1524 return FLUID_FAILED;
1526 player->division = fluid_midi_file_get_division(midifile);
1527 fluid_player_set_midi_tempo(player, player->miditempo); // Update deltatime
1528 /*FLUID_LOG(FLUID_DBG, "quarter note division=%d\n", player->division); */
1530 if (fluid_midi_file_load_tracks(midifile, player) != FLUID_OK) {
1534 delete_fluid_midi_file(midifile);
1535 return FLUID_FAILED;
1537 delete_fluid_midi_file(midifile);
1545 fluid_player_advancefile(fluid_player_t *player)
1547 if (player->playlist == NULL) {
1548 return; /* No files to play */
1550 if (player->currentfile != NULL) {
1551 player->currentfile = fluid_list_next(player->currentfile);
1553 if (player->currentfile == NULL) {
1554 if (player->loop == 0) {
1555 return; /* We're done playing */
1557 if (player->loop > 0) {
1560 player->currentfile = player->playlist;
1565 fluid_player_playlist_load(fluid_player_t *player, unsigned int msec)
1567 fluid_playlist_item* current_playitem;
1571 fluid_player_advancefile(player);
1572 if (player->currentfile == NULL) {
1573 /* Failed to find next song, probably since we're finished */
1574 player->status = FLUID_PLAYER_DONE;
1578 fluid_player_reset(player);
1579 current_playitem = (fluid_playlist_item *) player->currentfile->data;
1580 } while (fluid_player_load(player, current_playitem) != FLUID_OK);
1582 /* Successfully loaded midi file */
1584 player->begin_msec = msec;
1585 player->start_msec = msec;
1586 player->start_ticks = 0;
1587 player->cur_ticks = 0;
1589 if (player->reset_synth_between_songs) {
1590 fluid_synth_system_reset(player->synth);
1593 for (i = 0; i < player->ntracks; i++) {
1594 if (player->track[i] != NULL) {
1595 fluid_track_reset(player->track[i]);
1602 * fluid_player_callback
1605 fluid_player_callback(void *data, unsigned int msec)
1609 int status = FLUID_PLAYER_DONE;
1610 fluid_player_t *player;
1611 fluid_synth_t *synth;
1612 player = (fluid_player_t *) data;
1613 synth = player->synth;
1615 loadnextfile = player->currentfile == NULL ? 1 : 0;
1619 fluid_player_playlist_load(player, msec);
1620 if (player->currentfile == NULL) {
1625 player->cur_msec = msec;
1626 player->cur_ticks = (player->start_ticks
1627 + (int) ((double) (player->cur_msec - player->start_msec)
1628 / player->deltatime));
1630 for (i = 0; i < player->ntracks; i++) {
1631 if (!fluid_track_eot(player->track[i])) {
1632 status = FLUID_PLAYER_PLAYING;
1633 if (fluid_track_send_events(player->track[i], synth, player,
1634 player->cur_ticks) != FLUID_OK) {
1640 if (status == FLUID_PLAYER_DONE) {
1641 FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec", __FILE__,
1642 __LINE__, (msec - player->begin_msec) / 1000.0);
1645 } while (loadnextfile);
1647 player->status = status;
1653 * Activates play mode for a MIDI player if not already playing.
1654 * @param player MIDI player instance
1655 * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1658 fluid_player_play(fluid_player_t *player)
1660 if (player->status == FLUID_PLAYER_PLAYING) {
1664 if (player->playlist == NULL) {
1668 player->status = FLUID_PLAYER_PLAYING;
1670 if (player->use_system_timer) {
1671 player->system_timer = new_fluid_timer((int) player->deltatime,
1672 fluid_player_callback, (void *) player, TRUE, FALSE, TRUE);
1673 if (player->system_timer == NULL) {
1674 return FLUID_FAILED;
1677 player->sample_timer = new_fluid_sample_timer(player->synth,
1678 fluid_player_callback, (void *) player);
1680 if (player->sample_timer == NULL) {
1681 return FLUID_FAILED;
1688 * Stops a MIDI player.
1689 * @param player MIDI player instance
1690 * @return Always returns #FLUID_OK
1693 fluid_player_stop(fluid_player_t *player)
1695 if (player->system_timer != NULL) {
1696 delete_fluid_timer(player->system_timer);
1698 if (player->sample_timer != NULL) {
1699 delete_fluid_sample_timer(player->synth, player->sample_timer);
1701 player->status = FLUID_PLAYER_DONE;
1702 player->sample_timer = NULL;
1703 player->system_timer = NULL;
1708 * Get MIDI player status.
1709 * @param player MIDI player instance
1710 * @return Player status (#fluid_player_status)
1714 fluid_player_get_status(fluid_player_t *player)
1716 return player->status;
1720 * Enable looping of a MIDI player
1721 * @param player MIDI player instance
1722 * @param loop Times left to loop the playlist. -1 means loop infinitely.
1723 * @return Always returns #FLUID_OK
1726 * For example, if you want to loop the playlist twice, set loop to 2
1727 * and call this function before you start the player.
1729 int fluid_player_set_loop(fluid_player_t *player, int loop)
1731 player->loop = loop;
1736 * Set the tempo of a MIDI player.
1737 * @param player MIDI player instance
1738 * @param tempo Tempo to set playback speed to (in microseconds per quarter note, as per MIDI file spec)
1739 * @return Always returns #FLUID_OK
1741 int fluid_player_set_midi_tempo(fluid_player_t *player, int tempo)
1743 player->miditempo = tempo;
1744 player->deltatime = (double) tempo / player->division / 1000.0; /* in milliseconds */
1745 player->start_msec = player->cur_msec;
1746 player->start_ticks = player->cur_ticks;
1748 FLUID_LOG(FLUID_DBG,
1749 "tempo=%d, tick time=%f msec, cur time=%d msec, cur tick=%d",
1750 tempo, player->deltatime, player->cur_msec, player->cur_ticks);
1756 * Set the tempo of a MIDI player in beats per minute.
1757 * @param player MIDI player instance
1758 * @param bpm Tempo in beats per minute
1759 * @return Always returns #FLUID_OK
1762 fluid_player_set_bpm(fluid_player_t *player, int bpm)
1764 return fluid_player_set_midi_tempo(player, (int) ((double) 60 * 1e6 / bpm));
1768 * Wait for a MIDI player to terminate (when done playing).
1769 * @param player MIDI player instance
1770 * @return #FLUID_OK on success, #FLUID_FAILED otherwise
1773 fluid_player_join(fluid_player_t *player)
1775 if (player->system_timer) {
1776 return fluid_timer_join(player->system_timer);
1777 } else if (player->sample_timer) {
1778 /* Busy-wait loop, since there's no thread to wait for... */
1779 while (player->status != FLUID_PLAYER_DONE) {
1790 /************************************************************************
1796 * new_fluid_midi_parser
1798 fluid_midi_parser_t *
1799 new_fluid_midi_parser ()
1801 fluid_midi_parser_t *parser;
1802 parser = FLUID_NEW(fluid_midi_parser_t);
1803 if (parser == NULL) {
1804 FLUID_LOG(FLUID_ERR, "Out of memory");
1807 parser->status = 0; /* As long as the status is 0, the parser won't do anything -> no need to initialize all the fields. */
1812 * delete_fluid_midi_parser
1815 delete_fluid_midi_parser(fluid_midi_parser_t *parser)
1822 * Parse a MIDI stream one character at a time.
1823 * @param parser Parser instance
1824 * @param c Next character in MIDI stream
1825 * @return A parsed MIDI event or NULL if none. Event is internal and should
1826 * not be modified or freed and is only valid until next call to this function.
1828 fluid_midi_event_t *
1829 fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c)
1831 fluid_midi_event_t *event;
1833 /* Real-time messages (0xF8-0xFF) can occur anywhere, even in the middle
1834 * of another message. */
1836 if (c == MIDI_SYSTEM_RESET) {
1837 parser->event.type = c;
1838 parser->status = 0; /* clear the status */
1839 return &parser->event;
1845 /* Status byte? - If previous message not yet complete, it is discarded (re-sync). */
1847 /* Any status byte terminates SYSEX messages (not just 0xF7) */
1848 if (parser->status == MIDI_SYSEX && parser->nr_bytes > 0) {
1849 event = &parser->event;
1850 fluid_midi_event_set_sysex(event, parser->data, parser->nr_bytes,
1855 if (c < 0xF0) /* Voice category message? */
1857 parser->channel = c & 0x0F;
1858 parser->status = c & 0xF0;
1860 /* The event consumes x bytes of data... (subtract 1 for the status byte) */
1861 parser->nr_bytes_total = fluid_midi_event_length(parser->status)
1864 parser->nr_bytes = 0; /* 0 bytes read so far */
1865 } else if (c == MIDI_SYSEX) {
1866 parser->status = MIDI_SYSEX;
1867 parser->nr_bytes = 0;
1869 parser->status = 0; /* Discard other system messages (0xF1-0xF7) */
1871 return event; /* Return SYSEX event or NULL */
1874 /* Data/parameter byte */
1876 /* Discard data bytes for events we don't care about */
1877 if (parser->status == 0)
1880 /* Max data size exceeded? (SYSEX messages only really) */
1881 if (parser->nr_bytes == FLUID_MIDI_PARSER_MAX_DATA_SIZE) {
1882 parser->status = 0; /* Discard the rest of the message */
1886 /* Store next byte */
1887 parser->data[parser->nr_bytes++] = c;
1889 /* Do we still need more data to get this event complete? */
1890 if (parser->nr_bytes < parser->nr_bytes_total)
1893 /* Event is complete, return it.
1894 * Running status byte MIDI feature is also handled here. */
1895 parser->event.type = parser->status;
1896 parser->event.channel = parser->channel;
1897 parser->nr_bytes = 0; /* Reset data size, in case there are additional running status messages */
1899 switch (parser->status) {
1903 case CONTROL_CHANGE:
1904 case PROGRAM_CHANGE:
1905 case CHANNEL_PRESSURE:
1906 parser->event.param1 = parser->data[0]; /* For example key number */
1907 parser->event.param2 = parser->data[1]; /* For example velocity */
1910 /* Pitch-bend is transmitted with 14-bit precision. */
1911 parser->event.param1 = (parser->data[1] << 7) | parser->data[0];
1913 default: /* Unlikely */
1917 return &parser->event;
1921 * Returns the length of a MIDI message. */
1923 fluid_midi_event_length(unsigned char event)
1925 switch (event & 0xF0) {
1929 case CONTROL_CHANGE:
1932 case PROGRAM_CHANGE:
1933 case CHANNEL_PRESSURE:
1937 case MIDI_TIME_CODE:
1938 case MIDI_SONG_SELECT:
1942 case MIDI_TUNE_REQUEST:
1944 case MIDI_SONG_POSITION: