aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--INSTALL8
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp15
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.cpp12
-rw-r--r--qmidiplayer.pro11
-rw-r--r--visualization/qmpvisualization.cpp52
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)*lpt<viewdist*2||fabs((double)pool[i]->tce-ctk)*lpt<viewdist*2)
{
if(api->getChannelMask(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)*lpt<minnotelength/100.)a.z=((double)pool[i]->tcs-ctk)*lpt-minnotelength/100.;
+ 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);
}
}
@@ -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()&&elb<pool.size()&&((double)ctk-pool[elb]->tce)*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;i<pool.size();++i)delete pool[i];pool.clear();
api->unregisterVisualizationIntf(hvif);
api->unregisterEventReaderIntf(herif);
api->unregisterEventHandlerIntf(hehif);