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 mf->dtime = 0;
00276
00277 while (!found_track){
00278
00279 if (fluid_isasciistring((char*) id) == 0) {
00280 FLUID_LOG(FLUID_ERR, "An non-ascii track header found, currupt file");
00281 return FLUID_FAILED;
00282
00283 } else if (strcmp((char*) id, "MTrk") == 0) {
00284
00285 found_track = 1;
00286
00287 if (fluid_midi_file_read_tracklen(mf) != FLUID_OK) {
00288 return FLUID_FAILED;
00289 }
00290
00291 track = new_fluid_track(num);
00292 if (track == NULL) {
00293 FLUID_LOG(FLUID_ERR, "Out of memory");
00294 return FLUID_FAILED;
00295 }
00296
00297 while (!fluid_midi_file_eot(mf)) {
00298 if (fluid_midi_file_read_event(mf, track) != FLUID_OK) {
00299 return FLUID_FAILED;
00300 }
00301 }
00302
00303 fluid_player_add_track(player, track);
00304
00305 } else {
00306 found_track = 0;
00307 if (fluid_midi_file_read(mf, length, 4) != FLUID_OK) {
00308 return FLUID_FAILED;
00309 }
00310 skip = fluid_getlength(length);
00311
00312 if (fluid_midi_file_skip(mf, skip) != FLUID_OK) {
00313 return FLUID_FAILED;
00314 }
00315 }
00316 }
00317 if (feof(mf->fp)) {
00318 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00319 return FLUID_FAILED;
00320 }
00321 return FLUID_OK;
00322 }
00323
00324
00325
00326
00327 int fluid_midi_file_read_varlen(fluid_midi_file* mf)
00328 {
00329 int i;
00330 int c;
00331 mf->varlen = 0;
00332 for (i = 0;;i++) {
00333 if (i == 4) {
00334 FLUID_LOG(FLUID_ERR, "Invalid variable length number");
00335 return FLUID_FAILED;
00336 }
00337 c = fluid_midi_file_getc(mf);
00338 if (c < 0) {
00339 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00340 return FLUID_FAILED;
00341 }
00342 if (c & 0x80){
00343 mf->varlen |= (int) (c & 0x7F);
00344 mf->varlen <<= 7;
00345 } else {
00346 mf->varlen += c;
00347 break;
00348 }
00349 }
00350 return FLUID_OK;
00351 }
00352
00353
00354
00355
00356 int fluid_midi_file_read_event(fluid_midi_file* mf, fluid_track_t* track)
00357 {
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 mf->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 = mf->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 mf->dtime = 0;
00529 break;
00530
00531 case MIDI_SMPTE_OFFSET:
00532 if (mf->varlen != 5) {
00533 FLUID_LOG(FLUID_ERR, "Invalid length for SMPTE Offset meta event");
00534 result = FLUID_FAILED;
00535 break;
00536 }
00537 break;
00538
00539 case MIDI_TIME_SIGNATURE:
00540 if (mf->varlen != 4) {
00541 FLUID_LOG(FLUID_ERR, "Invalid length for TimeSignature meta event");
00542 result = FLUID_FAILED;
00543 break;
00544 }
00545 nominator = metadata[0];
00546 denominator = pow(2.0, (double) metadata[1]);
00547 clocks = metadata[2];
00548 notes = metadata[3];
00549
00550 FLUID_LOG(FLUID_DBG, "signature=%d/%d, metronome=%d, 32nd-notes=%d",
00551 nominator, denominator, clocks, notes);
00552
00553 break;
00554
00555 case MIDI_KEY_SIGNATURE:
00556 if (mf->varlen != 2) {
00557 FLUID_LOG(FLUID_ERR, "Invalid length for KeySignature meta event");
00558 result = FLUID_FAILED;
00559 break;
00560 }
00561 sf = metadata[0];
00562 mi = metadata[1];
00563 break;
00564
00565 case MIDI_SEQUENCER_EVENT:
00566 break;
00567
00568 default:
00569 break;
00570 }
00571
00572 if (dyn_buf) {
00573 FLUID_LOG(FLUID_DBG, "%s: %d: free metadata", __FILE__, __LINE__);
00574 FLUID_FREE(dyn_buf);
00575 }
00576
00577 return result;
00578
00579 } else {
00580
00581 type = status & 0xf0;
00582 channel = status & 0x0f;
00583
00584
00585 if ((param1 = fluid_midi_file_getc(mf)) < 0) {
00586 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00587 return FLUID_FAILED;
00588 }
00589
00590 switch (type) {
00591
00592 case NOTE_ON:
00593 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00594 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00595 return FLUID_FAILED;
00596 }
00597 break;
00598
00599 case NOTE_OFF:
00600 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00601 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00602 return FLUID_FAILED;
00603 }
00604 break;
00605
00606 case KEY_PRESSURE:
00607 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00608 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00609 return FLUID_FAILED;
00610 }
00611 break;
00612
00613 case CONTROL_CHANGE:
00614 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00615 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00616 return FLUID_FAILED;
00617 }
00618 break;
00619
00620 case PROGRAM_CHANGE:
00621 break;
00622
00623 case CHANNEL_PRESSURE:
00624 break;
00625
00626 case PITCH_BEND:
00627 if ((param2 = fluid_midi_file_getc(mf)) < 0) {
00628 FLUID_LOG(FLUID_ERR, "Unexpected end of file");
00629 return FLUID_FAILED;
00630 }
00631
00632 param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
00633 param2 = 0;
00634 break;
00635
00636 default:
00637
00638 FLUID_LOG(FLUID_ERR, "Unrecognized MIDI event");
00639 return FLUID_FAILED;
00640 }
00641 evt = new_fluid_midi_event();
00642 if (evt == NULL) {
00643 FLUID_LOG(FLUID_ERR, "Out of memory");
00644 return FLUID_FAILED;
00645 }
00646 evt->dtime = mf->dtime;
00647 evt->type = type;
00648 evt->channel = channel;
00649 evt->param1 = param1;
00650 evt->param2 = param2;
00651 fluid_track_add_event(track, evt);
00652 mf->dtime = 0;
00653 }
00654 }
00655 return FLUID_OK;
00656 }
00657
00658
00659
00660
00661 int fluid_midi_file_get_division(fluid_midi_file* midifile)
00662 {
00663 return midifile->division;
00664 }
00665
00666
00667
00668
00669
00670
00675 fluid_midi_event_t* new_fluid_midi_event()
00676 {
00677 fluid_midi_event_t* evt;
00678 evt = FLUID_NEW(fluid_midi_event_t);
00679 if (evt == NULL) {
00680 FLUID_LOG(FLUID_ERR, "Out of memory");
00681 return NULL;
00682 }
00683 evt->dtime = 0;
00684 evt->type = 0;
00685 evt->channel = 0;
00686 evt->param1 = 0;
00687 evt->param2 = 0;
00688 evt->next = NULL;
00689 return evt;
00690 }
00691
00697 int delete_fluid_midi_event(fluid_midi_event_t* evt)
00698 {
00699 fluid_midi_event_t *temp;
00700
00701 while (evt)
00702 {
00703 temp = evt->next;
00704 FLUID_FREE(evt);
00705 evt = temp;
00706 }
00707 return FLUID_OK;
00708 }
00709
00716 int fluid_midi_event_get_type(fluid_midi_event_t* evt)
00717 {
00718 return evt->type;
00719 }
00720
00728 int fluid_midi_event_set_type(fluid_midi_event_t* evt, int type)
00729 {
00730 evt->type = type;
00731 return FLUID_OK;
00732 }
00733
00739 int fluid_midi_event_get_channel(fluid_midi_event_t* evt)
00740 {
00741 return evt->channel;
00742 }
00743
00750 int fluid_midi_event_set_channel(fluid_midi_event_t* evt, int chan)
00751 {
00752 evt->channel = chan;
00753 return FLUID_OK;
00754 }
00755
00761 int fluid_midi_event_get_key(fluid_midi_event_t* evt)
00762 {
00763 return evt->param1;
00764 }
00765
00772 int fluid_midi_event_set_key(fluid_midi_event_t* evt, int v)
00773 {
00774 evt->param1 = v;
00775 return FLUID_OK;
00776 }
00777
00783 int fluid_midi_event_get_velocity(fluid_midi_event_t* evt)
00784 {
00785 return evt->param2;
00786 }
00787
00794 int fluid_midi_event_set_velocity(fluid_midi_event_t* evt, int v)
00795 {
00796 evt->param2 = v;
00797 return FLUID_OK;
00798 }
00799
00805 int fluid_midi_event_get_control(fluid_midi_event_t* evt)
00806 {
00807 return evt->param1;
00808 }
00809
00816 int fluid_midi_event_set_control(fluid_midi_event_t* evt, int v)
00817 {
00818 evt->param1 = v;
00819 return FLUID_OK;
00820 }
00821
00827 int fluid_midi_event_get_value(fluid_midi_event_t* evt)
00828 {
00829 return evt->param2;
00830 }
00831
00838 int fluid_midi_event_set_value(fluid_midi_event_t* evt, int v)
00839 {
00840 evt->param2 = v;
00841 return FLUID_OK;
00842 }
00843
00849 int fluid_midi_event_get_program(fluid_midi_event_t* evt)
00850 {
00851 return evt->param1;
00852 }
00853
00860 int fluid_midi_event_set_program(fluid_midi_event_t* evt, int val)
00861 {
00862 evt->param1 = val;
00863 return FLUID_OK;
00864 }
00865
00871 int fluid_midi_event_get_pitch(fluid_midi_event_t* evt)
00872 {
00873 return evt->param1;
00874 }
00875
00882 int fluid_midi_event_set_pitch(fluid_midi_event_t* evt, int val)
00883 {
00884 evt->param1 = val;
00885 return FLUID_OK;
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
00929
00930 fluid_track_t* new_fluid_track(int num)
00931 {
00932 fluid_track_t* track;
00933 track = FLUID_NEW(fluid_track_t);
00934 if (track == NULL) {
00935 return NULL;
00936 }
00937 track->name = NULL;
00938 track->num = num;
00939 track->first = NULL;
00940 track->cur = NULL;
00941 track->last = NULL;
00942 track->ticks = 0;
00943 return track;
00944 }
00945
00946
00947
00948
00949 int delete_fluid_track(fluid_track_t* track)
00950 {
00951 if (track->name != NULL) {
00952 FLUID_FREE(track->name);
00953 }
00954 if (track->first != NULL) {
00955 delete_fluid_midi_event(track->first);
00956 }
00957 FLUID_FREE(track);
00958 return FLUID_OK;
00959 }
00960
00961
00962
00963
00964 int fluid_track_set_name(fluid_track_t* track, char* name)
00965 {
00966 int len;
00967 if (track->name != NULL) {
00968 FLUID_FREE(track->name);
00969 }
00970 if (name == NULL) {
00971 track->name = NULL;
00972 return FLUID_OK;
00973 }
00974 len = FLUID_STRLEN(name);
00975 track->name = FLUID_MALLOC(len + 1);
00976 if (track->name == NULL) {
00977 FLUID_LOG(FLUID_ERR, "Out of memory");
00978 return FLUID_FAILED;
00979 }
00980 FLUID_STRCPY(track->name, name);
00981 return FLUID_OK;
00982 }
00983
00984
00985
00986
00987 char* fluid_track_get_name(fluid_track_t* track)
00988 {
00989 return track->name;
00990 }
00991
00992
00993
00994
00995 int fluid_track_get_duration(fluid_track_t* track)
00996 {
00997 int time = 0;
00998 fluid_midi_event_t* evt = track->first;
00999 while (evt != NULL) {
01000 time += evt->dtime;
01001 evt = evt->next;
01002 }
01003 return time;
01004 }
01005
01006
01007
01008
01009 int fluid_track_count_events(fluid_track_t* track, int* on, int* off)
01010 {
01011 fluid_midi_event_t* evt = track->first;
01012 while (evt != NULL) {
01013 if (evt->type == NOTE_ON) {
01014 (*on)++;
01015 } else if (evt->type == NOTE_OFF) {
01016 (*off)++;
01017 }
01018 evt = evt->next;
01019 }
01020 return FLUID_OK;
01021 }
01022
01023
01024
01025
01026 int fluid_track_add_event(fluid_track_t* track, fluid_midi_event_t* evt)
01027 {
01028 evt->next = NULL;
01029 if (track->first == NULL) {
01030 track->first = evt;
01031 track->cur = evt;
01032 track->last = evt;
01033 } else {
01034 track->last->next = evt;
01035 track->last = evt;
01036 }
01037 return FLUID_OK;
01038 }
01039
01040
01041
01042
01043 fluid_midi_event_t* fluid_track_first_event(fluid_track_t* track)
01044 {
01045 track->cur = track->first;
01046 return track->cur;
01047 }
01048
01049
01050
01051
01052 fluid_midi_event_t* fluid_track_next_event(fluid_track_t* track)
01053 {
01054 if (track->cur != NULL) {
01055 track->cur = track->cur->next;
01056 }
01057 return track->cur;
01058 }
01059
01060
01061
01062
01063 int
01064 fluid_track_reset(fluid_track_t* track)
01065 {
01066 track->ticks = 0;
01067 track->cur = track->first;
01068 return FLUID_OK;
01069 }
01070
01071
01072
01073
01074 int
01075 fluid_track_send_events(fluid_track_t* track,
01076 fluid_synth_t* synth,
01077 fluid_player_t* player,
01078 unsigned int ticks)
01079 {
01080 int status = FLUID_OK;
01081 fluid_midi_event_t* event;
01082
01083 while (1) {
01084
01085 event = track->cur;
01086 if (event == NULL) {
01087 return status;
01088 }
01089
01090
01091
01092
01093
01094
01095
01096
01097 if (track->ticks + event->dtime > ticks) {
01098 return status;
01099 }
01100
01101
01102 track->ticks += event->dtime;
01103 status = fluid_midi_send_event(synth, player, event);
01104 fluid_track_next_event(track);
01105
01106 }
01107 return status;
01108 }
01109
01110
01111
01112
01113
01114
01120 fluid_player_t* new_fluid_player(fluid_synth_t* synth)
01121 {
01122 int i;
01123 fluid_player_t* player;
01124 player = FLUID_NEW(fluid_player_t);
01125 if (player == NULL) {
01126 FLUID_LOG(FLUID_ERR, "Out of memory");
01127 return NULL;
01128 }
01129 player->status = FLUID_PLAYER_READY;
01130 player->loop = 0;
01131 player->ntracks = 0;
01132 for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
01133 player->track[i] = NULL;
01134 }
01135 player->synth = synth;
01136 player->timer = NULL;
01137 player->playlist = NULL;
01138 player->current_file = NULL;
01139 player->division = 0;
01140 player->send_program_change = 1;
01141 player->miditempo = 480000;
01142 player->deltatime = 4.0;
01143 return player;
01144 }
01145
01151 int delete_fluid_player(fluid_player_t* player)
01152 {
01153 if (player == NULL) {
01154 return FLUID_OK;
01155 }
01156 fluid_player_stop(player);
01157 fluid_player_reset(player);
01158 FLUID_FREE(player);
01159 return FLUID_OK;
01160 }
01161
01162 int fluid_player_reset(fluid_player_t* player)
01163 {
01164 int i;
01165
01166 for (i = 0; i < MAX_NUMBER_OF_TRACKS; i++) {
01167 if (player->track[i] != NULL) {
01168 delete_fluid_track(player->track[i]);
01169 player->track[i] = NULL;
01170 }
01171 }
01172 player->current_file = NULL;
01173 player->status = FLUID_PLAYER_READY;
01174 player->loop = 0;
01175 player->ntracks = 0;
01176 player->division = 0;
01177 player->send_program_change = 1;
01178 player->miditempo = 480000;
01179 player->deltatime = 4.0;
01180 return 0;
01181 }
01182
01183
01184
01185
01186 int fluid_player_add_track(fluid_player_t* player, fluid_track_t* track)
01187 {
01188 if (player->ntracks < MAX_NUMBER_OF_TRACKS) {
01189 player->track[player->ntracks++] = track;
01190 return FLUID_OK;
01191 } else {
01192 return FLUID_FAILED;
01193 }
01194 }
01195
01196
01197
01198
01199 int fluid_player_count_tracks(fluid_player_t* player)
01200 {
01201 return player->ntracks;
01202 }
01203
01204
01205
01206
01207 fluid_track_t* fluid_player_get_track(fluid_player_t* player, int i)
01208 {
01209 if ((i >= 0) && (i < MAX_NUMBER_OF_TRACKS)) {
01210 return player->track[i];
01211 } else {
01212 return NULL;
01213 }
01214 }
01215
01216 int fluid_player_add(fluid_player_t* player, char* midifile)
01217 {
01218 char *s = FLUID_STRDUP(midifile);
01219 player->playlist = fluid_list_append(player->playlist, s);
01220 return 0;
01221 }
01222
01223
01224
01225
01226 int fluid_player_load(fluid_player_t* player, char *filename)
01227 {
01228 fluid_midi_file* midifile;
01229
01230 midifile = new_fluid_midi_file(filename);
01231 if (midifile == NULL) {
01232 return FLUID_FAILED;
01233 }
01234 player->division = fluid_midi_file_get_division(midifile);
01235
01236
01237
01238 if (fluid_midi_file_load_tracks(midifile, player) != FLUID_OK){
01239 return FLUID_FAILED;
01240 }
01241 delete_fluid_midi_file(midifile);
01242 return FLUID_OK;
01243 }
01244
01245
01246
01247
01248 int fluid_player_callback(void* data, unsigned int msec)
01249 {
01250 int i;
01251 int status = FLUID_PLAYER_DONE;
01252 fluid_player_t* player;
01253 fluid_synth_t* synth;
01254 player = (fluid_player_t*) data;
01255 synth = player->synth;
01256
01257
01258 while (player->current_file == NULL) {
01259
01260 if (player->playlist == NULL) {
01261 return 0;
01262 }
01263
01264 fluid_player_reset(player);
01265
01266 player->current_file = fluid_list_get(player->playlist);
01267 player->playlist = fluid_list_next(player->playlist);
01268
01269 FLUID_LOG(FLUID_DBG, "%s: %d: Loading midifile %s", __FILE__, __LINE__, player->current_file);
01270
01271 if (fluid_player_load(player, player->current_file) == FLUID_OK) {
01272
01273 player->begin_msec = msec;
01274 player->start_msec = msec;
01275 player->start_ticks = 0;
01276 player->cur_ticks = 0;
01277
01278 for (i = 0; i < player->ntracks; i++) {
01279 if (player->track[i] != NULL) {
01280 fluid_track_reset(player->track[i]);
01281 }
01282 }
01283
01284 } else {
01285 player->current_file = NULL;
01286 }
01287 }
01288
01289 player->cur_msec = msec;
01290 player->cur_ticks = (player->start_ticks +
01291 (int) ((double) (player->cur_msec - player->start_msec) / player->deltatime));
01292
01293 for (i = 0; i < player->ntracks; i++) {
01294 if (!fluid_track_eot(player->track[i])) {
01295 status = FLUID_PLAYER_PLAYING;
01296 if (fluid_track_send_events(player->track[i], synth, player, player->cur_ticks) != FLUID_OK) {
01297
01298 }
01299 }
01300 }
01301
01302 player->status = status;
01303
01304 if (player->status == FLUID_PLAYER_DONE) {
01305 FLUID_LOG(FLUID_DBG, "%s: %d: Duration=%.3f sec",
01306 __FILE__, __LINE__, (msec - player->begin_msec) / 1000.0);
01307 player->current_file = NULL;
01308 }
01309
01310 return 1;
01311 }
01312
01318 int fluid_player_play(fluid_player_t* player)
01319 {
01320 if (player->status == FLUID_PLAYER_PLAYING) {
01321 return FLUID_OK;
01322 }
01323
01324 if (player->playlist == NULL) {
01325 return FLUID_OK;
01326 }
01327
01328 player->status = FLUID_PLAYER_PLAYING;
01329
01330 player->timer = new_fluid_timer((int) player->deltatime, fluid_player_callback,
01331 (void*) player, 1, 0);
01332 if (player->timer == NULL) {
01333 return FLUID_FAILED;
01334 }
01335 return FLUID_OK;
01336 }
01337
01343 int fluid_player_stop(fluid_player_t* player)
01344 {
01345 if (player->timer != NULL) {
01346 delete_fluid_timer(player->timer);
01347 }
01348 player->status = FLUID_PLAYER_DONE;
01349 player->timer = NULL;
01350 return FLUID_OK;
01351 }
01352
01353
01354
01361 int fluid_player_set_loop(fluid_player_t* player, int loop)
01362 {
01363 player->loop = loop;
01364 return FLUID_OK;
01365 }
01366
01374 int fluid_player_set_midi_tempo(fluid_player_t* player, int tempo)
01375 {
01376 player->miditempo = tempo;
01377 player->deltatime = (double) tempo / player->division / 1000.0;
01378 player->start_msec = player->cur_msec;
01379 player->start_ticks = player->cur_ticks;
01380
01381 FLUID_LOG(FLUID_DBG,"tempo=%d, tick time=%f msec, cur time=%d msec, cur tick=%d",
01382 tempo, player->deltatime, player->cur_msec, player->cur_ticks);
01383
01384 return FLUID_OK;
01385 }
01386
01393 int fluid_player_set_bpm(fluid_player_t* player, int bpm)
01394 {
01395 return fluid_player_set_midi_tempo(player, (int)((double) 60 * 1e6 / bpm));
01396 }
01397
01404 int fluid_player_join(fluid_player_t* player)
01405 {
01406 return player->timer? fluid_timer_join(player->timer) : FLUID_OK;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 fluid_midi_parser_t* new_fluid_midi_parser()
01418 {
01419 fluid_midi_parser_t* parser;
01420 parser = FLUID_NEW(fluid_midi_parser_t);
01421 if (parser == NULL) {
01422 FLUID_LOG(FLUID_ERR, "Out of memory");
01423 return NULL;
01424 }
01425 parser->status = 0;
01426 return parser;
01427 }
01428
01429
01430
01431
01432 int delete_fluid_midi_parser(fluid_midi_parser_t* parser)
01433 {
01434 FLUID_FREE(parser);
01435 return FLUID_OK;
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446 fluid_midi_event_t* fluid_midi_parser_parse(fluid_midi_parser_t* parser, unsigned char c)
01447 {
01448
01449
01450
01451
01452
01453
01454
01455
01456 if (c >= 0xF8){
01457 if (c == MIDI_SYSTEM_RESET){
01458 parser->event.type = c;
01459 parser->status = 0;
01460 return &parser->event;
01461 };
01462 return NULL;
01463 };
01464
01465
01466
01467
01468
01469
01470
01471
01472 if (c > 0xF0){
01473
01474
01475
01476
01477 parser->status = 0;
01478 return NULL;
01479 };
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492 if (c & 0x80){
01493 parser->channel = c & 0x0F;
01494 parser->status = c & 0xF0;
01495
01496 parser->nr_bytes_total=fluid_midi_event_length(parser->status)-1;
01497
01498 parser->nr_bytes = 0;
01499 return NULL;
01500 };
01501
01502
01503
01504
01505
01506
01507 if (parser->status == 0){
01508
01509
01510 return NULL;
01511 };
01512
01513
01514 if (parser->nr_bytes < FLUID_MIDI_PARSER_MAX_PAR){
01515 parser->p[parser->nr_bytes]=c;
01516 };
01517 parser->nr_bytes++;
01518
01519
01520 if (parser->nr_bytes < parser->nr_bytes_total){
01521 return NULL;
01522 };
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534 parser->event.type = parser->status;
01535 parser->event.channel = parser->channel;
01536 parser->nr_bytes = 0;
01537 switch (parser->status){
01538 case NOTE_OFF:
01539 case NOTE_ON:
01540 case KEY_PRESSURE:
01541 case CONTROL_CHANGE:
01542 case PROGRAM_CHANGE:
01543 case CHANNEL_PRESSURE:
01544 parser->event.param1 = parser->p[0];
01545 parser->event.param2 = parser->p[1];
01546 break;
01547 case PITCH_BEND:
01548
01549 parser->event.param1 = ((parser->p[1] << 7) | parser->p[0]);
01550 break;
01551 default:
01552
01553 return NULL;
01554 };
01555 return &parser->event;
01556 };
01557
01558
01559
01560
01561 int fluid_midi_event_length(unsigned char event){
01562 if ( event < 0xf0 ) {
01563 return remains_80e0[((event-0x80)>>4)&0x0f];
01564 } else if ( event < 0xf7 ) {
01565 return remains_f0f6[event-0xf0];
01566 } else {
01567 return 1;
01568 }
01569 }
01570
01571
01572
01573
01574
01575
01576
01577 int fluid_midi_send_event(fluid_synth_t* synth, fluid_player_t* player, fluid_midi_event_t* event)
01578 {
01579 switch (event->type) {
01580 case NOTE_ON:
01581 if (fluid_synth_noteon(synth, event->channel, event->param1, event->param2) != FLUID_OK) {
01582 return FLUID_FAILED;
01583 }
01584 break;
01585 case NOTE_OFF:
01586 if (fluid_synth_noteoff(synth, event->channel, event->param1) != FLUID_OK) {
01587 return FLUID_FAILED;
01588 }
01589 break;
01590 case CONTROL_CHANGE:
01591 if (fluid_synth_cc(synth, event->channel, event->param1, event->param2) != FLUID_OK) {
01592 return FLUID_FAILED;
01593 }
01594 break;
01595 case MIDI_SET_TEMPO:
01596 if (player != NULL) {
01597 if (fluid_player_set_midi_tempo(player, event->param1) != FLUID_OK) {
01598 return FLUID_FAILED;
01599 }
01600 }
01601 break;
01602 case PROGRAM_CHANGE:
01603 if (fluid_synth_program_change(synth, event->channel, event->param1) != FLUID_OK) {
01604 return FLUID_FAILED;
01605 }
01606 break;
01607 case PITCH_BEND:
01608 if (fluid_synth_pitch_bend(synth, event->channel, event->param1) != FLUID_OK) {
01609 return FLUID_FAILED;
01610 }
01611 break;
01612 default:
01613 break;
01614 }
01615 return FLUID_OK;
01616 }