aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2016-04-25 23:46:17 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2016-04-25 23:46:17 +0800
commit4ffde0ad55d041229793ca4457123bcbcbf8e0c0 (patch)
tree9457cee58f3a1f35ebe63de79c6811b1c16e36dc
parent800a0417e9ed175f220c472842a283202c77060b (diff)
downloadQMidiPlayer-4ffde0ad55d041229793ca4457123bcbcbf8e0c0.tar.xz
Plugin API now works correctly. Port old visualization code.
-rw-r--r--ChangeLog7
-rw-r--r--core/qmpmidiplay.cpp6
-rw-r--r--core/qmpmidiplay.hpp3
-rw-r--r--core/qmpmidiread.cpp8
-rw-r--r--include/qmpcorepublic.hpp57
-rw-r--r--qmidiplayer-desktop/qmpplugin.cpp8
-rw-r--r--visualization/qmpvisualization.cpp214
-rw-r--r--visualization/qmpvisualization.hpp61
-rw-r--r--visualization/visualization.pro6
9 files changed, 324 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index fdfc2f1..589b4aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
-2016-04-23 0.7.8 alpha
+2016-04-25 0.7.8 alpha
+Plugin API now works correctly.
+Port part of the old visualization code to the
+new Plugin API.
+
+2016-04-24 0.7.8 alpha
More implementation of plugin support.
Migrate channel activity indicator to the new
callback system.
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
index 4e28be0..ca2878c 100644
--- a/core/qmpmidiplay.cpp
+++ b/core/qmpmidiplay.cpp
@@ -49,7 +49,7 @@ void CMidiPlayer::fluidDeinitialize()
}
void CMidiPlayer::processEvent(const SEvent *e)
{
- SEventCallBackData cbd(e->type,e->p1,e->p2);
+ SEventCallBackData cbd(e->type,e->p1,e->p2,tceptr);
for(int i=0;i<16;++i)if(eventHandlerCB[i])
eventHandlerCB[i]->callBack(&cbd,eventHandlerCBuserdata[i]);
switch(e->type&0xF0)
@@ -317,9 +317,7 @@ void CMidiPlayer::playerPanic(bool reset)
}
bool CMidiPlayer::playerLoadFile(const char* fn)
{
- midiFile=new CMidiFile(fn);
- memcpy(midiFile->eventReaderCB,this->eventReaderCB,sizeof(this->eventReaderCB));
- memcpy(midiFile->eventReaderCBuserdata,this->eventReaderCBuserdata,sizeof(this->eventReaderCBuserdata));
+ midiFile=new CMidiFile(fn,this->eventReaderCB,this->eventReaderCBuserdata);
if(!midiFile->isValid())return false;
divs=midiFile->getDivision();
fileTimer1Pass();
diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp
index 35fecea..a89a925 100644
--- a/core/qmpmidiplay.hpp
+++ b/core/qmpmidiplay.hpp
@@ -23,7 +23,6 @@ struct SEvent
};
class CMidiFile
{
- friend class CMidiPlayer;
private:
std::vector<SEvent*>eventList;
char *title,*copyright;
@@ -45,7 +44,7 @@ class CMidiFile
int chunkReader(int hdrXp);
void dumpEvents();
public:
- CMidiFile(const char* fn);
+ CMidiFile(const char* fn,IMidiCallBack** ercb,void** ercbdata);
~CMidiFile();
const SEvent* getEvent(uint32_t id);
uint32_t getEventCount();
diff --git a/core/qmpmidiread.cpp b/core/qmpmidiread.cpp
index 762ce5d..380b603 100644
--- a/core/qmpmidiread.cpp
+++ b/core/qmpmidiread.cpp
@@ -172,6 +172,10 @@ int CMidiFile::eventReader()//returns 0 if End of Track encountered
error(0,"W: Unknown event type %#x",type);
}
lasttype=type;++curid;
+ SEvent* le=eventList[eventList.size()-1];
+ SEventCallBackData cbd(le->type,le->p1,le->p2,le->time);
+ for(int i=0;i<16;++i)if(eventReaderCB[i])
+ eventReaderCB[i]->callBack(&cbd,eventReaderCBuserdata[i]);
return 1;
}
void CMidiFile::trackChunkReader()
@@ -222,9 +226,11 @@ void CMidiFile::dumpEvents()
printf("type %x #%d @%d p1 %d p2 %d\n",eventList[i]->type,
eventList[i]->iid,eventList[i]->time,eventList[i]->p1,eventList[i]->p2);
}
-CMidiFile::CMidiFile(const char* fn)
+CMidiFile::CMidiFile(const char* fn,IMidiCallBack **ercb,void **ercbdata)
{
title=copyright=NULL;notes=0;std=0;valid=1;
+ memcpy(eventReaderCB,ercb,sizeof(eventReaderCB));
+ memcpy(eventReaderCBuserdata,ercbdata,sizeof(eventReaderCBuserdata));
try
{
if(!(f=fopen(fn,"rb")))throw (fprintf(stderr,"E: file %s doesn't exist!\n",fn),2);
diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp
index ad6a165..3654a75 100644
--- a/include/qmpcorepublic.hpp
+++ b/include/qmpcorepublic.hpp
@@ -4,8 +4,8 @@
#include <string>
struct SEventCallBackData
{
- uint32_t type,p1,p2;
- SEventCallBackData(uint32_t _t,uint32_t _p1,uint32_t _p2){type=_t;p1=_p1;p2=_p2;}
+ uint32_t time,type,p1,p2;
+ SEventCallBackData(uint32_t _t,uint32_t _p1,uint32_t _p2,uint32_t _tm){type=_t;p1=_p1;p2=_p2;time=_tm;}
};
class IMidiCallBack
{
@@ -17,6 +17,7 @@ class IMidiCallBack
class qmpPluginIntf
{
public:
+ qmpPluginIntf(){}
virtual ~qmpPluginIntf(){}
virtual void init(){}
virtual void deinit(){}
@@ -26,34 +27,40 @@ class qmpPluginIntf
class qmpVisualizationIntf
{
public:
- virtual void show();
- virtual void close();
+ qmpVisualizationIntf(){}
+ virtual void show()=0;
+ virtual void close()=0;
+ virtual void start()=0;
+ virtual void stop()=0;
+ virtual void pause()=0;
+ virtual void reset()=0;
+ virtual ~qmpVisualizationIntf(){}
};
extern "C"{
class qmpPluginAPI
{
public:
- uint32_t getDivision();
- uint32_t getRawTempo();
- double getRealTempo();
- uint32_t getTimeSig();
- int getKeySig();
- uint32_t getNoteCount();
- uint32_t getCurrentPolyphone();
- uint32_t getMaxPolyphone();
- uint32_t getCurrentTimeStamp();
- int registerVisualizationIntf(qmpVisualizationIntf* i);
- void unregisterVisualizationIntf(int intfhandle);
- int registerEventReaderIntf(IMidiCallBack* cb,void* userdata);
- void unregisterEventReaderIntf(int intfhandle);
- int registerEventHandlerIntf(IMidiCallBack* cb,void* userdata);
- void unregisterEventHandlerIntf(int intfhandle);
- void registerOptionInt(std::string desc,std::string key,int defaultval);
- int getOptionInt(std::string key);
- void registerOptionDouble(std::string desc,std::string key,double defaultval);
- double getOptionDouble(std::string key);
- void registerOptionString(std::string desc,std::string key,std::string defaultval);
- std::string getOptionString(std::string key);
+ virtual uint32_t getDivision();
+ virtual uint32_t getRawTempo();
+ virtual double getRealTempo();
+ virtual uint32_t getTimeSig();
+ virtual int getKeySig();
+ virtual uint32_t getNoteCount();
+ virtual uint32_t getCurrentPolyphone();
+ virtual uint32_t getMaxPolyphone();
+ virtual uint32_t getCurrentTimeStamp();
+ virtual int registerVisualizationIntf(qmpVisualizationIntf* i);
+ virtual void unregisterVisualizationIntf(int intfhandle);
+ virtual int registerEventReaderIntf(IMidiCallBack* cb,void* userdata);
+ virtual void unregisterEventReaderIntf(int intfhandle);
+ virtual int registerEventHandlerIntf(IMidiCallBack* cb,void* userdata);
+ virtual void unregisterEventHandlerIntf(int intfhandle);
+ virtual void registerOptionInt(std::string desc,std::string key,int defaultval);
+ virtual int getOptionInt(std::string key);
+ virtual void registerOptionDouble(std::string desc,std::string key,double defaultval);
+ virtual double getOptionDouble(std::string key);
+ virtual void registerOptionString(std::string desc,std::string key,std::string defaultval);
+ virtual std::string getOptionString(std::string key);
};
}
typedef qmpPluginIntf*(*qmpPluginEntry)(qmpPluginAPI*);
diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp
index 559b575..aea01da 100644
--- a/qmidiplayer-desktop/qmpplugin.cpp
+++ b/qmidiplayer-desktop/qmpplugin.cpp
@@ -89,3 +89,11 @@ int qmpPluginAPI::registerEventReaderIntf(IMidiCallBack *cb,void *userdata)
{return qmw->getPlayer()->setEventReaderCB(cb,userdata);}
void qmpPluginAPI::unregisterEventReaderIntf(int intfhandle)
{qmw->getPlayer()->unsetEventReaderCB(intfhandle);}
+int qmpPluginAPI::registerVisualizationIntf(qmpVisualizationIntf*){return 0;}
+void qmpPluginAPI::unregisterVisualizationIntf(int){}
+void qmpPluginAPI::registerOptionInt(std::string,std::string,int){}
+int qmpPluginAPI::getOptionInt(std::string){return 0;}
+void qmpPluginAPI::registerOptionDouble(std::string,std::string,double){}
+double qmpPluginAPI::getOptionDouble(std::string){return 0;}
+void qmpPluginAPI::registerOptionString(std::string,std::string,std::string){}
+std::string qmpPluginAPI::getOptionString(std::string){return "";}
diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp
index e8bb9fb..2d0b494 100644
--- a/visualization/qmpvisualization.cpp
+++ b/visualization/qmpvisualization.cpp
@@ -1,34 +1,218 @@
#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cmath>
#include "qmpvisualization.hpp"
+const int viewdist=100;
+const int notestretch=100;//length of quarter note
+const int minnotelength=100;
+DWORD chcolors[]={0XFFFF0000,0XFFFF8000,0XFFFFBF00,0XFFFFFF00,
+ 0XFFBFFF00,0XFF80FF00,0XFF00FF00,0XFF00FFBF,
+ 0XFF00FFFF,0XFF333333,0XFF00BFFF,0XFF007FFF,
+ 0XFF0000FF,0XFF7F00FF,0XFFBF00FF,0XFFFF00BF};
+
void CTestCallBack::callBack(void *callerdata,void *)
{
- if(par->c<3)
+ SEventCallBackData* cbd=(SEventCallBackData*)callerdata;
+ switch(cbd->type&0xF0)
{
- SEventCallBackData* cbd=(SEventCallBackData*)callerdata;
- printf("type %#x p1 %d p2 %d\n",cbd->type,cbd->p1,cbd->p2);
+ case 0x80:
+ par->pushNoteOff(cbd->time,cbd->type&0x0F,cbd->p1);
+ break;
+ case 0x90:
+ par->pushNoteOn(cbd->time,cbd->type&0x0F,cbd->p1,cbd->p2);
+ break;
}
}
+void qmpVisualization::show()
+{
+ sm=smGetInterface(SMELT_APILEVEL);
+ sm->smVidMode(800,600,true);
+ sm->smUpdateFunc(h);
+ sm->smWinTitle("A Stupid Midi Visualization");
+ sm->smSetFPS(FPS_VSYNC);
+ sm->smNoSuspend(true);
+ sm->smInit();
+ sm->smTextureOpt(TPOT_POT,TFLT_LINEAR);
+ chequer=sm->smTextureLoad("chequerboard.png");
+ tdscn=sm->smTargetCreate(800,600);
+ if(!font.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf",16))
+ printf("W: Font load failed.\n");
+ pos[0]=-0;pos[1]=70;pos[2]=20;
+ rot[0]=0;rot[1]=90;rot[2]=90;ctk=0;
+ rendererTh=new std::thread(&SMELT::smMainLoop,sm);
+}
+void qmpVisualization::close()
+{
+ sm->smFinale();
+ font.releaseTTF();
+ sm->smTextureFree(chequer);
+ sm->smTargetFree(tdscn);
+ sm->smRelease();
+}
+void qmpVisualization::reset()
+{
+ for(unsigned i=0;i<pool.size();++i)delete pool[i];
+ pool.clear();
+ for(int i=0;i<16;++i)for(int j=0;j<128;++j)
+ {
+ while(!pendingt[i][j].empty())pendingt[i][j].pop();
+ while(!pendingv[i][j].empty())pendingv[i][j].pop();
+ }
+}
+bool qmpVisualization::update()
+{
+ smQuad q;
+ for(int i=0;i<4;++i)
+ {q.v[i].col=0xFF999999;q.v[i].z=0;}
+ q.tex=chequer;q.blend=BLEND_ALPHABLEND;
+ q.v[0].x=q.v[3].x=-60;q.v[1].x=q.v[2].x=60;
+ q.v[0].y=q.v[1].y=-60;q.v[2].y=q.v[3].y=60;
+ q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=15;
+ q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=15;
+ sm->smRenderBegin3D(60,tdscn);
+ sm->sm3DCamera6f2v(pos,rot);
+ sm->smClrscr(0xFF666666);
+ sm->smRenderQuad(&q);
+ if(sm->smGetKeyState(SMK_D))pos[0]+=cos(smMath::deg2rad(rot[2]-90)),pos[1]+=sin(smMath::deg2rad(rot[2]-90));
+ if(sm->smGetKeyState(SMK_A))pos[0]-=cos(smMath::deg2rad(rot[2]-90)),pos[1]-=sin(smMath::deg2rad(rot[2]-90));
+ if(sm->smGetKeyState(SMK_S))pos[0]+=cos(smMath::deg2rad(rot[2])),pos[1]+=sin(smMath::deg2rad(rot[2]));
+ if(sm->smGetKeyState(SMK_W))pos[0]-=cos(smMath::deg2rad(rot[2])),pos[1]-=sin(smMath::deg2rad(rot[2]));
+ if(sm->smGetKeyState(SMK_Q))pos[2]+=1;
+ if(sm->smGetKeyState(SMK_E))pos[2]-=1;
+ if(sm->smGetKeyState(SMK_LBUTTON)==SMKST_HIT)
+ sm->smSetMouseGrab(true),sm->smGetMouse2f(&lastx,&lasty);
+ if(sm->smGetKeyState(SMK_LBUTTON)==SMKST_KEEP)
+ {
+ float x,y;
+ sm->smGetMouse2f(&x,&y);
+ rot[1]-=(y-lasty)*0.01;
+ rot[2]+=(x-lastx)*0.01;
+ while(rot[1]>360)rot[1]-=360;
+ while(rot[1]<0)rot[1]+=360;
+ while(rot[2]>360)rot[2]-=360;
+ while(rot[2]<0)rot[2]+=360;
+ }
+ if(sm->smGetKeyState(SMK_LBUTTON)==SMKST_RELEASE)
+ sm->smSetMouseGrab(false);
+ if(sm->smGetKeyState(SMK_I))rot[1]+=1;
+ if(sm->smGetKeyState(SMK_K))rot[1]-=1;
+ if(sm->smGetKeyState(SMK_L))rot[0]+=1;
+ if(sm->smGetKeyState(SMK_J))rot[0]-=1;
+ if(sm->smGetKeyState(SMK_U))rot[2]+=1;
+ if(sm->smGetKeyState(SMK_O))rot[2]-=1;
+ //printf("pos: %f %f %f\n",pos[0],pos[1],pos[2]);
+ //printf("rot: %f %f %f\n",rot[0],rot[1],rot[2]);
+ double lpt=(double)notestretch/dvs/10.;
+ for(uint32_t i=0;i<pool.size();++i)//need optimisation here
+ {
+ if(fabs((double)pool[i]->tcs-ctk)*lpt<viewdist*2||fabs((double)pool[i]->tce-ctk)*lpt<viewdist*2)
+ {
+ smvec3d a(((double)pool[i]->key-64),pool[i]->ch*-2.,((double)pool[i]->tce-ctk)*lpt);
+ smvec3d b(((double)pool[i]->key-64)+.9,pool[i]->ch*-2.+1.6,((double)pool[i]->tcs-ctk)*lpt);
+ if(((double)pool[i]->tce-pool[i]->tcs)*lpt<minnotelength/100.)a.z=((double)pool[i]->tcs-ctk)*lpt-minnotelength/100.;
+ drawCube(a,b,SETA(chcolors[pool[i]->ch],pool[i]->vel),0);
+ }
+ }
+ //ctk+=(int)(etps*sm->smGetDelta());
+ ctk=api->getCurrentTimeStamp();
+ if(ctk>fintk)return true;
+ sm->smRenderEnd();
+ for(int i=0;i<4;++i){q.v[i].col=0xFFFFFFFF;q.v[i].z=0;}
+ q.tex=sm->smTargetTexture(tdscn);
+ sm->smRenderBegin2D();
+ sm->smClrscr(0xFF000000);
+ q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=1;
+ q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=1;
+ q.v[0].x=q.v[1].x=0;q.v[2].x=q.v[3].x=800;
+ q.v[0].y=q.v[3].y=0;q.v[1].y=q.v[2].y=600;
+ sm->smRenderQuad(&q);
+ font.updateString(L"FPS: %.2f",sm->smGetFPS());
+ font.render(1,586,0xFFFFFFFF,ALIGN_LEFT);
+ font.render(0,585,0xFF000000,ALIGN_LEFT);
+ sm->smRenderEnd();
+ return false;
+}
+
+void qmpVisualization::drawCube(smvec3d a,smvec3d b,DWORD col,SMTEX tex)
+{
+ smQuad q;q.blend=BLEND_ALPHABLEND;
+ q.tex=tex;for(int i=0;i<4;++i)q.v[i].col=col;
+ //top
+ q.v[0].x=a.x;q.v[0].y=a.y;q.v[0].z=a.z;
+ q.v[1].x=b.x;q.v[1].y=a.y;q.v[1].z=a.z;
+ q.v[2].x=b.x;q.v[2].y=b.y;q.v[2].z=a.z;
+ q.v[3].x=a.x;q.v[3].y=b.y;q.v[3].z=a.z;
+ sm->smRenderQuad(&q);
+ //bottom
+ q.v[0].x=a.x;q.v[0].y=a.y;q.v[0].z=b.z;
+ q.v[1].x=b.x;q.v[1].y=a.y;q.v[1].z=b.z;
+ q.v[2].x=b.x;q.v[2].y=b.y;q.v[2].z=b.z;
+ q.v[3].x=a.x;q.v[3].y=b.y;q.v[3].z=b.z;
+ sm->smRenderQuad(&q);
+ //left
+ q.v[0].x=a.x;q.v[0].y=b.y;q.v[0].z=a.z;
+ q.v[1].x=a.x;q.v[1].y=b.y;q.v[1].z=b.z;
+ q.v[2].x=a.x;q.v[2].y=a.y;q.v[2].z=b.z;
+ q.v[3].x=a.x;q.v[3].y=a.y;q.v[3].z=a.z;
+ sm->smRenderQuad(&q);
+ //right
+ q.v[0].x=b.x;q.v[0].y=b.y;q.v[0].z=a.z;
+ q.v[1].x=b.x;q.v[1].y=b.y;q.v[1].z=b.z;
+ q.v[2].x=b.x;q.v[2].y=a.y;q.v[2].z=b.z;
+ q.v[3].x=b.x;q.v[3].y=a.y;q.v[3].z=a.z;
+ sm->smRenderQuad(&q);
+ //front
+ q.v[0].x=a.x;q.v[0].y=b.y;q.v[0].z=a.z;
+ q.v[1].x=b.x;q.v[1].y=b.y;q.v[1].z=a.z;
+ q.v[2].x=b.x;q.v[2].y=b.y;q.v[2].z=b.z;
+ q.v[3].x=a.x;q.v[3].y=b.y;q.v[3].z=b.z;
+ sm->smRenderQuad(&q);
+ //back
+ q.v[0].x=a.x;q.v[0].y=a.y;q.v[0].z=a.z;
+ q.v[1].x=b.x;q.v[1].y=a.y;q.v[1].z=a.z;
+ q.v[2].x=b.x;q.v[2].y=a.y;q.v[2].z=b.z;
+ q.v[3].x=a.x;q.v[3].y=a.y;q.v[3].z=b.z;
+ sm->smRenderQuad(&q);
+}
-qmpVisualization::qmpVisualization(qmpPluginAPI* _api)
-{api=_api;}
-qmpVisualization::~qmpVisualization()
-{api=NULL;}
+qmpVisualization::qmpVisualization(qmpPluginAPI* _api){api=_api;}
+qmpVisualization::~qmpVisualization(){api=NULL;}
void qmpVisualization::init()
{
puts("hello world from test plugin!");
- puts("I'll try to print the first 3 events from the file!");
- cb=new CTestCallBack(this);c=0;
- //!!FIXME: not working properly...
+ cb=new CTestCallBack(this);
+ vi=new CDemoVisualization(this);
+ h=new CMidiVisualHandler(this);
+ api->registerVisualizationIntf(vi);
api->registerEventReaderIntf(cb,NULL);
}
void qmpVisualization::deinit()
-{}
+{
+ delete cb;delete vi;
+ delete h;
+}
const char* qmpVisualization::pluginGetName()
{return "QMidiPlayer Default Visualization Plugin";}
const char* qmpVisualization::pluginGetVersion()
{return "0.7.8";}
+void qmpVisualization::pushNoteOn(uint32_t tc,uint32_t ch,uint32_t key,uint32_t vel)
+{
+ pendingt[ch][key].push(tc);
+ pendingv[ch][key].push(vel);
+}
+void qmpVisualization::pushNoteOff(uint32_t tc,uint32_t ch,uint32_t key)
+{
+ if(pendingt[ch][key].size()<1)return;
+ MidiVisualEvent *ne=new MidiVisualEvent();
+ ne->tcs=pendingt[ch][key].top();pendingt[ch][key].pop();
+ ne->tce=tc;ne->ch=ch;ne->key=key;
+ ne->vel=pendingv[ch][key].top();pendingv[ch][key].pop();
+ if(tc>fintk)fintk=tc;
+}
+
//dummy implementations of the api...
uint32_t qmpPluginAPI::getDivision(){return 0;}
uint32_t qmpPluginAPI::getRawTempo(){return 0;}
@@ -43,3 +227,11 @@ int qmpPluginAPI::registerEventHandlerIntf(IMidiCallBack*,void*){return -1;}
void qmpPluginAPI::unregisterEventHandlerIntf(int){}
int qmpPluginAPI::registerEventReaderIntf(IMidiCallBack*,void*){return -1;}
void qmpPluginAPI::unregisterEventReaderIntf(int){}
+int qmpPluginAPI::registerVisualizationIntf(qmpVisualizationIntf*){return 0;}
+void qmpPluginAPI::unregisterVisualizationIntf(int){}
+void qmpPluginAPI::registerOptionInt(std::string,std::string,int){}
+int qmpPluginAPI::getOptionInt(std::string){return 0;}
+void qmpPluginAPI::registerOptionDouble(std::string,std::string,double){}
+double qmpPluginAPI::getOptionDouble(std::string){return 0;}
+void qmpPluginAPI::registerOptionString(std::string,std::string,std::string){}
+std::string qmpPluginAPI::getOptionString(std::string){return "";}
diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp
index 847f37b..df9255c 100644
--- a/visualization/qmpvisualization.hpp
+++ b/visualization/qmpvisualization.hpp
@@ -1,6 +1,12 @@
#ifndef QMPVISUALIZATION_H
#define QMPVISUALIZATION_H
+#include <vector>
+#include <stack>
+#include <thread>
+#include <smelt.hpp>
+#include <smmath.hpp>
+#include <smttfont.hpp>
#include "../include/qmpcorepublic.hpp"
class qmpVisualization;
@@ -12,22 +18,73 @@ class CTestCallBack:public IMidiCallBack
CTestCallBack(qmpVisualization *_par){par=_par;}
void callBack(void *callerdata,void *userdata);
};
+struct MidiVisualEvent
+{
+ uint32_t tcs,tce;
+ uint32_t key,vel;
+ uint32_t ch;
+};
class qmpVisualization:public qmpPluginIntf
{
- friend class CTestCallBack;
private:
qmpPluginAPI* api;
- int c;
CTestCallBack* cb;
+ qmpVisualizationIntf* vi;
+ std::thread* rendererTh;
+ std::vector<MidiVisualEvent*>pool;
+ smHandler* h;
+ std::stack<uint32_t> pendingt[16][128],pendingv[16][128];
+ SMELT *sm;
+ SMTRG tdscn;
+ SMTEX chequer;
+ smTTFont font;
+ float pos[3],rot[3],lastx,lasty;
+ uint32_t ctc,dvs,ctk,fintk;
+ double etps;
+ void drawCube(smvec3d a,smvec3d b,DWORD col,SMTEX tex);
public:
qmpVisualization(qmpPluginAPI* _api);
~qmpVisualization();
+ void pushNoteOn(uint32_t tc,uint32_t ch,uint32_t key,uint32_t vel);
+ void pushNoteOff(uint32_t tc,uint32_t ch,uint32_t key);
+ void pushPitchBend(uint32_t tc,uint32_t ch,uint32_t key);
+ bool update();
+ void start();
+ void stop();
+ void pause();
+ void show();
+ void close();
+ void reset();
+
void init();
void deinit();
const char* pluginGetName();
const char* pluginGetVersion();
};
+class CMidiVisualHandler:public smHandler
+{
+ private:
+ qmpVisualization *p;
+ public:
+ CMidiVisualHandler(qmpVisualization* par){p=par;}
+ bool handlerFunc(){return p->update();}
+};
+
+class CDemoVisualization:public qmpVisualizationIntf
+{
+ private:
+ qmpVisualization* par;
+ public:
+ CDemoVisualization(qmpVisualization *p){par=p;}
+ void show(){par->show();}
+ void close(){par->close();}
+ void start(){par->start();}
+ void stop(){par->stop();}
+ void pause(){par->pause();}
+ void reset(){par->reset();}
+};
+
extern "C"{
qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
{return new qmpVisualization(api);}
diff --git a/visualization/visualization.pro b/visualization/visualization.pro
index 8cce718..10048bd 100644
--- a/visualization/visualization.pro
+++ b/visualization/visualization.pro
@@ -20,4 +20,10 @@ HEADERS += qmpvisualization.hpp
unix {
target.path = /usr/lib/qmidiplayer
INSTALLS += target
+ QMAKE_CXXFLAGS += -pthread -fPIC
}
+#well...
+INCLUDEPATH += /home/chrisoft/devel/BulletLabRemixIII/include/ /usr/include/freetype2
+LIBS += -L/home/chrisoft/devel/BulletLabRemixIII/smelt/sdl/
+LIBS += -L/home/chrisoft/devel/BulletLabRemixIII/extensions/
+LIBS += -lstdc++ -lSDL2 -ljpeg -lpng -lfreetype -lz -lsmeltext -lsmelt-dumb -lCxImage