00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #include "player.h"
00029 #include "sndcard.h"
00030 #include "midispec.h"
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <sys/time.h>
00034 #include "midistat.h"
00035 #include "mt32togm.h"
00036 
00037 
00038 
00039 
00040 #define T2MS(ticks) (((double)ticks)*(double)60000L)/((double)tempoToMetronomeTempo(tempo)*(double)info->ticksPerCuarterNote)
00041 
00042 #define MS2T(ms) (((ms)*(double)tempoToMetronomeTempo(tempo)*(double)info->ticksPerCuarterNote)/((double)60000L))
00043 
00044 #define REMOVEDUPSTRINGS
00045 
00046 MidiPlayer::MidiPlayer(DeviceManager *midi_,PlayerController *pctl)
00047 {
00048   midi=midi_;
00049   info=NULL;
00050   tracks=NULL;
00051   songLoaded=0;
00052   ctl=pctl;
00053   spev=NULL;
00054   na=NULL;
00055   parsesong=true;
00056   generatebeats=false;
00057 }
00058 
00059 MidiPlayer::~MidiPlayer()
00060 {
00061   removeSpecialEvents();
00062   removeSong();
00063 }
00064 
00065 void MidiPlayer::removeSong(void)
00066 {
00067   if ((songLoaded)&&(tracks!=NULL))
00068   {
00069 #ifdef PLAYERDEBUG
00070     printf("Removing song from memory\n");
00071 #endif
00072     int i=0;
00073     while (i<info->ntracks)
00074     {
00075       if (tracks[i]!=NULL) delete tracks[i];
00076       i++;
00077     }
00078     delete tracks;
00079     tracks=NULL;
00080     if (info!=NULL)
00081     {
00082       delete info;
00083       info=NULL;
00084     }
00085   }
00086   songLoaded=0;
00087 }
00088 
00089 int MidiPlayer::loadSong(const char *filename)
00090 {
00091   removeSong();
00092 #ifdef PLAYERDEBUG
00093   printf("Loading Song : %s\n",filename);
00094 #endif
00095   info=new MidiFileInfo;
00096   int ok;
00097   tracks=readMidiFile(filename,info,ok);
00098   if (ok<0) return ok;
00099   if (tracks==NULL) return -4;
00100 
00101   parseInfoData(info,tracks,ctl->ratioTempo);
00102 
00103   if (parsesong)
00104   {
00105     parseSpecialEvents();
00106     if (generatebeats) generateBeats();
00107   }
00108 
00109   songLoaded=1;
00110   return 0;
00111 }
00112 
00113 void MidiPlayer::insertBeat(SpecialEvent *ev,ulong ms,int num,int den)
00114 {
00115   SpecialEvent *beat=new SpecialEvent;
00116   beat->next=ev->next;
00117   ev->next=beat;
00118   beat->id=1;
00119   beat->type=7;
00120   beat->absmilliseconds=ms;
00121   beat->num=num;
00122   beat->den=den;
00123 }
00124 
00125 
00126 void MidiPlayer::generateBeats(void)
00127 {
00128 #ifdef PLAYERDEBUG
00129   printf("player::Generating Beats...\n");
00130 #endif
00131 
00132   if (spev==NULL) return;
00133   SpecialEvent *ev=spev;
00134   SpecialEvent *nextev=ev->next;
00135   ulong tempo=(ulong)(500000 * ctl->ratioTempo);
00136   int i=1;
00137   int num=4;
00138   int den=4;
00139   
00140   
00141   double ticksleft=(((double)info->ticksPerCuarterNote*4)/den);
00142 
00143   double beatstep=T2MS(ticksleft);
00144   double nextbeatms=0;
00145   double lastbeatms=0;
00146   double measurems=0;
00147 
00148   while (nextev!=NULL)
00149   {
00150     switch (ev->type)
00151     {
00152       case (0): 
00153     {
00154     };break;
00155       case (1): 
00156       case (2): 
00157     {
00158     };break;
00159       case (3): 
00160     {
00161       lastbeatms=ev->absmilliseconds;
00162       ticksleft=MS2T(nextbeatms-lastbeatms);
00163       tempo=ev->tempo;
00164       nextbeatms=lastbeatms+T2MS(ticksleft);
00165       
00166       
00167       beatstep=T2MS(((static_cast<double>(info->ticksPerCuarterNote)*4)/den));
00168     };break;
00169       case (6): 
00170     {
00171       num=ev->num;
00172       i=1;
00173       den=ev->den;
00174       
00175       
00176       
00177       beatstep=T2MS((((double)info->ticksPerCuarterNote*4)/den));
00178       nextbeatms=ev->absmilliseconds;
00179     };break;
00180     };
00181     if (nextev->absmilliseconds>nextbeatms)
00182     {
00183       
00184       
00185       
00186       if (i == 1) {
00187           measurems=nextbeatms;
00188       }
00189       insertBeat(ev, static_cast<unsigned long>(nextbeatms), i++, num);
00190       if (i > num) {
00191           i=1;
00192       }
00193       lastbeatms=nextbeatms;
00194       nextbeatms+=beatstep;
00195       
00196 
00197       ticksleft = ( (static_cast<double>(info->ticksPerCuarterNote)*4) / den);
00198 
00199     }
00200 
00201     ev=ev->next;
00202     nextev=ev->next;
00203   }
00204 
00205   
00206 
00207   if (ev!=NULL)
00208   {
00209     if (ev->type==0)
00210     {
00211       ev=spev;
00212       
00213 
00214 
00215       if (ev->next!=NULL)
00216     while (ev->next->type!=0) ev=ev->next;
00217     }
00218     while (nextbeatms<info->millisecsTotal)
00219     {
00220       
00221       if (i==1) measurems=nextbeatms;
00222       insertBeat(ev, static_cast<unsigned long>(nextbeatms), i++, num);
00223       if (i>num) i=1;
00224       nextbeatms+=beatstep;
00225       ev=ev->next;
00226     }
00227   }
00228 
00229   
00230 
00231   ev=spev;
00232   i=1;
00233   while (ev!=NULL)
00234   {
00235     ev->id=i++;
00236     ev=ev->next;
00237   }
00238 
00239 
00240 #ifdef PLAYERDEBUG
00241   printf("player::Beats Generated\n");
00242 #endif
00243 
00244 }
00245 
00246 void MidiPlayer::removeSpecialEvents(void)
00247 {
00248   SpecialEvent * ev=spev;
00249   while (spev!=NULL)
00250   {
00251     ev=spev->next;
00252     delete spev;
00253     spev=ev;
00254   }
00255   delete na;
00256   na=0;
00257 }
00258 
00259 void MidiPlayer::parseSpecialEvents(void)
00260 {
00261 #ifdef PLAYERDEBUG
00262   printf("player::Parsing...\n");
00263 #endif
00264   removeSpecialEvents();
00265   spev=new SpecialEvent;
00266   if (spev==NULL) return;
00267   SpecialEvent *pspev=spev;
00268   pspev->type=0;
00269   pspev->ticks=0;
00270   if (na) delete na;
00271   na=new NoteArray();
00272   if (!na) { delete spev; spev=0L; return; };
00273   int trk;
00274   int minTrk;
00275   double minTime=0;
00276   double maxTime;
00277   ulong tempo=(ulong)(500000 * (ctl->ratioTempo));
00278   ulong firsttempo=0;
00279   for (int i=0;i<info->ntracks;i++)
00280   {
00281     tracks[i]->init();
00282     tracks[i]->changeTempo(tempo);
00283   }
00284   MidiEvent *ev=new MidiEvent;
00285   
00286   double prevms=0;
00287   int spev_id=1;
00288   int j;
00289   int parsing=1;
00290 #ifdef REMOVEDUPSTRINGS
00291   char lasttext[1024];
00292   ulong lasttexttime=0;
00293   lasttext[0]=0;
00294   int lasttexttype=0;
00295 #endif
00296   while (parsing)
00297   {
00298     prevms=minTime;
00299     trk=0;
00300     minTrk=0;
00301     maxTime=minTime + 2 * 60000L;
00302     minTime=maxTime;
00303     parsing=0;
00304     while (trk<info->ntracks)
00305     {
00306       if (tracks[trk]->absMsOfNextEvent()<minTime)
00307       {
00308         minTrk=trk;
00309         minTime=tracks[minTrk]->absMsOfNextEvent();
00310         parsing=1;
00311       }
00312       trk++;
00313     }
00314     
00315     if (parsing==0)
00316     {
00317       
00318 #ifdef PLAYERDEBUG
00319       printf("END of parsing\n");
00320 #endif
00321     }
00322     else
00323     {
00324       
00325       trk=0;
00326       while (trk<info->ntracks)
00327       {
00328         tracks[trk]->currentMs(minTime);
00329         trk++;
00330       }     
00331     }
00332     trk=minTrk;
00333     tracks[trk]->readEvent(ev);
00334     switch (ev->command)
00335     {
00336       case (MIDI_NOTEON) :
00337         if (ev->vel==0) na->add((ulong)minTime,ev->chn,0, ev->note);
00338         else na->add((ulong)minTime,ev->chn,1,ev->note);
00339         break;
00340       case (MIDI_NOTEOFF) :
00341         na->add((ulong)minTime,ev->chn,0, ev->note);
00342         break;
00343       case (MIDI_PGM_CHANGE) :
00344         na->add((ulong)minTime,ev->chn, 2,ev->patch);
00345         break;
00346       case (MIDI_SYSTEM_PREFIX) :
00347         {
00348           if ((ev->command|ev->chn)==META_EVENT)
00349           {
00350             switch (ev->d1)
00351             {
00352               case (1) :
00353               case (5) :
00354                 {
00355                   if (pspev!=NULL)
00356                   {
00357                     pspev->absmilliseconds=(ulong)minTime;
00358                     pspev->type=ev->d1;
00359                     pspev->id=spev_id++;
00360 #ifdef PLAYERDEBUG
00361                     printf("ev->length %ld\n",ev->length);
00362  
00363 #endif
00364                     strncpy(pspev->text,(char *)ev->data,
00365                         (ev->length>1024)? (1023) : (ev->length) );
00366                     pspev->text[(ev->length>1024)? (1023):(ev->length)]=0;
00367 #ifdef PLAYERDEBUG
00368                     printf("(%s)(%s)\n",pspev->text,lasttext);
00369 #endif
00370 #ifdef REMOVEDUPSTRINGS
00371                     if ((strcmp(pspev->text,lasttext)!=0)||(pspev->absmilliseconds!=lasttexttime)||(pspev->type!=lasttexttype))
00372                     {
00373                       lasttexttime=pspev->absmilliseconds;
00374                       lasttexttype=pspev->type;
00375                       strncpy(lasttext, pspev->text, 1024);
00376                       lasttext[1023] = 0;
00377 #endif
00378                       pspev->next=new SpecialEvent;
00379 #ifdef PLAYERDEBUG
00380                       if (pspev->next==NULL) printf("pspev->next=NULL\n");
00381 #endif
00382                       pspev=pspev->next;
00383 #ifdef REMOVEDUPSTRINGS
00384                     }
00385 #endif
00386                   }
00387                 }
00388                 break;
00389               case (ME_SET_TEMPO) :
00390                 {
00391                   if (pspev!=NULL)
00392                   {
00393                     pspev->absmilliseconds=(ulong)minTime;
00394                     pspev->type=3;
00395                     pspev->id=spev_id++;
00396                     tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2])) * ctl->ratioTempo);
00397                     pspev->tempo=tempo;
00398                     if (firsttempo==0) firsttempo=tempo;
00399                     for (j=0;j<info->ntracks;j++)
00400                     {
00401                       tracks[j]->changeTempo(tempo);
00402                     }
00403                     pspev->next=new SpecialEvent;
00404                     pspev=pspev->next;
00405                   }
00406                 }
00407                 break;
00408               case (ME_TIME_SIGNATURE) :
00409                 {
00410                   if (pspev!=NULL)
00411                   {
00412                     pspev->absmilliseconds=(ulong)minTime;
00413                     pspev->type=6;
00414                     pspev->id=spev_id++;
00415                     pspev->num=ev->d2;
00416                     pspev->den=ev->d3;
00417                     pspev->next=new SpecialEvent;
00418                     pspev=pspev->next;
00419                   }
00420                 }
00421                 break;
00422             }
00423           }
00424         }
00425         break;
00426     }
00427   }
00428  
00429   delete ev;
00430   pspev->type=0;
00431   pspev->absmilliseconds=(ulong)prevms;
00432   pspev->next=NULL;
00433   if (firsttempo==0) firsttempo=tempo;
00434   ctl->tempo=firsttempo;
00435  
00436   
00437   for (int i=0;i<info->ntracks;i++)
00438   {
00439     tracks[i]->init();
00440   }
00441 }
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 void MidiPlayer::play(bool calloutput,void output(void))
00532 {       
00533 #ifdef PLAYERDEBUG
00534   printf("Playing...\n");
00535 #endif
00536   
00537   if (midi->midiPorts()+midi->synthDevices()==0) 
00538   {
00539     fprintf(stderr,"Player :: There are no midi ports !\n");
00540     ctl->error=1;
00541     return;
00542   }
00543 
00544   midi->openDev();
00545   if (midi->ok()==0) 
00546   {
00547     fprintf(stderr,"Player :: Couldn't play !\n");
00548     ctl->error=1;
00549     return;
00550   }
00551   midi->setVolumePercentage(ctl->volumepercentage);
00552   midi->initDev();
00553   
00554   midi->setPatchesToUse(info->patchesUsed);
00555 
00556   int trk;
00557   int minTrk;
00558   double minTime=0;
00559   double maxTime;
00560   int i;
00561   ulong tempo=(ulong)(500000 * ctl->ratioTempo);
00562   for (i=0;i<info->ntracks;i++)
00563   {
00564     tracks[i]->init();
00565     tracks[i]->changeTempo(tempo);
00566   }
00567 
00568   midi->tmrStart(info->ticksPerCuarterNote);
00569   MidiEvent *ev=new MidiEvent;
00570   ctl->ev=ev;
00571   ctl->ticksTotal=info->ticksTotal;
00572   ctl->ticksPlayed=0;
00573   
00574   ulong ticksplayed=0;
00575   double absTimeAtChangeTempo=0;
00576   double absTime=0;
00577   double diffTime=0;
00578   MidiStatus *midistat;
00579   
00580   double prevms=0;
00581   int j;
00582   int halt=0;
00583   ctl->tempo=tempo;
00584   ctl->num=4;
00585   ctl->den=4;
00586   int playing;
00587   ctl->paused=0;
00588   if ((ctl->message!=0)&&(ctl->message & PLAYER_SETPOS))
00589   {
00590     ctl->moving=1;
00591     ctl->message&=~PLAYER_SETPOS;
00592     midi->sync(1);
00593     midi->tmrStop();
00594     midi->closeDev();
00595     midistat = new MidiStatus();
00596     setPos(ctl->gotomsec,midistat);
00597     minTime=ctl->gotomsec;
00598     prevms=(ulong)minTime;
00599     midi->openDev();
00600     midi->tmrStart(info->ticksPerCuarterNote);
00601     diffTime=ctl->gotomsec;
00602     midistat->sendData(midi,ctl->gm);
00603     delete midistat;
00604     midi->setPatchesToUse(info->patchesUsed);
00605     ctl->moving=0;
00606   } else
00607     for (i=0;i<16;i++)
00608     {
00609       if (ctl->forcepgm[i])
00610       {
00611     midi->chnPatchChange(i, ctl->pgm[i]);
00612       }
00613     }
00614 
00615   timeval begintv;
00616   gettimeofday(&begintv, NULL);
00617   ctl->beginmillisec=begintv.tv_sec*1000+begintv.tv_usec/1000;
00618   ctl->OK=1;
00619   ctl->playing=playing=1;
00620 
00621   while (playing)
00622     {
00623       
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675     prevms=minTime;
00676       
00677       trk=0;
00678       minTrk=0;
00679       maxTime=minTime + 120000L ;
00680     minTime=maxTime;
00681       playing=0;
00682       while (trk<info->ntracks)
00683       {
00684     if (tracks[trk]->absMsOfNextEvent()<minTime)
00685     {
00686       minTrk=trk;
00687       minTime=tracks[minTrk]->absMsOfNextEvent();
00688       playing=1;
00689     }
00690     trk++;
00691       }
00692 #ifdef PLAYERDEBUG
00693       printf("minTime %g\n",minTime);
00694 #endif
00695       
00696       if (playing==0)
00697       {
00698     
00699 #ifdef PLAYERDEBUG
00700     printf("END of playing\n");
00701 #endif
00702       }
00703       else
00704       { 
00705     
00706     trk=0;
00707     while (trk<info->ntracks)
00708     {
00709       tracks[trk]->currentMs(minTime);
00710       trk++;
00711     }
00712     midi->wait(minTime-diffTime);
00713       }
00714       trk=minTrk;
00715       tracks[trk]->readEvent(ev);
00716       switch (ev->command)
00717       {
00718     case (MIDI_NOTEON) : 
00719       midi->noteOn(ev->chn, ev->note, ev->vel);break;
00720     case (MIDI_NOTEOFF): 
00721       midi->noteOff(ev->chn, ev->note, ev->vel);break;
00722     case (MIDI_KEY_PRESSURE) :
00723       midi->keyPressure(ev->chn, ev->note,ev->vel);break;
00724     case (MIDI_PGM_CHANGE) :
00725       if (!ctl->forcepgm[ev->chn])
00726         midi->chnPatchChange(ev->chn, (ctl->gm==1)?(ev->patch):(MT32toGM[ev->patch]));break;
00727     case (MIDI_CHN_PRESSURE) :
00728       midi->chnPressure(ev->chn, ev->vel);break;
00729     case (MIDI_PITCH_BEND) :
00730       midi->chnPitchBender(ev->chn, ev->d1,ev->d2);break;
00731     case (MIDI_CTL_CHANGE) :
00732       midi->chnController(ev->chn, ev->ctl,ev->d1);break;
00733     case (MIDI_SYSTEM_PREFIX) :
00734       if ((ev->command|ev->chn)==META_EVENT)
00735       {
00736         if ((ev->d1==5)||(ev->d1==1))
00737         {
00738           ctl->SPEVplayed++;
00739         }
00740         if (ev->d1==ME_SET_TEMPO)
00741         {
00742           absTimeAtChangeTempo=absTime;
00743           ticksplayed=0;
00744           ctl->SPEVplayed++;
00745           tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]))*ctl->ratioTempo);
00746 #ifdef PLAYERDEBUG
00747               printf("Tempo : %ld %g (ratio : %g)\n",tempo,tempoToMetronomeTempo(tempo),ctl->ratioTempo);
00748 #endif
00749               midi->tmrSetTempo((int)tempoToMetronomeTempo(tempo));
00750               ctl->tempo=tempo;       
00751           for (j=0;j<info->ntracks;j++)
00752           {
00753         tracks[j]->changeTempo(tempo);
00754           }
00755         }
00756         if (ev->d1==ME_TIME_SIGNATURE)
00757         {
00758           ctl->num=ev->d2;
00759           ctl->den=ev->d3;
00760           ctl->SPEVplayed++;
00761         }
00762       }
00763       break;
00764       }
00765       if (calloutput)
00766       {
00767     midi->sync();
00768     output();
00769       }
00770 
00771     }
00772   ctl->ev=NULL;
00773   delete ev;
00774 #ifdef PLAYERDEBUG
00775   printf("Syncronizing ...\n");
00776 #endif
00777   if (halt) 
00778     midi->sync(1);
00779   else 
00780     midi->sync();
00781 #ifdef PLAYERDEBUG
00782   printf("Closing device ...\n");
00783 #endif
00784   midi->allNotesOff();
00785   midi->closeDev();
00786   ctl->playing=0;
00787 #ifdef PLAYERDEBUG
00788   printf("Bye...\n");
00789 #endif
00790   ctl->OK=1;
00791   ctl->finished=1;
00792 }
00793 
00794 
00795 void MidiPlayer::setPos(ulong gotomsec,MidiStatus *midistat)
00796 {
00797   int trk,minTrk;
00798   ulong tempo=(ulong)(500000 * ctl->ratioTempo);
00799   double minTime=0,maxTime,prevms=0;
00800   int i,j,likeplaying=1;
00801 
00802   MidiEvent *ev=new MidiEvent;
00803   ctl->SPEVplayed=0;
00804   for (i=0;i<info->ntracks;i++)
00805   {
00806     tracks[i]->init();
00807     tracks[i]->changeTempo(tempo);
00808   }
00809 
00810   for (i=0;i<16;i++)
00811   {
00812     if (ctl->forcepgm[i]) midistat->chnPatchChange(i, ctl->pgm[i]);
00813   }
00814 
00815   while (likeplaying)
00816   {
00817     trk=0;
00818     minTrk=0;
00819     maxTime=minTime + 120000L; 
00820     minTime=maxTime;
00821     while (trk<info->ntracks)
00822     {
00823       if (tracks[trk]->absMsOfNextEvent()<minTime)
00824       {
00825     minTrk=trk;
00826     minTime=tracks[minTrk]->absMsOfNextEvent();
00827       }
00828       trk++;
00829     }
00830     if (minTime==maxTime) 
00831     {
00832       likeplaying=0;
00833 #ifdef GENERAL_DEBUG_MESSAGES
00834       printf("END of likeplaying\n");
00835 #endif
00836     }
00837     else
00838     {   
00839       if (minTime>=gotomsec)
00840       {
00841     prevms=gotomsec;
00842     likeplaying=0;
00843 #ifdef GENERAL_DEBUG_MESSAGES
00844     printf("Position reached !! \n");
00845 #endif
00846     minTime=gotomsec;
00847       }
00848       else
00849       {
00850     prevms=minTime;
00851       }
00852       trk=0;
00853       while (trk<info->ntracks)
00854       {
00855     tracks[trk]->currentMs(minTime);
00856     trk++;
00857       }
00858     }
00859 
00860     if (likeplaying)
00861     {
00862       trk=minTrk;
00863       tracks[trk]->readEvent(ev);
00864       switch (ev->command)
00865       {
00866     
00867 
00868 
00869 
00870 
00871 
00872 
00873     case (MIDI_PGM_CHANGE) :
00874       if (!ctl->forcepgm[ev->chn]) midistat->chnPatchChange(ev->chn, ev->patch);break;
00875     case (MIDI_CHN_PRESSURE) :
00876       midistat->chnPressure(ev->chn, ev->vel);break;
00877     case (MIDI_PITCH_BEND) :
00878       midistat->chnPitchBender(ev->chn, ev->d1,ev->d2);break;
00879     case (MIDI_CTL_CHANGE) :
00880       midistat->chnController(ev->chn, ev->ctl,ev->d1);break;
00881     case (MIDI_SYSTEM_PREFIX) :
00882       if ((ev->command|ev->chn)==META_EVENT)
00883       {
00884         if ((ev->d1==5)||(ev->d1==1))
00885         {
00886           ctl->SPEVplayed++;
00887         }
00888         if (ev->d1==ME_SET_TEMPO)
00889         {
00890           ctl->SPEVplayed++;
00891           tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]))*ctl->ratioTempo);
00892 
00893           midistat->tmrSetTempo((int)tempoToMetronomeTempo(tempo));     
00894           for (j=0;j<info->ntracks;j++)
00895           {
00896         tracks[j]->changeTempo(tempo);
00897           }
00898         }
00899         if (ev->d1==ME_TIME_SIGNATURE)
00900         {
00901           ctl->num=ev->d2;
00902           ctl->den=ev->d3;
00903           ctl->SPEVplayed++;
00904         }
00905       }
00906       break;
00907       }
00908     }
00909   }
00910   delete ev;
00911   ctl->tempo=tempo;
00912 }
00913 
00914 
00915 void MidiPlayer::debugSpecialEvents(void)
00916 {
00917   SpecialEvent *pspev=spev;
00918   printf("**************************************\n");
00919   while ((pspev!=NULL)&&(pspev->type!=0))
00920   {
00921     printf("t:%d ticks:%d diff:%ld abs:%ld s:%s tempo:%ld\n",pspev->type,pspev->ticks,pspev->diffmilliseconds,pspev->absmilliseconds,pspev->text,pspev->tempo);
00922     pspev=pspev->next;
00923   }
00924 
00925 }
00926 
00927 void MidiPlayer::setParseSong(bool b)
00928 {
00929   parsesong=b;
00930 }
00931 
00932 void MidiPlayer::setGenerateBeats(bool b)
00933 {
00934   generatebeats=b;
00935 }
00936 
00937 void MidiPlayer::setTempoRatio(double ratio)
00938 {
00939   if (songLoaded)
00940   {
00941     ctl->ratioTempo=ratio;
00942     parseInfoData(info,tracks,ctl->ratioTempo);
00943     if (parsesong)
00944     {
00945       parseSpecialEvents();
00946       if (generatebeats) generateBeats();
00947 
00948     }
00949   }
00950   else
00951   {
00952     ctl->tempo=(ulong)((ctl->tempo*ctl->ratioTempo)/ratio);
00953     ctl->ratioTempo=ratio;
00954   }
00955 
00956 }
00957 
00958 #undef T2MS
00959 #undef MS2T