aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2016-05-18 23:58:40 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2016-05-18 23:58:40 +0800
commit8ef9703ee2a4b22395935030606fcf69e3acad86 (patch)
treeafebccb5bc50afeed0291569cab993fddafd4d34
parent473470054a4f67c67fb3f40a0438e87aff68703c (diff)
downloadQMidiPlayer-8ef9703ee2a4b22395935030606fcf69e3acad86.tar.xz
Finally finish the particle system integration.
Add std::wstring version APIs to avoid wrong encoding. Update documentation.
-rw-r--r--ChangeLog13
-rw-r--r--core/qmpmidiplay.cpp1
-rw-r--r--doc/optionsdialog.html1
-rw-r--r--doc/visualization.html46
-rw-r--r--img/particle.pngbin0 -> 2063 bytes
-rw-r--r--img/visualizationss.pngbin0 -> 90230 bytes
-rw-r--r--include/qmpcorepublic.hpp1
-rwxr-xr-xqmidiplayer-desktop/qmidiplayer.desktop2
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp8
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.hpp1
-rw-r--r--qmidiplayer-desktop/qmpplugin.cpp2
-rw-r--r--visualization/extrasmeltutils.cpp4
-rw-r--r--visualization/qmpvisualization.cpp78
-rw-r--r--visualization/qmpvisualization.hpp2
-rw-r--r--visualization/visualization.pro2
15 files changed, 126 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 4cede60..c184f42 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-05-18 0.8.1 alpha
+Finally finish the particle system integration.
+Add std::wstring version APIs to avoid wrong encoding.
+Update documentation.
+
2016-05-17 0.8.1 alpha
Fix bugs in the particle system.
Add particle look at option.
@@ -33,7 +38,7 @@ Add channel label display. However it's still buggy so it's
currently disabled.
2016-05-09 0.8.1 alpha
-Add visualization documentaion stub.
+Add visualization documentation stub.
2016-05-07 0.8.1 alpha
Added two new options.
@@ -83,7 +88,7 @@ Plugins can be disabled now.
Show file name in window title.
Handle pitch bend in visualization.
Handle mute and solo in the default visualization.
-A little plugin sdk documentaion...
+A little plugin sdk documentation...
Remove stupid things.
2016-04-26 0.7.8 beta
@@ -135,7 +140,7 @@ Add panic action.
Minor changes on the panic function.
2016-04-17 0.7.2 beta
-A little more documentaion work...
+A little more documentation work...
2016-04-16 0.7.2 beta
Don't do full initialization before pharsing arguments.
@@ -217,7 +222,7 @@ Initial MIDI mapper stub.
2016-01-30 0.7.0 beta
Add support for a single, persistent fluidsynth instance.
(Experimental, may also break the original mode...)
-A little documentaion work...
+A little documentation work...
2016-01-26 0.6.2 beta
Maintaince release.
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
index cf34a18..63c4dda 100644
--- a/core/qmpmidiplay.cpp
+++ b/core/qmpmidiplay.cpp
@@ -311,6 +311,7 @@ void CMidiPlayer::playerPanic(bool reset)
fluid_synth_cc(synth,i,32,0);
}
fluid_synth_cc(synth,i,64,0);
+ fluid_synth_pitch_wheel_sens(synth,i,2);
fluid_synth_pitch_bend(synth,i,8192);
//all sounds off causes the minus polyphone bug...
fluid_synth_all_notes_off(synth,i);
diff --git a/doc/optionsdialog.html b/doc/optionsdialog.html
index ed38f35..8d59dc2 100644
--- a/doc/optionsdialog.html
+++ b/doc/optionsdialog.html
@@ -75,6 +75,7 @@
</ul>
<img src="../img/options5.png"><br>
Plugin manager. View details of plugins, enable or disable them here.<br>
+ Enabled plugin list is applied after a restart.<br>
Plugin scanning follows the order below:
<ul>
<li>(*nix) /usr/lib/qmidiplayer</li>
diff --git a/doc/visualization.html b/doc/visualization.html
index 8870e0c..33c6977 100644
--- a/doc/visualization.html
+++ b/doc/visualization.html
@@ -27,7 +27,51 @@
<img src="../img/visualizationss.png"><br>
The default visualization comes as a plugin of QMidiPlayer. So before using it you
have to enable it first in the plugin manager.<br>
- To use the visualization, click the Visualization button in the main window.
+ To use the visualization, click the Visualization button in the main window.<br>
+ The visualization plugin adds two new option tabs.
+ <h3>Controls</h3>
+ <pre>
+ forward
+ | ↱Press and hold left mouse button:
+ up | down ┌──┬──┐ Adjust camera direction.
+ ↓ ↓ ↓ │ │ │
+ Q W E ├──┴──┤
+ A S D │ │
+ ↑ ↑ ↑ │ │
+left | right │ │
+ | └─────┘
+ backward
+ </pre>
+ <h3>Options</h3>
+ <ul>
+ <li>
+ Visualization-Appearance
+ <ul>
+ <li>Show Piano: Whether to show the virtual piano in the visualization scene.</li>
+ <li>3D Notes: 2D notes are used when this is unchecked. Using 2D notes is less resource-hungry.</li>
+ <li>Arrange channels on a stair: If checked, virtual pianos will be arranged on a stair-like shape. This option has no effect if virtual piano is not shown.</li>
+ <li>Show channel labels: If checked, channel preset will be shown on the left side.</li>
+ <li>Show particles: Whether to draw particles. Very resource-intensive!</li>
+ <li>View distance: This option affects the maximum number of notes rendered on the screen.</li>
+ <li>Note stretch: The length multiplier of notes.</li>
+ <li>Minimum note length: Avoid notes that are too short to be visible by adjusting this value.</li>
+ <li>Chequer board tint: change the color of the chequer board background.</li>
+ <li>Background Image: Use a background image instead of the default dull grey color.</li>
+ </ul>
+ </li>
+ <li>
+ Visualization-Video
+ <ul>
+ <li>Enable VSync: Enable vertical synchronization.</li>
+ <li>Save Viewport: Restore last camera configuration when the visualization is started.</li>
+ <li>Window Width/Height: Change the window size. If the size equals to your screen size, the visualization will start in fullscreen mode.</li>
+ <li>FPS: FPS limit of the visualization.</li>
+ <li>Supersampling: Supersample anti-aliasing. 1 means no SSAA.</li>
+ <li>Multisampling: Multisample anti-aliasing. 0 means no MSAA.</li>
+ <li>FOV: Field of view.</li>
+ </ul>
+ </li>
+ </ul>
</div>
</body>
</html> \ No newline at end of file
diff --git a/img/particle.png b/img/particle.png
new file mode 100644
index 0000000..70d81af
--- /dev/null
+++ b/img/particle.png
Binary files differ
diff --git a/img/visualizationss.png b/img/visualizationss.png
new file mode 100644
index 0000000..8280456
--- /dev/null
+++ b/img/visualizationss.png
Binary files differ
diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp
index 88c54a7..eb53bb3 100644
--- a/include/qmpcorepublic.hpp
+++ b/include/qmpcorepublic.hpp
@@ -64,6 +64,7 @@ class qmpPluginAPI
virtual double getPitchBend(int ch);
virtual bool getChannelMask(int ch);
virtual std::string getTitle();
+ virtual std::wstring getWTitle();
virtual std::string getChannelPresetString(int ch);
virtual int registerVisualizationIntf(qmpVisualizationIntf* intf);
diff --git a/qmidiplayer-desktop/qmidiplayer.desktop b/qmidiplayer-desktop/qmidiplayer.desktop
index b49113f..2884d18 100755
--- a/qmidiplayer-desktop/qmidiplayer.desktop
+++ b/qmidiplayer-desktop/qmidiplayer.desktop
@@ -2,7 +2,7 @@
[Desktop Entry]
Type=Application
Name=QMidiPlayer
-Version=0.7.2
+Version=0.8.1
GenericName=MIDI Player
Comment=QMidiPlayer is a midi file player based on Fluidsynth and Qt.
Exec=/usr/bin/qmidiplayer
diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp
index ed3c884..f634375 100644
--- a/qmidiplayer-desktop/qmpmainwindow.cpp
+++ b/qmidiplayer-desktop/qmpmainwindow.cpp
@@ -306,6 +306,14 @@ std::string qmpMainWindow::getTitle()
toString().toStdString().c_str())->
toUnicode(player->getTitle()).toStdString();
}
+std::wstring qmpMainWindow::getWTitle()
+{
+ if(!qmpSettingsWindow::getSettingsIntf())return L"";
+ return QTextCodec::codecForName(
+ qmpSettingsWindow::getSettingsIntf()->value("Midi/TextEncoding","").
+ toString().toStdString().c_str())->
+ toUnicode(player->getTitle()).toStdWString();
+}
void qmpMainWindow::playerSetup()
{
diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp
index bf55fb9..9fc5d14 100644
--- a/qmidiplayer-desktop/qmpmainwindow.hpp
+++ b/qmidiplayer-desktop/qmpmainwindow.hpp
@@ -63,6 +63,7 @@ class qmpMainWindow:public QMainWindow
bool isFinalizing(){return fin;}
QString getFileName();
std::string getTitle();
+ std::wstring getWTitle();
int pharseArgs();
int registerVisualizationIntf(qmpVisualizationIntf* intf);
void unregisterVisualizationIntf(int handle);
diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp
index ef31472..22cb696 100644
--- a/qmidiplayer-desktop/qmpplugin.cpp
+++ b/qmidiplayer-desktop/qmpplugin.cpp
@@ -113,6 +113,8 @@ bool qmpPluginAPI::getChannelMask(int ch)
{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getChannelMask(ch):false;}
std::string qmpPluginAPI::getTitle()
{return qmw?qmw->getTitle():"";}
+std::wstring qmpPluginAPI::getWTitle()
+{return qmw?qmw->getWTitle():L"";}
std::string qmpPluginAPI::getChannelPresetString(int ch)
{
int b,p;char nm[25],ret[33];ret[0]=0;
diff --git a/visualization/extrasmeltutils.cpp b/visualization/extrasmeltutils.cpp
index dc12c8c..18fafa9 100644
--- a/visualization/extrasmeltutils.cpp
+++ b/visualization/extrasmeltutils.cpp
@@ -92,7 +92,7 @@ void smParticle::update()
q.v[3].x=v3.x+pos.x;q.v[3].y=v3.y+pos.y;q.v[3].z=v3.z+pos.z;
}
smParticleSystem::smParticleSystem()
-{sm=smGetInterface(SMELT_APILEVEL);particles.clear();posGenerator=NULL;}
+{sm=smGetInterface(SMELT_APILEVEL);particles.clear();posGenerator=NULL;active=false;}
smParticleSystem::~smParticleSystem()
{for(unsigned i=0;i<particles.size();++i)delete particles[i];particles.clear();}
void smParticleSystem::setParticleSystemInfo(smParticleSystemInfo _psinfo)
@@ -109,7 +109,7 @@ void smParticleSystem::stopPS()
void smParticleSystem::updatePS()
{
cemdelay+=sm->smGetDelta();
- if(cemdelay>nemdelay&&(int)particles.size()<psinfo.maxcount)
+ if(active&&cemdelay>nemdelay&&(int)particles.size()<psinfo.maxcount)
{
int ec=re.nextInt(psinfo.emissioncount-psinfo.ecvar,psinfo.emissioncount+psinfo.ecvar);
for(int i=0;i<ec;++i)
diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp
index 8c4f9db..5bcbe20 100644
--- a/visualization/qmpvisualization.cpp
+++ b/visualization/qmpvisualization.cpp
@@ -9,7 +9,7 @@ int viewdist=100;
int notestretch=100;//length of quarter note
int minnotelength=100;
int noteappearance=1,showpiano=1,stairpiano=1,savevp=1,showlabel=1;
-int wwidth=800,wheight=600,wsupersample=1,wmultisample=1;
+int wwidth=800,wheight=600,wsupersample=1,wmultisample=1,showparticle=1;
int fov=60,vsync=1,tfps=60;
DWORD chkrtint=0xFF999999;
DWORD iccolors[]={0XFFFF0000,0XFFFF8000,0XFFFFBF00,0XFFFFFF00,
@@ -56,6 +56,7 @@ void qmpVisualization::showThread()
showpiano=api->getOptionBool("Visualization/showpiano");
stairpiano=api->getOptionBool("Visualization/stairpiano");
showlabel=api->getOptionBool("Visualization/showlabel");
+ showparticle=api->getOptionBool("Visualization/showparticle");
savevp=api->getOptionBool("Visualization/savevp");
vsync=api->getOptionBool("Visualization/vsync");
tfps=api->getOptionInt("Visualization/tfps");
@@ -75,17 +76,26 @@ void qmpVisualization::showThread()
chequer=sm->smTextureLoad("/usr/share/qmidiplayer/img/chequerboard.png");
particletex=sm->smTextureLoad("particle.png");
bgtex=sm->smTextureLoad(api->getOptionString("Visualization/background").c_str());
- smParticleSystemInfo psinfo;
- psinfo.acc=smvec3d(0,0,-0.05);psinfo.accvar=smvec3d(0,0,0.005);
- psinfo.vel=smvec3d(0,0,0.5);psinfo.velvar=smvec3d(0.1,0.1,0.2);
- psinfo.rotv=psinfo.rota=psinfo.rotavar=smvec3d(0,0,0);psinfo.rotvvar=smvec3d(0.04,0.04,0.04);
- psinfo.lifespan=1;psinfo.lifespanvar=0.5;psinfo.maxcount=1000;psinfo.emissioncount=5;psinfo.ecvar=2;
- psinfo.emissiondelay=0.1;psinfo.edvar=0;psinfo.initsize=0.8;psinfo.initsizevar=0.1;
- psinfo.finalsize=0.1;psinfo.finalsizevar=0.05;psinfo.initcolor=0xFFFFFFFF;psinfo.finalcolor=0x00FFFFFF;
- psinfo.initcolorvar=psinfo.finalcolorvar=0;psinfo.texture=particletex;psinfo.blend=BLEND_ALPHAADD;
- test=new smParticleSystem();test->setPos(smvec3d(0,0,16));
- psepg=new smXLinePSGenerator(.75);test->setParticleSystemInfo(psinfo);
- test->setPSEmissionPosGen(psepg);test->startPS();
+ if(showparticle)
+ {
+ smParticleSystemInfo psinfo;
+ psinfo.acc=smvec3d(0,0,-0.05);psinfo.accvar=smvec3d(0,0,0.005);
+ psinfo.vel=smvec3d(0,0,0.5);psinfo.velvar=smvec3d(0.1,0.1,0.2);
+ psinfo.rotv=psinfo.rota=psinfo.rotavar=smvec3d(0,0,0);psinfo.rotvvar=smvec3d(0.04,0.04,0.04);
+ psinfo.lifespan=1;psinfo.lifespanvar=0.5;psinfo.maxcount=1000;psinfo.emissioncount=5;psinfo.ecvar=2;
+ psinfo.emissiondelay=0.1;psinfo.edvar=0;psinfo.initsize=0.8;psinfo.initsizevar=0.1;
+ psinfo.finalsize=0.1;psinfo.finalsizevar=0.05;psinfo.initcolor=0xFFFFFFFF;psinfo.finalcolor=0x00FFFFFF;
+ psinfo.initcolorvar=psinfo.finalcolorvar=0;psinfo.texture=particletex;psinfo.blend=BLEND_ALPHAADD;
+ psepg=new smXLinePSGenerator(.6);
+ for(int i=0;i<16;++i)for(int j=0;j<128;++j)
+ {
+ pss[i][j]=new smParticleSystem();
+ pss[i][j]->setPSEmissionPosGen(psepg);
+ psinfo.initcolor=accolors[i];psinfo.finalcolor=SETA(accolors[i],0);
+ pss[i][j]->setParticleSystemInfo(psinfo);
+ pss[i][j]->setPos(smvec3d(0.756*((double)j-64)+.48,(stairpiano?(56-i*7.):(64-i*8.)),stairpiano*i*2+0.1));
+ }
+ }else memset(pss,0,sizeof(pss));
if(showpiano)for(int i=0;i<16;++i)p3d[i]=new qmpVirtualPiano3D();
memset(traveld,0,sizeof(traveld));
if(noteappearance==1)nebuf=new smEntity3DBuffer();else nebuf=NULL;
@@ -128,7 +138,7 @@ void qmpVisualization::close()
}else return;
if(showpiano)for(int i=0;i<16;++i)delete p3d[i];
- delete test;
+ if(showparticle)for(int i=0;i>16;++i)for(int j=0;j<128;++j)delete pss[i][j];
if(noteappearance==1)delete nebuf;
sm->smFinale();
if(savevp)
@@ -156,6 +166,7 @@ void qmpVisualization::reset()
pool.clear();elb=ctk=0;
for(int i=0;i<16;++i)for(int j=0;j<128;++j)
{
+ if(showparticle&&pss[i][j])pss[i][j]->stopPS();
while(!pendingt[i][j].empty())pendingt[i][j].pop();
while(!pendingv[i][j].empty())pendingv[i][j].pop();
}
@@ -220,6 +231,15 @@ bool qmpVisualization::update()
a.x=0.63*((double)pool[i]->key-64+api->getPitchBend(pool[i]->ch))+.1,
b.x=0.63*((double)pool[i]->key-64+api->getPitchBend(pool[i]->ch))+.7;
notestatus[pool[i]->ch][pool[i]->key]|=isnoteon;a.x*=1.2;b.x*=1.2;
+ if(showparticle)
+ {
+ if(notestatus[pool[i]->ch][pool[i]->key])
+ {
+ pss[pool[i]->ch][pool[i]->key]->startPS();
+ pss[pool[i]->ch][pool[i]->key]->setPos(smvec3d(0.756*((double)pool[i]->key-64)+.48,(stairpiano?(56-pool[i]->ch*7.):(64-pool[i]->ch*8.)),stairpiano*pool[i]->ch*2+0.1));
+ }
+ else pss[pool[i]->ch][pool[i]->key]->stopPS();
+ }
if(((double)pool[i]->tce-pool[i]->tcs)*lpt<minnotelength/100.)a.z=((double)pool[i]->tcs-ctk)*lpt-minnotelength/100.+stairpiano*pool[i]->ch*2;
drawCube(a,b,SETA(isnoteon?accolors[pool[i]->ch]:iccolors[pool[i]->ch],int(pool[i]->vel*(isnoteon?2.0:1.6))),0);
}
@@ -249,13 +269,18 @@ bool qmpVisualization::update()
if(playing)ctk+=(int)(1e6/(api->getRawTempo()/api->getDivision())*sm->smGetDelta());
while(pool.size()&&elb<pool.size()&&((double)ctk-pool[elb]->tce)*lpt>viewdist*2)++elb;
sm->smRenderEnd();
- sm->smRenderBegin3D(fov,false,tdparticles);
- sm->sm3DCamera6f2v(pos,rot);
- sm->smClrscr(0,1,1);
- test->setPSLookAt(smvec3d(pos[0],pos[1],pos[2]));
- //!!Test only.
- //test->updatePS();test->renderPS();
- sm->smRenderEnd();
+ if(showparticle)
+ {
+ sm->smRenderBegin3D(fov,false,tdparticles);
+ sm->sm3DCamera6f2v(pos,rot);
+ sm->smClrscr(0,1,1);
+ for(int i=0;i<16;++i)for(int j=0;j<128;++j)
+ {
+ pss[i][j]->setPSLookAt(smvec3d(pos[0],pos[1],pos[2]));
+ pss[i][j]->updatePS();pss[i][j]->renderPS();
+ }
+ sm->smRenderEnd();
+ }
sm->smRenderBegin2D();
sm->smClrscr(0xFF666666);q.blend=BLEND_ALPHABLEND;
for(int i=0;i<4;++i){q.v[i].col=0xFFFFFFFF;q.v[i].z=0;}
@@ -274,11 +299,12 @@ bool qmpVisualization::update()
q.v[0].x=q.v[1].x=0;q.v[2].x=q.v[3].x=wwidth;
q.v[0].y=q.v[3].y=0;q.v[1].y=q.v[2].y=wheight;
sm->smRenderQuad(&q);
- q.tex=sm->smTargetTexture(tdparticles);
- sm->smRenderQuad(&q);
- wchar_t ws[1024];memset(ws,0,sizeof(ws));
- mbstowcs(ws,api->getTitle().c_str(),1024);
- font2.updateString(L"Title: %ls",ws);
+ if(showparticle)
+ {
+ q.tex=sm->smTargetTexture(tdparticles);
+ sm->smRenderQuad(&q);
+ }
+ font2.updateString(L"Title: %ls",api->getWTitle().c_str());
font2.render(1,wheight-64,0.5,0xFFFFFFFF,ALIGN_LEFT);
font2.render(0,wheight-65,0.5,0xFF000000,ALIGN_LEFT);
font.updateString(L"Tempo: %.2f",api->getRealTempo());
@@ -330,6 +356,7 @@ void qmpVisualization::init()
api->registerOptionBool("Visualization-Appearance","3D Notes","Visualization/3dnotes",true);
api->registerOptionBool("Visualization-Appearance","Arrange channels on a stair","Visualization/stairpiano",true);
api->registerOptionBool("Visualization-Appearance","Show channel labels","Visualization/showlabel",true);
+ api->registerOptionBool("Visualization-Appearance","Show Particles","Visualization/showparticle",true);
api->registerOptionBool("Visualization-Video","Enable VSync","Visualization/vsync",true);
api->registerOptionBool("Visualization-Video","Save Viewport","Visualization/savevp",true);
api->registerOptionInt("Visualization-Video","Window Width","Visualization/wwidth",320,3200,800);
@@ -358,6 +385,7 @@ void qmpVisualization::init()
showpiano=api->getOptionBool("Visualization/showpiano");
stairpiano=api->getOptionBool("Visualization/stairpiano");
showlabel=api->getOptionBool("Visualization/showlabel");
+ showparticle=api->getOptionBool("Visualization/showparticle");
savevp=api->getOptionBool("Visualization/savevp");
vsync=api->getOptionBool("Visualization/vsync");
tfps=api->getOptionInt("Visualization/tfps");
diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp
index 6c1e578..b2a6464 100644
--- a/visualization/qmpvisualization.hpp
+++ b/visualization/qmpvisualization.hpp
@@ -52,7 +52,7 @@ class qmpVisualization:public qmpPluginIntf
smTTFont font,font2,fonthdpi;
qmpVirtualPiano3D* p3d[16];
smEntity3DBuffer* nebuf;
- smParticleSystem* test;
+ smParticleSystem* pss[16][128];
smPSEmissionPositionGenerator* psepg;
float pos[3],rot[3],lastx,lasty;
uint32_t ctc,ctk,fintk,elb;
diff --git a/visualization/visualization.pro b/visualization/visualization.pro
index a0f1f96..7c79220 100644
--- a/visualization/visualization.pro
+++ b/visualization/visualization.pro
@@ -31,7 +31,7 @@ unix {
QMAKE_LFLAGS_RELEASE -= -O1
QMAKE_LFLAGS_RELEASE += -O3
res.path = $$DATADIR/qmidiplayer/img
- res.files += ../img/chequerboard.png
+ res.files += ../img/chequerboard.png ../img/particle.png
}
#well...
INCLUDEPATH += /home/chrisoft/devel/BulletLabRemixIII/include/ /usr/include/freetype2