Update fluidsynth
[ardour.git] / libs / fluidsynth / src / fluid_midi.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  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  */
20
21 #include "fluid_midi.h"
22 #include "fluid_sys.h"
23 #include "fluid_synth.h"
24 #include "fluid_settings.h"
25
26
27 static int fluid_midi_event_length(unsigned char event);
28
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.
33  */
34 static char* fluid_file_read_full(fluid_file fp, size_t* length);
35 #define READ_FULL_INITIAL_BUFLEN 1024
36
37 #if 0 // disable file I/O with Ardour
38 /***************************************************************
39  *
40  *                      MIDIFILE
41  */
42
43 /**
44  * Return a new MIDI file handle for parsing an already-loaded MIDI file.
45  * @internal
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.
50  */
51 fluid_midi_file *
52 new_fluid_midi_file(const char* buffer, size_t length)
53 {
54     fluid_midi_file *mf;
55
56     mf = FLUID_NEW(fluid_midi_file);
57     if (mf == NULL) {
58         FLUID_LOG(FLUID_ERR, "Out of memory");
59         return NULL;
60     }
61     FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file));
62
63     mf->c = -1;
64     mf->running_status = -1;
65
66     mf->buffer = buffer;
67     mf->buf_len = length;
68     mf->buf_pos = 0;
69     mf->eof = FALSE;
70
71     if (fluid_midi_file_read_mthd(mf) != FLUID_OK) {
72         FLUID_FREE(mf);
73         return NULL;
74     }
75     return mf;
76 }
77
78 static char*
79 fluid_file_read_full(fluid_file fp, size_t* length)
80 {
81     size_t buflen;
82     char* buffer;
83     size_t n;
84     /* Work out the length of the file in advance */
85     if (FLUID_FSEEK(fp, 0, SEEK_END) != 0)
86     {
87         FLUID_LOG(FLUID_ERR, "File load: Could not seek within file");
88         return NULL;
89     }
90     buflen = ftell(fp);
91     if (FLUID_FSEEK(fp, 0, SEEK_SET) != 0)
92     {
93         FLUID_LOG(FLUID_ERR, "File load: Could not seek within file");
94         return NULL;
95     }
96     FLUID_LOG(FLUID_DBG, "File load: Allocating %d bytes", buflen);
97     buffer = FLUID_MALLOC(buflen);
98     if (buffer == NULL) {
99         FLUID_LOG(FLUID_PANIC, "Out of memory");
100         return NULL;
101     }
102     n = FLUID_FREAD(buffer, 1, buflen, fp);
103     if (n != buflen) {
104         FLUID_LOG(FLUID_ERR, "Only read %d bytes; expected %d", n,
105                   buflen);
106         FLUID_FREE(buffer);
107         return NULL;
108     };
109     *length = n;
110     return buffer;
111 }
112
113 /**
114  * Delete a MIDI file handle.
115  * @internal
116  * @param mf MIDI file handle to close and free.
117  */
118 void
119 delete_fluid_midi_file (fluid_midi_file *mf)
120 {
121     if (mf == NULL) {
122         return;
123     }
124     FLUID_FREE(mf);
125     return;
126 }
127
128 /*
129  * Gets the next byte in a MIDI file, taking into account previous running status.
130  *
131  * returns FLUID_FAILED if EOF or read error
132  */
133 int
134 fluid_midi_file_getc (fluid_midi_file *mf)
135 {
136     unsigned char c;
137     if (mf->c >= 0) {
138         c = mf->c;
139         mf->c = -1;
140     } else {
141         if (mf->buf_pos >= mf->buf_len) {
142             mf->eof = TRUE;
143             return FLUID_FAILED;
144         }
145         c = mf->buffer[mf->buf_pos++];
146         mf->trackpos++;
147     }
148     return (int) c;
149 }
150
151 /*
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.
154  */
155 int
156 fluid_midi_file_push(fluid_midi_file *mf, int c)
157 {
158     mf->c = c;
159     return FLUID_OK;
160 }
161
162 /*
163  * fluid_midi_file_read
164  */
165 int
166 fluid_midi_file_read(fluid_midi_file *mf, void *buf, int len)
167 {
168     int num = len < mf->buf_len - mf->buf_pos
169         ? len : mf->buf_len - mf->buf_pos;
170     if (num != len) {
171         mf->eof = TRUE;
172     }
173     if (num < 0) {
174         num = 0;
175     }
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)
178      */
179     FLUID_MEMCPY(buf, mf->buffer+mf->buf_pos, num);
180     mf->buf_pos += num;
181     if (num == len)
182         mf->trackpos += num;
183 #if DEBUG
184     else
185         FLUID_LOG(FLUID_DBG, "Could not read the requested number of bytes");
186 #endif
187     return (num != len) ? FLUID_FAILED : FLUID_OK;
188 }
189
190 /*
191  * fluid_midi_file_skip
192  */
193 int
194 fluid_midi_file_skip (fluid_midi_file *mf, int skip)
195 {
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). */
199     if (new_pos < 0) {
200         FLUID_LOG(FLUID_ERR, "Failed to seek position in file");
201         return FLUID_FAILED;
202     }
203     /* Clear the EOF flag, even if moved past the end of the file (this is
204      * consistent with the behaviour of fseek). */
205     mf->eof = FALSE;
206     mf->buf_pos = new_pos;
207     return FLUID_OK;
208 }
209
210 /*
211  * fluid_midi_file_eof
212  */
213 int fluid_midi_file_eof(fluid_midi_file* mf)
214 {
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.
220          */
221         return mf->eof;
222 }
223
224 /*
225  * fluid_midi_file_read_mthd
226  */
227 int
228 fluid_midi_file_read_mthd(fluid_midi_file *mf)
229 {
230     char mthd[15];
231     if (fluid_midi_file_read(mf, mthd, 14) != FLUID_OK) {
232         return FLUID_FAILED;
233     }
234     if ((FLUID_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6)
235             || (mthd[9] > 2)) {
236         FLUID_LOG(FLUID_ERR,
237                 "Doesn't look like a MIDI file: invalid MThd header");
238         return FLUID_FAILED;
239     }
240     mf->type = mthd[9];
241     mf->ntracks = (unsigned) mthd[11];
242     mf->ntracks += (unsigned int) (mthd[10]) << 16;
243     if ((mthd[12]) < 0) {
244         mf->uses_smpte = 1;
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");
248         return FLUID_FAILED;
249     } else {
250         mf->uses_smpte = 0;
251         mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
252         FLUID_LOG(FLUID_DBG, "Division=%d", mf->division);
253     }
254     return FLUID_OK;
255 }
256
257 /*
258  * fluid_midi_file_load_tracks
259  */
260 int
261 fluid_midi_file_load_tracks(fluid_midi_file *mf, fluid_player_t *player)
262 {
263     int i;
264     for (i = 0; i < mf->ntracks; i++) {
265         if (fluid_midi_file_read_track(mf, player, i) != FLUID_OK) {
266             return FLUID_FAILED;
267         }
268     }
269     return FLUID_OK;
270 }
271
272 /*
273  * fluid_isasciistring
274  */
275 int
276 fluid_isasciistring(char *s)
277 {
278     int i;
279     int len = (int) FLUID_STRLEN(s);
280     for (i = 0; i < len; i++) {
281         if (!fluid_isascii(s[i])) {
282             return 0;
283         }
284     }
285     return 1;
286 }
287
288 /*
289  * fluid_getlength
290  */
291 long
292 fluid_getlength(unsigned char *s)
293 {
294     long i = 0;
295     i = s[3] | (s[2] << 8) | (s[1] << 16) | (s[0] << 24);
296     return i;
297 }
298
299 /*
300  * fluid_midi_file_read_tracklen
301  */
302 int
303 fluid_midi_file_read_tracklen(fluid_midi_file *mf)
304 {
305     unsigned char length[5];
306     if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
307         return FLUID_FAILED;
308     }
309     mf->tracklen = fluid_getlength(length);
310     mf->trackpos = 0;
311     mf->eot = 0;
312     return FLUID_OK;
313 }
314
315 /*
316  * fluid_midi_file_eot
317  */
318 int
319 fluid_midi_file_eot(fluid_midi_file *mf)
320 {
321 #if DEBUG
322     if (mf->trackpos > mf->tracklen) {
323         printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen);
324     }
325 #endif
326     return mf->eot || (mf->trackpos >= mf->tracklen);
327 }
328
329 /*
330  * fluid_midi_file_read_track
331  */
332 int
333 fluid_midi_file_read_track(fluid_midi_file *mf, fluid_player_t *player, int num)
334 {
335     fluid_track_t *track;
336     unsigned char id[5], length[5];
337     int found_track = 0;
338     int skip;
339
340     if (fluid_midi_file_read(mf, id, 4) != FLUID_OK) {
341         return FLUID_FAILED;
342     }
343     id[4] = '\0';
344     mf->dtime = 0;
345
346     while (!found_track) {
347
348         if (fluid_isasciistring((char *) id) == 0) {
349             FLUID_LOG(FLUID_ERR,
350                     "An non-ascii track header found, corrupt file");
351             return FLUID_FAILED;
352
353         } else if (strcmp((char *) id, "MTrk") == 0) {
354
355             found_track = 1;
356
357             if (fluid_midi_file_read_tracklen(mf) != FLUID_OK) {
358                 return FLUID_FAILED;
359             }
360
361             track = new_fluid_track(num);
362             if (track == NULL) {
363                 FLUID_LOG(FLUID_ERR, "Out of memory");
364                 return FLUID_FAILED;
365             }
366
367             while (!fluid_midi_file_eot(mf)) {
368                 if (fluid_midi_file_read_event(mf, track) != FLUID_OK) {
369                     delete_fluid_track(track);
370                     return FLUID_FAILED;
371                 }
372             }
373
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);
378                     return FLUID_FAILED;
379                 }
380             }
381
382             if (fluid_player_add_track(player, track) != FLUID_OK) {
383                 delete_fluid_track(track);
384                 return FLUID_FAILED;
385             }
386
387         } else {
388             found_track = 0;
389             if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
390                 return FLUID_FAILED;
391             }
392             skip = fluid_getlength(length);
393             /* fseek(mf->fp, skip, SEEK_CUR); */
394             if (fluid_midi_file_skip(mf, skip) != FLUID_OK) {
395                 return FLUID_FAILED;
396             }
397         }
398     }
399     if (fluid_midi_file_eof(mf)) {
400         FLUID_LOG(FLUID_ERR, "Unexpected end of file");
401         return FLUID_FAILED;
402     }
403     return FLUID_OK;
404 }
405
406 /*
407  * fluid_midi_file_read_varlen
408  */
409 int
410 fluid_midi_file_read_varlen(fluid_midi_file *mf)
411 {
412     int i;
413     int c;
414     mf->varlen = 0;
415     for (i = 0;; i++) {
416         if (i == 4) {
417             FLUID_LOG(FLUID_ERR, "Invalid variable length number");
418             return FLUID_FAILED;
419         }
420         c = fluid_midi_file_getc(mf);
421         if (c < 0) {
422             FLUID_LOG(FLUID_ERR, "Unexpected end of file");
423             return FLUID_FAILED;
424         }
425         if (c & 0x80) {
426             mf->varlen |= (int) (c & 0x7F);
427             mf->varlen <<= 7;
428         } else {
429             mf->varlen += c;
430             break;
431         }
432     }
433     return FLUID_OK;
434 }
435
436 /*
437  * fluid_midi_file_read_event
438  */
439 int
440 fluid_midi_file_read_event(fluid_midi_file *mf, fluid_track_t *track)
441 {
442     int status;
443     int type;
444     int tempo;
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;
450     int channel = 0;
451     int param1 = 0;
452     int param2 = 0;
453     int size;
454
455     /* read the delta-time of the event */
456     if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
457         return FLUID_FAILED;
458     }
459     mf->dtime += mf->varlen;
460
461     /* read the status byte */
462     status = fluid_midi_file_getc(mf);
463     if (status < 0) {
464         FLUID_LOG(FLUID_ERR, "Unexpected end of file");
465         return FLUID_FAILED;
466     }
467
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");
472             return FLUID_FAILED;
473         }
474         fluid_midi_file_push(mf, status);
475         status = mf->running_status;
476     }
477
478     /* check what message we have */
479
480     mf->running_status = status;
481
482     if ((status == MIDI_SYSEX)) { /* system exclusif */
483         /* read the length of the message */
484         if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
485             return FLUID_FAILED;
486         }
487
488         if (mf->varlen) {
489             FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__,
490                     __LINE__, mf->varlen);
491             metadata = FLUID_MALLOC(mf->varlen + 1);
492
493             if (metadata == NULL) {
494                 FLUID_LOG(FLUID_PANIC, "Out of memory");
495                 return FLUID_FAILED;
496             }
497
498             /* read the data of the message */
499             if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
500                 FLUID_FREE (metadata);
501                 return FLUID_FAILED;
502             }
503
504             evt = new_fluid_midi_event();
505             if (evt == NULL) {
506                 FLUID_LOG(FLUID_ERR, "Out of memory");
507                 FLUID_FREE (metadata);
508                 return FLUID_FAILED;
509             }
510
511             evt->dtime = mf->dtime;
512             size = mf->varlen;
513
514             if (metadata[mf->varlen - 1] == MIDI_EOX)
515                 size--;
516
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);
520             mf->dtime = 0;
521         }
522
523         return FLUID_OK;
524
525     } else if (status == MIDI_META_EVENT) { /* meta events */
526
527         int result = FLUID_OK;
528
529         /* get the type of the meta message */
530         type = fluid_midi_file_getc(mf);
531         if (type < 0) {
532             FLUID_LOG(FLUID_ERR, "Unexpected end of file");
533             return FLUID_FAILED;
534         }
535
536         /* get the length of the data part */
537         if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
538             return FLUID_FAILED;
539         }
540
541         if (mf->varlen < 255) {
542             metadata = &static_buf[0];
543         } else {
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");
549                 return FLUID_FAILED;
550             }
551             metadata = dyn_buf;
552         }
553
554         /* read the data */
555         if (mf->varlen) {
556             if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
557                 if (dyn_buf) {
558                     FLUID_FREE(dyn_buf);
559                 }
560                 return FLUID_FAILED;
561             }
562         }
563
564         /* handle meta data */
565         switch (type) {
566
567             case MIDI_COPYRIGHT:
568                 metadata[mf->varlen] = 0;
569                 break;
570
571             case MIDI_TRACK_NAME:
572                 metadata[mf->varlen] = 0;
573                 fluid_track_set_name(track, (char *) metadata);
574                 break;
575
576             case MIDI_INST_NAME:
577                 metadata[mf->varlen] = 0;
578                 break;
579
580             case MIDI_LYRIC:
581                 break;
582
583             case MIDI_MARKER:
584                 break;
585
586             case MIDI_CUE_POINT:
587                 break; /* don't care much for text events */
588
589             case MIDI_EOT:
590                 if (mf->varlen != 0) {
591                     FLUID_LOG(FLUID_ERR, "Invalid length for EndOfTrack event");
592                     result = FLUID_FAILED;
593                     break;
594                 }
595                 mf->eot = 1;
596                 evt = new_fluid_midi_event();
597                 if (evt == NULL) {
598                     FLUID_LOG(FLUID_ERR, "Out of memory");
599                     result = FLUID_FAILED;
600                     break;
601                 }
602                 evt->dtime = mf->dtime;
603                 evt->type = MIDI_EOT;
604                 fluid_track_add_event(track, evt);
605                 mf->dtime = 0;
606                 break;
607
608             case MIDI_SET_TEMPO:
609                 if (mf->varlen != 3) {
610                     FLUID_LOG(FLUID_ERR,
611                             "Invalid length for SetTempo meta event");
612                     result = FLUID_FAILED;
613                     break;
614                 }
615                 tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
616                 evt = new_fluid_midi_event();
617                 if (evt == NULL) {
618                     FLUID_LOG(FLUID_ERR, "Out of memory");
619                     result = FLUID_FAILED;
620                     break;
621                 }
622                 evt->dtime = mf->dtime;
623                 evt->type = MIDI_SET_TEMPO;
624                 evt->channel = 0;
625                 evt->param1 = tempo;
626                 evt->param2 = 0;
627                 fluid_track_add_event(track, evt);
628                 mf->dtime = 0;
629                 break;
630
631             case MIDI_SMPTE_OFFSET:
632                 if (mf->varlen != 5) {
633                     FLUID_LOG(FLUID_ERR,
634                             "Invalid length for SMPTE Offset meta event");
635                     result = FLUID_FAILED;
636                     break;
637                 }
638                 break; /* we don't use smtp */
639
640             case MIDI_TIME_SIGNATURE:
641                 if (mf->varlen != 4) {
642                     FLUID_LOG(FLUID_ERR,
643                             "Invalid length for TimeSignature meta event");
644                     result = FLUID_FAILED;
645                     break;
646                 }
647                 nominator = metadata[0];
648                 denominator = pow(2.0, (double) metadata[1]);
649                 clocks = metadata[2];
650                 notes = metadata[3];
651
652                 FLUID_LOG(FLUID_DBG,
653                         "signature=%d/%d, metronome=%d, 32nd-notes=%d",
654                         nominator, denominator, clocks, notes);
655
656                 break;
657
658             case MIDI_KEY_SIGNATURE:
659                 if (mf->varlen != 2) {
660                     FLUID_LOG(FLUID_ERR,
661                             "Invalid length for KeySignature meta event");
662                     result = FLUID_FAILED;
663                     break;
664                 }
665                 /* We don't care about key signatures anyway */
666                 /* sf = metadata[0];
667                 mi = metadata[1]; */
668                 break;
669
670             case MIDI_SEQUENCER_EVENT:
671                 break;
672
673             default:
674                 break;
675         }
676
677         if (dyn_buf) {
678             FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__);
679             FLUID_FREE(dyn_buf);
680         }
681
682         return result;
683
684     } else { /* channel messages */
685
686         type = status & 0xf0;
687         channel = status & 0x0f;
688
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");
692             return FLUID_FAILED;
693         }
694
695         switch (type) {
696
697             case NOTE_ON:
698                 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
699                     FLUID_LOG(FLUID_ERR, "Unexpected end of file");
700                     return FLUID_FAILED;
701                 }
702                 break;
703
704             case NOTE_OFF:
705                 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
706                     FLUID_LOG(FLUID_ERR, "Unexpected end of file");
707                     return FLUID_FAILED;
708                 }
709                 break;
710
711             case KEY_PRESSURE:
712                 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
713                     FLUID_LOG(FLUID_ERR, "Unexpected end of file");
714                     return FLUID_FAILED;
715                 }
716                 break;
717
718             case CONTROL_CHANGE:
719                 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
720                     FLUID_LOG(FLUID_ERR, "Unexpected end of file");
721                     return FLUID_FAILED;
722                 }
723                 break;
724
725             case PROGRAM_CHANGE:
726                 break;
727
728             case CHANNEL_PRESSURE:
729                 break;
730
731             case PITCH_BEND:
732                 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
733                     FLUID_LOG(FLUID_ERR, "Unexpected end of file");
734                     return FLUID_FAILED;
735                 }
736
737                 param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
738                 param2 = 0;
739                 break;
740
741             default:
742                 /* Can't possibly happen !? */
743                 FLUID_LOG(FLUID_ERR, "Unrecognized MIDI event");
744                 return FLUID_FAILED;
745         }
746         evt = new_fluid_midi_event();
747         if (evt == NULL) {
748             FLUID_LOG(FLUID_ERR, "Out of memory");
749             return FLUID_FAILED;
750         }
751         evt->dtime = mf->dtime;
752         evt->type = type;
753         evt->channel = channel;
754         evt->param1 = param1;
755         evt->param2 = param2;
756         fluid_track_add_event(track, evt);
757         mf->dtime = 0;
758     }
759     return FLUID_OK;
760 }
761
762 /*
763  * fluid_midi_file_get_division
764  */
765 int
766 fluid_midi_file_get_division(fluid_midi_file *midifile)
767 {
768     return midifile->division;
769 }
770 #endif
771
772 /******************************************************
773  *
774  *     fluid_track_t
775  */
776
777 /**
778  * Create a MIDI event structure.
779  * @return New MIDI event structure or NULL when out of memory.
780  */
781 fluid_midi_event_t *
782 new_fluid_midi_event ()
783 {
784     fluid_midi_event_t* evt;
785     evt = FLUID_NEW(fluid_midi_event_t);
786     if (evt == NULL) {
787         FLUID_LOG(FLUID_ERR, "Out of memory");
788         return NULL;
789     }
790     evt->dtime = 0;
791     evt->type = 0;
792     evt->channel = 0;
793     evt->param1 = 0;
794     evt->param2 = 0;
795     evt->next = NULL;
796     evt->paramptr = NULL;
797     return evt;
798 }
799
800 /**
801  * Delete MIDI event structure.
802  * @param evt MIDI event structure
803  * @return Always returns #FLUID_OK
804  */
805 int
806 delete_fluid_midi_event(fluid_midi_event_t *evt)
807 {
808     fluid_midi_event_t *temp;
809
810     while (evt) {
811         temp = evt->next;
812
813         /* Dynamic SYSEX event? - free (param2 indicates if dynamic) */
814         if (evt->type == MIDI_SYSEX && evt->paramptr && evt->param2)
815             FLUID_FREE (evt->paramptr);
816
817         FLUID_FREE(evt);
818         evt = temp;
819     }
820     return FLUID_OK;
821 }
822
823 /**
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)
827  */
828 int
829 fluid_midi_event_get_type(fluid_midi_event_t *evt)
830 {
831     return evt->type;
832 }
833
834 /**
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
839  */
840 int
841 fluid_midi_event_set_type(fluid_midi_event_t *evt, int type)
842 {
843     evt->type = type;
844     return FLUID_OK;
845 }
846
847 /**
848  * Get the channel field of a MIDI event structure.
849  * @param evt MIDI event structure
850  * @return Channel field
851  */
852 int
853 fluid_midi_event_get_channel(fluid_midi_event_t *evt)
854 {
855     return evt->channel;
856 }
857
858 /**
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
863  */
864 int
865 fluid_midi_event_set_channel(fluid_midi_event_t *evt, int chan)
866 {
867     evt->channel = chan;
868     return FLUID_OK;
869 }
870
871 /**
872  * Get the key field of a MIDI event structure.
873  * @param evt MIDI event structure
874  * @return MIDI note number (0-127)
875  */
876 int
877 fluid_midi_event_get_key(fluid_midi_event_t *evt)
878 {
879     return evt->param1;
880 }
881
882 /**
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
887  */
888 int
889 fluid_midi_event_set_key(fluid_midi_event_t *evt, int v)
890 {
891     evt->param1 = v;
892     return FLUID_OK;
893 }
894
895 /**
896  * Get the velocity field of a MIDI event structure.
897  * @param evt MIDI event structure
898  * @return MIDI velocity number (0-127)
899  */
900 int
901 fluid_midi_event_get_velocity(fluid_midi_event_t *evt)
902 {
903     return evt->param2;
904 }
905
906 /**
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
911  */
912 int
913 fluid_midi_event_set_velocity(fluid_midi_event_t *evt, int v)
914 {
915     evt->param2 = v;
916     return FLUID_OK;
917 }
918
919 /**
920  * Get the control number of a MIDI event structure.
921  * @param evt MIDI event structure
922  * @return MIDI control number
923  */
924 int
925 fluid_midi_event_get_control(fluid_midi_event_t *evt)
926 {
927     return evt->param1;
928 }
929
930 /**
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
935  */
936 int
937 fluid_midi_event_set_control(fluid_midi_event_t *evt, int v)
938 {
939     evt->param1 = v;
940     return FLUID_OK;
941 }
942
943 /**
944  * Get the value field from a MIDI event structure.
945  * @param evt MIDI event structure
946  * @return Value field
947  */
948 int
949 fluid_midi_event_get_value(fluid_midi_event_t *evt)
950 {
951     return evt->param2;
952 }
953
954 /**
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
959  */
960 int
961 fluid_midi_event_set_value(fluid_midi_event_t *evt, int v)
962 {
963     evt->param2 = v;
964     return FLUID_OK;
965 }
966
967 /**
968  * Get the program field of a MIDI event structure.
969  * @param evt MIDI event structure
970  * @return MIDI program number (0-127)
971  */
972 int
973 fluid_midi_event_get_program(fluid_midi_event_t *evt)
974 {
975     return evt->param1;
976 }
977
978 /**
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
983  */
984 int
985 fluid_midi_event_set_program(fluid_midi_event_t *evt, int val)
986 {
987     evt->param1 = val;
988     return FLUID_OK;
989 }
990
991 /**
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)
995  */
996 int
997 fluid_midi_event_get_pitch(fluid_midi_event_t *evt)
998 {
999     return evt->param1;
1000 }
1001
1002 /**
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
1007  */
1008 int
1009 fluid_midi_event_set_pitch(fluid_midi_event_t *evt, int val)
1010 {
1011     evt->param1 = val;
1012     return FLUID_OK;
1013 }
1014
1015 /**
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
1024  *
1025  * NOTE: Unlike the other event assignment functions, this one sets evt->type.
1026  */
1027 int
1028 fluid_midi_event_set_sysex(fluid_midi_event_t *evt, void *data, int size, int dynamic)
1029 {
1030     evt->type = MIDI_SYSEX;
1031     evt->paramptr = data;
1032     evt->param1 = size;
1033     evt->param2 = dynamic;
1034     return FLUID_OK;
1035 }
1036
1037 /******************************************************
1038  *
1039  *     fluid_track_t
1040  */
1041 #if 0 // disable fluid file player in Ardour
1042 /*
1043  * new_fluid_track
1044  */
1045 fluid_track_t *
1046 new_fluid_track(int num)
1047 {
1048     fluid_track_t *track;
1049     track = FLUID_NEW(fluid_track_t);
1050     if (track == NULL) {
1051         return NULL;
1052     }
1053     track->name = NULL;
1054     track->num = num;
1055     track->first = NULL;
1056     track->cur = NULL;
1057     track->last = NULL;
1058     track->ticks = 0;
1059     return track;
1060 }
1061
1062 /*
1063  * delete_fluid_track
1064  */
1065 int
1066 delete_fluid_track(fluid_track_t *track)
1067 {
1068     if (track->name != NULL) {
1069         FLUID_FREE(track->name);
1070     }
1071     if (track->first != NULL) {
1072         delete_fluid_midi_event(track->first);
1073     }
1074     FLUID_FREE(track);
1075     return FLUID_OK;
1076 }
1077
1078 /*
1079  * fluid_track_set_name
1080  */
1081 int
1082 fluid_track_set_name(fluid_track_t *track, char *name)
1083 {
1084     int len;
1085     if (track->name != NULL) {
1086         FLUID_FREE(track->name);
1087     }
1088     if (name == NULL) {
1089         track->name = NULL;
1090         return FLUID_OK;
1091     }
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;
1097     }
1098     FLUID_STRCPY(track->name, name);
1099     return FLUID_OK;
1100 }
1101
1102 /*
1103  * fluid_track_get_name
1104  */
1105 char *
1106 fluid_track_get_name(fluid_track_t *track)
1107 {
1108     return track->name;
1109 }
1110
1111 /*
1112  * fluid_track_get_duration
1113  */
1114 int
1115 fluid_track_get_duration(fluid_track_t *track)
1116 {
1117     int time = 0;
1118     fluid_midi_event_t *evt = track->first;
1119     while (evt != NULL) {
1120         time += evt->dtime;
1121         evt = evt->next;
1122     }
1123     return time;
1124 }
1125
1126 /*
1127  * fluid_track_count_events
1128  */
1129 static int
1130 fluid_track_count_events(fluid_track_t *track, int *on, int *off)
1131 {
1132     fluid_midi_event_t *evt = track->first;
1133     while (evt != NULL) {
1134         if (evt->type == NOTE_ON) {
1135             (*on)++;
1136         } else if (evt->type == NOTE_OFF) {
1137             (*off)++;
1138         }
1139         evt = evt->next;
1140     }
1141     return FLUID_OK;
1142 }
1143
1144 /*
1145  * fluid_track_add_event
1146  */
1147 int
1148 fluid_track_add_event(fluid_track_t *track, fluid_midi_event_t *evt)
1149 {
1150     evt->next = NULL;
1151     if (track->first == NULL) {
1152         track->first = evt;
1153         track->cur = evt;
1154         track->last = evt;
1155     } else {
1156         track->last->next = evt;
1157         track->last = evt;
1158     }
1159     return FLUID_OK;
1160 }
1161
1162 /*
1163  * fluid_track_first_event
1164  */
1165 fluid_midi_event_t *
1166 fluid_track_first_event(fluid_track_t *track)
1167 {
1168     track->cur = track->first;
1169     return track->cur;
1170 }
1171
1172 /*
1173  * fluid_track_next_event
1174  */
1175 fluid_midi_event_t *
1176 fluid_track_next_event(fluid_track_t *track)
1177 {
1178     if (track->cur != NULL) {
1179         track->cur = track->cur->next;
1180     }
1181     return track->cur;
1182 }
1183
1184 /*
1185  * fluid_track_reset
1186  */
1187 int
1188 fluid_track_reset(fluid_track_t *track)
1189 {
1190     track->ticks = 0;
1191     track->cur = track->first;
1192     return FLUID_OK;
1193 }
1194
1195 /*
1196  * fluid_track_send_events
1197  */
1198 int
1199 fluid_track_send_events(fluid_track_t *track,
1200                         fluid_synth_t *synth,
1201                         fluid_player_t *player,
1202                         unsigned int ticks)
1203 {
1204     int status = FLUID_OK;
1205     fluid_midi_event_t *event;
1206
1207     while (1) {
1208
1209         event = track->cur;
1210         if (event == NULL) {
1211             return status;
1212         }
1213
1214         /*              printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */
1215         /*                     track->num, */
1216         /*                     ticks, */
1217         /*                     track->ticks, */
1218         /*                     event->dtime, */
1219         /*                     track->ticks + event->dtime); */
1220
1221         if (track->ticks + event->dtime > ticks) {
1222             return status;
1223         }
1224
1225         track->ticks += event->dtime;
1226
1227         if (!player || event->type == MIDI_EOT) {
1228         }
1229         else if (event->type == MIDI_SET_TEMPO) {
1230             fluid_player_set_midi_tempo(player, event->param1);
1231         }
1232         else {
1233             if (player->playback_callback)
1234                 player->playback_callback(player->playback_userdata, event);
1235         }
1236
1237         fluid_track_next_event(track);
1238
1239     }
1240     return status;
1241 }
1242
1243 /******************************************************
1244  *
1245  *     fluid_player
1246  */
1247
1248 /**
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)
1252  */
1253 fluid_player_t *
1254 new_fluid_player(fluid_synth_t *synth)
1255 {
1256     int i;
1257     fluid_player_t *player;
1258     player = FLUID_NEW(fluid_player_t);
1259     if (player == NULL) {
1260         FLUID_LOG(FLUID_ERR, "Out of memory");
1261         return NULL;
1262     }
1263     player->status = FLUID_PLAYER_READY;
1264     player->loop = 1;
1265     player->ntracks = 0;
1266     for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
1267         player->track[i] = NULL;
1268     }
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);
1281
1282     player->use_system_timer = fluid_settings_str_equal(synth->settings,
1283             "player.timing-source", "system");
1284
1285     fluid_settings_getint(synth->settings, "player.reset-synth", &i);
1286     player->reset_synth_between_songs = i;
1287
1288     return player;
1289 }
1290
1291 /**
1292  * Delete a MIDI player instance.
1293  * @param player MIDI player instance
1294  * @return Always returns #FLUID_OK
1295  */
1296 int
1297 delete_fluid_player(fluid_player_t *player)
1298 {
1299     fluid_list_t *q;
1300     fluid_playlist_item* pi;
1301
1302     if (player == NULL) {
1303         return FLUID_OK;
1304     }
1305     fluid_player_stop(player);
1306     fluid_player_reset(player);
1307
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);
1313         FLUID_FREE(pi);
1314         delete1_fluid_list(player->playlist);
1315         player->playlist = q;
1316     }
1317
1318     FLUID_FREE(player);
1319     return FLUID_OK;
1320 }
1321
1322 /**
1323  * Registers settings related to the MIDI player
1324  */
1325 void
1326 fluid_player_settings(fluid_settings_t *settings)
1327 {
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,
1331             NULL, NULL);
1332     fluid_settings_add_option(settings, "player.timing-source", "sample");
1333     fluid_settings_add_option(settings, "player.timing-source", "system");
1334
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);
1338 }
1339
1340
1341 int
1342 fluid_player_reset(fluid_player_t *player)
1343 {
1344     int i;
1345
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;
1350         }
1351     }
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;
1360     return 0;
1361 }
1362
1363 /*
1364  * fluid_player_add_track
1365  */
1366 int
1367 fluid_player_add_track(fluid_player_t *player, fluid_track_t *track)
1368 {
1369     if (player->ntracks < MAX_NUMBER_OF_TRACKS) {
1370         player->track[player->ntracks++] = track;
1371         return FLUID_OK;
1372     } else {
1373         return FLUID_FAILED;
1374     }
1375 }
1376
1377 /*
1378  * fluid_player_count_tracks
1379  */
1380 int
1381 fluid_player_count_tracks(fluid_player_t *player)
1382 {
1383     return player->ntracks;
1384 }
1385
1386 /*
1387  * fluid_player_get_track
1388  */
1389 fluid_track_t *
1390 fluid_player_get_track(fluid_player_t *player, int i)
1391 {
1392     if ((i >= 0) && (i < MAX_NUMBER_OF_TRACKS)) {
1393         return player->track[i];
1394     } else {
1395         return NULL;
1396     }
1397 }
1398
1399 /**
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
1409  * @returns FLUID_OK
1410  * @since 1.1.4
1411  */
1412 int 
1413 fluid_player_set_playback_callback(fluid_player_t* player, 
1414     handle_midi_event_func_t handler, void* handler_data)
1415 {
1416     player->playback_callback = handler;
1417     player->playback_userdata = handler_data;
1418     return FLUID_OK;
1419 }
1420
1421 /**
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
1426  */
1427 int
1428 fluid_player_add(fluid_player_t *player, const char *midifile)
1429 {
1430     fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item));
1431     char* f = FLUID_STRDUP(midifile);
1432     if (!pi || !f) {
1433         FLUID_FREE(pi);
1434         FLUID_FREE(f);
1435         FLUID_LOG(FLUID_PANIC, "Out of memory");
1436         return FLUID_FAILED;
1437     }
1438
1439     pi->filename = f;
1440     pi->buffer = NULL;
1441     pi->buffer_len = 0;
1442     player->playlist = fluid_list_append(player->playlist, pi);
1443     return FLUID_OK;
1444 }
1445
1446 /**
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
1454  */
1455 int
1456 fluid_player_add_mem(fluid_player_t* player, const void *buffer, size_t len)
1457 {
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) {
1462         FLUID_FREE(pi);
1463         FLUID_FREE(buf_copy);
1464         FLUID_LOG(FLUID_PANIC, "Out of memory");
1465         return FLUID_FAILED;
1466     }
1467
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);
1473     return FLUID_OK;
1474 }
1475
1476 /*
1477  * fluid_player_load
1478  */
1479 int
1480 fluid_player_load(fluid_player_t *player, fluid_playlist_item *item)
1481 {
1482     fluid_midi_file *midifile;
1483     char* buffer;
1484     size_t buffer_length;
1485     int buffer_owned;
1486
1487     if (item->filename != NULL)
1488     {
1489         fluid_file fp;
1490         /* This file is specified by filename; load the file from disk */
1491         FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile %s", __FILE__, __LINE__,
1492                 item->filename);
1493         /* Read the entire contents of the file into the buffer */
1494         fp = FLUID_FOPEN(item->filename, "rb");
1495         if (fp == NULL) {
1496             FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file");
1497             return FLUID_FAILED;
1498         }
1499         buffer = fluid_file_read_full(fp, &buffer_length);
1500         if (buffer == NULL)
1501         {
1502             FLUID_FCLOSE(fp);
1503             return FLUID_FAILED;
1504         }
1505         buffer_owned = 1;
1506         FLUID_FCLOSE(fp);
1507     }
1508     else
1509     {
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) */
1516         buffer_owned = 0;
1517     }
1518
1519     midifile = new_fluid_midi_file(buffer, buffer_length);
1520     if (midifile == NULL) {
1521         if (buffer_owned) {
1522             FLUID_FREE(buffer);
1523         }
1524         return FLUID_FAILED;
1525     }
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); */
1529
1530     if (fluid_midi_file_load_tracks(midifile, player) != FLUID_OK) {
1531         if (buffer_owned) {
1532             FLUID_FREE(buffer);
1533         }
1534         delete_fluid_midi_file(midifile);
1535         return FLUID_FAILED;
1536     }
1537     delete_fluid_midi_file(midifile);
1538     if (buffer_owned) {
1539         FLUID_FREE(buffer);
1540     }
1541     return FLUID_OK;
1542 }
1543
1544 static void
1545 fluid_player_advancefile(fluid_player_t *player)
1546 {
1547     if (player->playlist == NULL) {
1548         return; /* No files to play */
1549     }
1550     if (player->currentfile != NULL) {
1551         player->currentfile = fluid_list_next(player->currentfile);
1552     }
1553     if (player->currentfile == NULL) {
1554         if (player->loop == 0) {
1555             return; /* We're done playing */
1556         }
1557         if (player->loop > 0) {
1558             player->loop--;
1559         }
1560         player->currentfile = player->playlist;
1561     }
1562 }
1563
1564 static void
1565 fluid_player_playlist_load(fluid_player_t *player, unsigned int msec)
1566 {
1567     fluid_playlist_item* current_playitem;
1568     int i;
1569
1570     do {
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;
1575             return;
1576         }
1577
1578         fluid_player_reset(player);
1579         current_playitem = (fluid_playlist_item *) player->currentfile->data;
1580     } while (fluid_player_load(player, current_playitem) != FLUID_OK);
1581
1582     /* Successfully loaded midi file */
1583
1584     player->begin_msec = msec;
1585     player->start_msec = msec;
1586     player->start_ticks = 0;
1587     player->cur_ticks = 0;
1588
1589     if (player->reset_synth_between_songs) {
1590         fluid_synth_system_reset(player->synth);
1591     }
1592
1593     for (i = 0; i < player->ntracks; i++) {
1594         if (player->track[i] != NULL) {
1595             fluid_track_reset(player->track[i]);
1596         }
1597     }
1598 }
1599
1600
1601 /*
1602  * fluid_player_callback
1603  */
1604 int
1605 fluid_player_callback(void *data, unsigned int msec)
1606 {
1607     int i;
1608     int loadnextfile;
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;
1614
1615     loadnextfile = player->currentfile == NULL ? 1 : 0;
1616     do {
1617         if (loadnextfile) {
1618             loadnextfile = 0;
1619             fluid_player_playlist_load(player, msec);
1620             if (player->currentfile == NULL) {
1621                 return 0;
1622             }
1623         }
1624
1625         player->cur_msec = msec;
1626         player->cur_ticks = (player->start_ticks
1627                 + (int) ((double) (player->cur_msec - player->start_msec)
1628                         / player->deltatime));
1629
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) {
1635                     /* */
1636                 }
1637             }
1638         }
1639
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);
1643             loadnextfile = 1;
1644         }
1645     } while (loadnextfile);
1646
1647     player->status = status;
1648
1649     return 1;
1650 }
1651
1652 /**
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
1656  */
1657 int
1658 fluid_player_play(fluid_player_t *player)
1659 {
1660     if (player->status == FLUID_PLAYER_PLAYING) {
1661         return FLUID_OK;
1662     }
1663
1664     if (player->playlist == NULL) {
1665         return FLUID_OK;
1666     }
1667
1668     player->status = FLUID_PLAYER_PLAYING;
1669
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;
1675         }
1676     } else {
1677         player->sample_timer = new_fluid_sample_timer(player->synth,
1678                 fluid_player_callback, (void *) player);
1679
1680         if (player->sample_timer == NULL) {
1681             return FLUID_FAILED;
1682         }
1683     }
1684     return FLUID_OK;
1685 }
1686
1687 /**
1688  * Stops a MIDI player.
1689  * @param player MIDI player instance
1690  * @return Always returns #FLUID_OK
1691  */
1692 int
1693 fluid_player_stop(fluid_player_t *player)
1694 {
1695     if (player->system_timer != NULL) {
1696         delete_fluid_timer(player->system_timer);
1697     }
1698     if (player->sample_timer != NULL) {
1699         delete_fluid_sample_timer(player->synth, player->sample_timer);
1700     }
1701     player->status = FLUID_PLAYER_DONE;
1702     player->sample_timer = NULL;
1703     player->system_timer = NULL;
1704     return FLUID_OK;
1705 }
1706
1707 /**
1708  * Get MIDI player status.
1709  * @param player MIDI player instance
1710  * @return Player status (#fluid_player_status)
1711  * @since 1.1.0
1712  */
1713 int
1714 fluid_player_get_status(fluid_player_t *player)
1715 {
1716     return player->status;
1717 }
1718
1719 /**
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
1724  * @since 1.1.0
1725  *
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.
1728  */
1729 int fluid_player_set_loop(fluid_player_t *player, int loop)
1730 {
1731     player->loop = loop;
1732     return FLUID_OK;
1733 }
1734
1735 /**
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
1740  */
1741 int fluid_player_set_midi_tempo(fluid_player_t *player, int tempo)
1742 {
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;
1747
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);
1751
1752     return FLUID_OK;
1753 }
1754
1755 /**
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
1760  */
1761 int
1762 fluid_player_set_bpm(fluid_player_t *player, int bpm)
1763 {
1764     return fluid_player_set_midi_tempo(player, (int) ((double) 60 * 1e6 / bpm));
1765 }
1766
1767 /**
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
1771  */
1772 int
1773 fluid_player_join(fluid_player_t *player)
1774 {
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) {
1780 #if defined(WIN32)
1781             Sleep(10);
1782 #else
1783             usleep(10000);
1784 #endif
1785         }
1786     }
1787     return FLUID_OK;
1788 }
1789
1790 /************************************************************************
1791  *       MIDI PARSER
1792  *
1793  */
1794
1795 /*
1796  * new_fluid_midi_parser
1797  */
1798 fluid_midi_parser_t *
1799 new_fluid_midi_parser ()
1800 {
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");
1805         return NULL;
1806     }
1807     parser->status = 0; /* As long as the status is 0, the parser won't do anything -> no need to initialize all the fields. */
1808     return parser;
1809 }
1810
1811 /*
1812  * delete_fluid_midi_parser
1813  */
1814 int
1815 delete_fluid_midi_parser(fluid_midi_parser_t *parser)
1816 {
1817     FLUID_FREE(parser);
1818     return FLUID_OK;
1819 }
1820
1821 /**
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.
1827  */
1828 fluid_midi_event_t *
1829 fluid_midi_parser_parse(fluid_midi_parser_t *parser, unsigned char c)
1830 {
1831     fluid_midi_event_t *event;
1832
1833     /* Real-time messages (0xF8-0xFF) can occur anywhere, even in the middle
1834      * of another message. */
1835     if (c >= 0xF8) {
1836         if (c == MIDI_SYSTEM_RESET) {
1837             parser->event.type = c;
1838             parser->status = 0; /* clear the status */
1839             return &parser->event;
1840         }
1841
1842         return NULL;
1843     }
1844
1845     /* Status byte? - If previous message not yet complete, it is discarded (re-sync). */
1846     if (c & 0x80) {
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,
1851                     FALSE);
1852         } else
1853             event = NULL;
1854
1855         if (c < 0xF0) /* Voice category message? */
1856         {
1857             parser->channel = c & 0x0F;
1858             parser->status = c & 0xF0;
1859
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)
1862                     - 1;
1863
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;
1868         } else
1869             parser->status = 0; /* Discard other system messages (0xF1-0xF7) */
1870
1871         return event; /* Return SYSEX event or NULL */
1872     }
1873
1874     /* Data/parameter byte */
1875
1876     /* Discard data bytes for events we don't care about */
1877     if (parser->status == 0)
1878         return NULL;
1879
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 */
1883         return NULL;
1884     }
1885
1886     /* Store next byte */
1887     parser->data[parser->nr_bytes++] = c;
1888
1889     /* Do we still need more data to get this event complete? */
1890     if (parser->nr_bytes < parser->nr_bytes_total)
1891         return NULL;
1892
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 */
1898
1899     switch (parser->status) {
1900         case NOTE_OFF:
1901         case NOTE_ON:
1902         case KEY_PRESSURE:
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 */
1908             break;
1909         case PITCH_BEND:
1910             /* Pitch-bend is transmitted with 14-bit precision. */
1911             parser->event.param1 = (parser->data[1] << 7) | parser->data[0];
1912             break;
1913         default: /* Unlikely */
1914             return NULL;
1915     }
1916
1917     return &parser->event;
1918 }
1919
1920 /* Purpose:
1921  * Returns the length of a MIDI message. */
1922 static int
1923 fluid_midi_event_length(unsigned char event)
1924 {
1925     switch (event & 0xF0) {
1926         case NOTE_OFF:
1927         case NOTE_ON:
1928         case KEY_PRESSURE:
1929         case CONTROL_CHANGE:
1930         case PITCH_BEND:
1931             return 3;
1932         case PROGRAM_CHANGE:
1933         case CHANNEL_PRESSURE:
1934             return 2;
1935     }
1936     switch (event) {
1937         case MIDI_TIME_CODE:
1938         case MIDI_SONG_SELECT:
1939         case 0xF4:
1940         case 0xF5:
1941             return 2;
1942         case MIDI_TUNE_REQUEST:
1943             return 1;
1944         case MIDI_SONG_POSITION:
1945             return 3;
1946     }
1947     return 1;
1948 }
1949 #endif