diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | core/qmpmidiplay.cpp | 1 | ||||
-rw-r--r-- | doc/optionsdialog.html | 1 | ||||
-rw-r--r-- | doc/visualization.html | 46 | ||||
-rw-r--r-- | img/particle.png | bin | 0 -> 2063 bytes | |||
-rw-r--r-- | img/visualizationss.png | bin | 0 -> 90230 bytes | |||
-rw-r--r-- | include/qmpcorepublic.hpp | 1 | ||||
-rwxr-xr-x | qmidiplayer-desktop/qmidiplayer.desktop | 2 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpmainwindow.cpp | 8 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpmainwindow.hpp | 1 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpplugin.cpp | 2 | ||||
-rw-r--r-- | visualization/extrasmeltutils.cpp | 4 | ||||
-rw-r--r-- | visualization/qmpvisualization.cpp | 78 | ||||
-rw-r--r-- | visualization/qmpvisualization.hpp | 2 | ||||
-rw-r--r-- | visualization/visualization.pro | 2 |
15 files changed, 126 insertions, 35 deletions
@@ -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 Binary files differnew file mode 100644 index 0000000..70d81af --- /dev/null +++ b/img/particle.png diff --git a/img/visualizationss.png b/img/visualizationss.png Binary files differnew file mode 100644 index 0000000..8280456 --- /dev/null +++ b/img/visualizationss.png 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 |