From f0d2584fdad44703f3966eb0b1e695341a4ca01c Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sat, 7 May 2016 23:58:52 +0800 Subject: Added two new options. Fixed several crashes related to options without a description. Sanitise deinitialize order again. Fixed several memory leaks. --- ChangeLog | 6 ++++ INSTALL | 8 ++++- qmidiplayer-desktop/qmpmainwindow.cpp | 15 ++++----- qmidiplayer-desktop/qmpsettingswindow.cpp | 12 +++++-- qmidiplayer.pro | 11 +++++-- visualization/qmpvisualization.cpp | 52 +++++++++++++++++++++++++------ 6 files changed, 81 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b26c98..8b7c6f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-05-07 0.8.1 alpha +Added two new options. +Fixed several crashes related to options without a description. +Sanitise deinitialize order again. +Fixed several memory leaks. + 2016-05-06 0.8.1 alpha Use new SMELT rendering API for notes drawing. Deinitialize classes in a correct order to avoid crashes. diff --git a/INSTALL b/INSTALL index 373aaf8..83c734b 100644 --- a/INSTALL +++ b/INSTALL @@ -1,3 +1,9 @@ Use qmake or Qt Creator. -Dependencies: libfluidsynth 1.1.4+, Qt5 (not sure whether 4 will work) and RtMidi. + +Dependencies: +> libfluidsynth 1.1.4+, Qt5 (not sure whether 4 will work) and RtMidi. + C++11 is required to build the project. + +To build the default visualization plugin, you need the latest SMELT, +which can be found [here](https://github.com/BearKidsTeam/SMELT). diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 3842757..c377010 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -62,7 +62,14 @@ qmpMainWindow::qmpMainWindow(QWidget *parent) : qmpMainWindow::~qmpMainWindow() { delete pmgr;if(player)delete player; - if(timer)delete timer;delete ui; + if(timer)delete timer; + delete helpw;helpw=NULL; + delete efxw;efxw=NULL; + delete chnlw;chnlw=NULL; + delete plistw;plistw=NULL; + delete infow;infow=NULL; + delete settingsw;settingsw=NULL; + delete ui; } void qmpMainWindow::init() @@ -183,12 +190,6 @@ void qmpMainWindow::closeEvent(QCloseEvent *event) efxw->close();chnlw->close(); plistw->close();infow->close(); settingsw->close(); - delete helpw;helpw=NULL; - delete efxw;efxw=NULL; - delete chnlw;chnlw=NULL; - delete plistw;plistw=NULL; - delete infow;infow=NULL; - delete settingsw;settingsw=NULL; event->accept(); } diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp index 45f84c3..81ac364 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.cpp +++ b/qmidiplayer-desktop/qmpsettingswindow.cpp @@ -330,24 +330,25 @@ void qmpSettingsWindow::updateCustomOptions() { case 0:case 1: { - QSpinBox* sb=(QSpinBox*)i->second.widget; + QSpinBox* sb=(QSpinBox*)i->second.widget;if(!i->second.widget)break; settings->setValue(QString(i->first.c_str()),sb->value()); break; } case 2: { + if(!i->second.widget)break; settings->setValue(QString(i->first.c_str()),((QCheckBox*)i->second.widget)->isChecked()?1:0); break; } case 3: { - QDoubleSpinBox* sb=(QDoubleSpinBox*)i->second.widget; + QDoubleSpinBox* sb=(QDoubleSpinBox*)i->second.widget;if(!i->second.widget)break; settings->setValue(QString(i->first.c_str()),sb->value()); break; } case 4: { - QLineEdit* te=(QLineEdit*)i->second.widget; + QLineEdit* te=(QLineEdit*)i->second.widget;if(!i->second.widget)break; settings->setValue(QString(i->first.c_str()),te->text()); } } @@ -393,6 +394,7 @@ int qmpSettingsWindow::getOptionInt(std::string key) void qmpSettingsWindow::setOptionInt(std::string key,int val) { settings->setValue(QString(key.c_str()),val); + if(customOptions[key].widget) ((QSpinBox*)customOptions[key].widget)->setValue(val); } @@ -436,6 +438,7 @@ unsigned qmpSettingsWindow::getOptionUint(std::string key) void qmpSettingsWindow::setOptionUint(std::string key,unsigned val) { settings->setValue(QString(key.c_str()),val); + if(customOptions[key].widget) ((QSpinBox*)customOptions[key].widget)->setValue(val); } @@ -472,6 +475,7 @@ bool qmpSettingsWindow::getOptionBool(std::string key) void qmpSettingsWindow::setOptionBool(std::string key,bool val) { settings->setValue(QString(key.c_str()),val?1:0); + if(customOptions[key].widget) ((QCheckBox*)customOptions[key].widget)->setChecked(val); } @@ -515,6 +519,7 @@ double qmpSettingsWindow::getOptionDouble(std::string key) void qmpSettingsWindow::setOptionDouble(std::string key,double val) { settings->setValue(QString(key.c_str()),val); + if(customOptions[key].widget) ((QDoubleSpinBox*)customOptions[key].widget)->setValue(val); } @@ -554,5 +559,6 @@ std::string qmpSettingsWindow::getOptionString(std::string key) void qmpSettingsWindow::setOptionString(std::string key,std::string val) { settings->setValue(QString(key.c_str()),QString(val.c_str())); + if(customOptions[key].widget) ((QLineEdit*)customOptions[key].widget)->setText(val.c_str()); } diff --git a/qmidiplayer.pro b/qmidiplayer.pro index da362f3..0c08e3c 100644 --- a/qmidiplayer.pro +++ b/qmidiplayer.pro @@ -1,5 +1,12 @@ TEMPLATE = subdirs +!android { SUBDIRS = \ - qmidiplayer-desktop \ - qmidiplayer-lite + qmidiplayer-desktop \ + qmidiplayer-lite \ + visualization +} +android { +SUBDIRS = \ + qmidiplayer-lite +} diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp index 80fd07b..23b981d 100644 --- a/visualization/qmpvisualization.cpp +++ b/visualization/qmpvisualization.cpp @@ -8,7 +8,7 @@ int viewdist=100; int notestretch=100;//length of quarter note int minnotelength=100; -int noteappearance=1,showpiano=1; +int noteappearance=1,showpiano=1,stairpiano=1,savevp=1; int wwidth=800,wheight=600,wsupersample=1,wmultisample=1; int fov=60,vsync=1,tfps=60; DWORD iccolors[]={0XFFFF0000,0XFFFF8000,0XFFFFBF00,0XFFFFFF00, @@ -53,6 +53,8 @@ void qmpVisualization::showThread() fov=api->getOptionInt("Visualization/fov"); noteappearance=api->getOptionBool("Visualization/3dnotes"); showpiano=api->getOptionBool("Visualization/showpiano"); + stairpiano=api->getOptionBool("Visualization/stairpiano"); + savevp=api->getOptionBool("Visualization/savevp"); vsync=api->getOptionBool("Visualization/vsync"); tfps=api->getOptionInt("Visualization/tfps"); viewdist=api->getOptionInt("Visualization/viewdist"); @@ -77,8 +79,17 @@ void qmpVisualization::showThread() printf("W: Font load failed.\n"); if(!font2.loadTTF("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",16)) printf("W: Font load failed.\n"); - pos[0]=0;pos[1]=100;pos[2]=20; - rot[0]=0;rot[1]=90;rot[2]=90;ctk=0; + pos[0]=0;pos[1]=120;pos[2]=70; + rot[0]=0;rot[1]=75;rot[2]=90;ctk=0; + if(savevp) + { + pos[0]=api->getOptionDouble("Visualization/px"); + pos[1]=api->getOptionDouble("Visualization/py"); + pos[2]=api->getOptionDouble("Visualization/pz"); + rot[0]=api->getOptionDouble("Visualization/rx"); + rot[1]=api->getOptionDouble("Visualization/ry"); + rot[2]=api->getOptionDouble("Visualization/rz"); + } sm->smMainLoop(); } void qmpVisualization::show() @@ -88,14 +99,24 @@ void qmpVisualization::show() void qmpVisualization::close() { shouldclose=true; - rendererTh->join(); + rendererTh->join();delete rendererTh; if(showpiano)for(int i=0;i<16;++i)delete p3d[i]; if(noteappearance==1)delete nebuf; sm->smFinale(); + if(savevp) + { + api->setOptionDouble("Visualization/px",pos[0]); + api->setOptionDouble("Visualization/py",pos[1]); + api->setOptionDouble("Visualization/pz",pos[2]); + api->setOptionDouble("Visualization/rx",rot[0]); + api->setOptionDouble("Visualization/ry",rot[1]); + api->setOptionDouble("Visualization/rz",rot[2]); + } font.releaseTTF(); font2.releaseTTF(); sm->smTextureFree(chequer); + if(bgtex)sm->smTextureFree(bgtex); sm->smTargetFree(tdscn); sm->smRelease(); } @@ -163,13 +184,13 @@ bool qmpVisualization::update() if(fabs((double)pool[i]->tcs-ctk)*lpttce-ctk)*lptgetChannelMask(pool[i]->ch))continue; - smvec3d a(0.63*((double)pool[i]->key-64)+.1,64-pool[i]->ch*8.,((double)pool[i]->tce-ctk)*lpt); - smvec3d b(0.63*((double)pool[i]->key-64)+.7,64-pool[i]->ch*8.+.4,((double)pool[i]->tcs-ctk)*lpt); + smvec3d a(0.63*((double)pool[i]->key-64)+.1,(stairpiano?(56-pool[i]->ch*7.):(64-pool[i]->ch*8.)),((double)pool[i]->tce-ctk)*lpt+stairpiano*pool[i]->ch*2.); + smvec3d b(0.63*((double)pool[i]->key-64)+.7,(stairpiano?(56-pool[i]->ch*7.):(64-pool[i]->ch*8.))+.4,((double)pool[i]->tcs-ctk)*lpt+stairpiano*pool[i]->ch*2.); bool isnoteon=pool[i]->tcs<=ctk&&pool[i]->tce>=ctk;if(isnoteon) 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(((double)pool[i]->tce-pool[i]->tcs)*lpttcs-ctk)*lpt-minnotelength/100.; + if(((double)pool[i]->tce-pool[i]->tcs)*lpttcs-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); } } @@ -185,10 +206,10 @@ bool qmpVisualization::update() if(traveld[i][j]>0)traveld[i][j]-=2;else traveld[i][j]=0; p3d[i]->setKeyTravelDist(j,traveld[i][j]/10.); } - p3d[i]->render(smvec3d(0.63*api->getPitchBend(i),62-i*8,0)); + p3d[i]->render(smvec3d(0.756*api->getPitchBend(i),stairpiano?55-i*7:62-i*8,stairpiano*i*2)); } if(playing)ctk+=(int)(1e6/(api->getRawTempo()/api->getDivision())*sm->smGetDelta()); - while(pool.size()&&((double)ctk-pool[elb]->tce)*lpt>viewdist*2)++elb; + while(pool.size()&&elbtce)*lpt>viewdist*2)++elb; sm->smRenderEnd(); sm->smRenderBegin2D(); sm->smClrscr(0xFF666666);q.blend=BLEND_ALPHABLEND; @@ -259,7 +280,9 @@ void qmpVisualization::init() hehif=api->registerEventHandlerIntf(hcb,NULL); api->registerOptionBool("Visualization-Appearance","Show Piano","Visualization/showpiano",true); api->registerOptionBool("Visualization-Appearance","3D Notes","Visualization/3dnotes",true); + api->registerOptionBool("Visualization-Appearance","Arrange channels on a stair","Visualization/stairpiano",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); api->registerOptionInt("Visualization-Video","Window Height","Visualization/wheight",320,3200,600); api->registerOptionInt("Visualization-Video","FPS","Visualization/tfps",5,1000,60); @@ -270,6 +293,12 @@ void qmpVisualization::init() api->registerOptionInt("Visualization-Appearance","Note stretch","Visualization/notestretch",20,500,100); api->registerOptionInt("Visualization-Appearance","Minimum note length","Visualization/minnotelen",20,500,100); api->registerOptionString("Visualization-Appearance","Background Image","Visualization/background",""); + api->registerOptionDouble("","","Visualization/px",-999999999,999999999,0); + api->registerOptionDouble("","","Visualization/py",-999999999,999999999,120); + api->registerOptionDouble("","","Visualization/pz",-999999999,999999999,70); + api->registerOptionDouble("","","Visualization/rx",-999999999,999999999,0); + api->registerOptionDouble("","","Visualization/ry",-999999999,999999999,75); + api->registerOptionDouble("","","Visualization/rz",-999999999,999999999,90); wwidth=api->getOptionInt("Visualization/wwidth"); wheight=api->getOptionInt("Visualization/wheight"); wsupersample=api->getOptionInt("Visualization/supersampling"); @@ -277,6 +306,8 @@ void qmpVisualization::init() fov=api->getOptionInt("Visualization/fov"); noteappearance=api->getOptionBool("Visualization/3dnotes"); showpiano=api->getOptionBool("Visualization/showpiano"); + stairpiano=api->getOptionBool("Visualization/stairpiano"); + savevp=api->getOptionBool("Visualization/savevp"); vsync=api->getOptionBool("Visualization/vsync"); tfps=api->getOptionInt("Visualization/tfps"); viewdist=api->getOptionInt("Visualization/viewdist"); @@ -285,7 +316,8 @@ void qmpVisualization::init() } void qmpVisualization::deinit() { - close(); + if(!api)return;close(); + for(unsigned i=0;iunregisterVisualizationIntf(hvif); api->unregisterEventReaderIntf(herif); api->unregisterEventHandlerIntf(hehif); -- cgit v1.2.3