aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2016-04-08 23:49:24 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2016-04-08 23:49:24 +0800
commit2b46ba471830d4e6e22be5afc720adc2489efcfe (patch)
tree8445440ba0204a67d1cb49185297a49e326dc9ab /core
parent8f8782f43bd838e825f3792b611d27fffa90399b (diff)
downloadQMidiPlayer-2b46ba471830d4e6e22be5afc720adc2489efcfe.tar.xz
the Awakening of the Evil.
Diffstat (limited to 'core')
-rw-r--r--core/qmpmidiplay.cpp13
-rw-r--r--core/qmpmidiplay.hpp12
2 files changed, 24 insertions, 1 deletions
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
index e65a2a1..4ee812f 100644
--- a/core/qmpmidiplay.cpp
+++ b/core/qmpmidiplay.cpp
@@ -55,10 +55,12 @@ void CMidiPlayer::processEvent(const SEvent *e)
case 0x90://Note on
if((mute>>(e->type&0x0F))&1)break;//muted
if(solo&&!((solo>>(e->type&0x0F))&1))break;
+ if(noteOnCB)noteOnCB->callBack(noteOnCBUserData);
if(mappedoutput[e->type&0x0F])
mapper->noteOn(mappedoutput[e->type&0x0F]-1,e->type*0x0F,e->p1,e->p2);
else
fluid_synth_noteon(synth,e->type&0x0F,e->p1,e->p2);
+ chstate[e->type&0x0F]=1;
break;
case 0xB0://CC
if(e->p1==100)rpnid=e->p2;
@@ -182,15 +184,20 @@ void CMidiPlayer::playEvents()
for(uint32_t ct=midiFile->getEvent(0)->time;tceptr<midiFile->getEventCount();)
{
while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ using namespace std::chrono;
+ high_resolution_clock::time_point b=high_resolution_clock::now();
while(!tcstop&&midiFile&&tceptr<midiFile->getEventCount()&&ct==midiFile->getEvent(tceptr)->time)
processEvent(midiFile->getEvent(tceptr++));
if(tcstop||!midiFile||tceptr>=midiFile->getEventCount())break;
+ high_resolution_clock::time_point a=high_resolution_clock::now();
+ auto sendtime=a-b;
if(resumed)resumed=false;
else
+ if(sendtime.count()<(midiFile->getEvent(tceptr)->time-ct)*dpt)
#if 0
w32usleep((midiFile->getEvent(tceptr)->time-ct)*(dpt/1000));
#else
- std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt);
+ std::this_thread::sleep_for(std::chrono::nanoseconds((midiFile->getEvent(tceptr)->time-ct)*dpt-sendtime.count()));
#endif
if(tcstop||!midiFile)break;
ct=midiFile->getEvent(tceptr)->time;
@@ -251,6 +258,7 @@ CMidiPlayer::CMidiPlayer(bool singleInst)
{
midiFile=NULL;resumed=false;singleInstance=singleInst;
settings=NULL;synth=NULL;adriver=NULL;waitvoice=true;
+ noteOnCB=NULL;noteOnCBUserData=NULL;
memset(mappedoutput,0,sizeof(mappedoutput));
memset(deviceusage,0,sizeof(deviceusage));
mapper=new qmpMidiMapperRtMidi();
@@ -444,3 +452,6 @@ void CMidiPlayer::setChannelOutput(int ch,int devid)
if(!deviceusage[origoutput-1])mapper->deviceDeinit(origoutput-1);
}
}
+uint8_t* CMidiPlayer::getChstates(){return chstate;}
+void CMidiPlayer::setNoteOnCallBack(CMidiCallBack *cb,void *userdata)
+{noteOnCB=cb;noteOnCBUserData=userdata;}
diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp
index a7e7f88..4592ea0 100644
--- a/core/qmpmidiplay.hpp
+++ b/core/qmpmidiplay.hpp
@@ -19,6 +19,13 @@ struct SEvent
if(s){str=new char[strlen(s)+2];strcpy(str,s);}else str=NULL;
}
};
+class CMidiCallBack
+{
+ public:
+ CMidiCallBack(){}
+ virtual void callBack(void* data)=0;
+ virtual ~CMidiCallBack(){}
+};
class CMidiFile
{
private:
@@ -72,6 +79,9 @@ class CMidiPlayer
uint32_t finished,resumed;
qmpMidiMapperRtMidi *mapper;
int mappedoutput[16],deviceusage[16],deviceiid[128];
+ uint8_t chstate[16];
+ CMidiCallBack *noteOnCB;
+ void* noteOnCBUserData;
void setBit(uint16_t &n,uint16_t bn,uint16_t b);
void processEvent(const SEvent *e);
@@ -139,5 +149,7 @@ class CMidiPlayer
qmpMidiMapperRtMidi* getMidiMapper();
void setChannelOutput(int ch,int devid);
+ uint8_t* getChstates();
+ void setNoteOnCallBack(CMidiCallBack *cb,void *userdata);
};
#endif