aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--INSTALL7
-rw-r--r--README.md11
-rw-r--r--debian/changelog13
-rw-r--r--debian/control6
-rw-r--r--doc/APIdoc.md47
-rw-r--r--doc/version_internal.html4
-rw-r--r--qmidiplayer-desktop/qmidiplayer-desktop.pro1
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.cpp1
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.hpp5
-rw-r--r--qmidiplayer.pro13
-rw-r--r--visualization/extrasmeltutils.cpp1
-rw-r--r--visualization/qmpvisualization.cpp14
-rw-r--r--visualization/visualization.pro23
14 files changed, 128 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index ac03d46..6d7c17a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
-2016-09-23 0.8.3 alpha
+2016-12-27 0.8.3 alpha
+First official version with experimental support for
+the visualization plugin on Windows. Fixed several
+critical bugs causing the plugin to crash QMP.
+
+2016-12-11 0.8.3 alpha
Update the preset selection dialog to improve support
for external MIDI devices.
diff --git a/INSTALL b/INSTALL
index 83c734b..631d26d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,9 +1,12 @@
Use qmake or Qt Creator.
Dependencies:
-> libfluidsynth 1.1.4+, Qt5 (not sure whether 4 will work) and RtMidi.
+> libfluidsynth 1.1.4+, Qt5 and RtMidi.
-C++11 is required to build the project.
+C++11 is required to build the project. Qt4 will not work without
+several tweaks.
To build the default visualization plugin, you need the latest SMELT,
which can be found [here](https://github.com/BearKidsTeam/SMELT).
+Some dependencies in the project file are hard-coded paths. You may
+have to modify them first.
diff --git a/README.md b/README.md
index c878a1f..ba87e64 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,19 @@ Features:
* Playlists
* Editing synthesizer effects
* Rendering midi to wave file
-* Visualization using SMELT (currently Linux only)
+* Visualization using SMELT (highly experimental Windows version now available)
* MIDI mapping (based on RtMidi)
Tested on Debian sid and Windows Vista~10.
A QML version is now in construction. It's only a technology preview and
should not be used for non-testing purpose.
+
+# Building QMidiPlayer
+Please follow the instruction found in the file "INSTALL".
+
+_Warning: building QMidiPlayer for Windows is somehow a formidable task._
+_Go ahead if you are ready to deal with metaphysics._
+
+# Manual
+Try the button in the top-right corner.
diff --git a/debian/changelog b/debian/changelog
index 00d2283..8e099e7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+qmidiplayer (0.8.3-2) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- chrisoft <chirs241097@gmail.com> Tue, 27 Dec 2016 23:14:32 +0800
+
+
+qmidiplayer (0.8.3-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- chrisoft <chirs241097@gmail.com> Fri, 28 Oct 2016 16:41:20 +0800
+
qmidiplayer (0.8.3-0) UNRELEASED; urgency=low
* New upstream release.
diff --git a/debian/control b/debian/control
index 51e40c3..2773d44 100644
--- a/debian/control
+++ b/debian/control
@@ -12,7 +12,11 @@ Build-Depends: debhelper (>= 9),
qml-module-qtquick-window2,
qml-module-qtquick2,
libqt5qml5,
- librtmidi-dev
+ librtmidi-dev,
+ libglfw3-dev,
+ libglew-dev,
+ libfreetype6-dev,
+ zlib1g-dev
Package: qmidiplayer
Architecture: any
diff --git a/doc/APIdoc.md b/doc/APIdoc.md
new file mode 100644
index 0000000..043c1c0
--- /dev/null
+++ b/doc/APIdoc.md
@@ -0,0 +1,47 @@
+# The API documentation of QMidiPlayer for plugin developers
+
+*This manual is not yet complete. It's only a working draft for the always-changing plugin system in QMP.*
+*Handle with care.*
+
+# 0. Overview
+
+Plugin for QMidiPlayer is a dynamically-loaded library that exports the symbol "qmpPluginGetInterface".
+Before starting developing your own plugin, make sure to have a look at the sample plugin in the "sample-plugin" folder.
+
+# 1. "QMidiPlayer Plugin SDK"
+
+SDK for developing QMidiPlayer plugins is merely the "qmpcorepublic.hpp" header found in the "include" directory in
+the source tree. It includes classes used by QMidiPlayer's internal plugin infrastructure.
+
+# 2. Basics for a working plugin.
+
+First of all, you should make your library distinct from other libraries that are not QMidiPlayer plugins. You can achive
+it by exporting the symbol "qmpPluginGetInterface". Specifically, what you should do is to add the following snipplet to
+somewhere of your code:
+
+> extern "C"{
+> EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
+> //semicolon or implementation here.
+> }
+
+The EXPORTSYM macro tells the compiler to export the following symbol. qmpPluginIntf is the abstract class which every
+plugin class should derive from. The parameter api provides access to QMidiPlayer's plugin API, which should be stored
+for future use.
+
+Next you should create your own plugin class which implements the abstract class "qmpPluginIntf".
+
+# 3. A Peek into the class "qmpPluginIntf"
+
+It has 6 public members: one default constructor, one default destructor and four methods:
+
+- void init()
+ Called on start up if the plugin is loaded successfully and enabled.
+- void deinit()
+ Called on shutdown if the plugin is enabled.
+- const char* pluginGetName()
+ This function should return the display name of the plugin.
+- const char* pluginGetVersion()
+ This function should return the version of the plugin, which will be shown in the plugin manager.
+
+Your plugin is expected to register handlers and functionalities when init() is called by the host,
+and do clean-up jobs when deinit() is caled.
diff --git a/doc/version_internal.html b/doc/version_internal.html
index e68a10e..ddd32c8 100644
--- a/doc/version_internal.html
+++ b/doc/version_internal.html
@@ -10,11 +10,11 @@
QMidiPlayer -- An MIDI player based on fluidsynth and Qt.<br>
Written by Chris Xiong.<br>
Version APP_VERSION<br>
- Built at BUILD_DATE<br>
+ Built at BUILD_DATE on BUILD_MACHINE<br>
libfluidsynth version: RT_FLUIDSYNTH_VERSION (Built against CT_FLUIDSYNTH_VERSION)<br>
Qt version: RT_QT_VERSION_STR (Built against CT_QT_VERSION_STR)<br>
</div><br>
<a href="index_internal.html">Return</a>
</td>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/qmidiplayer-desktop/qmidiplayer-desktop.pro b/qmidiplayer-desktop/qmidiplayer-desktop.pro
index 1aa1a27..5572479 100644
--- a/qmidiplayer-desktop/qmidiplayer-desktop.pro
+++ b/qmidiplayer-desktop/qmidiplayer-desktop.pro
@@ -55,6 +55,7 @@ FORMS += qmpmainwindow.ui \
qmphelpwindow.ui
TRANSLATIONS += translations/qmp_zh_CN.ts
+DEFINES += BUILD_MACHINE=$${QMAKE_HOST.name}
unix{
isEmpty(PREFIX) {
diff --git a/qmidiplayer-desktop/qmphelpwindow.cpp b/qmidiplayer-desktop/qmphelpwindow.cpp
index c9f4667..b2346dd 100644
--- a/qmidiplayer-desktop/qmphelpwindow.cpp
+++ b/qmidiplayer-desktop/qmphelpwindow.cpp
@@ -40,6 +40,7 @@ void qmpHelpWindow::on_textBrowser_sourceChanged(const QUrl &src)
s.replace("RT_FLUIDSYNTH_VERSION",fluid_version_str());
s.replace("APP_VERSION",APP_VERSION);
s.replace("BUILD_DATE",parseDate(__DATE__).c_str());
+ s.replace("BUILD_MACHINE",sss(BUILD_MACHINE));
ui->textBrowser->setHtml(s);
}
}
diff --git a/qmidiplayer-desktop/qmphelpwindow.hpp b/qmidiplayer-desktop/qmphelpwindow.hpp
index 690d126..61d9963 100644
--- a/qmidiplayer-desktop/qmphelpwindow.hpp
+++ b/qmidiplayer-desktop/qmphelpwindow.hpp
@@ -3,6 +3,11 @@
#include <QDialog>
#define APP_VERSION "0.8.3"
+#ifndef BUILD_MACHINE
+#define BUILD_MACHINE UNKNOWN
+#endif
+#define ss(s) #s
+#define sss(s) ss(s)
namespace Ui {
class qmpHelpWindow;
diff --git a/qmidiplayer.pro b/qmidiplayer.pro
index 62515f5..0f4a262 100644
--- a/qmidiplayer.pro
+++ b/qmidiplayer.pro
@@ -2,15 +2,12 @@ TEMPLATE = subdirs
!android {
SUBDIRS = \
- qmidiplayer-desktop \
- qmidiplayer-lite \
- sample-plugin
+ qmidiplayer-desktop \
+ qmidiplayer-lite \
+ sample-plugin \
+ visualization
}
android {
SUBDIRS = \
- qmidiplayer-lite
-}
-
-!win32 {
-SUBDIRS += visualization\
+ qmidiplayer-lite
}
diff --git a/visualization/extrasmeltutils.cpp b/visualization/extrasmeltutils.cpp
index 18fafa9..6c8dd93 100644
--- a/visualization/extrasmeltutils.cpp
+++ b/visualization/extrasmeltutils.cpp
@@ -61,6 +61,7 @@ void smEntity3DBuffer::addTransformedEntity(smEntity3D *entity,smMatrix t,smvec3
}
void smEntity3DBuffer::drawBatch()
{
+ if(!vertices.size())return;
sm->smDrawCustomIndexedVertices(&vertices[0],&indices[0],vertices.size(),indices.size(),BLEND_ALPHABLEND,0);
vertices.clear();indices.clear();
}
diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp
index 29a1925..f17a92a 100644
--- a/visualization/qmpvisualization.cpp
+++ b/visualization/qmpvisualization.cpp
@@ -14,8 +14,8 @@ int wwidth=800,wheight=600,wsupersample=1,wmultisample=0,showparticle=1;
int horizontal=1,flat=0,osdpos=0,fontsize=16;
int fov=60,vsync=1,tfps=60,usespectrum=0;
DWORD chkrtint=0xFF999999;
-const char* minors="abebbbf c g d a e b f#c#g#d#a#";
-const char* majors="CbGbDbAbEbBbF C G D A E B F#C#";
+const wchar_t* minors=L"abebbbf c g d a e b f#c#g#d#a#";
+const wchar_t* majors=L"CbGbDbAbEbBbF C G D A E B F#C#";
double fpoffsets[]={1,18,28,50,55,82,98,109,130,137,161,164,191};
double froffsets[]={0,18,33,50,65,82,98,113,130,145,161,176,191};
DWORD iccolors[]={0XFFFF0000,0XFFFF8000,0XFFFFBF00,0XFFFFFF00,
@@ -131,12 +131,15 @@ void qmpVisualization::showThread()
tdparticles=sm->smTargetCreate(wwidth*wsupersample,wheight*wsupersample,wmultisample);
if(!font.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf",fontsize))
if(!font.loadTTF("/usr/share/fonts/gnu-free-fonts/FreeMono.otf",fontsize))
+ if(!font.loadTTF("C:/Windows/Fonts/cour.ttf",fontsize))
printf("W: Font load failed.\n");
if(!fonthdpi.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf",180))
if(!fonthdpi.loadTTF("/usr/share/fonts/gnu-free-fonts/FreeMono.otf",180))
+ if(!fonthdpi.loadTTF("C:/Windows/Fonts/cour.ttf",180))
printf("W: Font load failed.\n");
if(!font2.loadTTF("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",fontsize))
if(!font2.loadTTF("/usr/share/fonts/wenquanyi/wqy-microhei/wqy-microhei.ttc",fontsize))
+ if(!font2.loadTTF("C:/Windows/Fonts/segoeui.ttf",fontsize))
printf("W: Font load failed.\n");
if(horizontal)
{
@@ -175,7 +178,7 @@ void qmpVisualization::close()
}else return;
if(showpiano&&!horizontal)for(int i=0;i<16;++i)delete p3d[i];
- if(showparticle&&!horizontal)for(int i=0;i>16;++i)for(int j=0;j<128;++j)delete pss[i][j];
+ if(showparticle&&!horizontal)for(int i=0;i>16;++i)for(int j=0;j<128;++j){delete pss[i][j];pss[i][j]=0;}
if(noteappearance==1)delete nebuf;
sm->smFinale();
if(savevp)
@@ -657,7 +660,7 @@ bool qmpVisualization::update()
}
if(osdpos==4){sm->smRenderEnd();return shouldclose;}
int t,r;t=api->getKeySig();r=(int8_t)((t>>8)&0xFF)+7;t&=0xFF;
- std::string ts(t?minors:majors);ts=ts.substr(2*r,2);
+ std::wstring ts(t?minors:majors);ts=ts.substr(2*r,2);
int step=int(1.25*fontsize),xp=(osdpos&1)?wwidth-step-1:1,yp=osdpos<2?wheight-step*5-4:step+4,align=osdpos&1?ALIGN_RIGHT:ALIGN_LEFT;
font2.updateString(L"Title: %ls",api->getWTitle().c_str());
font2.render(xp,yp,0.5,0xFFFFFFFF,align);
@@ -665,7 +668,7 @@ bool qmpVisualization::update()
font.updateString(L"Time Sig: %d/%d",api->getTimeSig()>>8,1<<(api->getTimeSig()&0xFF));
font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
font.render(xp-1,yp-1,0.5,0xFF000000,align);
- font.updateString(L"Key Sig: %s",ts.c_str());
+ font.updateString(L"Key Sig: %ls",ts.c_str());
font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
font.render(xp-1,yp-1,0.5,0xFF000000,align);
font.updateString(L"Tempo: %.2f",api->getRealTempo());
@@ -776,6 +779,7 @@ void qmpVisualization::init()
accolors[i]=api->getOptionUint("Visualization/chActiveColor"+std::to_string(i));
iccolors[i]=api->getOptionUint("Visualization/chInactiveColor"+std::to_string(i));
}
+ memset(pss,0,sizeof(pss));
}
void qmpVisualization::deinit()
{
diff --git a/visualization/visualization.pro b/visualization/visualization.pro
index 65f1a48..fedd636 100644
--- a/visualization/visualization.pro
+++ b/visualization/visualization.pro
@@ -32,9 +32,22 @@ unix {
QMAKE_LFLAGS_RELEASE += -O3
res.path = $$DATADIR/qmidiplayer/img
res.files += ../img/chequerboard.png ../img/particle.png ../img/kb_128.png
+ #well...
+ INCLUDEPATH += /home/chrisoft/devel/SMELT/include/ /usr/include/freetype2
+ LIBS += -L/home/chrisoft/devel/SMELT/smelt/glfw/
+ LIBS += -L/home/chrisoft/devel/SMELT/extensions/
+ LIBS += -lstdc++ -lfreetype -lz -lsmeltext -lsmelt-dumb -lCxImage -ljpeg -lpng -lglfw -lGLEW -lGL
+}
+win32 {
+ #Change these before producing your own build!
+ INCLUDEPATH += "C:\Users\Chris Xiong\Documents\devel\SMELT\include"
+ INCLUDEPATH += "C:\Users\Chris Xiong\Documents\devel\freetype-2.7\include"
+ INCLUDEPATH += "C:\Users\Chris Xiong\Documents\devel\zlib-1.2.8"
+ CONFIG(release, debug|release){
+ LIBS += -L"C:\Users\Chris Xiong\Documents\devel\SMELT\msvc\libdeps"
+ LIBS += -lfreetype27MT -lzlib -lsmeltext -lsmelt -ljpeg-static -llibpng16 -lglfw3 -lglew32s -lopengl32 -luser32 -lgdi32 -lshell32
+ }else{
+ LIBS += -L"C:\Users\Chris Xiong\Documents\devel\SMELT\msvc\libdepsd"
+ LIBS += -lfreetype27MTd -lzlib -lsmeltextd -lsmeltd -ljpeg-static -llibpng16 -lglfw3 -lglew32sd -lopengl32 -luser32 -lgdi32 -lshell32
+ }
}
-#well...
-INCLUDEPATH += /home/chrisoft/devel/SMELT/include/ /usr/include/freetype2
-LIBS += -L/home/chrisoft/devel/SMELT/smelt/glfw/
-LIBS += -L/home/chrisoft/devel/SMELT/extensions/
-LIBS += -lstdc++ -lfreetype -lz -lsmeltext -lsmelt-dumb -lCxImage -ljpeg -lpng -lglfw -lGLEW -lGL