00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "fluid_midi.h"
00022 #include "fluid_sys.h"
00023 #include "fluid_synth.h"
00024 #include "fluid_settings.h"
00025
00026
00027 #define MIDI_MESSAGE_LENGTH 1024
00028 char midi_message_buffer[MIDI_MESSAGE_LENGTH];
00029
00030
00031
00032
00033 static int remains_f0f6[] = {
00034 0,
00035 2,
00036 3,
00037 2,
00038 2,
00039 2,
00040 1
00041 };
00042
00043 static int remains_80e0[] = {
00044 3,
00045 3,
00046 3,
00047 3,
00048 2,
00049 2,
00050 3
00051 };
00052
00053
00054
00055
00056
00057
00058
00065 fluid_midi_file* new_fluid_midi_file(char* filename)
00066 {
00067 fluid_midi_file* mf;
00068
00069 mf = FLUID_NEW(fluid_midi_file);
00070 if (mf == NULL) {
00071 FLUID_LOG(FLUID_ERR, "Out of memory");
00072 return NULL;
00073 }
00074 FLUID_MEMSET(mf, 0, sizeof(fluid_midi_file));
00075
00076 mf->c = -1;
00077 mf->running_status = -1;
00078 mf->fp = FLUID_FOPEN(filename, "rb");
00079
00080 if (mf->fp == NULL) {
00081 FLUID_LOG(FLUID_ERR, "Couldn't open the MIDI file");
00082 FLUID_FREE(mf);
00083 return NULL;
00084 }
00085
00086 if (fluid_midi_file_read_mthd(mf) != FLUID_OK) {
00087 FLUID_FREE(mf);
00088 return NULL;
00089 }
00090 return mf;
00091 }
00092
00098 void delete_fluid_midi_file(fluid_midi_file* mf)
00099 {
00100 if (mf == NULL) {
00101 return;
00102 }
00103 if (mf->fp != NULL) {
00104 FLUID_FCLOSE(mf->fp);
00105 }
00106 FLUID_FREE(mf);
00107 return;
00108 }
00109
00110
00111
00112
00113 int fluid_midi_file_getc(fluid_midi_file* mf)
00114 {
00115 unsigned char c;
00116 int n;
00117 if (mf->c >= 0) {
00118 c = mf->c;
00119 mf->c = -1;
00120 } else {
00121 n = FLUID_FREAD(&c, 1, 1, mf->fp);
00122 mf->trackpos++;
00123 }
00124 return (int) c;
00125 }
00126
00127
00128
00129
00130 int fluid_midi_file_push(fluid_midi_file* mf, int c)
00131 {
00132 mf->c = c;
00133 return FLUID_OK;
00134 }
00135
00136
00137
00138
00139 int fluid_midi_file_read(fluid_midi_file* mf, void* buf, int len)
00140 {
00141 int num = FLUID_FREAD(buf, 1, len, mf->fp);
00142 mf->trackpos += num;
00143 #if DEBUG
00144 if (num != len) {
00145 FLUID_LOG(FLUID_DBG, "Coulnd't read the requested number of bytes");
00146 }
00147 #endif
00148 return (num != len)? FLUID_FAILED : FLUID_OK;
00149 }
00150
00151
00152
00153
00154 int fluid_midi_file_skip(fluid_midi_file* mf, int skip)
00155 {
00156 int err = FLUID_FSEEK(mf->fp, skip, SEEK_CUR);
00157 if (err) {
00158 FLUID_LOG(FLUID_ERR, "Failed to seek position in file");
00159 return FLUID_FAILED;
00160 }
00161 return FLUID_OK;
00162 }
00163
00164
00165
00166
00167 int fluid_midi_file_read_mthd(fluid_midi_file* mf)
00168 {
00169 char mthd[15];
00170 if (fluid_midi_file_read(mf, mthd, 14) != FLUID_OK) {
00171 return FLUID_FAILED;
00172 }
00173 if ((FLUID_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6) || (mthd[9] > 2)) {
00174 FLUID_LOG(FLUID_ERR, "Doesn't look like a MIDI file: invalid MThd header");
00175 return FLUID_FAILED;
00176 }
00177 mf->type = mthd[9];
00178 mf->ntracks = (unsigned) mthd[11];
00179 mf->ntracks += (unsigned int) (mthd[10]) << 16;
00180 if((mthd[12]) < 0){
00181 mf->uses_smpte = 1;
00182 mf->smpte_fps = -mthd[12];
00183 mf->smpte_res = (unsigned) mthd[13];
00184 FLUID_LOG(FLUID_ERR, "File uses SMPTE timing -- Not implemented yet");
00185 return FLUID_FAILED;
00186 } else {
00187 mf->uses_smpte = 0;
00188 mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
00189 FLUID_LOG(FLUID_DBG, "Division=%d", mf->division);
00190 }
00191 return FLUID_OK;
00192 }
00193
00194
00195
00196
00197 int fluid_midi_file_load_tracks(fluid_midi_file* mf, fluid_player_t* player)
00198 {
00199 int i;
00200 for (i = 0; i < mf->ntracks; i++) {
00201 if (fluid_midi_file_read_track(mf, player, i) != FLUID_OK) {
00202 return FLUID_FAILED;
00203 }
00204 }
00205 return FLUID_OK;
00206 }
00207
00208
00209
00210
00211 int fluid_isasciistring(char* s)
00212 {
00213 int i;
00214 int len = (int) FLUID_STRLEN(s);
00215 for (i = 0; i < len; i++) {
00216 if (!fluid_isascii(s[i])) {
00217 return 0;
00218 }
00219 }
00220 return 1;
00221 }
00222
00223
00224
00225
00226 long fluid_getlength(unsigned char *s)
00227 {
00228 long i = 0;
00229 i = s[3] | (s[2]<<8) | (s[1]<<16) | (s[0]<<24);
00230 return i;
00231 }
00232
00233
00234
00235
00236 int fluid_midi_file_read_tracklen(fluid_midi_file* mf)
00237 {
00238 unsigned char length[5];
00239 if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
00240 return FLUID_FAILED;
00241 }
00242 mf->tracklen = fluid_getlength(length);
00243 mf->trackpos = 0;
00244 mf->eot = 0;
00245 return FLUID_OK;
00246 }
00247
00248
00249
00250
00251 int fluid_midi_file_eot(fluid_midi_file* mf)
00252 {
00253 #if DEBUG
00254 if (mf->trackpos > mf->tracklen) {
00255 printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen);
00256 }
00257 #endif
00258 return mf->eot || (mf->trackpos >= mf->tracklen);
00259 }
00260
00261
00262
00263
00264 int fluid_midi_file_read_track(fluid_midi_file* mf, fluid_player_t* player, int num)
00265 {
00266 fluid_track_t* track;
00267 unsigned char id[5], length[5];
00268 int found_track = 0;
00269 int skip;
00270
00271 if (fluid_midi_file_read(mf, id, 4) != FLUID_OK) {
00272 return FLUID_FAILED;
00273 }
00274 id[4]='\0';
00275
00276 while (!found_track){
00277
00278 if (fluid_isasciistring((char*) id) == 0) {
00279 FLUID_LOG(FLUID_ERR, "An non-ascii track header found, currupt file");
00280 return FLUID_FAILED;
00281
00282 } else if (strcmp((char*) id, "MTrk") == 0) {
00283
00284 found_track = 1;
00285
00286 if (fluid_midi_file_read_tracklen(mf) != FLUID_OK) {
00287 return FLUID_FAILED;
00288 }
00289
00290 track = new_fluid_track(num);
00291 if (track == NULL) {
00292 FLUID_LOG(FLUID_ERR, "Out of memory");
00293 return FLUID_FAILED;
00294 }
00295
00296 while (!fluid_midi_file_eot(mf)) {
00297 if (fluid_midi_file_read_event(mf, track) != FLUID_OK) {
00298 return FLUID_FAILED;
00299 }
00300 }
00301
00302 fluid_player_add_track(player, track);
00303
00304 } else {
00305 found_track = 0;
00306 if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
00307 return FLUID_FAILED;
00308 }
00309 skip = fluid_getlength(length);
00310
00311 if (fluid_midi_file_skip(mf, skip) != FLUID_OK) {
00312 return FLUID_FAILED;
00313 }
00314 }
00315 }
00316 if (feof(mf->fp)) {
00317 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00318 return FLUID_FAILED;
00319 }
00320 return FLUID_OK;
00321 }
00322
00323
00324
00325
00326 int fluid_midi_file_read_varlen(fluid_midi_file* mf)
00327 {
00328 int i;
00329 int c;
00330 mf->varlen = 0;
00331 for (i = 0;;i++) {
00332 if (i == 4) {
00333 FLUID_LOG(FLUID_ERR, "Invalid variable length number");
00334 return FLUID_FAILED;
00335 }
00336 c = fluid_midi_file_getc(mf);
00337 if (c < 0) {
00338 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00339 return FLUID_FAILED;
00340 }
00341 if (c & 0x80){
00342 mf->varlen |= (int) (c & 0x7F);
00343 mf->varlen <<= 7;
00344 } else {
00345 mf->varlen += c;
00346 break;
00347 }
00348 }
00349 return FLUID_OK;
00350 }
00351
00352
00353
00354
00355 int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
00356 {
00357 int dtime;
00358 int status;
00359 int type;
00360 int tempo;
00361 unsigned char* metadata = NULL;
00362 unsigned char* dyn_buf = NULL;
00363 unsigned char static_buf[256];
00364 int nominator, denominator, clocks, notes, sf, mi;
00365 fluid_midi_event_t* evt;
00366 int channel = 0;
00367 int param1 = 0;
00368 int param2 = 0;
00369
00370
00371 if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
00372 return FLUID_FAILED;
00373 }
00374 dtime = mf->varlen;
00375
00376
00377 status = fluid_midi_file_getc(mf);
00378 if (status < 0) {
00379 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00380 return FLUID_FAILED;
00381 }
00382
00383
00384 if ((status & 0x80) == 0) {
00385 if ((mf->running_status & 0x80) == 0) {
00386 FLUID_LOG(FLUID_ERR, "Undefined status and invalid running status");
00387 return FLUID_FAILED;
00388 }
00389 fluid_midi_file_push(mf, status);
00390 status = mf->running_status;
00391 }
00392
00393
00394 if (status & 0x80) {
00395 mf->running_status = status;
00396
00397 if ((status == MIDI_SYSEX) || (status == MIDI_EOX)) {
00398
00399
00400
00401
00402 if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
00403 return FLUID_FAILED;
00404 }
00405
00406 if (mf->varlen) {
00407
00408 if (mf->varlen < 255) {
00409 metadata = &static_buf[0];
00410 } else {
00411 FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
00412 dyn_buf = FLUID_MALLOC(mf->varlen + 1);
00413 if (dyn_buf == NULL) {
00414 FLUID_LOG(FLUID_PANIC, "Out of memory");
00415 return FLUID_FAILED;
00416 }
00417 metadata = dyn_buf;
00418 }
00419
00420
00421 if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
00422 if (dyn_buf) {
00423 FLUID_FREE(dyn_buf);
00424 }
00425 return FLUID_FAILED;
00426 }
00427
00428 if (dyn_buf) {
00429 FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__);
00430 FLUID_FREE(dyn_buf);
00431 }
00432 }
00433
00434 return FLUID_OK;
00435
00436 } else if (status == MIDI_META_EVENT) {
00437
00438 int result = FLUID_OK;
00439
00440
00441 type = fluid_midi_file_getc(mf);
00442 if (type < 0) {
00443 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00444 return FLUID_FAILED;
00445 }
00446
00447
00448 if (fluid_midi_file_read_varlen(mf) != FLUID_OK) {
00449 return FLUID_FAILED;
00450 }
00451
00452 if (mf->varlen < 255) {
00453 metadata = &static_buf[0];
00454 } else {
00455 FLUID_LOG(FLUID_DBG, "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
00456 dyn_buf = FLUID_MALLOC(mf->varlen + 1);
00457 if (dyn_buf == NULL) {
00458 FLUID_LOG(FLUID_PANIC, "Out of memory");
00459 return FLUID_FAILED;
00460 }
00461 metadata = dyn_buf;
00462 }
00463
00464
00465 if (mf->varlen)
00466 {
00467 if (fluid_midi_file_read(mf, metadata, mf->varlen) != FLUID_OK) {
00468 if (dyn_buf) {
00469 FLUID_FREE(dyn_buf);
00470 }
00471 return FLUID_FAILED;
00472 }
00473 }
00474
00475
00476 switch (type) {
00477
00478 case MIDI_COPYRIGHT:
00479 metadata[mf->varlen] = 0;
00480 break;
00481
00482 case MIDI_TRACK_NAME:
00483 metadata[mf->varlen] = 0;
00484 fluid_track_set_name(track, (char*) metadata);
00485 break;
00486
00487 case MIDI_INST_NAME:
00488 metadata[mf->varlen] = 0;
00489 break;
00490
00491 case MIDI_LYRIC:
00492 break;
00493
00494 case MIDI_MARKER:
00495 break;
00496
00497 case MIDI_CUE_POINT:
00498 break;
00499
00500 case MIDI_EOT:
00501 if (mf->varlen != 0) {
00502 FLUID_LOG(FLUID_ERR, "Invalid length for EndOfTrack event");
00503 result = FLUID_FAILED;
00504 break;
00505 }
00506 mf->eot = 1;
00507 break;
00508
00509 case MIDI_SET_TEMPO:
00510 if (mf->varlen != 3) {
00511 FLUID_LOG(FLUID_ERR, "Invalid length for SetTempo meta event");
00512 result = FLUID_FAILED;
00513 break;
00514 }
00515 tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
00516 evt = new_fluid_midi_event();
00517 if (evt == NULL) {
00518 FLUID_LOG(FLUID_ERR, "Out of memory");
00519 result = FLUID_FAILED;
00520 break;
00521 }
00522 evt->dtime = dtime;
00523 evt->type = MIDI_SET_TEMPO;
00524 evt->channel = 0;
00525 evt->param1 = tempo;
00526 evt->param2 = 0;
00527 fluid_track_add_event(track, evt);
00528 break;
00529
00530 case MIDI_SMPTE_OFFSET:
00531 if (mf->varlen != 5) {
00532 FLUID_LOG(FLUID_ERR, "Invalid length for SMPTE Offset meta event");
00533 result = FLUID_FAILED;
00534 break;
00535 }
00536 break;
00537
00538 case MIDI_TIME_SIGNATURE:
00539 if (mf->varlen != 4) {
00540 FLUID_LOG(FLUID_ERR, "Invalid length for TimeSignature meta event");
00541 result = FLUID_FAILED;
00542 break;
00543 }
00544 nominator = metadata[0];
00545 denominator = pow(2.0, (double) metadata[1]);
00546 clocks = metadata[2];
00547 notes = metadata[3];
00548
00549 FLUID_LOG(FLUID_DBG, "signature=%d/%d, metronome=%d, 32nd-notes=%d",
00550 nominator, denominator, clocks, notes);
00551
00552 break;
00553
00554 case MIDI_KEY_SIGNATURE:
00555 if (mf->varlen != 2) {
00556 FLUID_LOG(FLUID_ERR, "Invalid length for KeySignature meta event");
00557 result = FLUID_FAILED;
00558 break;
00559 }
00560 sf = metadata[0];
00561 mi = metadata[1];
00562 break;
00563
00564 case MIDI_SEQUENCER_EVENT:
00565 break;
00566
00567 default:
00568 break;
00569 }
00570
00571 if (dyn_buf) {
00572 FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__);
00573 FLUID_FREE(dyn_buf);
00574 }
00575
00576 return result;
00577
00578 } else {
00579
00580 type = status & 0xf0;
00581 channel = status & 0x0f;
00582
00583
00584 if ((param1 = fluid_midi_file_getc(mf)) < 0) {
00585 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00586 return FLUID_FAILED;
00587 }
00588
00589 switch (type) {
00590
00591 case NOTE_ON:
00592 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00593 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00594 return FLUID_FAILED;
00595 }
00596 break;
00597
00598 case NOTE_OFF:
00599 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00600 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00601 return FLUID_FAILED;
00602 }
00603 break;
00604
00605 case KEY_PRESSURE:
00606 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00607 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00608 return FLUID_FAILED;
00609 }
00610 break;
00611
00612 case CONTROL_CHANGE:
00613 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00614 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00615 return FLUID_FAILED;
00616 }
00617 break;
00618
00619 case PROGRAM_CHANGE:
00620 break;
00621
00622 case CHANNEL_PRESSURE:
00623 break;
00624
00625 case PITCH_BEND:
00626 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00627 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00628 return FLUID_FAILED;
00629 }
00630
00631 param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
00632 param2 = 0;
00633 break;
00634
00635 default:
00636
00637 FLUID_LOG(FLUID_ERR, "Unrecognized MIDI event");
00638 return FLUID_FAILED;
00639 }
00640 evt = new_fluid_midi_event();
00641 if (evt == NULL) {
00642 FLUID_LOG(FLUID_ERR, "Out of memory");
00643 return FLUID_FAILED;
00644 }
00645 evt->dtime = dtime;
00646 evt->type = type;
00647 evt->channel = channel;
00648 evt->param1 = param1;
00649 evt->param2 = param2;
00650 fluid_track_add_event(track, evt);
00651 }
00652 }
00653 return FLUID_OK;
00654 }
00655
00656
00657
00658
00659 int fluid_midi_file_get_division(fluid_midi_file* midifile)
00660 {
00661 return midifile->division;
00662 }
00663
00664
00665
00666
00667
00668
00673 fluid_midi_event_t* new_fluid_midi_event()
00674 {
00675 fluid_midi_event_t* evt;
00676 evt = FLUID_NEW(fluid_midi_event_t);
00677 if (evt == NULL) {
00678 FLUID_LOG(FLUID_ERR, "Out of memory");
00679 return NULL;
00680 }
00681 evt->dtime = 0;
00682 evt->type = 0;
00683 evt->channel = 0;
00684 evt->param1 = 0;
00685 evt->param2 = 0;
00686 evt->next = NULL;
00687 return evt;
00688 }
00689
00695 int delete_fluid_midi_event(fluid_midi_event_t* evt)
00696 {
00697 fluid_midi_event_t *temp;
00698
00699 while (evt)
00700 {
00701 temp = evt->next;
00702 FLUID_FREE(evt);
00703 evt = temp;
00704 }
00705 return FLUID_OK;
00706 }
00707
00714 int fluid_midi_event_get_type(fluid_midi_event_t* evt)
00715 {
00716 return evt->type;
00717 }
00718
00726 int fluid_midi_event_set_type(fluid_midi_event_t* evt, int type)
00727 {
00728 evt->type = type;
00729 return FLUID_OK;
00730 }
00731
00737 int fluid_midi_event_get_channel(fluid_midi_event_t* evt)
00738 {
00739 return evt->channel;
00740 }
00741
00748 int fluid_midi_event_set_channel(fluid_midi_event_t* evt, int chan)
00749 {
00750 evt->channel = chan;
00751 return FLUID_OK;
00752 }
00753
00759 int fluid_midi_event_get_key(fluid_midi_event_t* evt)
00760 {
00761 return evt->param1;
00762 }
00763
00770 int fluid_midi_event_set_key(fluid_midi_event_t* evt, int v)
00771 {
00772 evt->param1 = v;
00773 return FLUID_OK;
00774 }
00775
00781 int fluid_midi_event_get_velocity(fluid_midi_event_t* evt)
00782 {
00783 return evt->param2;
00784 }
00785
00792 int fluid_midi_event_set_velocity(fluid_midi_event_t* evt, int v)
00793 {
00794 evt->param2 = v;
00795 return FLUID_OK;
00796 }
00797
00803 int fluid_midi_event_get_control(fluid_midi_event_t* evt)
00804 {
00805 return evt->param1;
00806 }
00807
00814 int fluid_midi_event_set_control(fluid_midi_event_t* evt, int v)
00815 {
00816 evt->param1 = v;
00817 return FLUID_OK;
00818 }
00819
00825 int fluid_midi_event_get_value(fluid_midi_event_t* evt)
00826 {
00827 return evt->param2;
00828 }
00829
00836 int fluid_midi_event_set_value(fluid_midi_event_t* evt, int v)
00837 {
00838 evt->param2 = v;
00839 return FLUID_OK;
00840 }
00841
00847 int fluid_midi_event_get_program(fluid_midi_event_t* evt)
00848 {
00849 return evt->param1;
00850 }
00851
00858 int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val)
00859 {
00860 evt->param1 = val;
00861 return FLUID_OK;
00862 }
00863
00869 int fluid_midi_event_get_pitch(fluid_midi_event_t* evt)
00870 {
00871 return evt->param1;
00872 }
00873
00880 int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val)
00881 {
00882 evt->param1 = val;
00883 return FLUID_OK;
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 fluid_track_t* new_fluid_track(int num)
00929 {
00930 fluid_track_t* track;
00931 track = FLUID_NEW(fluid_track_t);
00932 if (track == NULL) {
00933 return NULL;
00934 }
00935 track->name = NULL;
00936 track->num = num;
00937 track->first = NULL;
00938 track->cur = NULL;
00939 track->last = NULL;
00940 track->ticks = 0;
00941 return track;
00942 }
00943
00944
00945
00946
00947 int delete_fluid_track(fluid_track_t* track)
00948 {
00949 if (track->name != NULL) {
00950 FLUID_FREE(track->name);
00951 }
00952 if (track->first != NULL) {
00953 delete_fluid_midi_event(track->first);
00954 }
00955 FLUID_FREE(track);
00956 return FLUID_OK;
00957 }
00958
00959
00960
00961
00962 int fluid_track_set_name(fluid_track_t* track, char* name)
00963 {
00964 int len;
00965 if (track->name != NULL) {
00966 FLUID_FREE(track->name);
00967 }
00968 if (name == NULL) {
00969 track->name = NULL;
00970 return FLUID_OK;
00971 }
00972 len = FLUID_STRLEN(name);
00973 track->name = FLUID_MALLOC(len + 1);
00974 if (track->name == NULL) {
00975 FLUID_LOG(FLUID_ERR, "Out of memory");
00976 return FLUID_FAILED;
00977 }
00978 FLUID_STRCPY(track->name, name);
00979 return FLUID_OK;
00980 }
00981
00982
00983
00984
00985 char* fluid_track_get_name(fluid_track_t* track)
00986 {
00987 return track->name;
00988 }
00989
00990
00991
00992
00993 int fluid_track_get_duration(fluid_track_t* track)
00994 {
00995 int time = 0;
00996 fluid_midi_event_t* evt = track->first;
00997 while (evt != NULL) {
00998 time += evt->dtime;
00999 evt = evt->next;
01000 }
01001 return time;
01002 }
01003
01004
01005
01006
01007 int fluid_track_count_events(fluid_track_t* track, int* on, int* off)
01008 {
01009 fluid_midi_event_t* evt = track->first;
01010 while (evt != NULL) {
01011 if (evt->type == NOTE_ON) {
01012 (*on)++;
01013 } else if (evt->type == NOTE_OFF) {
01014 (*off)++;
01015 }
01016 evt = evt->next;
01017 }
01018 return FLUID_OK;
01019 }
01020
01021
01022
01023
01024 int fluid_track_add_event(fluid_track_t* track, fluid_midi_event_t* evt)
01025 {
01026 evt->next = NULL;
01027 if (track->first == NULL) {
01028 track->first = evt;
01029 track->cur = evt;
01030 track->last = evt;
01031 } else {
01032 track->last->next = evt;
01033 track->last = evt;
01034 }
01035 return FLUID_OK;
01036 }
01037
01038
01039
01040
01041 fluid_midi_event_t* fluid_track_first_event(fluid_track_t* track)
01042 {
01043 track->cur = track->first;
01044 return track->cur;
01045 }
01046
01047
01048
01049
01050 fluid_midi_event_t* fluid_track_next_event(fluid_track_t* track)
01051 {
01052 if (track->cur != NULL) {
01053 track->cur = track->cur->next;
01054 }
01055 return track->cur;
01056 }
01057
01058
01059
01060
01061 int
01062 fluid_track_reset(fluid_track_t* track)
01063 {
01064 track->ticks = 0;
01065 track->cur = track->first;
01066 return FLUID_OK;
01067 }
01068
01069
01070
01071
01072 int
01073 fluid_track_send_events(fluid_track_t* track,
01074 fluid_synth_t* synth,
01075 fluid_player_t* player,
01076 unsigned int ticks)
01077 {
01078 int status = FLUID_OK;
01079 fluid_midi_event_t* event;
01080
01081 while (1) {
01082
01083 event = track->cur;
01084 if (event == NULL) {
01085 return status;
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095 if (track->ticks + event->dtime > ticks) {
01096 return status;
01097 }
01098
01099
01100 track->ticks += event->dtime;
01101 status = fluid_midi_send_event(synth, player, event);
01102 fluid_track_next_event(track);
01103
01104 }
01105 return status;
01106 }
01107
01108
01109
01110
01111
01112
01118 fluid_player_t* new_fluid_player(fluid_synth_t* synth)
01119 {
01120 int i;
01121 fluid_player_t* player;
01122 player = FLUID_NEW(fluid_player_t);
01123 if (player == NULL) {
01124 FLUID_LOG(FLUID_ERR, "Out of memory");
01125 return NULL;
01126 }
01127 player->status = FLUID_PLAYER_READY;
01128 player->loop = 0;
01129 player->ntracks = 0;
01130 for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
01131 player->track[i] = NULL;
01132 }
01133 player->synth = synth;
01134 player->timer = NULL;
01135 player->playlist = NULL;
01136 player->current_file = NULL;
01137 player->division = 0;
01138 player->send_program_change = 1;
01139 player->miditempo = 480000;
01140 player->deltatime = 4.0;
01141 return player;
01142 }
01143
01149 int delete_fluid_player(fluid_player_t* player)
01150 {
01151 if (player == NULL) {
01152 return FLUID_OK;
01153 }
01154 fluid_player_stop(player);
01155 fluid_player_reset(player);
01156 FLUID_FREE(player);
01157 return FLUID_OK;
01158 }
01159
01160 int fluid_player_reset(fluid_player_t* player)
01161 {
01162 int i;
01163
01164 for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
01165 if (player->track[i] != NULL) {
01166 delete_fluid_track(player->track[i]);
01167 player->track[i] = NULL;
01168 }
01169 }
01170 player->current_file = NULL;
01171 player->status = FLUID_PLAYER_READY;
01172 player->loop = 0;
01173 player->ntracks = 0;
01174 player->division = 0;
01175 player->send_program_change = 1;
01176 player->miditempo = 480000;
01177 player->deltatime = 4.0;
01178 return 0;
01179 }
01180
01181
01182
01183
01184 int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track)
01185 {
01186 if (player->ntracks < MAX_NUMBER_OF_TRACKS) {
01187 player->track[player->ntracks++] = track;
01188 return FLUID_OK;
01189 } else {
01190 return FLUID_FAILED;
01191 }
01192 }
01193
01194
01195
01196
01197 int fluid_player_count_tracks(fluid_player_t* player)
01198 {
01199 return player->ntracks;
01200 }
01201
01202
01203
01204
01205 fluid_track_t* fluid_player_get_track(fluid_player_t* player, int i)
01206 {
01207 if ((i >= 0) && (i < MAX_NUMBER_OF_TRACKS)) {
01208 return player->track[i];
01209 } else {
01210 return NULL;
01211 }
01212 }
01213
01214 int fluid_player_add(fluid_player_t* player, char* midifile)
01215 {
01216 char *s = FLUID_STRDUP(midifile);
01217 player->playlist = fluid_list_append(player->playlist, s);
01218 return 0;
01219 }
01220
01221
01222
01223
01224 int fluid_player_load(fluid_player_t* player, char *filename)
01225 {
01226 fluid_midi_file* midifile;
01227
01228 midifile = new_fluid_midi_file(filename);
01229 if (midifile == NULL) {
01230 return FLUID_FAILED;
01231 }
01232 player->division = fluid_midi_file_get_division(midifile);
01233
01234
01235
01236 if (fluid_midi_file_load_tracks(midifile, player) != FLUID_OK){
01237 return FLUID_FAILED;
01238 }
01239 delete_fluid_midi_file(midifile);
01240 return FLUID_OK;
01241 }
01242
01243
01244
01245
01246 int fluid_player_callback(void* data, unsigned int msec)
01247 {
01248 int i;
01249 int status = FLUID_PLAYER_DONE;
01250 fluid_player_t* player;
01251 fluid_synth_t* synth;
01252 player = (fluid_player_t*) data;
01253 synth = player->synth;
01254
01255
01256 while (player->current_file == NULL) {
01257
01258 if (player->playlist == NULL) {
01259 return 0;
01260 }
01261
01262 fluid_player_reset(player);
01263
01264 player->current_file = fluid_list_get(player->playlist);
01265 player->playlist = fluid_list_next(player->playlist);
01266
01267 FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile %s", __FILE__, __LINE__, player->current_file);
01268
01269 if (fluid_player_load(player, player->current_file) == FLUID_OK) {
01270
01271 player->begin_msec = msec;
01272 player->start_msec = msec;
01273 player->start_ticks = 0;
01274 player->cur_ticks = 0;
01275
01276 for (i = 0; i < player->ntracks; i++) {
01277 if (player->track[i] != NULL) {
01278 fluid_track_reset(player->track[i]);
01279 }
01280 }
01281
01282 } else {
01283 player->current_file = NULL;
01284 }
01285 }
01286
01287 player->cur_msec = msec;
01288 player->cur_ticks = (player->start_ticks +
01289 (int) ((double) (player->cur_msec - player->start_msec) / player->deltatime));
01290
01291 for (i = 0; i < player->ntracks; i++) {
01292 if (!fluid_track_eot(player->track[i])) {
01293 status = FLUID_PLAYER_PLAYING;
01294 if (fluid_track_send_events(player->track[i], synth, player, player->cur_ticks) != FLUID_OK) {
01295
01296 }
01297 }
01298 }
01299
01300 player->status = status;
01301
01302 if (player->status == FLUID_PLAYER_DONE) {
01303 FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec",
01304 __FILE__, __LINE__, (msec - player->begin_msec) / 1000.0);
01305 player->current_file = NULL;
01306 }
01307
01308 return 1;
01309 }
01310
01316 int fluid_player_play(fluid_player_t* player)
01317 {
01318 if (player->status == FLUID_PLAYER_PLAYING) {
01319 return FLUID_OK;
01320 }
01321
01322 if (player->playlist == NULL) {
01323 return FLUID_OK;
01324 }
01325
01326 player->status = FLUID_PLAYER_PLAYING;
01327
01328 player->timer = new_fluid_timer((int) player->deltatime, fluid_player_callback,
01329 (void*) player, 1, 0);
01330 if (player->timer == NULL) {
01331 return FLUID_FAILED;
01332 }
01333 return FLUID_OK;
01334 }
01335
01341 int fluid_player_stop(fluid_player_t* player)
01342 {
01343 if (player->timer != NULL) {
01344 delete_fluid_timer(player->timer);
01345 }
01346 player->status = FLUID_PLAYER_DONE;
01347 player->timer = NULL;
01348 return FLUID_OK;
01349 }
01350
01351
01352
01359 int fluid_player_set_loop(fluid_player_t* player, int loop)
01360 {
01361 player->loop = loop;
01362 return FLUID_OK;
01363 }
01364
01372 int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo)
01373 {
01374 player->miditempo = tempo;
01375 player->deltatime = (double) tempo / player->division / 1000.0;
01376 player->start_msec = player->cur_msec;
01377 player->start_ticks = player->cur_ticks;
01378
01379 FLUID_LOG(FLUID_DBG,"tempo=%d, tick time=%f msec, cur time=%d msec, cur tick=%d",
01380 tempo, player->deltatime, player->cur_msec, player->cur_ticks);
01381
01382 return FLUID_OK;
01383 }
01384
01391 int fluid_player_set_bpm(fluid_player_t* player, int bpm)
01392 {
01393 return fluid_player_set_midi_tempo(player, (int)((double) 60 * 1e6 / bpm));
01394 }
01395
01402 int fluid_player_join(fluid_player_t* player)
01403 {
01404 return player->timer? fluid_timer_join(player->timer) : FLUID_OK;
01405 }
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415 fluid_midi_parser_t* new_fluid_midi_parser()
01416 {
01417 fluid_midi_parser_t* parser;
01418 parser = FLUID_NEW(fluid_midi_parser_t);
01419 if (parser == NULL) {
01420 FLUID_LOG(FLUID_ERR, "Out of memory");
01421 return NULL;
01422 }
01423 parser->status = 0;
01424 return parser;
01425 }
01426
01427
01428
01429
01430 int delete_fluid_midi_parser(fluid_midi_parser_t* parser)
01431 {
01432 FLUID_FREE(parser);
01433 return FLUID_OK;
01434 }
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444 fluid_midi_event_t* fluid_midi_parser_parse(fluid_midi_parser_t* parser, unsigned char c)
01445 {
01446
01447
01448
01449
01450
01451
01452
01453
01454 if (c >= 0xF8){
01455 if (c == MIDI_SYSTEM_RESET){
01456 parser->event.type = c;
01457 parser->status = 0;
01458 return &parser->event;
01459 };
01460 return NULL;
01461 };
01462
01463
01464
01465
01466
01467
01468
01469
01470 if (c > 0xF0){
01471
01472
01473
01474
01475 parser->status = 0;
01476 return NULL;
01477 };
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 if (c & 0x80){
01491 parser->channel = c & 0x0F;
01492 parser->status = c & 0xF0;
01493
01494 parser->nr_bytes_total=fluid_midi_event_length(parser->status)-1;
01495
01496 parser->nr_bytes = 0;
01497 return NULL;
01498 };
01499
01500
01501
01502
01503
01504
01505 if (parser->status == 0){
01506
01507
01508 return NULL;
01509 };
01510
01511
01512 if (parser->nr_bytes < FLUID_MIDI_PARSER_MAX_PAR){
01513 parser->p[parser->nr_bytes]=c;
01514 };
01515 parser->nr_bytes++;
01516
01517
01518 if (parser->nr_bytes < parser->nr_bytes_total){
01519 return NULL;
01520 };
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532 parser->event.type = parser->status;
01533 parser->event.channel = parser->channel;
01534 parser->nr_bytes = 0;
01535 switch (parser->status){
01536 case NOTE_OFF:
01537 case NOTE_ON:
01538 case KEY_PRESSURE:
01539 case CONTROL_CHANGE:
01540 case PROGRAM_CHANGE:
01541 case CHANNEL_PRESSURE:
01542 parser->event.param1 = parser->p[0];
01543 parser->event.param2 = parser->p[1];
01544 break;
01545 case PITCH_BEND:
01546
01547 parser->event.param1 = ((parser->p[1] << 7) | parser->p[0]);
01548 break;
01549 default:
01550
01551 return NULL;
01552 };
01553 return &parser->event;
01554 };
01555
01556
01557
01558
01559 int fluid_midi_event_length(unsigned char event){
01560 if ( event < 0xf0 ) {
01561 return remains_80e0[((event-0x80)>>4)&0x0f];
01562 } else if ( event < 0xf7 ) {
01563 return remains_f0f6[event-0xf0];
01564 } else {
01565 return 1;
01566 }
01567 }
01568
01569
01570
01571
01572
01573
01574
01575 int fluid_midi_send_event(fluid_synth_t* synth, fluid_player_t* player, fluid_midi_event_t* event)
01576 {
01577 switch (event->type) {
01578 case NOTE_ON:
01579 if (fluid_synth_noteon(synth, event->channel, event->param1, event->param2) != FLUID_OK) {
01580 return FLUID_FAILED;
01581 }
01582 break;
01583 case NOTE_OFF:
01584 if (fluid_synth_noteoff(synth, event->channel, event->param1) != FLUID_OK) {
01585 return FLUID_FAILED;
01586 }
01587 break;
01588 case CONTROL_CHANGE:
01589 if (fluid_synth_cc(synth, event->channel, event->param1, event->param2) != FLUID_OK) {
01590 return FLUID_FAILED;
01591 }
01592 break;
01593 case MIDI_SET_TEMPO:
01594 if (player != NULL) {
01595 if (fluid_player_set_midi_tempo(player, event->param1) != FLUID_OK) {
01596 return FLUID_FAILED;
01597 }
01598 }
01599 break;
01600 case PROGRAM_CHANGE:
01601 if (fluid_synth_program_change(synth, event->channel, event->param1) != FLUID_OK) {
01602 return FLUID_FAILED;
01603 }
01604 break;
01605 case PITCH_BEND:
01606 if (fluid_synth_pitch_bend(synth, event->channel, event->param1) != FLUID_OK) {
01607 return FLUID_FAILED;
01608 }
01609 break;
01610 default:
01611 break;
01612 }
01613 return FLUID_OK;
01614 }