aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2019-04-22 00:16:50 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2019-04-22 00:16:50 +0800
commiteba45fdf11a98113b439db0510b55f14845db8fb (patch)
tree1d73816893ccb36fa3a5f1f5c63a629bac7f0787
parentd2b00a80c237c1c3d8bc9551966cf781292525e6 (diff)
downloadQMidiPlayer-eba45fdf11a98113b439db0510b55f14845db8fb.tar.xz
New development cycle!
Partially reintroduce High DPI handling. Pressing enter when a preset is focused now opens the preset selection dialog. Close all functionality windows before shutting down. Temporary fix for switching all channels of an external synth to mono mode unintentionally. And the most important one of them all: simple visualization! I'm ditching the 0.8.6 cycle because there was no clear goal for that release now (as the OPL3 emulation is now delayed indefinitely). In contrast, the 0.8.7 release has a pretty good-looking feature set mainly focused on improving support for external synthesizers: - Per-device initialization profile. - Instrument mapping files. - And a simple visualization ~~for showing off your external synthesizers~~. As always no ETA is set, nor will I promise the implementaion of all the features listed above.
-rw-r--r--.gitignore3
-rw-r--r--ChangeLog7
-rw-r--r--core/qmpmidiplay.cpp6
-rw-r--r--qmidiplayer-desktop/main.cpp2
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.cpp13
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.hpp3
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp7
-rw-r--r--simple-visualization/qmpkeyboardwindow.cpp36
-rw-r--r--simple-visualization/qmpkeyboardwindow.hpp36
-rw-r--r--simple-visualization/qmppianowidget.cpp62
-rw-r--r--simple-visualization/qmppianowidget.hpp25
-rw-r--r--simple-visualization/simple-visualization.pro39
-rw-r--r--simple-visualization/simplevisualization.cpp29
-rw-r--r--simple-visualization/simplevisualization.hpp32
14 files changed, 295 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
index a0f2e60..a46a9f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
# User configuration
*.pro.user
build/
+
+# KDE-generated rubbish
+.directory
diff --git a/ChangeLog b/ChangeLog
index d7490c8..892f273 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2019-04-22 0.8.7 indev
+New development cycle!
+Partially reintroduce High DPI handling.
+Pressing enter when a preset is focused now opens the preset selection dialog.
+Close all functionality windows before shutting down.
+And the most important one of them all: new simple visualization!
+
2019-03-18 0.8.6 alpha
Fixed initial preset selection in XG mode.
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
index 84561ae..29f636f 100644
--- a/core/qmpmidiplay.cpp
+++ b/core/qmpmidiplay.cpp
@@ -332,11 +332,11 @@ void CMidiPlayer::playerInit()
chstatus[9][0]=127;
for(int i=0;i<16;++i)
{
- chstatus[i][7]=100;chstatus[i][11]=127;
+ chstatus[i][7]=100;chstatus[i][8]=64;chstatus[i][11]=127;
chstatus[i][10]=chstatus[i][71]=chstatus[i][72]=
chstatus[i][73]=chstatus[i][74]=chstatus[i][75]=
chstatus[i][76]=chstatus[i][77]=chstatus[i][78]=64;
- for(int cc=0;cc<127;++cc)
+ for(int cc=0;cc<124;++cc)//Temporary fix before introduction of per-device initialization profile
mididev[mappedoutput[i]].dev->basicMessage(0xB0|i,cc,chstatus[i][cc]);
}
}
@@ -486,7 +486,7 @@ void CMidiPlayer::setChannelOutput(int ch,int outid)
int origoutput=mappedoutput[ch];
SMidiDev& dnew=mididev[outid];
dnew.dev->onMapped(ch,++dnew.refcnt);
- for(int i=0;i<128;++i)
+ for(int i=0;i<124;++i)
if(i!=6&&i!=38&&i!=100&&i!=101)//avoid sending RPN/NRPN
dnew.dev->basicMessage(0xB0|ch,i,chstatus[ch][i]);
dnew.dev->basicMessage(0xC0|ch,chstatus[ch][128],0);
diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp
index a2375ca..f62429c 100644
--- a/qmidiplayer-desktop/main.cpp
+++ b/qmidiplayer-desktop/main.cpp
@@ -24,6 +24,8 @@
int main(int argc,char **argv)
{
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ if(!qgetenv("QT_SCALE_FACTOR").length()&&!qgetenv("QT_SCREEN_SCALE_FACTORS").length())
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc,argv);
QTranslator qtTranslator;
qtTranslator.load("qt_"+QLocale::system().name(),
diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp
index 6b1b8b4..3b54069 100644
--- a/qmidiplayer-desktop/qmpchannelswindow.cpp
+++ b/qmidiplayer-desktop/qmpchannelswindow.cpp
@@ -71,6 +71,7 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) :
ui->twChannels->setColumnWidth(3,192);
ui->twChannels->setColumnWidth(4,208);
ui->twChannels->setColumnWidth(5,32);
+ ui->twChannels->installEventFilter(this);
qmpMainWindow::getInstance()->registerFunctionality(
chnlf=new qmpChannelFunc(this),
std::string("Channel"),
@@ -224,6 +225,18 @@ void qmpChannelsWindow::changeMidiMapping(int chid,int idx)
qmpMainWindow::getInstance()->getPlayer()->setChannelOutput(chid,idx);
}
+bool qmpChannelsWindow::eventFilter(QObject *o,QEvent *e)
+{
+ if(e->type()==QEvent::KeyPress&&ui->twChannels->currentColumn()==4)
+ {
+ QKeyEvent *ke=static_cast<QKeyEvent*>(e);
+ if(ke->key()!=Qt::Key_Enter&&ke->key()!=Qt::Key_Return)return false;
+ showPresetWindow(ui->twChannels->currentRow(),4);
+ return true;
+ }
+ return false;
+}
+
qmpChannelFunc::qmpChannelFunc(qmpChannelsWindow *par)
{p=par;}
void qmpChannelFunc::show()
diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp
index 9ff0cd0..cb7b791 100644
--- a/qmidiplayer-desktop/qmpchannelswindow.hpp
+++ b/qmidiplayer-desktop/qmpchannelswindow.hpp
@@ -90,6 +90,9 @@ class qmpChannelsWindow:public QWidget
void on_pbUnmute_clicked();
void on_pbUnsolo_clicked();
+ protected:
+ bool eventFilter(QObject *o,QEvent *e);
+
private:
Ui::qmpChannelsWindow *ui;
qmpPresetSelector *pselectw;
diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp
index 335a3c5..baebe4f 100644
--- a/qmidiplayer-desktop/qmpmainwindow.cpp
+++ b/qmidiplayer-desktop/qmpmainwindow.cpp
@@ -177,8 +177,11 @@ void qmpMainWindow::closeEvent(QCloseEvent *event)
}
on_pbStop_clicked();fin=true;
for(auto i=mfunc.begin();i!=mfunc.end();++i)
- i->second.setAssignedControl((QReflectiveAction*)NULL),
- i->second.setAssignedControl((QReflectivePushButton*)NULL);
+ {
+ i->second.i()->close();
+ i->second.setAssignedControl((QReflectiveAction*)NULL),
+ i->second.setAssignedControl((QReflectivePushButton*)NULL);
+ }
efxw->close();chnlw->close();
plistw->close();infow->close();
settingsw->close();
diff --git a/simple-visualization/qmpkeyboardwindow.cpp b/simple-visualization/qmpkeyboardwindow.cpp
new file mode 100644
index 0000000..a42a2e0
--- /dev/null
+++ b/simple-visualization/qmpkeyboardwindow.cpp
@@ -0,0 +1,36 @@
+#include <QVBoxLayout>
+#include <QCloseEvent>
+#include "qmpkeyboardwindow.hpp"
+
+qmpKeyboardWindow::qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent):
+ QWidget(parent,Qt::Dialog),api(_api)
+{
+ setLayout(new QVBoxLayout());
+ for(int ch=0;ch<16;++ch)
+ layout()->addWidget(pw[ch]=new qmpPianoWidget(this));
+ hide();
+ api->registerEventHandlerIntf(ec=new EventCallback(),this);
+ connect(ec,&EventCallback::keystateupdated,this,&qmpKeyboardWindow::onkeystatesupdate);
+}
+qmpKeyboardWindow::~qmpKeyboardWindow()
+{
+}
+void qmpKeyboardWindow::closeEvent(QCloseEvent *event)
+{
+ api->setFuncState("Keyboard",false);
+ event->accept();
+}
+void qmpKeyboardWindow::onkeystatesupdate(int ch,int key,bool state)
+{pw[ch]->setKeyState(key,state);}
+void qmpKeyboardWindow::resetAll()
+{for(int ch=0;ch<16;++ch)pw[ch]->reset();}
+
+void EventCallback::callBack(void* callerdata,void* userdata)
+{
+ qmpKeyboardWindow *w=(qmpKeyboardWindow*)userdata;
+ SEventCallBackData *cbd=(SEventCallBackData*)callerdata;
+ if((cbd->type&0xF0)==0x80)
+ emit keystateupdated(cbd->type&0xF,cbd->p1,false);
+ if((cbd->type&0xF0)==0x90)
+ emit keystateupdated(cbd->type&0xF,cbd->p1,cbd->p2>0);
+}
diff --git a/simple-visualization/qmpkeyboardwindow.hpp b/simple-visualization/qmpkeyboardwindow.hpp
new file mode 100644
index 0000000..a99e62e
--- /dev/null
+++ b/simple-visualization/qmpkeyboardwindow.hpp
@@ -0,0 +1,36 @@
+#ifndef QMPKEYBOARDWINDOW_HPP
+#define QMPKEYBOARDWINDOW_HPP
+
+#include "../include/qmpcorepublic.hpp"
+#include "qmppianowidget.hpp"
+
+#include <QWidget>
+
+class EventCallback:public QObject,public ICallBack
+{
+ Q_OBJECT
+ public:
+ void callBack(void* callerdata,void* userdata);
+ signals:
+ void keystateupdated(int ch,int key,bool state);
+};
+
+class qmpKeyboardWindow:public QWidget
+{
+ Q_OBJECT
+ friend class EventCallback;
+ private:
+ qmpPianoWidget *pw[16];
+ qmpPluginAPI *api;
+ EventCallback *ec;
+ public:
+ qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent);
+ ~qmpKeyboardWindow();
+ void resetAll();
+ protected:
+ void closeEvent(QCloseEvent *event);
+ public slots:
+ void onkeystatesupdate(int ch,int key,bool state);
+};
+
+#endif
diff --git a/simple-visualization/qmppianowidget.cpp b/simple-visualization/qmppianowidget.cpp
new file mode 100644
index 0000000..febd90f
--- /dev/null
+++ b/simple-visualization/qmppianowidget.cpp
@@ -0,0 +1,62 @@
+#include <cstring>
+#include <QPainter>
+#include "qmppianowidget.hpp"
+
+qmpPianoWidget::qmpPianoWidget(QWidget *parent) : QWidget(parent)
+{
+ memset(keystates,0,sizeof(keystates));
+}
+void qmpPianoWidget::setKeyState(int key,bool state)
+{
+ keystates[key]=state;
+ update();
+}
+void qmpPianoWidget::reset()
+{
+ memset(keystates,0,sizeof(keystates));
+ update();
+}
+QSize qmpPianoWidget::minimumSizeHint()const
+{
+ return QSize(320,22);
+}
+
+void qmpPianoWidget::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+ for(int i=0;i<128;++i)
+ {
+ QRectF r=getKeyRect(i);
+ paintKey(r,QColor(keystates[i]?0xff66cc:0x66ccff));
+ }
+}
+
+QRectF qmpPianoWidget::getKeyRect(int key)
+{
+ int octave=key/12;key%=12;
+ bool is_black=(key<5&&(key&1))||(key>5&&((key&1)^1));
+ double key_width=width()/75.;
+ QRectF ret(0,0,key_width,height()/2.);
+ if(!is_black)
+ {
+ ret.moveTop(height()/2.);
+ int shift=(key+(key>=5))>>1;
+ ret.moveLeft((octave*7+shift)*key_width);
+ }
+ else
+ ret.moveLeft((octave*7+(key+(key>=5))/2.)*key_width);
+ return ret;
+}
+void qmpPianoWidget::paintKey(QRectF keyrect,QColor keycolor)
+{
+ QColor bordercolor(keycolor);
+ if(keycolor.valueF()>0.5)
+ bordercolor=bordercolor.darker(150);
+ else
+ bordercolor=bordercolor.lighter(150);
+ QPainter *p=new QPainter(this);
+ p->setPen(bordercolor);
+ p->setBrush(QBrush(keycolor));
+ p->drawRect(keyrect.adjusted(1,1,-1,-1));
+ delete p;
+}
diff --git a/simple-visualization/qmppianowidget.hpp b/simple-visualization/qmppianowidget.hpp
new file mode 100644
index 0000000..22af6ce
--- /dev/null
+++ b/simple-visualization/qmppianowidget.hpp
@@ -0,0 +1,25 @@
+#ifndef QMPPIANOWIDGET_HPP
+#define QMPPIANOWIDGET_HPP
+
+#include <QWidget>
+#include <bitset>
+
+class qmpPianoWidget : public QWidget
+{
+ Q_OBJECT
+ public:
+ explicit qmpPianoWidget(QWidget *parent = nullptr);
+ void setKeyState(int key,bool state);
+ void reset();
+ QSize minimumSizeHint()const override;
+
+ protected:
+ void paintEvent(QPaintEvent *event)override;
+
+ private:
+ bool keystates[128];
+ QRectF getKeyRect(int key);
+ void paintKey(QRectF keyrect,QColor keycolor);
+};
+
+#endif // QMPPIANOWIDGET_HPP
diff --git a/simple-visualization/simple-visualization.pro b/simple-visualization/simple-visualization.pro
new file mode 100644
index 0000000..7a22769
--- /dev/null
+++ b/simple-visualization/simple-visualization.pro
@@ -0,0 +1,39 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2019-04-08T17:50:57
+#
+#-------------------------------------------------
+
+QT += widgets
+QT += gui
+
+TARGET = simple-visualization
+TEMPLATE = lib
+
+DEFINES += SIMPLEVISUALIZATION_LIBRARY
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ simplevisualization.cpp \
+ qmppianowidget.cpp \
+ qmpkeyboardwindow.cpp
+
+HEADERS += \
+ simplevisualization.hpp \
+ qmppianowidget.hpp \
+ qmpkeyboardwindow.hpp
+
+unix {
+ target.path = /usr/lib
+ INSTALLS += target
+}
diff --git a/simple-visualization/simplevisualization.cpp b/simple-visualization/simplevisualization.cpp
new file mode 100644
index 0000000..0a1de02
--- /dev/null
+++ b/simple-visualization/simplevisualization.cpp
@@ -0,0 +1,29 @@
+#include "simplevisualization.hpp"
+#include "qmpkeyboardwindow.hpp"
+
+qmpSimpleVisualization::qmpSimpleVisualization(qmpPluginAPI *_api){api=_api;}
+void qmpSimpleVisualization::show(){p->show();}
+void qmpSimpleVisualization::close(){p->close();}
+void qmpSimpleVisualization::init()
+{
+ api->registerFunctionality(this,"Keyboard","Keyboard",api->isDarkTheme()?":/img/visualization_i.svg":":/img/visualization.svg",0,true);
+ p=new qmpKeyboardWindow(api,NULL);
+ uihs=api->registerUIHook("main.stop",qmpSimpleVisualization::cbstop,(void*)this);
+}
+void qmpSimpleVisualization::deinit()
+{
+ if(!api)return;close();
+ api->unregisterFunctionality("Keyboard");
+ api->unregisterUIHook("main.stop",uihs);
+ delete p;
+}
+const char* qmpSimpleVisualization::pluginGetName()
+{return "QMidiPlayer Simple Visualization Plugin";}
+const char* qmpSimpleVisualization::pluginGetVersion()
+{return "0.8.6";}
+
+void qmpSimpleVisualization::cbstop(void*,void* usrd)
+{
+ qmpSimpleVisualization *v=(qmpSimpleVisualization*)usrd;
+ v->p->resetAll();
+}
diff --git a/simple-visualization/simplevisualization.hpp b/simple-visualization/simplevisualization.hpp
new file mode 100644
index 0000000..b3edeee
--- /dev/null
+++ b/simple-visualization/simplevisualization.hpp
@@ -0,0 +1,32 @@
+#ifndef SIMPLEVISUALIZATION_HPP
+#define SIMPLEVISUALIZATION_HPP
+
+#include "../include/qmpcorepublic.hpp"
+
+class qmpKeyboardWindow;
+class qmpSimpleVisualization:public qmpPluginIntf,public qmpFuncBaseIntf
+{
+ private:
+ qmpPluginAPI* api;
+ qmpKeyboardWindow *p;
+ int uihs;
+ public:
+ qmpSimpleVisualization(qmpPluginAPI* _api);
+ void show();
+ void close();
+ void init();
+ void deinit();
+ const char* pluginGetName();
+ const char* pluginGetVersion();
+
+ static void cbstop(void* cbd,void* usrd);
+};
+
+extern "C"{
+ EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
+ {return new qmpSimpleVisualization(api);}
+ EXPORTSYM const char* qmpPluginGetAPIRev()
+ {return QMP_PLUGIN_API_REV;}
+}
+
+#endif // SIMPLEVISUALIZATION_HPP