summaryrefslogtreecommitdiffstats
path: root/libkmid/player.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libkmid/player.cc')
-rw-r--r--libkmid/player.cc959
1 files changed, 0 insertions, 959 deletions
diff --git a/libkmid/player.cc b/libkmid/player.cc
deleted file mode 100644
index a68a9b147..000000000
--- a/libkmid/player.cc
+++ /dev/null
@@ -1,959 +0,0 @@
-/**************************************************************************
-
- player.cc - class MidiPlayer. Plays a set of tracks
- This file is part of LibKMid 0.9.5
- Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez
- LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
- $Id$
-
- Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
-
-***************************************************************************/
-#include "player.h"
-#include "sndcard.h"
-#include "midispec.h"
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "midistat.h"
-#include "mt32togm.h"
-
-//#define PLAYERDEBUG
-//#define GENERAL_DEBUG_MESSAGES
-
-#define T2MS(ticks) (((double)ticks)*(double)60000L)/((double)tempoToMetronomeTempo(tempo)*(double)info->ticksPerCuarterNote)
-
-#define MS2T(ms) (((ms)*(double)tempoToMetronomeTempo(tempo)*(double)info->ticksPerCuarterNote)/((double)60000L))
-
-#define REMOVEDUPSTRINGS
-
-MidiPlayer::MidiPlayer(DeviceManager *midi_,PlayerController *pctl)
-{
- midi=midi_;
- info=NULL;
- tracks=NULL;
- songLoaded=0;
- ctl=pctl;
- spev=NULL;
- na=NULL;
- parsesong=true;
- generatebeats=false;
-}
-
-MidiPlayer::~MidiPlayer()
-{
- removeSpecialEvents();
- removeSong();
-}
-
-void MidiPlayer::removeSong(void)
-{
- if ((songLoaded)&&(tracks!=NULL))
- {
-#ifdef PLAYERDEBUG
- printf("Removing song from memory\n");
-#endif
- int i=0;
- while (i<info->ntracks)
- {
- if (tracks[i]!=NULL) delete tracks[i];
- i++;
- }
- delete tracks;
- tracks=NULL;
- if (info!=NULL)
- {
- delete info;
- info=NULL;
- }
- }
- songLoaded=0;
-}
-
-int MidiPlayer::loadSong(const char *filename)
-{
- removeSong();
-#ifdef PLAYERDEBUG
- printf("Loading Song : %s\n",filename);
-#endif
- info=new MidiFileInfo;
- int ok;
- tracks=readMidiFile(filename,info,ok);
- if (ok<0) return ok;
- if (tracks==NULL) return -4;
-
- parseInfoData(info,tracks,ctl->ratioTempo);
-
- if (parsesong)
- {
- parseSpecialEvents();
- if (generatebeats) generateBeats();
- }
-
- songLoaded=1;
- return 0;
-}
-
-void MidiPlayer::insertBeat(SpecialEvent *ev,ulong ms,int num,int den)
-{
- SpecialEvent *beat=new SpecialEvent;
- beat->next=ev->next;
- ev->next=beat;
- beat->id=1;
- beat->type=7;
- beat->absmilliseconds=ms;
- beat->num=num;
- beat->den=den;
-}
-
-
-void MidiPlayer::generateBeats(void)
-{
-#ifdef PLAYERDEBUG
- printf("player::Generating Beats...\n");
-#endif
-
- if (spev==NULL) return;
- SpecialEvent *ev=spev;
- SpecialEvent *nextev=ev->next;
- ulong tempo=(ulong)(500000 * ctl->ratioTempo);
- int i=1;
- int num=4;
- int den=4;
- // ulong beatstep=((double)tempo*4/(den*1000));
- // ulong beatstep=T2MS(info->ticksPerCuarterNote*(4/den));
- double ticksleft=(((double)info->ticksPerCuarterNote*4)/den);
-
- double beatstep=T2MS(ticksleft);
- double nextbeatms=0;
- double lastbeatms=0;
- double measurems=0;
-
- while (nextev!=NULL)
- {
- switch (ev->type)
- {
- case (0): // End of list
- {
- };break;
- case (1): // Text
- case (2): // Lyrics
- {
- };break;
- case (3): // Change Tempo
- {
- lastbeatms=ev->absmilliseconds;
- ticksleft=MS2T(nextbeatms-lastbeatms);
- tempo=ev->tempo;
- nextbeatms=lastbeatms+T2MS(ticksleft);
- // printf("Change at %lu to %d\n",ev->absmilliseconds,ev->tempo);
- // beatstep=((double)tempo*4/(den*1000));
- beatstep=T2MS(((static_cast<double>(info->ticksPerCuarterNote)*4)/den));
- };break;
- case (6): // Change number of beats per measure
- {
- num=ev->num;
- i=1;
- den=ev->den;
- // printf("Change at %lu to %d/%d\n",ev->absmilliseconds,num,den);
- // beatstep=((double)tempo*4/(den*1000));
- // beatstep=T2MS(info->ticksPerCuarterNote*(4/den));
- beatstep=T2MS((((double)info->ticksPerCuarterNote*4)/den));
- nextbeatms=ev->absmilliseconds;
- };break;
- };
- if (nextev->absmilliseconds>nextbeatms)
- {
- //printf("Adding %d,%d\n",num,tot);
- //printf("beat at %g , %d/%d\n",nextbeatms,i,num);
- //printf(" %ld %d\n",nextev->absmilliseconds,nextev->type);
- if (i == 1) {
- measurems=nextbeatms;
- }
- insertBeat(ev, static_cast<unsigned long>(nextbeatms), i++, num);
- if (i > num) {
- i=1;
- }
- lastbeatms=nextbeatms;
- nextbeatms+=beatstep;
- // nextbeatms=measurems+beatstep*i;
-
- ticksleft = ( (static_cast<double>(info->ticksPerCuarterNote)*4) / den);
-
- }
-
- ev=ev->next;
- nextev=ev->next;
- }
-
- /* ev==NULL doesn't indicate the end of the song, so continue generating beats */
-
- if (ev!=NULL)
- {
- if (ev->type==0)
- {
- ev=spev;
- /* Looking if ev->next is NULL is not needed because
- we are sure that a ev->type == 0 exists, we just have
- to assure that the first spev is not the only one */
- if (ev->next!=NULL)
- while (ev->next->type!=0) ev=ev->next;
- }
- while (nextbeatms<info->millisecsTotal)
- {
- // printf("beat2 at %g , %d/%d\n",nextbeatms,i,num);
- if (i==1) measurems=nextbeatms;
- insertBeat(ev, static_cast<unsigned long>(nextbeatms), i++, num);
- if (i>num) i=1;
- nextbeatms+=beatstep;
- ev=ev->next;
- }
- }
-
- /* Regenerate IDs */
-
- ev=spev;
- i=1;
- while (ev!=NULL)
- {
- ev->id=i++;
- ev=ev->next;
- }
-
-
-#ifdef PLAYERDEBUG
- printf("player::Beats Generated\n");
-#endif
-
-}
-
-void MidiPlayer::removeSpecialEvents(void)
-{
- SpecialEvent * ev=spev;
- while (spev!=NULL)
- {
- ev=spev->next;
- delete spev;
- spev=ev;
- }
- delete na;
- na=0;
-}
-
-void MidiPlayer::parseSpecialEvents(void)
-{
-#ifdef PLAYERDEBUG
- printf("player::Parsing...\n");
-#endif
- removeSpecialEvents();
- spev=new SpecialEvent;
- if (spev==NULL) return;
- SpecialEvent *pspev=spev;
- pspev->type=0;
- pspev->ticks=0;
- if (na) delete na;
- na=new NoteArray();
- if (!na) { delete spev; spev=0L; return; };
- int trk;
- int minTrk;
- double minTime=0;
- double maxTime;
- ulong tempo=(ulong)(500000 * (ctl->ratioTempo));
- ulong firsttempo=0;
- for (int i=0;i<info->ntracks;i++)
- {
- tracks[i]->init();
- tracks[i]->changeTempo(tempo);
- }
- MidiEvent *ev=new MidiEvent;
- //ulong mspass;
- double prevms=0;
- int spev_id=1;
- int j;
- int parsing=1;
-#ifdef REMOVEDUPSTRINGS
- char lasttext[1024];
- ulong lasttexttime=0;
- lasttext[0]=0;
- int lasttexttype=0;
-#endif
- while (parsing)
- {
- prevms=minTime;
- trk=0;
- minTrk=0;
- maxTime=minTime + 2 * 60000L;
- minTime=maxTime;
- parsing=0;
- while (trk<info->ntracks)
- {
- if (tracks[trk]->absMsOfNextEvent()<minTime)
- {
- minTrk=trk;
- minTime=tracks[minTrk]->absMsOfNextEvent();
- parsing=1;
- }
- trk++;
- }
- // if ((minTime==maxTime))
- if (parsing==0)
- {
- // parsing=0;
-#ifdef PLAYERDEBUG
- printf("END of parsing\n");
-#endif
- }
- else
- {
- // mspass=(ulong)(minTime-prevms);
- trk=0;
- while (trk<info->ntracks)
- {
- tracks[trk]->currentMs(minTime);
- trk++;
- }
- }
- trk=minTrk;
- tracks[trk]->readEvent(ev);
- switch (ev->command)
- {
- case (MIDI_NOTEON) :
- if (ev->vel==0) na->add((ulong)minTime,ev->chn,0, ev->note);
- else na->add((ulong)minTime,ev->chn,1,ev->note);
- break;
- case (MIDI_NOTEOFF) :
- na->add((ulong)minTime,ev->chn,0, ev->note);
- break;
- case (MIDI_PGM_CHANGE) :
- na->add((ulong)minTime,ev->chn, 2,ev->patch);
- break;
- case (MIDI_SYSTEM_PREFIX) :
- {
- if ((ev->command|ev->chn)==META_EVENT)
- {
- switch (ev->d1)
- {
- case (1) :
- case (5) :
- {
- if (pspev!=NULL)
- {
- pspev->absmilliseconds=(ulong)minTime;
- pspev->type=ev->d1;
- pspev->id=spev_id++;
-#ifdef PLAYERDEBUG
- printf("ev->length %ld\n",ev->length);
-
-#endif
- strncpy(pspev->text,(char *)ev->data,
- (ev->length>= sizeof(lasttext))? sizeof(lasttext)-1 : (ev->length) );
- pspev->text[(ev->length>= sizeof(lasttext))? sizeof(lasttext)-1:(ev->length)]=0;
-#ifdef PLAYERDEBUG
- printf("(%s)(%s)\n",pspev->text,lasttext);
-#endif
-#ifdef REMOVEDUPSTRINGS
- if ((strcmp(pspev->text,lasttext)!=0)||(pspev->absmilliseconds!=lasttexttime)||(pspev->type!=lasttexttype))
- {
- lasttexttime=pspev->absmilliseconds;
- lasttexttype=pspev->type;
- strncpy(lasttext, pspev->text, 1024);
- lasttext[sizeof(lasttext)-1] = 0;
-#endif
- pspev->next=new SpecialEvent;
-#ifdef PLAYERDEBUG
- if (pspev->next==NULL) printf("pspev->next=NULL\n");
-#endif
- pspev=pspev->next;
-#ifdef REMOVEDUPSTRINGS
- }
-#endif
- }
- }
- break;
- case (ME_SET_TEMPO) :
- {
- if (pspev!=NULL)
- {
- pspev->absmilliseconds=(ulong)minTime;
- pspev->type=3;
- pspev->id=spev_id++;
- tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2])) * ctl->ratioTempo);
- pspev->tempo=tempo;
- if (firsttempo==0) firsttempo=tempo;
- for (j=0;j<info->ntracks;j++)
- {
- tracks[j]->changeTempo(tempo);
- }
- pspev->next=new SpecialEvent;
- pspev=pspev->next;
- }
- }
- break;
- case (ME_TIME_SIGNATURE) :
- {
- if (pspev!=NULL)
- {
- pspev->absmilliseconds=(ulong)minTime;
- pspev->type=6;
- pspev->id=spev_id++;
- pspev->num=ev->d2;
- pspev->den=ev->d3;
- pspev->next=new SpecialEvent;
- pspev=pspev->next;
- }
- }
- break;
- }
- }
- }
- break;
- }
- }
-
- delete ev;
- pspev->type=0;
- pspev->absmilliseconds=(ulong)prevms;
- pspev->next=NULL;
- if (firsttempo==0) firsttempo=tempo;
- ctl->tempo=firsttempo;
-
- //writeSPEV();
- for (int i=0;i<info->ntracks;i++)
- {
- tracks[i]->init();
- }
-}
-
-/*
-NoteArray *MidiPlayer::parseNotes(void)
-{
-#ifdef PLAYERDEBUG
- printf("player::Parsing Notes...\n");
-#endif
- NoteArray *na=new NoteArray();
- int trk;
- int minTrk;
- double minTime=0;
- double maxTime;
- for (int i=0;i<info->ntracks;i++)
- {
- tracks[i]->init();
- };
- ulong tempo=1000000;
- ulong tmp;
- Midi_event *ev=new Midi_event;
- //ulong mspass;
- double prevms=0;
- int j;
- int parsing=1;
- while (parsing)
- {
- prevms=minTime;
- trk=0;
- minTrk=0;
- maxTime=minTime + 2 * 60000L;
- minTime=maxTime;
- while (trk<info->ntracks)
- {
- if (tracks[trk]->absMsOfNextEvent()<minTime)
- {
- minTrk=trk;
- minTime=tracks[minTrk]->absMsOfNextEvent();
- };
- trk++;
- };
- if ((minTime==maxTime))
- {
- parsing=0;
-#ifdef PLAYERDEBUG
- printf("END of parsing\n");
-#endif
- }
- else
- {
- // mspass=(ulong)(minTime-prevms);
- trk=0;
- while (trk<info->ntracks)
- {
- tracks[trk]->currentMs(minTime);
- trk++;
- };
- };
- trk=minTrk;
- tracks[trk]->readEvent(ev);
- if (ev->command==MIDI_NOTEON)
- {
- if (ev->vel==0) {printf("note off at %g\n",minTime);na->add((ulong)minTime,ev->chn,0, ev->note);}
- else {printf("note on at %g\n",minTime);na->add((ulong)minTime,ev->chn,1,ev->note);}
- }
- else
- if (ev->command==MIDI_NOTEOFF) na->add((ulong)minTime,ev->chn,0, ev->note);
- if (ev->command==MIDI_PGM_CHANGE) na->add((ulong)minTime,ev->chn, 2,ev->patch);
- if (ev->command==MIDI_SYSTEM_PREFIX)
- {
- if (((ev->command|ev->chn)==META_EVENT)&&(ev->d1==ME_SET_TEMPO))
- {
- tempo=(ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]);
- for (j=0;j<info->ntracks;j++)
- {
- tracks[j]->changeTempo(tempo);
- };
- };
- };
-
- };
-
- delete ev;
- for (int i=0;i<info->ntracks;i++)
- {
- tracks[i]->init();
- };
- return na;
-};
-*/
-
-void MidiPlayer::play(bool calloutput,void output(void))
-{
-#ifdef PLAYERDEBUG
- printf("Playing...\n");
-#endif
-
- if (midi->midiPorts()+midi->synthDevices()==0)
- {
- fprintf(stderr,"Player :: There are no midi ports !\n");
- ctl->error=1;
- return;
- }
-
- midi->openDev();
- if (midi->ok()==0)
- {
- fprintf(stderr,"Player :: Couldn't play !\n");
- ctl->error=1;
- return;
- }
- midi->setVolumePercentage(ctl->volumepercentage);
- midi->initDev();
- // parsePatchesUsed(tracks,info,ctl->gm);
- midi->setPatchesToUse(info->patchesUsed);
-
- int trk;
- int minTrk;
- double minTime=0;
- double maxTime;
- int i;
- ulong tempo=(ulong)(500000 * ctl->ratioTempo);
- for (i=0;i<info->ntracks;i++)
- {
- tracks[i]->init();
- tracks[i]->changeTempo(tempo);
- }
-
- midi->tmrStart(info->ticksPerCuarterNote);
- MidiEvent *ev=new MidiEvent;
- ctl->ev=ev;
- ctl->ticksTotal=info->ticksTotal;
- ctl->ticksPlayed=0;
- //ctl->millisecsPlayed=0;
- ulong ticksplayed=0;
- double absTimeAtChangeTempo=0;
- double absTime=0;
- double diffTime=0;
- MidiStatus *midistat;
- //ulong mspass;
- double prevms=0;
- int j;
- int halt=0;
- ctl->tempo=tempo;
- ctl->num=4;
- ctl->den=4;
- int playing;
- ctl->paused=0;
- if ((ctl->message!=0)&&(ctl->message & PLAYER_SETPOS))
- {
- ctl->moving=1;
- ctl->message&=~PLAYER_SETPOS;
- midi->sync(1);
- midi->tmrStop();
- midi->closeDev();
- midistat = new MidiStatus();
- setPos(ctl->gotomsec,midistat);
- minTime=ctl->gotomsec;
- prevms=(ulong)minTime;
- midi->openDev();
- midi->tmrStart(info->ticksPerCuarterNote);
- diffTime=ctl->gotomsec;
- midistat->sendData(midi,ctl->gm);
- delete midistat;
- midi->setPatchesToUse(info->patchesUsed);
- ctl->moving=0;
- } else
- for (i=0;i<16;i++)
- {
- if (ctl->forcepgm[i])
- {
- midi->chnPatchChange(i, ctl->pgm[i]);
- }
- }
-
- timeval begintv;
- gettimeofday(&begintv, NULL);
- ctl->beginmillisec=begintv.tv_sec*1000+begintv.tv_usec/1000;
- ctl->OK=1;
- ctl->playing=playing=1;
-
- while (playing)
- {
- /*
- if (ctl->message!=0)
- {
- if (ctl->message & PLAYER_DOPAUSE)
- {
- diffTime=minTime;
- ctl->message&=~PLAYER_DOPAUSE;
- midi->sync(1);
- midi->tmrStop();
- ctl->paused=1;
- midi->closeDev();
- while ((ctl->paused)&&(!(ctl->message&PLAYER_DOSTOP))
- &&(!(ctl->message&PLAYER_HALT))) sleep(1);
- midi->openDev();
- midi->tmrStart();
- ctl->OK=1;
- printf("Continue playing ... \n");
- };
- if (ctl->message & PLAYER_DOSTOP)
- {
- ctl->message&=~PLAYER_DOSTOP;
- playing=0;
- };
- if (ctl->message & PLAYER_HALT)
- {
- ctl->message&=~PLAYER_HALT;
- playing=0;
- halt=1;
- };
- if (ctl->message & PLAYER_SETPOS)
- {
- ctl->moving=1;
- ctl->message&=~PLAYER_SETPOS;
- midi->sync(1);
- midi->tmrStop();
- midi->closeDev();
- midistat = new midiStat();
- SetPos(ctl->gotomsec,midistat);
- minTime=ctl->gotomsec;
- prevms=(ulong)minTime;
- midi->openDev();
- midi->tmrStart();
- diffTime=ctl->gotomsec;
- ctl->moving=0;
- midistat->sendData(midi,ctl->gm);
- delete midistat;
- ctl->OK=1;
- while (ctl->OK==1) ;
- ctl->moving=0;
- };
- };
- */
- prevms=minTime;
- // ctl->millisecsPlayed=minTime;
- trk=0;
- minTrk=0;
- maxTime=minTime + 120000L /* milliseconds */;
- minTime=maxTime;
- playing=0;
- while (trk<info->ntracks)
- {
- if (tracks[trk]->absMsOfNextEvent()<minTime)
- {
- minTrk=trk;
- minTime=tracks[minTrk]->absMsOfNextEvent();
- playing=1;
- }
- trk++;
- }
-#ifdef PLAYERDEBUG
- printf("minTime %g\n",minTime);
-#endif
- // if ((minTime==maxTime)/* || (minTicks> 60000L)*/)
- if (playing==0)
- {
- // playing=0;
-#ifdef PLAYERDEBUG
- printf("END of playing\n");
-#endif
- }
- else
- {
- // mspass=(ulong)(minTime-prevms);
- trk=0;
- while (trk<info->ntracks)
- {
- tracks[trk]->currentMs(minTime);
- trk++;
- }
- midi->wait(minTime-diffTime);
- }
- trk=minTrk;
- tracks[trk]->readEvent(ev);
- switch (ev->command)
- {
- case (MIDI_NOTEON) :
- midi->noteOn(ev->chn, ev->note, ev->vel);break;
- case (MIDI_NOTEOFF):
- midi->noteOff(ev->chn, ev->note, ev->vel);break;
- case (MIDI_KEY_PRESSURE) :
- midi->keyPressure(ev->chn, ev->note,ev->vel);break;
- case (MIDI_PGM_CHANGE) :
- if (!ctl->forcepgm[ev->chn])
- midi->chnPatchChange(ev->chn, (ctl->gm==1)?(ev->patch):(MT32toGM[ev->patch]));break;
- case (MIDI_CHN_PRESSURE) :
- midi->chnPressure(ev->chn, ev->vel);break;
- case (MIDI_PITCH_BEND) :
- midi->chnPitchBender(ev->chn, ev->d1,ev->d2);break;
- case (MIDI_CTL_CHANGE) :
- midi->chnController(ev->chn, ev->ctl,ev->d1);break;
- case (MIDI_SYSTEM_PREFIX) :
- if ((ev->command|ev->chn)==META_EVENT)
- {
- if ((ev->d1==5)||(ev->d1==1))
- {
- ctl->SPEVplayed++;
- }
- if (ev->d1==ME_SET_TEMPO)
- {
- absTimeAtChangeTempo=absTime;
- ticksplayed=0;
- ctl->SPEVplayed++;
- tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]))*ctl->ratioTempo);
-#ifdef PLAYERDEBUG
- printf("Tempo : %ld %g (ratio : %g)\n",tempo,tempoToMetronomeTempo(tempo),ctl->ratioTempo);
-#endif
- midi->tmrSetTempo((int)tempoToMetronomeTempo(tempo));
- ctl->tempo=tempo;
- for (j=0;j<info->ntracks;j++)
- {
- tracks[j]->changeTempo(tempo);
- }
- }
- if (ev->d1==ME_TIME_SIGNATURE)
- {
- ctl->num=ev->d2;
- ctl->den=ev->d3;
- ctl->SPEVplayed++;
- }
- }
- break;
- }
- if (calloutput)
- {
- midi->sync();
- output();
- }
-
- }
- ctl->ev=NULL;
- delete ev;
-#ifdef PLAYERDEBUG
- printf("Syncronizing ...\n");
-#endif
- if (halt)
- midi->sync(1);
- else
- midi->sync();
-#ifdef PLAYERDEBUG
- printf("Closing device ...\n");
-#endif
- midi->allNotesOff();
- midi->closeDev();
- ctl->playing=0;
-#ifdef PLAYERDEBUG
- printf("Bye...\n");
-#endif
- ctl->OK=1;
- ctl->finished=1;
-}
-
-
-void MidiPlayer::setPos(ulong gotomsec,MidiStatus *midistat)
-{
- int trk,minTrk;
- ulong tempo=(ulong)(500000 * ctl->ratioTempo);
- double minTime=0,maxTime,prevms=0;
- int i,j,likeplaying=1;
-
- MidiEvent *ev=new MidiEvent;
- ctl->SPEVplayed=0;
- for (i=0;i<info->ntracks;i++)
- {
- tracks[i]->init();
- tracks[i]->changeTempo(tempo);
- }
-
- for (i=0;i<16;i++)
- {
- if (ctl->forcepgm[i]) midistat->chnPatchChange(i, ctl->pgm[i]);
- }
-
- while (likeplaying)
- {
- trk=0;
- minTrk=0;
- maxTime=minTime + 120000L; /*milliseconds (2 minutes)*/
- minTime=maxTime;
- while (trk<info->ntracks)
- {
- if (tracks[trk]->absMsOfNextEvent()<minTime)
- {
- minTrk=trk;
- minTime=tracks[minTrk]->absMsOfNextEvent();
- }
- trk++;
- }
- if (minTime==maxTime)
- {
- likeplaying=0;
-#ifdef GENERAL_DEBUG_MESSAGES
- printf("END of likeplaying\n");
-#endif
- }
- else
- {
- if (minTime>=gotomsec)
- {
- prevms=gotomsec;
- likeplaying=0;
-#ifdef GENERAL_DEBUG_MESSAGES
- printf("Position reached !! \n");
-#endif
- minTime=gotomsec;
- }
- else
- {
- prevms=minTime;
- }
- trk=0;
- while (trk<info->ntracks)
- {
- tracks[trk]->currentMs(minTime);
- trk++;
- }
- }
-
- if (likeplaying)
- {
- trk=minTrk;
- tracks[trk]->readEvent(ev);
- switch (ev->command)
- {
- /* case (MIDI_NOTEON) :
- midistat->noteOn(ev->chn, ev->note, ev->vel);break;
- case (MIDI_NOTEOFF):
- midistat->noteOff(ev->chn, ev->note, ev->vel);break;
- case (MIDI_KEY_PRESSURE) :
- midistat->keyPressure(ev->chn, ev->note,ev->vel);break;
- */
- case (MIDI_PGM_CHANGE) :
- if (!ctl->forcepgm[ev->chn]) midistat->chnPatchChange(ev->chn, ev->patch);break;
- case (MIDI_CHN_PRESSURE) :
- midistat->chnPressure(ev->chn, ev->vel);break;
- case (MIDI_PITCH_BEND) :
- midistat->chnPitchBender(ev->chn, ev->d1,ev->d2);break;
- case (MIDI_CTL_CHANGE) :
- midistat->chnController(ev->chn, ev->ctl,ev->d1);break;
- case (MIDI_SYSTEM_PREFIX) :
- if ((ev->command|ev->chn)==META_EVENT)
- {
- if ((ev->d1==5)||(ev->d1==1))
- {
- ctl->SPEVplayed++;
- }
- if (ev->d1==ME_SET_TEMPO)
- {
- ctl->SPEVplayed++;
- tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]))*ctl->ratioTempo);
-
- midistat->tmrSetTempo((int)tempoToMetronomeTempo(tempo));
- for (j=0;j<info->ntracks;j++)
- {
- tracks[j]->changeTempo(tempo);
- }
- }
- if (ev->d1==ME_TIME_SIGNATURE)
- {
- ctl->num=ev->d2;
- ctl->den=ev->d3;
- ctl->SPEVplayed++;
- }
- }
- break;
- }
- }
- }
- delete ev;
- ctl->tempo=tempo;
-}
-
-
-void MidiPlayer::debugSpecialEvents(void)
-{
- SpecialEvent *pspev=spev;
- printf("**************************************\n");
- while ((pspev!=NULL)&&(pspev->type!=0))
- {
- 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);
- pspev=pspev->next;
- }
-
-}
-
-void MidiPlayer::setParseSong(bool b)
-{
- parsesong=b;
-}
-
-void MidiPlayer::setGenerateBeats(bool b)
-{
- generatebeats=b;
-}
-
-void MidiPlayer::setTempoRatio(double ratio)
-{
- if (songLoaded)
- {
- ctl->ratioTempo=ratio;
- parseInfoData(info,tracks,ctl->ratioTempo);
- if (parsesong)
- {
- parseSpecialEvents();
- if (generatebeats) generateBeats();
-
- }
- }
- else
- {
- ctl->tempo=(ulong)((ctl->tempo*ctl->ratioTempo)/ratio);
- ctl->ratioTempo=ratio;
- }
-
-}
-
-#undef T2MS
-#undef MS2T