aboutsummaryrefslogtreecommitdiff
path: root/qmidiplayer-desktop
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2016-04-06 16:54:29 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2016-04-06 16:54:29 +0800
commit70fd2d85c1bd6fb8732e680e8fda9d36c317c732 (patch)
tree4f048e7af294a2d40d3cabb9ea0ff266aa1fc36c /qmidiplayer-desktop
parentcf7eafca1fbc9aae495d7b7d7e1fb4bc92e6819f (diff)
downloadQMidiPlayer-70fd2d85c1bd6fb8732e680e8fda9d36c317c732.tar.xz
Too young too simple.
Diffstat (limited to 'qmidiplayer-desktop')
-rw-r--r--qmidiplayer-desktop/main.cpp29
-rw-r--r--qmidiplayer-desktop/qdialskulpturestyle.cpp437
-rw-r--r--qmidiplayer-desktop/qdialskulpturestyle.hpp39
-rw-r--r--qmidiplayer-desktop/qmidiplayer-desktop.pro64
-rw-r--r--qmidiplayer-desktop/qmpchanneleditor.cpp193
-rw-r--r--qmidiplayer-desktop/qmpchanneleditor.hpp42
-rw-r--r--qmidiplayer-desktop/qmpchanneleditor.ui602
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.cpp132
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.hpp71
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.ui146
-rw-r--r--qmidiplayer-desktop/qmpefxwindow.cpp198
-rw-r--r--qmidiplayer-desktop/qmpefxwindow.hpp62
-rw-r--r--qmidiplayer-desktop/qmpefxwindow.ui478
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.cpp31
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.hpp26
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.ui34
-rw-r--r--qmidiplayer-desktop/qmpimidimapper.hpp16
-rw-r--r--qmidiplayer-desktop/qmpinfowindow.cpp57
-rw-r--r--qmidiplayer-desktop/qmpinfowindow.hpp24
-rw-r--r--qmidiplayer-desktop/qmpinfowindow.ui91
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp510
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.hpp90
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.ui413
-rw-r--r--qmidiplayer-desktop/qmpplistwindow.cpp308
-rw-r--r--qmidiplayer-desktop/qmpplistwindow.hpp57
-rw-r--r--qmidiplayer-desktop/qmpplistwindow.ui263
-rw-r--r--qmidiplayer-desktop/qmppresetselect.cpp99
-rw-r--r--qmidiplayer-desktop/qmppresetselect.hpp36
-rw-r--r--qmidiplayer-desktop/qmppresetselect.ui106
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.cpp289
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.hpp47
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.ui761
-rw-r--r--qmidiplayer-desktop/resources.qrc36
33 files changed, 5787 insertions, 0 deletions
diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp
new file mode 100644
index 0000000..c9f3b42
--- /dev/null
+++ b/qmidiplayer-desktop/main.cpp
@@ -0,0 +1,29 @@
+/*
+ *QMidiPlayer, a cross-platform player for midi files.
+ *Copyright (C) 2015 Chris Xiong
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program is distributed in the hope that it will be useful,
+ *but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *GNU General Public License for more details.
+ *
+ *You should have received a copy of the GNU General Public License
+ *along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "qmpmainwindow.hpp"
+#include <QApplication>
+#include <QStyle>
+
+int main(int argc,char **argv)
+{
+ QApplication a(argc,argv);
+ qmpMainWindow w;
+ if(w.pharseArgs(argc,argv)==1)return 0;
+
+ return a.exec();
+}
diff --git a/qmidiplayer-desktop/qdialskulpturestyle.cpp b/qmidiplayer-desktop/qdialskulpturestyle.cpp
new file mode 100644
index 0000000..7c181a0
--- /dev/null
+++ b/qmidiplayer-desktop/qdialskulpturestyle.cpp
@@ -0,0 +1,437 @@
+/******************************************************************************
+
+ Skulpture - Classical Three-Dimensional Artwork for Qt 4
+
+ Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*****************************************************************************/
+#include <cmath>
+#include <QStyleOptionSlider>
+#include <QPixmapCache>
+#include <QPainter>
+
+#include "qdialskulpturestyle.hpp"
+
+#ifndef M_PI
+#define M_PI 3.141592653589793f
+#endif
+
+static const bool UsePixmapCache = true;
+
+static void
+paintIndicatorCached(QPainter *painter, const QStyleOption *option, void (*paintIndicator)(QPainter *painter, const QStyleOption *option), bool useCache, const QString &pixmapName)
+{
+ QPixmap pixmap;
+
+ if (!useCache || !QPixmapCache::find(pixmapName, pixmap)) {
+ pixmap = QPixmap(option->rect.size());
+#if 1
+ pixmap.fill(Qt::transparent);
+ // pixmap.fill(Qt::red);
+#else
+ pixmap.fill(option->palette.color(QPalette::Window));
+#endif
+ QPainter p(&pixmap);
+ QStyleOption opt = *option;
+ opt.rect = QRect(QPoint(0, 0), option->rect.size());
+ // p.setCompositionMode(QPainter::CompositionMode_Clear);
+ // p.setCompositionMode(QPainter::CompositionMode_Source);
+ // p.fillRect(opt.rect, Qt::transparent);
+ // p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ p.setFont(painter->font());
+ p.setRenderHint(QPainter::Antialiasing, true);
+ paintIndicator(&p, &opt);
+ p.end();
+ if (useCache) {
+ QPixmapCache::insert(pixmapName, pixmap);
+ // qDebug() << "inserted into cache:" << pixmapName;
+ }
+ }
+ painter->drawPixmap(option->rect, pixmap);
+}
+
+void
+paintDialBase(QPainter *painter, const QStyleOption *option)
+{
+// painter->fillRect(option->rect, Qt::red);
+// painter->save();
+// painter->setRenderHint(QPainter::Antialiasing, true);
+ int d = qMin(option->rect.width(), option->rect.height());
+/* if (d > 20 && option->notchTarget > 0) {
+ d += -1;
+ }
+*/ QRectF r((option->rect.width() - d) / 2.0, (option->rect.height() - d) / 2.0, d, d);
+ const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
+// const qreal angle = 90;
+
+ painter->setPen(Qt::NoPen);
+ QColor border_color = option->palette.color(QPalette::Window);
+#if 0
+ {
+ QRadialGradient depth_gradient(r.center(), d / 2);
+// depth_gradient.setColorAt(0.0, QColor(0, 0, 0, 255));
+ depth_gradient.setColorAt(0.5, QColor(0, 0, 0, 255));
+ depth_gradient.setColorAt(1.0, QColor(0, 0, 0, 0));
+ painter->setBrush(depth_gradient);
+ painter->drawEllipse(r);
+ }
+#endif
+#if 1
+ if (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange) {
+ painter->setBrush(option->palette.color(QPalette::Highlight).darker(180));
+ r.adjust(1, 1, -1, -1);
+ painter->drawEllipse(r);
+ painter->setBrush(border_color);
+ r.adjust(1, 1, -1, -1);
+ painter->drawEllipse(r);
+ r.adjust(1, 1, -1, -1);
+ } else {
+ painter->setBrush(border_color);
+ r.adjust(1, 1, -1, -1);
+ painter->drawEllipse(r);
+ r.adjust(1, 1, -1, -1);
+ QConicalGradient border_gradient(r.center(), angle);
+ if (!(option->state & QStyle::State_Enabled)) {
+ border_color = border_color.lighter(120);
+ }
+ border_gradient.setColorAt(0.0, border_color.darker(180));
+ border_gradient.setColorAt(0.3, border_color.darker(130));
+ border_gradient.setColorAt(0.5, border_color.darker(170));
+ border_gradient.setColorAt(0.7, border_color.darker(130));
+ border_gradient.setColorAt(1.0, border_color.darker(180));
+ painter->setBrush(border_gradient);
+// painter->setBrush(Qt::blue);
+ painter->drawEllipse(r);
+ r.adjust(1, 1, -1, -1);
+ }
+ d -= 6;
+
+ QColor dial_color;
+ if (option->state & QStyle::State_Enabled) {
+ dial_color = option->palette.color(QPalette::Button).lighter(101);
+ if (option->state & QStyle::State_MouseOver) {
+ dial_color = dial_color.lighter(103);
+ }
+ } else {
+ dial_color = option->palette.color(QPalette::Window);
+ }
+ qreal t = option->state & QStyle::State_Enabled ? 2.0 : 1.5;
+ if (1) {
+ // ###: work around Qt 4.3.0 bug? (this works for 4.3.1)
+ QConicalGradient border_gradient(r.center(), angle);
+ border_gradient.setColorAt(0.0, dial_color.lighter(120));
+ border_gradient.setColorAt(0.2, dial_color);
+ border_gradient.setColorAt(0.5, dial_color.darker(130));
+ border_gradient.setColorAt(0.8, dial_color);
+ border_gradient.setColorAt(1.0, dial_color.lighter(120));
+ painter->setPen(QPen(border_gradient, t));
+ } else {
+ painter->setPen(QPen(Qt::red, t));
+ }
+#if 0
+ QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
+ dial_gradient.setColorAt(0.0, dial_color.darker(105));
+ dial_gradient.setColorAt(0.5, dial_color.lighter(102));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(105));
+#elif 1
+ QLinearGradient dial_gradient(option->direction == Qt::LeftToRight ? r.topLeft() : r.topRight(), option->direction == Qt::LeftToRight ? r.bottomRight() : r.bottomLeft());
+// QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
+ if (true || option->state & QStyle::State_Enabled) {
+#if 1
+ dial_gradient.setColorAt(0.0, dial_color.darker(106));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(104));
+#else
+ dial_gradient.setColorAt(0.0, dial_color.lighter(101));
+ dial_gradient.setColorAt(0.5, dial_color.darker(103));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(104));
+#endif
+ } else {
+ dial_gradient.setColorAt(0.0, dial_color);
+ dial_gradient.setColorAt(1.0, dial_color);
+ }
+#elif 0
+ QConicalGradient dial_gradient(r.center(), angle);
+ dial_gradient.setColorAt(0.0, dial_color.lighter(102));
+ dial_gradient.setColorAt(0.5, dial_color.darker(103));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(102));
+#else
+ QBrush dial_gradient(dial_color);
+#endif
+ painter->setBrush(dial_gradient);
+ t = t / 2;
+ painter->drawEllipse(r.adjusted(t, t, -t, -t));
+
+// painter->setPen(Qt::NoPen);
+// painter->setBrush(dial_color);
+// painter->drawEllipse(r.adjusted(d / 4, d / 4, - d / 4, - d / 4));
+
+#if 0
+ QLinearGradient border2_gradient(r.topLeft(), r.bottomRight());
+ border2_gradient.setColorAt(1.0, dial_color.darker(425));
+ border2_gradient.setColorAt(0.9, dial_color);
+ border2_gradient.setColorAt(0.0, dial_color.darker(400));
+ painter->setPen(QPen(border2_gradient, 1.3));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawEllipse(r.adjusted(0.3, 0.3, -0.3, -0.3));
+#endif
+// painter->restore();
+#endif
+}
+
+void
+paintCachedDialBase(QPainter *painter, const QStyleOptionSlider *option)
+{
+ bool useCache = UsePixmapCache;
+ QString pixmapName;
+ QRect r = option->rect;
+ int d = qMin(r.width(), r.height());
+
+ if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 128) {
+ useCache = false;
+ }
+ if (useCache) {
+ uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_KeyboardFocusChange | QStyle::State_HasFocus);
+ if (!(state & QStyle::State_Enabled)) {
+ state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange);
+ }
+ // state &= ~(QStyle::State_HasFocus);
+ pixmapName.sprintf("scp-qdb-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d);
+ }
+ paintIndicatorCached(painter, option, paintDialBase, useCache, pixmapName);
+}
+
+void
+paintIndicatorDial(QPainter *painter, const QStyleOptionSlider *option)
+{
+ int d = qMin(option->rect.width(), option->rect.height());
+ QRect rect(option->rect.center() - QPoint((d - 1) / 2, (d - 1) / 2), QSize(d, d));
+ QStyleOptionSlider opt;
+ opt.QStyleOption::operator=(*option);
+ opt.rect = rect;
+ paintCachedDialBase(painter, &opt);
+}
+
+QColor
+shaded_color(const QColor &color, int shade)
+{
+#if 1
+ const qreal contrast = 1.0;
+ int r, g, b;
+ color.getRgb(&r, &g, &b);
+ int gray = qGray(r, g, b);
+ gray = qMax(r, qMax(g, b));
+ gray = (r + b + g + 3 * gray) / 6;
+ if (shade < 0) {
+ qreal k = 220.0 / 255.0 * shade;
+ k *= contrast;
+ int a = 255;
+ if (gray > 0) {
+ a = int(k * 255 / (0 - gray));
+ if (a < 0) a = 0;
+ if (a > 255) a = 255;
+ }
+ return QColor(0, 0, 0, a);
+ } else {
+ qreal k = (255 - 220.0) / (255.0) * shade;
+ k *= contrast;
+ int a = 255;
+ if (gray < 255) {
+ a = int(k * 255 / (255 - gray));
+ if (a < 0) a = 0;
+ if (a > 255) a = 255;
+ }
+ return QColor(255, 255, 255, a);
+ }
+#else
+ if (shade < 0) {
+ return QColor(0, 0, 0, -shade);
+ } else {
+ return QColor(255, 255, 255, shade);
+ }
+#endif
+}
+
+static void
+paintGrip(QPainter *painter, const QStyleOption *option)
+{
+// painter->fillRect(option->rect, Qt::red);
+ int d = qMin(option->rect.width(), option->rect.height());
+ // good values are 3 (very small), 4 (small), 5 (good), 7 (large), 9 (huge)
+ // int d = 5;
+ QRectF rect(QRectF(option->rect).center() - QPointF(d / 2.0, d / 2.0), QSizeF(d, d));
+ const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
+// const qreal angle = 90;
+ QColor color;
+ qreal opacity = 0.9;
+
+ painter->save();
+ painter->setPen(Qt::NoPen);
+ if (option->state & QStyle::State_Enabled) {
+ if (option->state & QStyle::State_Sunken) {
+ color = option->palette.color(QPalette::Highlight).darker(110);
+ } else {
+ color = option->palette.color(QPalette::Button);
+ }
+ } else {
+ color = option->palette.color(QPalette::Button);
+ opacity = 0.5;
+ }
+
+ QConicalGradient gradient1(rect.center(), angle);
+ gradient1.setColorAt(0.0, shaded_color(color, -110));
+ gradient1.setColorAt(0.25, shaded_color(color, -30));
+ gradient1.setColorAt(0.5, shaded_color(color, 180));
+ gradient1.setColorAt(0.75, shaded_color(color, -30));
+ gradient1.setColorAt(1.0, shaded_color(color, -110));
+ painter->setBrush(color);
+ painter->drawEllipse(rect);
+ painter->setBrush(gradient1);
+#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
+ // ### merge opacity into color
+ painter->setOpacity(opacity);
+#endif
+ painter->drawEllipse(rect);
+#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
+ painter->setOpacity(1.0);
+ if (d > 2) {
+ QConicalGradient gradient2(rect.center(), angle);
+ gradient2.setColorAt(0.0, shaded_color(color, -40));
+ gradient2.setColorAt(0.25, shaded_color(color, 0));
+ gradient2.setColorAt(0.5, shaded_color(color, 210));
+ gradient2.setColorAt(0.75, shaded_color(color, 0));
+ gradient2.setColorAt(1.0, shaded_color(color, -40));
+ rect.adjust(1, 1, -1, -1);
+ painter->setBrush(color);
+ painter->drawEllipse(rect);
+ painter->setBrush(gradient2);
+ painter->setOpacity(opacity);
+ painter->drawEllipse(rect);
+ painter->setOpacity(1.0);
+ if (d > 8) {
+ QConicalGradient gradient3(rect.center(), angle);
+ gradient3.setColorAt(0.0, shaded_color(color, -10));
+ gradient3.setColorAt(0.25, shaded_color(color, 0));
+ gradient3.setColorAt(0.5, shaded_color(color, 180));
+ gradient3.setColorAt(0.75, shaded_color(color, 0));
+ gradient3.setColorAt(1.0, shaded_color(color, -10));
+ rect.adjust(2, 2, -2, -2);
+ painter->setBrush(color);
+ painter->drawEllipse(rect);
+ painter->setBrush(gradient3);
+ painter->setOpacity(opacity);
+ painter->drawEllipse(rect);
+ painter->setOpacity(1.0);
+ }
+ }
+#endif
+ painter->restore();
+}
+
+void
+paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole /*bgrole*/)
+{
+ bool useCache = UsePixmapCache;
+ QString pixmapName;
+
+ if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) {
+ useCache = false;
+ }
+ if (useCache) {
+ uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus);
+ if (!(state & QStyle::State_Enabled)) {
+ state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus);
+ }
+ state &= ~(QStyle::State_HasFocus);
+ QByteArray colorName = option->palette.color(QPalette::Button).name().toLatin1();
+ pixmapName.sprintf("scp-isg-%x-%x-%s-%x-%x", state, option->direction, colorName.constData(), option->rect.width(), option->rect.height());
+ }
+ paintIndicatorCached(painter, option, paintGrip, useCache, pixmapName);
+}
+
+void
+QDialSkulptureStyle::drawComplexControl( ComplexControl cc,
+ const QStyleOptionComplex *optc,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+
+ if (cc != QStyle::CC_Dial) {
+ QCommonStyle::drawComplexControl(cc, optc, painter, widget);
+ return;
+ }
+
+ const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(optc);
+ if (option == NULL)
+ return;
+
+ int d = qMin(option->rect.width() & ~1, option->rect.height() & ~1);
+ QStyleOptionSlider opt = *option;
+ const QAbstractSlider *slider = NULL;
+ // always highlight knob if pressed (even if mouse is not over knob)
+ if ((option->state & QStyle::State_HasFocus) && (slider = qobject_cast<const QAbstractSlider *>(widget))) {
+ if (slider->isSliderDown()) {
+ opt.state |= QStyle::State_MouseOver;
+ }
+ }
+
+ // tickmarks
+ opt.palette.setColor(QPalette::Inactive, QPalette::WindowText, QColor(80, 80, 80, 255));
+ opt.palette.setColor(QPalette::Active, QPalette::WindowText, QColor(80, 80, 80, 255));
+ opt.state &= ~QStyle::State_HasFocus;
+ opt.rect.setWidth(opt.rect.width() & ~1);
+ opt.rect.setHeight(opt.rect.height() & ~1);
+ //((QCommonStyle *) this)->
+ QCommonStyle::drawComplexControl(QStyle::CC_Dial, &opt, painter, widget);
+
+ // focus rectangle
+ if (option->state & QStyle::State_HasFocus) {
+ QStyleOptionFocusRect focus;
+ opt.state |= QStyle::State_HasFocus;
+ focus.QStyleOption::operator=(opt);
+ focus.rect.adjust(-1, -1, 1, 1);
+ //drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget);
+ }
+ opt.palette = option->palette;
+
+ // dial base
+ if (d <= 256) {
+ paintIndicatorDial(painter, &opt);
+ } else {
+ // large dials are slow to render, do not render them
+ }
+
+ // dial knob
+ d -= 6;
+ int gripSize = (option->fontMetrics.height() / 4) * 2 - 1;
+ opt.rect.setSize(QSize(gripSize, gripSize));
+ opt.rect.moveCenter(option->rect.center());
+ // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA.
+ qreal angle;
+ int sliderPosition = option->upsideDown ? option->sliderPosition : (option->maximum - option->sliderPosition);
+ int range = option->maximum - option->minimum;
+ if (!range) {
+ angle = M_PI / 2;
+ } else if (option->dialWrapping) {
+ angle = M_PI * 1.5 - (sliderPosition - option->minimum) * 2 * M_PI / range;
+ } else {
+ angle = (M_PI * 8 - (sliderPosition - option->minimum) * 10 * M_PI / range) / 6;
+ }
+
+ qreal rr = d / 2.0 - gripSize - 2;
+ opt.rect.translate(int(0.5 + rr * cos(angle)), int(0.5 - rr * sin(angle)));
+ paintCachedGrip(painter, &opt, option->state & QStyle::State_Enabled ? QPalette::Button : QPalette::Window);
+}
diff --git a/qmidiplayer-desktop/qdialskulpturestyle.hpp b/qmidiplayer-desktop/qdialskulpturestyle.hpp
new file mode 100644
index 0000000..2f3ba04
--- /dev/null
+++ b/qmidiplayer-desktop/qdialskulpturestyle.hpp
@@ -0,0 +1,39 @@
+/******************************************************************************
+
+ Skulpture - Classical Three-Dimensional Artwork for Qt 4
+
+ Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*****************************************************************************/
+
+#ifndef QDIALSKULPTURESTYLE_H
+#define QDIALSKULPTURESTYLE_H
+
+#include <QCommonStyle>
+
+class QDialSkulptureStyle:public QCommonStyle
+{
+public:
+ QDialSkulptureStyle(){}
+ virtual ~QDialSkulptureStyle(){}
+
+ virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget=0) const;
+
+};
+
+#endif // QDIALSKULPTURESTYLE_H
diff --git a/qmidiplayer-desktop/qmidiplayer-desktop.pro b/qmidiplayer-desktop/qmidiplayer-desktop.pro
new file mode 100644
index 0000000..328af5d
--- /dev/null
+++ b/qmidiplayer-desktop/qmidiplayer-desktop.pro
@@ -0,0 +1,64 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2015-12-25T20:24:49
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = qmidiplayer
+TEMPLATE = app
+
+
+SOURCES += main.cpp\
+ qmpmainwindow.cpp \
+ ../core/qmpmidiplay.cpp \
+ ../core/qmpmidiread.cpp \
+ qmpplistwindow.cpp \
+ qmpchannelswindow.cpp \
+ qmppresetselect.cpp \
+ qmpchanneleditor.cpp \
+ qmpefxwindow.cpp \
+ qmpinfowindow.cpp \
+ qmpsettingswindow.cpp \
+ qmphelpwindow.cpp \
+ qdialskulpturestyle.cpp
+
+HEADERS += qmpmainwindow.hpp \
+ ../core/qmpmidiplay.hpp \
+ qmpplistwindow.hpp \
+ qmpchannelswindow.hpp \
+ qmppresetselect.hpp \
+ qmpchanneleditor.hpp \
+ qmpefxwindow.hpp \
+ qmpinfowindow.hpp \
+ qmpsettingswindow.hpp \
+ qmphelpwindow.hpp \
+ qdialskulpturestyle.hpp \
+ qmpimidimapper.hpp
+
+FORMS += qmpmainwindow.ui \
+ qmpplistwindow.ui \
+ qmpchannelswindow.ui \
+ qmppresetselect.ui \
+ qmpchanneleditor.ui \
+ qmpefxwindow.ui \
+ qmpinfowindow.ui \
+ qmpsettingswindow.ui \
+ qmphelpwindow.ui
+
+unix{
+ isEmpty(PREFIX) {
+ PREFIX = /usr/local
+ }
+ BINDIR = $$PREFIX/bin
+ target.path = $$BINDIR
+ INSTALLS += target
+ QMAKE_CXXFLAGS += -std=c++11 -Wall
+ LIBS += -lfluidsynth
+}
+win32:LIBS += e:/libs/fluidsynth/fluidsynth.lib winmm.lib #You have to change these
+win32:INCLUDEPATH += e:/libs/fluidsynth/include #before building...
+RESOURCES = resources.qrc
diff --git a/qmidiplayer-desktop/qmpchanneleditor.cpp b/qmidiplayer-desktop/qmpchanneleditor.cpp
new file mode 100644
index 0000000..f1d4e5e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchanneleditor.cpp
@@ -0,0 +1,193 @@
+#include <cstdio>
+#include "qmpchanneleditor.hpp"
+#include "ui_qmpchanneleditor.h"
+#include "qmpmainwindow.hpp"
+
+qmpChannelEditor::qmpChannelEditor(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpChannelEditor)
+{
+ ui->setupUi(this);
+ styl=new QDialSkulptureStyle();
+ QList<QDial*> dials=findChildren<QDial*>();
+ for(int i=0;i<dials.count();++i)
+ dials.at(i)->setStyle(styl);
+}
+
+qmpChannelEditor::~qmpChannelEditor()
+{
+ delete styl;
+ delete ui;
+}
+
+void qmpChannelEditor::setupWindow(int chid)
+{
+ char str[256];if(~chid)ch=chid;
+ sprintf(str,"Channel Parameter Editor - Channel #%d",ch+1);
+ setWindowTitle(str);
+ CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+ int b,p;
+ player->getChannelPreset(ch,&b,&p,str);
+ ui->lbPresetName->setText(str);
+ sprintf(str,"BK: %d",b);ui->lbBank->setText(str);
+ sprintf(str,"PC: %d",p);ui->lbPreset->setText(str);
+ ui->lbChannelNumber->setText(QString::number(ch+1));
+#define setupControl(ccid,lb,d,ccname)\
+ b=player->getCC(ch,ccid);\
+ sprintf(str,"%s %d",ccname,b);\
+ ui->lb->setText(str);\
+ ui->d->setValue(b);
+ setupControl(7,lbVol,dVol,"Vol.");
+ setupControl(91,lbReverb,dReverb,"Rev.");
+ setupControl(93,lbChorus,dChorus,"Chr.");
+ setupControl(71,lbReso,dReso,"Res.");
+ setupControl(74,lbCut,dCut,"Cut.");
+ setupControl(73,lbAttack,dAttack,"Atk.");
+ setupControl(75,lbDecay,dDecay,"Dec.");
+ setupControl(72,lbRelease,dRelease,"Rel.");
+ setupControl(76,lbRate,dRate,"Rate");
+ setupControl(77,lbDepth,dDepth,"Dep.");
+ setupControl(78,lbDelay,dDelay,"Del.");
+ b=player->getCC(ch,10);
+ if(b==64)strcpy(str,"Pan. C");
+ else if(b<64)sprintf(str,"Pan. L%d",64-b);else sprintf(str,"Pan. R%d",b-64);
+ ui->lbPan->setText(str);
+ ui->dPan->setValue(b);
+}
+
+void qmpChannelEditor::sendCC()
+{
+ CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+ player->setCC(ch,7,ui->dVol->value());
+ player->setCC(ch,10,ui->dPan->value());
+ player->setCC(ch,91,ui->dReverb->value());
+ player->setCC(ch,93,ui->dChorus->value());
+ player->setCC(ch,71,ui->dReso->value());
+ player->setCC(ch,74,ui->dCut->value());
+ player->setCC(ch,73,ui->dAttack->value());
+ player->setCC(ch,75,ui->dDecay->value());
+ player->setCC(ch,72,ui->dRelease->value());
+ player->setCC(ch,76,ui->dRate->value());
+ player->setCC(ch,77,ui->dDepth->value());
+ player->setCC(ch,78,ui->dDelay->value());
+}
+
+void qmpChannelEditor::showEvent(QShowEvent *e)
+{
+ knobpressed=0;
+ setupWindow();
+ connectSlots();
+ connect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));
+ e->accept();
+}
+void qmpChannelEditor::closeEvent(QCloseEvent *e)
+{
+ disconnectSlots();
+ disconnect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));
+ e->accept();
+}
+
+void qmpChannelEditor::on_pbChLeft_clicked()
+{
+ disconnectSlots();
+ if(ch>0)--ch;else ch=15;setupWindow();
+ connectSlots();
+}
+
+void qmpChannelEditor::on_pbChRight_clicked()
+{
+ disconnectSlots();
+ if(ch<15)++ch;else ch=0;setupWindow();
+ connectSlots();
+}
+
+void qmpChannelEditor::commonPressed()
+{disconnect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));knobpressed=1;}
+void qmpChannelEditor::commonReleased()
+{connect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));sendCC();knobpressed=0;}
+void qmpChannelEditor::commonChanged()
+{if(knobpressed){sendCC();setupWindow();}}
+
+void qmpChannelEditor::connectSlots()
+{
+ connect(ui->dCut,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dReso,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dReverb,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dChorus,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dVol,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dPan,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dAttack,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dDecay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dRelease,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dRate,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dDepth,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ connect(ui->dDelay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+
+ connect(ui->dCut,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dReso,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dReverb,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dChorus,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dVol,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dPan,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dAttack,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dDecay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dRelease,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dRate,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dDepth,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ connect(ui->dDelay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+
+ connect(ui->dCut,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dReso,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dReverb,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dChorus,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dVol,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dPan,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dAttack,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dDecay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dRelease,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dRate,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dDepth,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ connect(ui->dDelay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+}
+
+void qmpChannelEditor::disconnectSlots()
+{
+ disconnect(ui->dCut,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dReso,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dReverb,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dChorus,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dVol,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dPan,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dAttack,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dDecay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dRelease,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dRate,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dDepth,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+ disconnect(ui->dDelay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+
+ disconnect(ui->dCut,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dReso,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dReverb,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dChorus,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dVol,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dPan,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dAttack,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dDecay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dRelease,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dRate,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dDepth,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+ disconnect(ui->dDelay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+
+ disconnect(ui->dCut,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dReso,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dReverb,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dChorus,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dVol,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dPan,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dAttack,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dDecay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dRelease,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dRate,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dDepth,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+ disconnect(ui->dDelay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+}
diff --git a/qmidiplayer-desktop/qmpchanneleditor.hpp b/qmidiplayer-desktop/qmpchanneleditor.hpp
new file mode 100644
index 0000000..0653af5
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchanneleditor.hpp
@@ -0,0 +1,42 @@
+#ifndef QMPCHANNELEDITOR_H
+#define QMPCHANNELEDITOR_H
+
+#include <QDialog>
+#include <QShowEvent>
+#include <QCloseEvent>
+#include "qdialskulpturestyle.hpp"
+
+namespace Ui {
+ class qmpChannelEditor;
+}
+
+class qmpChannelEditor:public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpChannelEditor(QWidget *parent=0);
+ ~qmpChannelEditor();
+ protected:
+ void showEvent(QShowEvent *e);
+ void closeEvent(QCloseEvent *e);
+ public slots:
+ void setupWindow(int chid=-1);
+
+ private slots:
+ void commonPressed();
+ void commonReleased();
+ void commonChanged();
+ void on_pbChLeft_clicked();
+ void on_pbChRight_clicked();
+
+ private:
+ Ui::qmpChannelEditor *ui;
+ int ch,knobpressed;
+ void sendCC();
+ void connectSlots();
+ void disconnectSlots();
+ QCommonStyle* styl;
+};
+
+#endif // QMPCHANNELEDITOR_H
diff --git a/qmidiplayer-desktop/qmpchanneleditor.ui b/qmidiplayer-desktop/qmpchanneleditor.ui
new file mode 100644
index 0000000..49e8c8e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchanneleditor.ui
@@ -0,0 +1,602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpChannelEditor</class>
+ <widget class="QDialog" name="qmpChannelEditor">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>422</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>422</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>422</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <widget class="QPushButton" name="pbChLeft">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>21</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbChannelNumber">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>10</y>
+ <width>21</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>1</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbChRight">
+ <property name="geometry">
+ <rect>
+ <x>50</x>
+ <y>10</y>
+ <width>21</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbPresetName">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>10</y>
+ <width>261</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>16</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string>Yamaha Grand Piano</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbBank">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>81</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>BK: 0</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbPreset">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>81</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PC: 0</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" name="gFilters">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>70</y>
+ <width>141</width>
+ <height>101</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Filters</string>
+ </property>
+ <widget class="QLabel" name="lbReso">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Res. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dReso">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dCut">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbCut">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>80</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Cut. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" name="gEffects">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>70</y>
+ <width>141</width>
+ <height>101</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Effects</string>
+ </property>
+ <widget class="QLabel" name="lbChorus">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Chr. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dChorus">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dReverb">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbReverb">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>80</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Rev. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" name="gEnvelope">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>170</y>
+ <width>211</width>
+ <height>101</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Envelope</string>
+ </property>
+ <widget class="QLabel" name="lbDecay">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Dec. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dDecay">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dAttack">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbAttack">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>80</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Atk. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dRelease">
+ <property name="geometry">
+ <rect>
+ <x>150</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbRelease">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Rel. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" name="gVibrato">
+ <property name="geometry">
+ <rect>
+ <x>210</x>
+ <y>170</y>
+ <width>211</width>
+ <height>101</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Vibrato</string>
+ </property>
+ <widget class="QLabel" name="lbDepth">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Dep. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dDepth">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dRate">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbRate">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>80</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Rate 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dDelay">
+ <property name="geometry">
+ <rect>
+ <x>150</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbDelay">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Del. 64</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" name="gMixer">
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>70</y>
+ <width>141</width>
+ <height>101</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Mixer</string>
+ </property>
+ <widget class="QLabel" name="lbPan">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Pan. C</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dPan">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbVol">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>80</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Vol. 127</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QDial" name="dVol">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp
new file mode 100644
index 0000000..a9cf60e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchannelswindow.cpp
@@ -0,0 +1,132 @@
+#include <QCheckBox>
+#include <QPushButton>
+#include <QComboBox>
+#include "qmpchannelswindow.hpp"
+#include "ui_qmpchannelswindow.h"
+#include "qmpmainwindow.hpp"
+
+qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpChannelsWindow)
+{
+ ui->setupUi(this);
+ pselectw=new qmpPresetSelector(this);
+ ceditw=new qmpChannelEditor(this);
+ connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+ for(int i=0;i<16;++i)
+ {
+ ui->twChannels->setCellWidget(i,0,new QCheckBox(""));
+ connect(ui->twChannels->cellWidget(i,0),SIGNAL(stateChanged(int)),this,SLOT(channelMSChanged()));
+ ui->twChannels->setCellWidget(i,1,new QCheckBox(""));
+ connect(ui->twChannels->cellWidget(i,1),SIGNAL(stateChanged(int)),this,SLOT(channelMSChanged()));
+ ui->twChannels->setCellWidget(i,2,new QComboBox());
+ QComboBox *cb=(QComboBox*)ui->twChannels->cellWidget(i,2);
+ //stub
+ cb->addItem("Internal FluidSynth");
+ ui->twChannels->setCellWidget(i,3,new QDCLabel(""));
+ ((QDCLabel*)ui->twChannels->cellWidget(i,3))->setID(i);
+ connect(ui->twChannels->cellWidget(i,3),SIGNAL(onDoubleClick(int)),this,SLOT(showPresetWindow(int)));
+ ui->twChannels->setCellWidget(i,4,new QDCPushButton("..."));
+ ((QDCLabel*)ui->twChannels->cellWidget(i,4))->setID(i);
+ connect(ui->twChannels->cellWidget(i,4),SIGNAL(onClick(int)),this,SLOT(showChannelEditorWindow(int)));
+ }
+ ui->twChannels->setColumnWidth(0,32);
+ ui->twChannels->setColumnWidth(1,32);
+ ui->twChannels->setColumnWidth(2,192);
+ ui->twChannels->setColumnWidth(3,192);
+ ui->twChannels->setColumnWidth(4,32);
+}
+
+void qmpChannelsWindow::showEvent(QShowEvent *event)
+{
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",1);
+ }
+ event->accept();
+}
+
+void qmpChannelsWindow::closeEvent(QCloseEvent *event)
+{
+ setVisible(false);
+ if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",0);
+ }
+ emit dialogClosing();
+ event->accept();
+}
+
+void qmpChannelsWindow::moveEvent(QMoveEvent *event)
+{
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlW",event->pos());
+ }
+}
+
+void qmpChannelsWindow::channelWindowsUpdate()
+{
+ if(qmpMainWindow::getInstance()->getPlayer()->isFinished())
+ {
+ for(int i=0;i<16;++i)
+ ((QLabel*)ui->twChannels->cellWidget(i,3))->setText("");
+ return;
+ }
+ for(int i=0;i<16;++i)
+ {
+ char data[128],nm[24];
+ int b,p;
+ qmpMainWindow::getInstance()->getPlayer()->getChannelPreset(i,&b,&p,nm);
+ sprintf(data,"%d:%d %s",b,p,nm);
+ ((QLabel*)ui->twChannels->cellWidget(i,3))->setText(data);
+ }
+}
+
+void qmpChannelsWindow::channelMSChanged()
+{
+ for(int i=0;i<16;++i)
+ {
+ QCheckBox *m,*s;
+ m=(QCheckBox*)ui->twChannels->cellWidget(i,0);
+ s=(QCheckBox*)ui->twChannels->cellWidget(i,1);
+ if(m->isChecked()&&s->isChecked())s->setChecked(false);
+ qmpMainWindow::getInstance()->getPlayer()->setMute(i,m->isChecked());
+ qmpMainWindow::getInstance()->getPlayer()->setSolo(i,s->isChecked());
+ }
+}
+
+qmpChannelsWindow::~qmpChannelsWindow()
+{
+ delete ui;
+}
+
+void qmpChannelsWindow::on_pbUnmute_clicked()
+{
+ for(int i=0;i<16;++i)
+ {
+ ((QCheckBox*)ui->twChannels->cellWidget(i,0))->setChecked(false);
+ qmpMainWindow::getInstance()->getPlayer()->setMute(i,false);
+ }
+}
+
+void qmpChannelsWindow::on_pbUnsolo_clicked()
+{
+ for(int i=0;i<16;++i)
+ {
+ ((QCheckBox*)ui->twChannels->cellWidget(i,1))->setChecked(false);
+ qmpMainWindow::getInstance()->getPlayer()->setSolo(i,false);
+ }
+}
+
+void qmpChannelsWindow::showPresetWindow(int chid)
+{
+ pselectw->show();
+ pselectw->setupWindow(chid);
+}
+
+void qmpChannelsWindow::showChannelEditorWindow(int chid)
+{
+ ceditw->show();
+ ceditw->setupWindow(chid);
+}
diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp
new file mode 100644
index 0000000..f0591b6
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchannelswindow.hpp
@@ -0,0 +1,71 @@
+#ifndef QMPCHANNELSWINDOW_H
+#define QMPCHANNELSWINDOW_H
+
+#include <QLabel>
+#include <QPushButton>
+#include <QDialog>
+#include <QShowEvent>
+#include <QCloseEvent>
+#include <QMoveEvent>
+#include "qmppresetselect.hpp"
+#include "qmpchanneleditor.hpp"
+
+namespace Ui {
+ class qmpChannelsWindow;
+}
+
+class QDCLabel:public QLabel
+{
+ Q_OBJECT
+ private:
+ int id;
+ protected:
+ void mouseDoubleClickEvent(QMouseEvent *event){event->accept();emit onDoubleClick(id);}
+ public:
+ QDCLabel(QString s):QLabel(s){id=-1;}
+ void setID(int _id){id=_id;}
+ signals:
+ void onDoubleClick(int id);
+};
+
+class QDCPushButton:public QPushButton
+{
+ Q_OBJECT
+ private:
+ int id;
+ protected:
+ void mousePressEvent(QMouseEvent *event){QPushButton::mousePressEvent(event);emit onClick(id);}
+ public:
+ QDCPushButton(QString s):QPushButton(s){id=-1;}
+ void setID(int _id){id=_id;}
+ signals:
+ void onClick(int id);
+};
+
+class qmpChannelsWindow:public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpChannelsWindow(QWidget *parent = 0);
+ ~qmpChannelsWindow();
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void moveEvent(QMoveEvent *event);
+ signals:
+ void dialogClosing();
+ public slots:
+ void channelWindowsUpdate();
+ void channelMSChanged();
+ void showPresetWindow(int chid);
+ void showChannelEditorWindow(int chid);
+ void on_pbUnmute_clicked();
+ void on_pbUnsolo_clicked();
+
+ private:
+ Ui::qmpChannelsWindow *ui;
+ qmpPresetSelector *pselectw;
+ qmpChannelEditor *ceditw;
+};
+
+#endif // QMPCHANNELSWINDOW_H
diff --git a/qmidiplayer-desktop/qmpchannelswindow.ui b/qmidiplayer-desktop/qmpchannelswindow.ui
new file mode 100644
index 0000000..a8b43cb
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchannelswindow.ui
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpChannelsWindow</class>
+ <widget class="QDialog" name="qmpChannelsWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>580</width>
+ <height>410</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>580</width>
+ <height>410</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>580</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Channels</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_1">
+ <item>
+ <widget class="QTableWidget" name="twChannels">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::NoSelection</enum>
+ </property>
+ <property name="cornerButtonEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="rowCount">
+ <number>16</number>
+ </property>
+ <property name="columnCount">
+ <number>5</number>
+ </property>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <row/>
+ <column>
+ <property name="text">
+ <string>M</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>S</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Device</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Preset</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </column>
+ <item row="0" column="0">
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="pbSave">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbLoad">
+ <property name="text">
+ <string>Load</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbUnmute">
+ <property name="text">
+ <string>Unmute All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbUnsolo">
+ <property name="text">
+ <string>Unsolo All</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpefxwindow.cpp b/qmidiplayer-desktop/qmpefxwindow.cpp
new file mode 100644
index 0000000..7d9c08e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpefxwindow.cpp
@@ -0,0 +1,198 @@
+#include <cmath>
+#include "qmpefxwindow.hpp"
+#include "ui_qmpefxwindow.h"
+#include "qmpmainwindow.hpp"
+
+qmpEfxWindow::qmpEfxWindow(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpEfxWindow)
+{
+ ui->setupUi(this);initialized=false;
+ styl=new QDialSkulptureStyle();
+ QList<QDial*> dials=findChildren<QDial*>();
+ for(int i=0;i<dials.count();++i)
+ dials.at(i)->setStyle(styl);
+ connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+ //stub. read these from settings after the setting module is implemented
+ QSettings *settings=qmpSettingsWindow::getSettingsIntf();
+ ui->cbEnabledC->setChecked(settings->value("Effects/ChorusEnabled",1).toInt());
+ ui->cbEnabledR->setChecked(settings->value("Effects/ReverbEnabled",1).toInt());
+ rr=settings->value("Effects/ReverbRoom",FLUID_REVERB_DEFAULT_ROOMSIZE).toDouble();
+ rd=settings->value("Effects/ReverbDamp",FLUID_REVERB_DEFAULT_DAMP).toDouble();
+ rw=settings->value("Effects/ReverbWidth",FLUID_REVERB_DEFAULT_WIDTH).toDouble();
+ rl=settings->value("Effects/ReverbLevel",FLUID_REVERB_DEFAULT_LEVEL).toDouble();
+
+ cfb=settings->value("Effects/ChorusFeedbk",FLUID_CHORUS_DEFAULT_N).toInt();
+ cl=settings->value("Effects/ChorusLevel",FLUID_CHORUS_DEFAULT_LEVEL).toDouble();
+ cr=settings->value("Effects/ChorusRate",FLUID_CHORUS_DEFAULT_SPEED).toDouble();
+ cd=settings->value("Effects/ChorusDepth",FLUID_CHORUS_DEFAULT_DEPTH).toDouble();
+ ct=settings->value("Effects/ChorusType",FLUID_CHORUS_DEFAULT_TYPE).toInt();
+}
+
+qmpEfxWindow::~qmpEfxWindow()
+{
+ delete styl;
+ delete ui;
+}
+
+void qmpEfxWindow::closeEvent(QCloseEvent *event)
+{
+ setVisible(false);
+ if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",0);
+ }
+ emit dialogClosing();
+ event->accept();
+}
+
+void qmpEfxWindow::showEvent(QShowEvent *event)
+{
+ //CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+ //These parameters will never be modified outside this window...
+ /*if(initialized)
+ {
+ player->getReverbPara(&rr,&rd,&rw,&rl);
+ player->getChorusPara(&cfb,&cl,&cr,&cd,&ct);
+ }*/
+ ui->sbRoom->setValue((int)round(rr*100));ui->dRoom->setValue((int)round(rr*100));
+ ui->sbDamp->setValue((int)round(rd*100));ui->dDamp->setValue((int)round(rd*100));
+ ui->sbWidth->setValue((int)round(rw*100));ui->dWidth->setValue((int)round(rw*100));
+ ui->sbLevelR->setValue((int)round(rl*100));ui->dLevelR->setValue((int)round(rl*100));
+
+ ui->sbFeedBack->setValue(cfb);ui->dFeedBack->setValue(cfb);
+ ui->sbRate->setValue(cr);ui->dRate->setValue((int)round(cr*100));
+ ui->sbDepth->setValue(cd);ui->dDepth->setValue((int)round(cd*10));
+ ui->sbLevelC->setValue((int)round(cl*100));ui->dLevelC->setValue((int)round(cl*100));
+ if(ct==FLUID_CHORUS_MOD_SINE)ui->rbSine->setChecked(true),ui->rbTriangle->setChecked(false);
+ if(ct==FLUID_CHORUS_MOD_TRIANGLE)ui->rbSine->setChecked(false),ui->rbTriangle->setChecked(true);
+ initialized=true;
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",1);
+ }
+ event->accept();
+}
+
+void qmpEfxWindow::moveEvent(QMoveEvent *event)
+{
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxW",event->pos());
+ }
+}
+
+void qmpEfxWindow::sendEfxChange()
+{
+ if(!qmpMainWindow::getInstance()||!initialized)return;
+ rr=ui->sbRoom->value()/100.;rd=ui->sbDamp->value()/100.;
+ rw=ui->sbWidth->value()/100.;rl=ui->sbLevelR->value()/100.;
+ ct=ui->rbSine->isChecked()?FLUID_CHORUS_MOD_SINE:FLUID_CHORUS_MOD_TRIANGLE;
+ cfb=ui->sbFeedBack->value();cl=ui->sbLevelC->value()/100.;
+ cr=ui->sbRate->value();cd=ui->sbDepth->value();
+ CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+ player->setReverbPara(ui->cbEnabledR->isChecked()?1:0,rr,rd,rw,rl);
+ player->setChorusPara(ui->cbEnabledC->isChecked()?1:0,cfb,cl,cr,cd,ct);
+
+ QSettings *settings=qmpSettingsWindow::getSettingsIntf();
+ settings->setValue("Effects/ChorusEnabled",ui->cbEnabledC->isChecked()?1:0);
+ settings->setValue("Effects/ReverbEnabled",ui->cbEnabledR->isChecked()?1:0);
+ settings->setValue("Effects/ReverbRoom",rr);
+ settings->setValue("Effects/ReverbDamp",rd);
+ settings->setValue("Effects/ReverbWidth",rw);
+ settings->setValue("Effects/ReverbLevel",rl);
+
+ settings->setValue("Effects/ChorusFeedbk",cfb);
+ settings->setValue("Effects/ChorusLevel",cl);
+ settings->setValue("Effects/ChorusRate",cr);
+ settings->setValue("Effects/ChorusDepth",cd);
+ settings->setValue("Effects/ChorusType",ct);
+}
+
+void qmpEfxWindow::dailValueChange()
+{
+ if(!initialized)return;
+ ui->sbRoom->setValue(ui->dRoom->value());
+ ui->sbDamp->setValue(ui->dDamp->value());
+ ui->sbWidth->setValue(ui->dWidth->value());
+ ui->sbLevelR->setValue(ui->dLevelR->value());
+ ui->sbFeedBack->setValue(ui->dFeedBack->value());
+ ui->sbRate->setValue(ui->dRate->value()/100.);
+ ui->sbDepth->setValue(ui->dDepth->value()/10.);
+ ui->sbLevelC->setValue(ui->dLevelC->value());
+ sendEfxChange();
+}
+
+void qmpEfxWindow::spinValueChange()
+{
+ if(!initialized)return;
+ ui->dRoom->setValue(ui->sbRoom->value());
+ ui->dDamp->setValue(ui->sbDamp->value());
+ ui->dWidth->setValue(ui->sbWidth->value());
+ ui->dLevelR->setValue(ui->sbLevelR->value());
+ ui->dFeedBack->setValue(ui->sbFeedBack->value());
+ ui->dRate->setValue((int)(ui->sbRate->value()*100));
+ ui->dDepth->setValue((int)(ui->sbDepth->value()*10));
+ ui->dLevelC->setValue(ui->sbLevelC->value());
+ sendEfxChange();
+}
+
+void qmpEfxWindow::on_dRoom_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dDamp_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dWidth_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dLevelR_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dFeedBack_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dRate_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dDepth_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dLevelC_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_sbRoom_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbDamp_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbWidth_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbLevelR_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbFeedBack_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbRate_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbDepth_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbLevelC_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_cbEnabledC_stateChanged()
+{sendEfxChange();}
+
+void qmpEfxWindow::on_cbEnabledR_stateChanged()
+{sendEfxChange();}
+
+void qmpEfxWindow::on_rbSine_toggled()
+{sendEfxChange();}
+
+void qmpEfxWindow::on_rbTriangle_toggled()
+{sendEfxChange();}
diff --git a/qmidiplayer-desktop/qmpefxwindow.hpp b/qmidiplayer-desktop/qmpefxwindow.hpp
new file mode 100644
index 0000000..2a080f0
--- /dev/null
+++ b/qmidiplayer-desktop/qmpefxwindow.hpp
@@ -0,0 +1,62 @@
+#ifndef QMPEFXWINDOW_HPP
+#define QMPEFXWINDOW_HPP
+
+#include <QDialog>
+#include <QCloseEvent>
+#include <QShowEvent>
+#include <QMoveEvent>
+
+#include "qdialskulpturestyle.hpp"
+
+namespace Ui {
+ class qmpEfxWindow;
+}
+
+class qmpEfxWindow : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpEfxWindow(QWidget *parent=0);
+ ~qmpEfxWindow();
+ void closeEvent(QCloseEvent *event);
+ void showEvent(QShowEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void sendEfxChange();
+
+ signals:
+ void dialogClosing();
+
+ private slots:
+ void on_dRoom_valueChanged();
+ void on_dDamp_valueChanged();
+ void on_dWidth_valueChanged();
+ void on_dLevelR_valueChanged();
+ void on_dFeedBack_valueChanged();
+ void on_dRate_valueChanged();
+ void on_dDepth_valueChanged();
+ void on_dLevelC_valueChanged();
+ void on_sbRoom_valueChanged(QString s);
+ void on_sbDamp_valueChanged(QString s);
+ void on_sbWidth_valueChanged(QString s);
+ void on_sbLevelR_valueChanged(QString s);
+ void on_sbFeedBack_valueChanged(QString s);
+ void on_sbRate_valueChanged(QString s);
+ void on_sbDepth_valueChanged(QString s);
+ void on_sbLevelC_valueChanged(QString s);
+ void on_cbEnabledC_stateChanged();
+ void on_cbEnabledR_stateChanged();
+ void on_rbSine_toggled();
+ void on_rbTriangle_toggled();
+
+ private:
+ void dailValueChange();
+ void spinValueChange();
+ Ui::qmpEfxWindow *ui;
+ double rr,rd,rw,rl;
+ int cfb,ct,initialized;
+ double cl,cr,cd;
+ QCommonStyle* styl;
+};
+
+#endif // QMPEFXWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmpefxwindow.ui b/qmidiplayer-desktop/qmpefxwindow.ui
new file mode 100644
index 0000000..4a1e0c6
--- /dev/null
+++ b/qmidiplayer-desktop/qmpefxwindow.ui
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpEfxWindow</class>
+ <widget class="QDialog" name="qmpEfxWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>546</width>
+ <height>177</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>546</width>
+ <height>177</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>546</width>
+ <height>177</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Effects</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QGroupBox" name="gReverb">
+ <property name="title">
+ <string>Reverb</string>
+ </property>
+ <widget class="QCheckBox" name="cbEnabledR">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>4</y>
+ <width>21</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ <widget class="QDial" name="dRoom">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>120</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dDamp">
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dWidth">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>103</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dLevelR">
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>103</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbRoom">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>30</y>
+ <width>41</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Room</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="sbRoom">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>50</y>
+ <width>51</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>120</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbDamp">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>30</y>
+ <width>51</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Damp</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="sbDamp">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>50</y>
+ <width>56</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbWidth">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>100</y>
+ <width>51</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Width</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="sbWidth">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>120</y>
+ <width>56</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbLevelR">
+ <property name="geometry">
+ <rect>
+ <x>145</x>
+ <y>100</y>
+ <width>51</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Level</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="sbLevelR">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>120</y>
+ <width>56</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="gChorus">
+ <property name="title">
+ <string>Chorus</string>
+ </property>
+ <widget class="QCheckBox" name="cbEnabledC">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>4</y>
+ <width>21</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ <widget class="QDial" name="dFeedBack">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>99</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dRate">
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>30</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="minimum">
+ <number>29</number>
+ </property>
+ <property name="maximum">
+ <number>500</number>
+ </property>
+ <property name="value">
+ <number>29</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dDepth">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>103</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>210</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QDial" name="dLevelC">
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>103</y>
+ <width>50</width>
+ <height>51</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbFeedBack">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>30</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Feedback</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="sbFeedBack">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>50</y>
+ <width>51</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>99</number>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbRate">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>30</y>
+ <width>51</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Rate</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbDepth">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>100</y>
+ <width>51</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Depth</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbLevelC">
+ <property name="geometry">
+ <rect>
+ <x>145</x>
+ <y>100</y>
+ <width>51</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Level</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QSpinBox" name="sbLevelC">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>120</y>
+ <width>56</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="sbRate">
+ <property name="geometry">
+ <rect>
+ <x>137</x>
+ <y>50</y>
+ <width>61</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="minimum">
+ <double>0.290000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>5.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbLFO">
+ <property name="geometry">
+ <rect>
+ <x>35</x>
+ <y>77</y>
+ <width>41</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>LFO</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="rbSine">
+ <property name="geometry">
+ <rect>
+ <x>70</x>
+ <y>77</y>
+ <width>61</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Sine</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="rbTriangle">
+ <property name="geometry">
+ <rect>
+ <x>145</x>
+ <y>77</y>
+ <width>91</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Trian&amp;gle</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="sbDepth">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>120</y>
+ <width>51</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="decimals">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <double>21.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmphelpwindow.cpp b/qmidiplayer-desktop/qmphelpwindow.cpp
new file mode 100644
index 0000000..10cf083
--- /dev/null
+++ b/qmidiplayer-desktop/qmphelpwindow.cpp
@@ -0,0 +1,31 @@
+#include <fluidsynth.h>
+#include "qmphelpwindow.hpp"
+#include "ui_qmphelpwindow.h"
+
+qmpHelpWindow::qmpHelpWindow(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpHelpWindow)
+{
+ ui->setupUi(this);
+ ui->textBrowser->setSearchPaths(QStringList(QString(":/doc"))+QStringList(QString(":/img")));
+ ui->textBrowser->setSource(QUrl("qrc:///doc/index.html"));
+}
+
+qmpHelpWindow::~qmpHelpWindow()
+{
+ delete ui;
+}
+
+void qmpHelpWindow::on_textBrowser_sourceChanged(const QUrl &src)
+{
+ if(src.fileName()==QString("version.html"))
+ {
+ QString s=ui->textBrowser->toHtml();
+ s.replace("CT_QT_VERSION_STR",QT_VERSION_STR);
+ s.replace("RT_QT_VERSION_STR",qVersion());
+ s.replace("CT_FLUIDSYNTH_VERSION",FLUIDSYNTH_VERSION);
+ s.replace("RT_FLUIDSYNTH_VERSION",fluid_version_str());
+ s.replace("APP_VERSION",APP_VERSION);
+ ui->textBrowser->setHtml(s);
+ }
+}
diff --git a/qmidiplayer-desktop/qmphelpwindow.hpp b/qmidiplayer-desktop/qmphelpwindow.hpp
new file mode 100644
index 0000000..c2052b2
--- /dev/null
+++ b/qmidiplayer-desktop/qmphelpwindow.hpp
@@ -0,0 +1,26 @@
+#ifndef QMPHELPWINDOW_H
+#define QMPHELPWINDOW_H
+
+#include <QDialog>
+#define APP_VERSION "0.7.0"
+
+namespace Ui {
+ class qmpHelpWindow;
+}
+
+class qmpHelpWindow : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpHelpWindow(QWidget *parent = 0);
+ ~qmpHelpWindow();
+
+ private slots:
+ void on_textBrowser_sourceChanged(const QUrl &src);
+
+ private:
+ Ui::qmpHelpWindow *ui;
+};
+
+#endif // QMPHELPWINDOW_H
diff --git a/qmidiplayer-desktop/qmphelpwindow.ui b/qmidiplayer-desktop/qmphelpwindow.ui
new file mode 100644
index 0000000..fd21b5f
--- /dev/null
+++ b/qmidiplayer-desktop/qmphelpwindow.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpHelpWindow</class>
+ <widget class="QDialog" name="qmpHelpWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>640</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>640</width>
+ <height>360</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Help</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextBrowser" name="textBrowser">
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpimidimapper.hpp b/qmidiplayer-desktop/qmpimidimapper.hpp
new file mode 100644
index 0000000..d35dbb9
--- /dev/null
+++ b/qmidiplayer-desktop/qmpimidimapper.hpp
@@ -0,0 +1,16 @@
+#ifndef QMPIMIDIMAPPER_H
+#define QMPIMIDIMAPPER_H
+class qmpIMidiMapper
+{
+ virtual void deviceInit(int id)=0;
+ virtual void deviceDeinit(int id)=0;
+ virtual void noteOn(int ch,int key,int vel)=0;
+ virtual void noteOff(int ch,int key)=0;
+ virtual void ctrlChange(int ch,int cc,int val)=0;
+ virtual void progChange(int ch,int val)=0;
+ virtual void pitchBend(int ch,int val)=0;
+ virtual void sysEx(int length,const char* data)=0;
+ virtual static int enumDevices()=0;
+ virtual static char* deviceName(int id)=0;
+};
+#endif // QMPIMIDIMAPPER_H
diff --git a/qmidiplayer-desktop/qmpinfowindow.cpp b/qmidiplayer-desktop/qmpinfowindow.cpp
new file mode 100644
index 0000000..689a756
--- /dev/null
+++ b/qmidiplayer-desktop/qmpinfowindow.cpp
@@ -0,0 +1,57 @@
+#include <QTextCodec>
+#include "qmpinfowindow.hpp"
+#include "ui_qmpinfowindow.h"
+#include "qmpmainwindow.hpp"
+#include "qmpsettingswindow.hpp"
+
+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 char* standards="? GM GM2GS XG ";
+
+qmpInfoWindow::qmpInfoWindow(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpInfoWindow)
+{
+ ui->setupUi(this);
+}
+
+qmpInfoWindow::~qmpInfoWindow()
+{
+ delete ui;
+}
+
+void qmpInfoWindow::updateInfo()
+{
+ char str[256];
+ CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+ QSettings* settings=qmpSettingsWindow::getSettingsIntf();
+ ui->lbFileName->setText(QString("File name: ")+qmpMainWindow::getInstance()->getFileName());
+ if(player->getTitle())
+ {
+ if(settings->value("Midi/TextEncoding","").toString()!="Unicode")
+ ui->lbTitle->setText(QString("Title: ")+
+ QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getTitle()));
+ else
+ ui->lbTitle->setText(QString("Title: ")+player->getTitle());
+ }
+ else ui->lbTitle->setText(QString("Title: "));
+ if(player->getCopyright())
+ {
+ if(settings->value("Midi/TextEncoding","").toString()!="Unicode")
+ ui->lbCopyright->setText(QString("Copyright: ")+
+ QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getCopyright()));
+ else
+ ui->lbCopyright->setText(QString("Copyright: ")+player->getCopyright());
+ }
+ else ui->lbCopyright->setText(QString("Copyright: "));
+ ui->lbTempo->setText(QString("Tempo: ")+QString::number(player->getTempo(),'g',5));
+ int t,r;player->getCurrentKeySignature(&t);r=(int8_t)((t>>8)&0xFF)+7;
+ strncpy(str,t&0xFF?minors+2*r:majors+2*r,2);str[2]='\0';
+ ui->lbKeySig->setText(QString("Key Sig.: ")+str);
+ player->getCurrentTimeSignature(&t,&r);sprintf(str,"Time Sig.: %d/%d",t,r);
+ ui->lbTimeSig->setText(str);
+ sprintf(str,"Note count: %u",player->getFileNoteCount());
+ ui->lbNoteCount->setText(str);
+ strncpy(str,standards+player->getFileStandard()*3,3);str[3]='\0';
+ ui->lbFileStandard->setText(QString("File standard: ")+str);
+}
diff --git a/qmidiplayer-desktop/qmpinfowindow.hpp b/qmidiplayer-desktop/qmpinfowindow.hpp
new file mode 100644
index 0000000..9a1e389
--- /dev/null
+++ b/qmidiplayer-desktop/qmpinfowindow.hpp
@@ -0,0 +1,24 @@
+#ifndef QMPINFOWINDOW_HPP
+#define QMPINFOWINDOW_HPP
+
+#include <QDialog>
+
+namespace Ui {
+ class qmpInfoWindow;
+}
+
+class qmpInfoWindow : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpInfoWindow(QWidget *parent = 0);
+ ~qmpInfoWindow();
+ public slots:
+ void updateInfo();
+
+ private:
+ Ui::qmpInfoWindow *ui;
+};
+
+#endif // QMPINFOWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmpinfowindow.ui b/qmidiplayer-desktop/qmpinfowindow.ui
new file mode 100644
index 0000000..664531a
--- /dev/null
+++ b/qmidiplayer-desktop/qmpinfowindow.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpInfoWindow</class>
+ <widget class="QDialog" name="qmpInfoWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>142</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>142</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>File Information</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="lbFileName">
+ <property name="text">
+ <string>File name: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="lbTempo">
+ <property name="text">
+ <string>Tempo: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lbKeySig">
+ <property name="text">
+ <string>Key Sig.: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lbTimeSig">
+ <property name="text">
+ <string>Time Sig.:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="lbTitle">
+ <property name="text">
+ <string>Title: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lbCopyright">
+ <property name="text">
+ <string>Copyright: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="lbNoteCount">
+ <property name="text">
+ <string>Note count: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lbFileStandard">
+ <property name="text">
+ <string>File standard: </string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp
new file mode 100644
index 0000000..58caea1
--- /dev/null
+++ b/qmidiplayer-desktop/qmpmainwindow.cpp
@@ -0,0 +1,510 @@
+#include <cstdio>
+#include <QUrl>
+#include <QMimeData>
+#include <QDirIterator>
+#include <QDesktopWidget>
+#include "qmpmainwindow.hpp"
+#include "ui_qmpmainwindow.h"
+#include "../core/qmpmidiplay.hpp"
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+qmpMainWindow* qmpMainWindow::ref=NULL;
+
+qmpMainWindow::qmpMainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::qmpMainWindow)
+{
+ ui->setupUi(this);
+ ui->lbFileName->setText("");ref=this;
+ playing=false;stopped=true;dragging=false;
+ settingsw=new qmpSettingsWindow(this);
+ plistw=new qmpPlistWindow(this);
+ chnlw=new qmpChannelsWindow(this);
+ efxw=new qmpEfxWindow(this);
+ infow=new qmpInfoWindow(this);
+ helpw=new qmpHelpWindow(this);
+ timer=new QTimer(this);
+ fnA1=new QAction("File Information",ui->lbFileName);
+ fnA2=new QAction("Render to Wave",ui->lbFileName);
+ ui->lbFileName->addAction(fnA1);
+ ui->lbFileName->addAction(fnA2);
+ singleFS=qmpSettingsWindow::getSettingsIntf()->value("Behavior/SingleInstance",0).toInt();
+ player=new CMidiPlayer(singleFS);
+ if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize();
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus",0).toInt())
+ {
+ QRect g=geometry();
+ g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/MainW",QPoint(-999,-999)).toPoint());
+ if(g.topLeft()!=QPoint(-999,-999))setGeometry(g);
+ else setGeometry(QStyle::alignedRect(
+ Qt::LeftToRight,Qt::AlignCenter,size(),
+ qApp->desktop()->availableGeometry()));
+ }show();
+ if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListWShown",0).toInt())
+ {ui->pbPList->setChecked(true);on_pbPList_clicked();}
+ if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlWShown",0).toInt())
+ {ui->pbChannels->setChecked(true);on_pbChannels_clicked();}
+ if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxWShown",0).toInt())
+ {ui->pbEfx->setChecked(true);on_pbEfx_clicked();}
+ ui->vsMasterVol->setValue(qmpSettingsWindow::getSettingsIntf()->value("Audio/Gain",50).toInt());
+ connect(fnA1,SIGNAL(triggered()),this,SLOT(onfnA1()));
+ connect(fnA2,SIGNAL(triggered()),this,SLOT(onfnA2()));
+ connect(timer,SIGNAL(timeout()),this,SLOT(updateWidgets()));
+ connect(timer,SIGNAL(timeout()),chnlw,SLOT(channelWindowsUpdate()));
+ connect(timer,SIGNAL(timeout()),infow,SLOT(updateInfo()));
+}
+
+qmpMainWindow::~qmpMainWindow()
+{
+ delete player;
+ delete timer;
+ delete ui;
+}
+
+int qmpMainWindow::pharseArgs(int argc,char** argv)
+{
+ bool havemidi=false,loadfolder=false;
+ for(int i=1;i<argc;++i)
+ {
+ if(argv[i][0]=='-')
+ {
+ if(!strcmp(argv[i],"--help"))
+ {
+ printf("Usage: %s [Options] [Midi Files]\n",argv[0]);
+ printf("Possible options are: \n");
+ printf("-l, --load-all-files Load all files from the same folder.\n");
+ printf("--help Show this help and exit.\n");
+ printf("--version Show this version information and exit.\n");
+ return 1;
+ }
+ if(!strcmp(argv[i],"--version"))
+ {
+ printf("QMidiPlayer %s\n",APP_VERSION);
+ return 1;
+ }
+ if(!strcmp(argv[i],"-l")||!strcmp(argv[i],"--load-all-files"))
+ loadfolder=true;
+ }
+ else
+ if(fluid_is_midifile(argv[i]))
+ {
+ if(!havemidi){havemidi=true;plistw->emptyList();}
+ if(loadfolder||qmpSettingsWindow::getSettingsIntf()->value("Behavior/LoadFolder",0).toInt())
+ {
+ QDirIterator di(QUrl(argv[i]).adjusted(QUrl::RemoveFilename).toString());
+ while(di.hasNext())
+ {
+ QString c=di.next();
+ if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str()))
+ plistw->insertItem(c.toStdString().c_str());
+ }
+ }
+ else
+ plistw->insertItem(argv[i]);
+ }
+ }
+ if(havemidi)on_pbPlayPause_clicked();
+ return 0;
+}
+
+void qmpMainWindow::closeEvent(QCloseEvent *event)
+{
+ on_pbStop_clicked();fin=true;
+ 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();
+}
+
+void qmpMainWindow::moveEvent(QMoveEvent *event)
+{
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/MainW",event->pos());
+ }
+}
+void qmpMainWindow::dropEvent(QDropEvent *event)
+{
+ QList<QUrl> l=event->mimeData()->urls();
+ QStringList sl;
+ for(int i=0;i<l.size();++i)
+ sl.push_back(l.at(i).toLocalFile());
+ plistw->insertItems(sl);
+}
+void qmpMainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ //if(event->mimeData()->hasFormat("application/x-midi"))
+ event->acceptProposedAction();
+}
+
+void qmpMainWindow::updateWidgets()
+{
+ fnA2->setEnabled(stopped);
+ if(player->isFinished()&&playerTh)
+ {
+ if(!plistw->getRepeat())
+ {
+ timer->stop();stopped=true;playing=false;
+ fnA2->setEnabled(stopped);
+ player->playerDeinit();playerTh->join();
+ delete playerTh;playerTh=NULL;
+ if(singleFS)player->playerPanic(true);
+ chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+ ui->pbPlayPause->setIcon(QIcon(":/img/play.png"));
+ ui->hsTimer->setValue(0);
+ ui->lbPolyphone->setText("Poly: 0/0");
+ ui->lbCurTime->setText("00:00");
+ }
+ else
+ {
+ timer->stop();player->playerDeinit();playerTh->join();
+ delete playerTh;playerTh=NULL;
+ ui->hsTimer->setValue(0);
+ if(singleFS)player->playerPanic(true);
+ chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+ QString fns=plistw->getNextItem();
+ ui->lbFileName->setText(QUrl(fns).fileName());
+ if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+ player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+ player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+ playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+ SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+ st=std::chrono::steady_clock::now();offset=0;
+ timer->start(100);
+ }
+ }
+ if(renderTh)
+ {
+ if(player->isFinished())
+ {
+ renderTh->join();timer->stop();
+ ui->centralWidget->setEnabled(true);
+ delete renderTh;renderTh=NULL;
+ player->rendererDeinit();
+ if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize();}
+ }
+ }
+ while(!player->isFinished()&&player->getTCeptr()>player->getStamp(ui->hsTimer->value())
+ &&ui->hsTimer->value()<=100&&!dragging)
+ ui->hsTimer->setValue(ui->hsTimer->value()+1);
+ if(playing)
+ {
+ std::chrono::duration<double> elapsed=
+ std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now()-st);
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)(elapsed.count()+offset)/60,(int)(elapsed.count()+offset)%60);
+ ui->lbCurTime->setText(ts);
+ sprintf(ts,"Poly: %d/%d",player->getPolyphone(),player->getMaxPolyphone());
+ ui->lbPolyphone->setText(ts);
+ }
+}
+
+QString qmpMainWindow::getFileName(){return ui->lbFileName->text();}
+
+void qmpMainWindow::playerSetup()
+{
+ fluid_settings_t* fsettings=player->getFluidSettings();
+ QSettings* settings=qmpSettingsWindow::getSettingsIntf();
+ fluid_settings_setstr(fsettings,"audio.driver",settings->value("Audio/Driver","").toString().toStdString().c_str());
+ fluid_settings_setint(fsettings,"audio.period-size",settings->value("Audio/BufSize","").toInt());
+ fluid_settings_setint(fsettings,"audio.periods",settings->value("Audio/BufCnt","").toInt());
+ fluid_settings_setstr(fsettings,"audio.sample-format",settings->value("Audio/Format","").toString().toStdString().c_str());
+ fluid_settings_setint(fsettings,"synth.sample-rate",settings->value("Audio/Frequency","").toInt());
+ fluid_settings_setint(fsettings,"synth.polyphony",settings->value("Audio/Polyphony","").toInt());
+ fluid_settings_setint(fsettings,"synth.cpu-cores",settings->value("Audio/Threads","").toInt());
+ char bsmode[4];
+ if(!singleFS&&settings->value("Audio/AutoBS",1).toInt()&&player->getFileStandard())
+ switch(player->getFileStandard())
+ {
+ case 1:strcpy(bsmode,"gm");break;
+ case 2:strcpy(bsmode,"mma");break;
+ case 3:strcpy(bsmode,"gs");break;
+ case 4:strcpy(bsmode,"xg");break;
+ }
+ else
+ {
+ if(settings->value("Audio/BankSelect","CC#0").toString()==QString("Ignored"))
+ strcpy(bsmode,"gm");
+ if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0"))
+ strcpy(bsmode,"gs");
+ if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#32"))
+ strcpy(bsmode,"xg");
+ if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0*128+CC#32"))
+ strcpy(bsmode,"mma");
+ }
+ fluid_settings_setstr(fsettings,"synth.midi-bank-select",bsmode);
+ player->sendSysX(settings->value("Midi/SendSysEx",1).toInt());
+}
+
+void qmpMainWindow::on_pbPlayPause_clicked()
+{
+ playing=!playing;
+ if(stopped)
+ {
+ QString fns=plistw->getFirstItem();
+ if(!fns.length())
+ {
+ plistw->on_pbAdd_clicked();
+ fns=plistw->getFirstItem();
+ if(!fns.length())return(void)(playing=false);
+ }
+ ui->lbFileName->setText(QUrl(fns).fileName());
+ if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+ player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+ player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+ playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+ SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+ st=std::chrono::steady_clock::now();offset=0;
+ timer->start(100);
+ stopped=false;
+ }
+ else
+ {
+ if(!playing)
+ {
+ player->playerPanic();
+ offset=ui->hsTimer->value()/100.*player->getFtime();
+ }
+ else
+ {
+ st=std::chrono::steady_clock::now();
+ player->setResumed();
+ }
+ player->setTCpaused(!playing);
+ }
+ ui->pbPlayPause->setIcon(QIcon(playing?":/img/pause.png":":/img/play.png"));
+}
+
+void qmpMainWindow::on_hsTimer_sliderPressed()
+{
+ dragging=true;
+}
+
+void qmpMainWindow::on_hsTimer_sliderReleased()
+{
+ dragging=false;
+ if(playing)
+ {
+ if(ui->hsTimer->value()==100){on_pbNext_clicked();return;}
+ player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
+ player->playerPanic();
+ offset=ui->hsTimer->value()/100.*player->getFtime();
+ st=std::chrono::steady_clock::now();
+ }
+ else
+ {
+ player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
+ offset=ui->hsTimer->value()/100.*player->getFtime();
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60);
+ ui->lbCurTime->setText(ts);
+ }
+}
+
+void qmpMainWindow::on_vsMasterVol_valueChanged()
+{
+ if(!stopped)player->setGain(ui->vsMasterVol->value()/250.);
+ qmpSettingsWindow::getSettingsIntf()->setValue("Audio/Gain",ui->vsMasterVol->value());
+}
+
+void qmpMainWindow::on_pbStop_clicked()
+{
+ if(!stopped)
+ {
+ timer->stop();stopped=true;playing=false;
+ player->playerDeinit();fnA2->setEnabled(stopped);
+ if(singleFS)player->playerPanic(true);
+ if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+ chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+ ui->pbPlayPause->setIcon(QIcon(":/img/play.png"));
+ ui->hsTimer->setValue(0);
+ ui->lbPolyphone->setText("Poly: 0/0");
+ ui->lbCurTime->setText("00:00");
+ }
+}
+
+void qmpMainWindow::dialogClosed()
+{
+ if(!plistw->isVisible())ui->pbPList->setChecked(false);
+ if(!chnlw->isVisible())ui->pbChannels->setChecked(false);
+ if(!efxw->isVisible())ui->pbEfx->setChecked(false);
+ if(!settingsw->isVisible())ui->pbSettings->setChecked(false);
+}
+
+void qmpMainWindow::on_pbPList_clicked()
+{
+ if(ui->pbPList->isChecked())
+ {
+ QRect g=plistw->geometry();
+ g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QPoint(-999,-999)).toPoint());
+ if(g.topLeft()==QPoint(-999,-999))
+ g.setTopLeft(window()->mapToGlobal(window()->rect().center())-plistw->rect().center());
+ plistw->setGeometry(g);
+ plistw->show();
+ }else plistw->close();
+}
+
+void qmpMainWindow::on_pbChannels_clicked()
+{
+ if(ui->pbChannels->isChecked())
+ {
+ QRect g=chnlw->geometry();
+ g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QPoint(-999,-999)).toPoint());
+ if(g.topLeft()==QPoint(-999,-999))
+ g.setTopLeft(window()->mapToGlobal(window()->rect().center())-chnlw->rect().center());
+ chnlw->setGeometry(g);
+ chnlw->show();
+ }else chnlw->close();
+}
+
+void qmpMainWindow::on_pbPrev_clicked()
+{
+ timer->stop();player->playerDeinit();
+ if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+ if(singleFS)player->playerPanic(true);
+ ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+ QString fns=plistw->getPrevItem();if(fns.length()==0)return on_pbStop_clicked();
+ ui->lbFileName->setText(QUrl(fns).fileName());
+ if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+ player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+ player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+ playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+ SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+ st=std::chrono::steady_clock::now();offset=0;
+ timer->start(100);
+}
+
+void qmpMainWindow::on_pbNext_clicked()
+{
+ timer->stop();player->playerDeinit();
+ if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+ if(singleFS)player->playerPanic(true);
+ ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+ QString fns=plistw->getNextItem();if(fns.length()==0)return on_pbStop_clicked();
+ ui->lbFileName->setText(QUrl(fns).fileName());
+ if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+ player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+ player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+ playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+ SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+ st=std::chrono::steady_clock::now();offset=0;
+ timer->start(100);
+}
+
+void qmpMainWindow::selectionChanged()
+{
+ stopped=false;playing=true;
+ ui->pbPlayPause->setIcon(QIcon(":/img/pause.png"));
+ timer->stop();player->playerDeinit();
+ if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+ if(singleFS)player->playerPanic(true);
+ ui->hsTimer->setValue(0);
+ chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+ QString fns=plistw->getSelectedItem();
+ ui->lbFileName->setText(QUrl(fns).fileName());
+ if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+ char ts[100];
+ sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+ player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+ player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+ playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+ SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+ st=std::chrono::steady_clock::now();offset=0;
+ timer->start(100);
+}
+
+void qmpMainWindow::on_pbEfx_clicked()
+{
+ if(ui->pbEfx->isChecked())
+ {
+ QRect g=efxw->geometry();
+ g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QPoint(-999,-999)).toPoint());
+ if(g.topLeft()==QPoint(-999,-999))
+ g.setTopLeft(window()->mapToGlobal(window()->rect().center())-efxw->rect().center());
+ efxw->setGeometry(g);
+ efxw->show();
+ }
+ else efxw->close();
+}
+
+void qmpMainWindow::on_lbFileName_customContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu(ui->lbFileName);
+ menu.addActions(ui->lbFileName->actions());
+ menu.exec(this->pos()+ui->lbFileName->pos()+pos);
+}
+
+void qmpMainWindow::onfnA1()
+{
+ infow->show();
+}
+
+void qmpMainWindow::onfnA2()
+{
+ if(singleFS)player->fluidDeinitialize();
+ player->rendererLoadFile((plistw->getSelectedItem()+QString(".wav")).toStdString().c_str());
+ playerSetup();player->rendererInit(plistw->getSelectedItem().toStdString().c_str());
+ ui->centralWidget->setEnabled(false);
+ for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+ player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());
+ player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();timer->start(100);
+ renderTh=new std::thread(&CMidiPlayer::rendererThread,player);
+}
+
+void qmpMainWindow::on_pbSettings_clicked()
+{
+ if(ui->pbSettings->isChecked())settingsw->show();else settingsw->close();
+}
+
+void qmpMainWindow::on_pushButton_clicked()
+{
+ helpw->show();
+}
diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp
new file mode 100644
index 0000000..a409d2e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpmainwindow.hpp
@@ -0,0 +1,90 @@
+#ifndef QMPMAINWINDOW_H
+#define QMPMAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include <QCloseEvent>
+#include <QMoveEvent>
+#include <QDropEvent>
+#include <QDragEnterEvent>
+#include <QAction>
+#include <QMenu>
+#include <thread>
+#include <chrono>
+#include "../core/qmpmidiplay.hpp"
+#include "qmpplistwindow.hpp"
+#include "qmpchannelswindow.hpp"
+#include "qmpefxwindow.hpp"
+#include "qmpinfowindow.hpp"
+#include "qmpsettingswindow.hpp"
+#include "qmphelpwindow.hpp"
+
+namespace Ui {
+ class qmpMainWindow;
+}
+
+class qmpMainWindow:public QMainWindow
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpMainWindow(QWidget *parent = 0);
+ void closeEvent(QCloseEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void dropEvent(QDropEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ ~qmpMainWindow();
+ CMidiPlayer* getPlayer(){return player;}
+ QTimer* getTimer(){return timer;}
+ bool isFinalizing(){return fin;}
+ QString getFileName();
+ int pharseArgs(int argc,char** argv);
+
+ private slots:
+ void on_pbPlayPause_clicked();
+ void updateWidgets();
+ void on_hsTimer_sliderPressed();
+ void on_hsTimer_sliderReleased();
+ void on_vsMasterVol_valueChanged();
+ void on_pbStop_clicked();
+ void on_pbPList_clicked();
+ void on_pbPrev_clicked();
+ void on_pbNext_clicked();
+ void on_pbChannels_clicked();
+ void on_pbEfx_clicked();
+ void on_lbFileName_customContextMenuRequested(const QPoint &pos);
+ void on_pbSettings_clicked();
+ void onfnA1();
+ void onfnA2();
+
+ void on_pushButton_clicked();
+
+ public slots:
+ void dialogClosed();
+ void selectionChanged();
+
+ private:
+ Ui::qmpMainWindow *ui;
+ QTimer *timer;
+ bool playing,stopped,dragging,fin,singleFS;
+ std::thread *playerTh=NULL;
+ std::thread *renderTh=NULL;
+ std::chrono::steady_clock::time_point st;
+ double offset;
+ CMidiPlayer *player;
+ qmpPlistWindow *plistw;
+ qmpChannelsWindow *chnlw;
+ qmpEfxWindow *efxw;
+ qmpInfoWindow *infow;
+ qmpSettingsWindow *settingsw;
+ qmpHelpWindow *helpw;
+
+ QAction *fnA1,*fnA2;
+ void playerSetup();
+
+ private:
+ static qmpMainWindow* ref;
+ public: static qmpMainWindow* getInstance(){return ref;}
+};
+
+#endif // QMPMAINWINDOW_H
diff --git a/qmidiplayer-desktop/qmpmainwindow.ui b/qmidiplayer-desktop/qmpmainwindow.ui
new file mode 100644
index 0000000..0764e09
--- /dev/null
+++ b/qmidiplayer-desktop/qmpmainwindow.ui
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpMainWindow</class>
+ <widget class="QMainWindow" name="qmpMainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>435</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>435</width>
+ <height>245</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>435</width>
+ <height>245</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="windowTitle">
+ <string>QMidiPlayer</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/qmidiplyr.png</normaloff>:/img/qmidiplyr.png</iconset>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <widget class="QLabel" name="lbFileName">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>20</y>
+ <width>311</width>
+ <height>41</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>18</pointsize>
+ </font>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="text">
+ <string>somefile.mid</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider" name="hsTimer">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>90</y>
+ <width>321</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="pageStep">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbPlayPause">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>110</y>
+ <width>61</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/play.png</normaloff>:/img/play.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbStop">
+ <property name="geometry">
+ <rect>
+ <x>80</x>
+ <y>110</y>
+ <width>61</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/stop.png</normaloff>:/img/stop.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbPrev">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>110</y>
+ <width>61</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/prev.png</normaloff>:/img/prev.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbNext">
+ <property name="geometry">
+ <rect>
+ <x>200</x>
+ <y>110</y>
+ <width>61</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/next.png</normaloff>:/img/next.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbSettings">
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>110</y>
+ <width>61</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/settings.png</normaloff>:/img/settings.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbChannels">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>160</y>
+ <width>151</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Channels</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/channel.png</normaloff>:/img/channel.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbPList">
+ <property name="geometry">
+ <rect>
+ <x>190</x>
+ <y>160</y>
+ <width>151</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Playlist</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/list.png</normaloff>:/img/list.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbEfx">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>200</y>
+ <width>151</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Effects</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/effects.png</normaloff>:/img/effects.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbVisualization">
+ <property name="geometry">
+ <rect>
+ <x>190</x>
+ <y>200</y>
+ <width>151</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Visualization</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/visualization.png</normaloff>:/img/visualization.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbPolyphone">
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>20</y>
+ <width>111</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Poly: 0/0&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QSlider" name="vsMasterVol">
+ <property name="geometry">
+ <rect>
+ <x>370</x>
+ <y>50</y>
+ <width>20</width>
+ <height>160</height>
+ </rect>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbMasterVol">
+ <property name="geometry">
+ <rect>
+ <x>360</x>
+ <y>210</y>
+ <width>61</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Master</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbCurTime">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>70</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>00:00</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbFinTime">
+ <property name="geometry">
+ <rect>
+ <x>270</x>
+ <y>70</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>00:00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>21</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>?</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpplistwindow.cpp b/qmidiplayer-desktop/qmpplistwindow.cpp
new file mode 100644
index 0000000..8f04fc1
--- /dev/null
+++ b/qmidiplayer-desktop/qmpplistwindow.cpp
@@ -0,0 +1,308 @@
+#include <cstdlib>
+#include <ctime>
+#include <QFileDialog>
+#include <QDir>
+#include <QDirIterator>
+#include <QSettings>
+#include <QUrl>
+#include <QMimeData>
+#include "qmpplistwindow.hpp"
+#include "ui_qmpplistwindow.h"
+#include "qmpmainwindow.hpp"
+
+qmpPlistWindow::qmpPlistWindow(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpPlistWindow)
+{
+ ui->setupUi(this);
+ connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+ connect(this,SIGNAL(selectionChanging()),parent,SLOT(selectionChanged()));
+ repeat=0;shuffle=0;
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt())
+ {
+ QSettings* plist=new QSettings(QDir::homePath()+QString("/.config/qmpplist"),
+ QSettings::IniFormat);
+ int fc=plist->value("Playlist/FileCount",0).toInt();
+ ui->lwFiles->clear();for(int i=1;i<=fc;++i)
+ ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
+ repeat=plist->value("Playlist/Repeat",0).toInt();
+ shuffle=plist->value("Playlist/Shuffle",0).toInt();
+ switch(shuffle)
+ {
+ case 1:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
+ ui->pbShuffle->setText("Shuffle On");
+ break;
+ case 0:
+ default:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
+ ui->pbShuffle->setText("Shuffle Off");
+ break;
+ }
+ switch(repeat)
+ {
+ case 0:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
+ ui->pbRepeat->setText("Repeat Off");
+ break;
+ case 1:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
+ ui->pbRepeat->setText("Repeat One");
+ break;
+ case 2:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
+ ui->pbRepeat->setText("Repeat All");
+ break;
+ }
+ delete plist;
+ }
+}
+
+qmpPlistWindow::~qmpPlistWindow()
+{
+ delete ui;
+}
+
+void qmpPlistWindow::showEvent(QShowEvent *event)
+{
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",1);
+ }
+ event->accept();
+}
+
+void qmpPlistWindow::closeEvent(QCloseEvent *event)
+{
+ setVisible(false);
+ if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",0);
+ }
+ if(qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt())
+ {
+ QSettings* plist=new QSettings(QDir::homePath()+QString("/.config/qmpplist"),
+ QSettings::IniFormat);
+ plist->setValue("Playlist/FileCount",ui->lwFiles->count());
+ for(int i=0;i<ui->lwFiles->count();++i)
+ plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text());
+ plist->setValue("Playlist/Repeat",repeat);
+ plist->setValue("Playlist/Shuffle",shuffle);
+ plist->sync();
+ delete plist;
+ }
+ emit dialogClosing();
+ event->accept();
+}
+
+void qmpPlistWindow::moveEvent(QMoveEvent *event)
+{
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ {
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListW",event->pos());
+ }
+}
+
+void qmpPlistWindow::dropEvent(QDropEvent *event)
+{
+ QList<QUrl> l=event->mimeData()->urls();
+ QStringList sl;
+ for(int i=0;i<l.size();++i)
+ sl.push_back(l.at(i).toLocalFile());
+ insertItems(sl);
+}
+void qmpPlistWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ //if(event->mimeData()->hasFormat("application/x-midi"))
+ event->acceptProposedAction();
+}
+
+void qmpPlistWindow::emptyList()
+{
+ ui->lwFiles->clear();
+}
+void qmpPlistWindow::insertItem(QString i)
+{
+ ui->lwFiles->addItem(new QListWidgetItem(i));
+}
+void qmpPlistWindow::insertItems(QStringList il)
+{
+ ui->lwFiles->addItems(il);
+}
+
+void qmpPlistWindow::on_pbAdd_clicked()
+{
+ QStringList sl;
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ sl=QFileDialog::getOpenFileNames(this,"Add File",qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/FileDialogPath","").toString(),"Midi files (*.mid *.midi)");
+ else
+ sl=QFileDialog::getOpenFileNames(this,"Add File","","Midi files (*.mid *.midi)");
+ if(sl.empty())return;
+ for(int i=0;i<sl.size();++i)
+ {
+ ui->lwFiles->addItem(new QListWidgetItem(sl.at(i)));
+ }
+ if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+ qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/FileDialogPath",
+ QUrl(sl.at(0)).toString(QUrl::RemoveFilename));
+}
+
+void qmpPlistWindow::on_pbAddFolder_clicked()
+{
+ QDirIterator di(QFileDialog::getExistingDirectory(this,"Add Folder"));
+ while(di.hasNext())
+ {
+ QString c=di.next();
+ if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str()))
+ ui->lwFiles->addItem(new QListWidgetItem(c));
+ }
+}
+
+void qmpPlistWindow::on_pbRemove_clicked()
+{
+ QList<QListWidgetItem*> sl=ui->lwFiles->selectedItems();
+ for(int i=0;i<sl.size();++i)
+ {
+ ui->lwFiles->removeItemWidget(sl.at(i));
+ delete sl.at(i);
+ }
+}
+
+void qmpPlistWindow::on_pbClear_clicked()
+{
+ while(ui->lwFiles->count()>0)
+ {
+ QListWidgetItem *d=ui->lwFiles->item(0);
+ ui->lwFiles->removeItemWidget(d);
+ delete d;
+ }
+}
+
+void qmpPlistWindow::on_pbRepeat_clicked()
+{
+ ++repeat;repeat%=3;
+ switch(repeat)
+ {
+ case 0:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
+ ui->pbRepeat->setText("Repeat Off");
+ break;
+ case 1:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
+ ui->pbRepeat->setText("Repeat One");
+ break;
+ case 2:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
+ ui->pbRepeat->setText("Repeat All");
+ break;
+ }
+}
+
+void qmpPlistWindow::on_pbShuffle_clicked()
+{
+ shuffle=1-shuffle;
+ switch(shuffle)
+ {
+ case 1:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
+ ui->pbShuffle->setText("Shuffle On");
+ break;
+ case 0:
+ default:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
+ ui->pbShuffle->setText("Shuffle Off");
+ break;
+ }
+}
+
+QString qmpPlistWindow::getFirstItem()
+{
+ if(ui->lwFiles->count()==0)return QString();
+ int id=0;
+ if(shuffle)id=rand()%ui->lwFiles->count();
+ ui->lwFiles->setCurrentRow(id);
+ return ui->lwFiles->item(id)->text();
+}
+QString qmpPlistWindow::getNextItem()
+{
+ if(ui->lwFiles->count()==0)return QString();
+ if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+ int id=ui->lwFiles->currentRow();++id;id%=ui->lwFiles->count();
+ if(shuffle)id=rand()%ui->lwFiles->count();
+ ui->lwFiles->setCurrentRow(id);
+ return ui->lwFiles->item(id)->text();
+}
+QString qmpPlistWindow::getPrevItem()
+{
+ if(ui->lwFiles->count()==0)return QString();
+ if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+ int id=ui->lwFiles->currentRow();--id;
+ id<0?id+=ui->lwFiles->count():0;
+ if(shuffle)id=rand()%ui->lwFiles->count();
+ ui->lwFiles->setCurrentRow(id);
+ return ui->lwFiles->item(id)->text();
+}
+QString qmpPlistWindow::getSelectedItem()
+{
+ if(ui->lwFiles->count()==0)return QString();
+ return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+}
+int qmpPlistWindow::getRepeat(){return repeat;}
+
+void qmpPlistWindow::on_lwFiles_itemDoubleClicked()
+{
+ emit selectionChanging();
+}
+
+void qmpPlistWindow::on_pbSave_clicked()
+{
+ QSettings* plist=new QSettings(QFileDialog::getSaveFileName(this,"Save playlist",""),
+ QSettings::IniFormat);
+ plist->setValue("Playlist/FileCount",ui->lwFiles->count());
+ for(int i=0;i<ui->lwFiles->count();++i)
+ plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text());
+ plist->setValue("Playlist/Repeat",repeat);
+ plist->setValue("Playlist/Shuffle",shuffle);
+ plist->sync();
+ delete plist;
+}
+
+void qmpPlistWindow::on_pbLoad_clicked()
+{
+ QSettings* plist=new QSettings(QFileDialog::getOpenFileName(this,"Load playlist",""),
+ QSettings::IniFormat);
+ int fc=plist->value("Playlist/FileCount",0).toInt();
+ if(!fc)return;
+ ui->lwFiles->clear();for(int i=1;i<=fc;++i)
+ ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
+ repeat=plist->value("Playlist/Repeat",0).toInt();
+ shuffle=plist->value("Playlist/Shuffle",0).toInt();
+ switch(shuffle)
+ {
+ case 1:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
+ ui->pbShuffle->setText("Shuffle On");
+ break;
+ case 0:
+ default:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
+ ui->pbShuffle->setText("Shuffle Off");
+ break;
+ }
+ switch(repeat)
+ {
+ case 0:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
+ ui->pbRepeat->setText("Repeat Off");
+ break;
+ case 1:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
+ ui->pbRepeat->setText("Repeat One");
+ break;
+ case 2:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
+ ui->pbRepeat->setText("Repeat All");
+ break;
+ }
+ delete plist;
+}
diff --git a/qmidiplayer-desktop/qmpplistwindow.hpp b/qmidiplayer-desktop/qmpplistwindow.hpp
new file mode 100644
index 0000000..6ceeb60
--- /dev/null
+++ b/qmidiplayer-desktop/qmpplistwindow.hpp
@@ -0,0 +1,57 @@
+#ifndef QMPPLISTWINDOW_H
+#define QMPPLISTWINDOW_H
+
+#include <QDialog>
+#include <QShowEvent>
+#include <QCloseEvent>
+#include <QMoveEvent>
+#include <QDropEvent>
+#include <QDragEnterEvent>
+#include <QListWidgetItem>
+
+namespace Ui {
+ class qmpPlistWindow;
+}
+
+class qmpPlistWindow : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpPlistWindow(QWidget *parent=0);
+ ~qmpPlistWindow();
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void dropEvent(QDropEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ int getRepeat();
+ QString getFirstItem();
+ QString getNextItem();
+ QString getPrevItem();
+ QString getSelectedItem();
+ void emptyList();
+ void insertItem(QString i);
+ void insertItems(QStringList il);
+ signals:
+ void dialogClosing();
+ void selectionChanging();
+
+ public slots:
+ void on_pbAdd_clicked();
+ private slots:
+ void on_pbAddFolder_clicked();
+ void on_pbRemove_clicked();
+ void on_pbClear_clicked();
+ void on_pbRepeat_clicked();
+ void on_pbShuffle_clicked();
+ void on_lwFiles_itemDoubleClicked();
+ void on_pbSave_clicked();
+ void on_pbLoad_clicked();
+
+ private:
+ Ui::qmpPlistWindow *ui;
+ int shuffle,repeat;//rep 0=off 1=one 2=all
+};
+
+#endif // QMPPLISTWINDOW_H
diff --git a/qmidiplayer-desktop/qmpplistwindow.ui b/qmidiplayer-desktop/qmpplistwindow.ui
new file mode 100644
index 0000000..99124df
--- /dev/null
+++ b/qmidiplayer-desktop/qmpplistwindow.ui
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpPlistWindow</class>
+ <widget class="QDialog" name="qmpPlistWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>530</width>
+ <height>321</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>530</width>
+ <height>321</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>530</width>
+ <height>321</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="windowTitle">
+ <string>Playlist</string>
+ </property>
+ <widget class="QPushButton" name="pbAdd">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>280</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/add.png</normaloff>:/img/add.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbAddFolder">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>280</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Add Folder</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/addfolder.png</normaloff>:/img/addfolder.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbRepeat">
+ <property name="geometry">
+ <rect>
+ <x>270</x>
+ <y>240</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Repeat Off</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/repeat-non.png</normaloff>:/img/repeat-non.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbShuffle">
+ <property name="geometry">
+ <rect>
+ <x>400</x>
+ <y>240</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Shuffle Off</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/shuffle-off.png</normaloff>:/img/shuffle-off.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbSave">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>240</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/save.png</normaloff>:/img/save.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbLoad">
+ <property name="geometry">
+ <rect>
+ <x>140</x>
+ <y>240</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Load</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/load.png</normaloff>:/img/load.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbRemove">
+ <property name="geometry">
+ <rect>
+ <x>270</x>
+ <y>280</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/remove.png</normaloff>:/img/remove.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbClear">
+ <property name="geometry">
+ <rect>
+ <x>400</x>
+ <y>280</y>
+ <width>121</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">text-align:left</string>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/clear.png</normaloff>:/img/clear.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="QListWidget" name="lwFiles">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>511</width>
+ <height>221</height>
+ </rect>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::InternalMove</enum>
+ </property>
+ </widget>
+ </widget>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmppresetselect.cpp b/qmidiplayer-desktop/qmppresetselect.cpp
new file mode 100644
index 0000000..be589c5
--- /dev/null
+++ b/qmidiplayer-desktop/qmppresetselect.cpp
@@ -0,0 +1,99 @@
+#include <cstdio>
+#include "qmppresetselect.hpp"
+#include "ui_qmppresetselect.h"
+#include "qmpmainwindow.hpp"
+
+qmpPresetSelector::qmpPresetSelector(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpPresetSelector)
+{
+ ui->setupUi(this);
+}
+
+qmpPresetSelector::~qmpPresetSelector()
+{
+ delete ui;
+}
+
+void qmpPresetSelector::showEvent(QShowEvent *e)
+{
+ memset(presets,0,sizeof(presets));
+ CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
+ if(!plyr->getSFCount())return e->ignore();
+ int sfc=plyr->getSFCount();
+ for(int i=sfc-1;i>=0;--i)
+ {
+ fluid_sfont_t* psf=plyr->getSFPtr(i);
+ fluid_preset_t preset;
+ psf->iteration_start(psf);
+ while(psf->iteration_next(psf,&preset))
+ strcpy(presets[preset.get_banknum(&preset)][preset.get_num(&preset)],preset.get_name(&preset));
+ }
+ ui->lwBankSelect->clear();
+ ui->lwPresetSelect->clear();
+ for(int i=0;i<=128;++i)
+ {
+ int b=0;
+ for(int j=0;j<128;++j)if(strlen(presets[i][j])){b=1;break;}
+ if(b)ui->lwBankSelect->addItem(QString::number(i));
+ }
+ e->accept();
+}
+void qmpPresetSelector::setupWindow(int chid)
+{
+ CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
+ if(!plyr->getSFCount())return;
+ ch=chid;int b=0,p=0,r;char name[64];
+ sprintf(name,"Preset Selection - Channel #%d",ch+1);
+ setWindowTitle(name);
+ plyr->getChannelPreset(chid,&b,&p,name);
+ for(int i=0;i<ui->lwBankSelect->count();++i)
+ {
+ sscanf(ui->lwBankSelect->item(i)->text().toStdString().c_str(),"%d",&r);
+ if(r==b){ui->lwBankSelect->setCurrentRow(i);break;}
+ }
+ r=0;
+ ui->lwPresetSelect->clear();
+ for(int i=0,cr=0;i<128;++i)
+ if(strlen(presets[b][i]))
+ {
+ sprintf(name,"%d %s",i,presets[b][i]);
+ if(i==p)r=cr;
+ ui->lwPresetSelect->addItem(name);
+ cr++;
+ }
+ ui->lwPresetSelect->setCurrentRow(r);
+}
+
+void qmpPresetSelector::on_pbCancel_clicked()
+{
+ close();
+}
+
+void qmpPresetSelector::on_pbOk_clicked()
+{
+ CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
+ int b,p;sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
+ sscanf(ui->lwPresetSelect->currentItem()->text().toStdString().c_str(),"%d",&p);
+ plyr->setChannelPreset(ch,b,p);
+ close();
+}
+
+void qmpPresetSelector::on_lwPresetSelect_itemDoubleClicked()
+{
+ on_pbOk_clicked();
+}
+
+void qmpPresetSelector::on_lwBankSelect_currentRowChanged()
+{
+ ui->lwPresetSelect->clear();
+ if(!ui->lwBankSelect->currentItem())return;
+ char name[30];int b;
+ sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
+ for(int i=0;i<128;++i)
+ if(strlen(presets[b][i]))
+ {
+ sprintf(name,"%d %s",i,presets[b][i]);
+ ui->lwPresetSelect->addItem(name);
+ }
+}
diff --git a/qmidiplayer-desktop/qmppresetselect.hpp b/qmidiplayer-desktop/qmppresetselect.hpp
new file mode 100644
index 0000000..54f5764
--- /dev/null
+++ b/qmidiplayer-desktop/qmppresetselect.hpp
@@ -0,0 +1,36 @@
+#ifndef QMPPRESETSELECT_H
+#define QMPPRESETSELECT_H
+
+#include <QDialog>
+#include <QShowEvent>
+
+namespace Ui {
+ class qmpPresetSelector;
+}
+
+class qmpPresetSelector:public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpPresetSelector(QWidget *parent = 0);
+ ~qmpPresetSelector();
+ void showEvent(QShowEvent* e);
+ void setupWindow(int chid);
+
+ private slots:
+ void on_pbCancel_clicked();
+
+ void on_pbOk_clicked();
+
+ void on_lwBankSelect_currentRowChanged();
+
+ void on_lwPresetSelect_itemDoubleClicked();
+
+ private:
+ Ui::qmpPresetSelector *ui;
+ char presets[129][128][24];
+ int ch;
+};
+
+#endif // QMPPRESETSELECT_H
diff --git a/qmidiplayer-desktop/qmppresetselect.ui b/qmidiplayer-desktop/qmppresetselect.ui
new file mode 100644
index 0000000..f18600d
--- /dev/null
+++ b/qmidiplayer-desktop/qmppresetselect.ui
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpPresetSelector</class>
+ <widget class="QDialog" name="qmpPresetSelector">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>404</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>404</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>404</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Preset Selection</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <widget class="QListWidget" name="lwBankSelect">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>71</width>
+ <height>221</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QListWidget" name="lwPresetSelect">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>30</y>
+ <width>301</width>
+ <height>221</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbBnk">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Bank</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="lbPst">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>10</y>
+ <width>66</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Preset</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbOk">
+ <property name="geometry">
+ <rect>
+ <x>300</x>
+ <y>260</y>
+ <width>97</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pbCancel">
+ <property name="geometry">
+ <rect>
+ <x>190</x>
+ <y>260</y>
+ <width>97</width>
+ <height>36</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp
new file mode 100644
index 0000000..c2e31a2
--- /dev/null
+++ b/qmidiplayer-desktop/qmpsettingswindow.cpp
@@ -0,0 +1,289 @@
+#include <QFileDialog>
+#include <QDir>
+#include "qmpsettingswindow.hpp"
+#include "ui_qmpsettingswindow.h"
+#include "qmpmainwindow.hpp"
+
+QSettings *qmpSettingsWindow::settings=NULL;
+
+void qmpFluidForEachOpt(void* data,char* /*name*/,char* option)
+{
+ QComboBox *pcb=(QComboBox*)data;
+ pcb->addItem(option);
+}
+
+qmpSettingsWindow::qmpSettingsWindow(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpSettingsWindow)
+{
+ ui->setupUi(this);
+ connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+ settings=new QSettings(QDir::homePath()+QString("/.config/qmprc"),QSettings::IniFormat);
+ settingsInit();
+}
+
+qmpSettingsWindow::~qmpSettingsWindow()
+{
+ delete settings;
+ delete ui;
+}
+
+void qmpSettingsWindow::closeEvent(QCloseEvent *event)
+{
+ setVisible(false);
+ settings->sync();
+ emit dialogClosing();
+ event->accept();
+}
+
+QListWidget* qmpSettingsWindow::getSFWidget(){return ui->lwSoundfont;}
+
+void qmpSettingsWindow::on_buttonBox_accepted()
+{
+ settingsUpdate();
+ emit dialogClosing();
+}
+
+void qmpSettingsWindow::on_buttonBox_rejected()
+{
+ settingsInit();
+ emit dialogClosing();
+}
+
+void qmpSettingsWindow::settingsInit()
+{
+ fluid_settings_t *fsettings=new_fluid_settings();
+
+ settings->setValue("Midi/DefaultOutput",settings->value("Midi/DefaultOutput","Internal FluidSynth"));
+ //this item is still a stub...
+
+ settings->setValue("Midi/DisableMapping",settings->value("Midi/DisableMapping",0));
+ ui->cbDisableMapping->setChecked(settings->value("Midi/DisableMapping",0).toInt());
+
+ settings->setValue("Midi/SendSysEx",settings->value("Midi/SendSysEx",1));
+ ui->cbSendSysx->setChecked(settings->value("Midi/SendSysEx",1).toInt());
+
+ settings->setValue("Midi/WaitVoice",settings->value("Midi/WaitVoice",1));
+ ui->cbWaitVoice->setChecked(settings->value("Midi/WaitVoice",1).toInt());
+
+ int selected=-1;
+ for(int i=0;i<ui->cbEncoding->count();++i)
+ if(ui->cbEncoding->itemText(i)==settings->value("Midi/TextEncoding","Unicode").toString())
+ {selected=i;break;}
+ if(~selected)ui->cbEncoding->setCurrentIndex(selected);
+ settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText());
+
+ fluid_settings_foreach_option(fsettings,"audio.driver",(void*)ui->cbAudioDrv,qmpFluidForEachOpt);
+ selected=-1;
+ for(int i=0;i<ui->cbAudioDrv->count();++i)
+ if(ui->cbAudioDrv->itemText(i)==settings->value("Audio/Driver","pulseaudio").toString())
+ {selected=i;break;}
+ if(~selected)ui->cbAudioDrv->setCurrentIndex(selected);
+ settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText());
+
+#ifdef _WIN32
+#define DefBufSize 8192
+#else
+#define DefBufSize 128
+#endif
+ selected=-1;
+ for(int i=0;i<ui->cbBufSize->count();++i)
+ if(ui->cbBufSize->itemText(i).toInt()==settings->value("Audio/BufSize",DefBufSize).toInt())
+ {selected=i;break;}
+ if(~selected)ui->cbBufSize->setCurrentIndex(selected);
+ else if(settings->value("Audio/BufSize",DefBufSize).toInt()>=64&&settings->value("Audio/BufSize",DefBufSize).toInt()<=8192)
+ ui->cbBufSize->setCurrentText(settings->value("Audio/BufSize",DefBufSize).toString());
+ else ui->cbBufSize->setCurrentText(QString::number(DefBufSize));
+ settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt());
+#undef DefBufSize
+
+ selected=-1;
+ for(int i=0;i<ui->cbBufCnt->count();++i)
+ if(ui->cbBufCnt->itemText(i).toInt()==settings->value("Audio/BufCnt",2).toInt())
+ {selected=i;break;}
+ if(~selected)ui->cbBufCnt->setCurrentIndex(selected);
+ else if(settings->value("Audio/BufCnt",2).toInt()>=2&&settings->value("Audio/BufCnt",2).toInt()<=64)
+ ui->cbBufCnt->setCurrentText(settings->value("Audio/BufCnt",2).toString());
+ else ui->cbBufCnt->setCurrentText("2");
+ settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt());
+
+ selected=-1;
+ for(int i=0;i<ui->cbFormat->count();++i)
+ if(ui->cbFormat->itemText(i)==settings->value("Audio/Format","16bits").toString())
+ {selected=i;break;}
+ if(~selected)ui->cbFormat->setCurrentIndex(selected);
+ settings->setValue("Audio/Format",ui->cbFormat->currentText());
+
+ selected=-1;
+ for(int i=0;i<ui->cbFrequency->count();++i)
+ if(ui->cbFormat->itemText(i).toInt()==settings->value("Audio/Frequency",48000).toInt())
+ {selected=i;break;}
+ if(~selected)ui->cbFrequency->setCurrentIndex(selected);
+ settings->setValue("Audio/Frequency",ui->cbFrequency->currentText());
+
+ ui->sbPolyphony->setValue(settings->value("Audio/Polyphony",2048).toInt());
+ if(ui->sbPolyphony->value()<1||ui->sbPolyphony->value()>65535)ui->sbPolyphony->setValue(2048);
+ settings->setValue("Audio/Polyphony",ui->sbPolyphony->value());
+
+ ui->sbCPUCores->setValue(settings->value("Audio/Threads",1).toInt());
+ if(ui->sbCPUCores->value()<1||ui->sbCPUCores->value()>256)ui->sbCPUCores->setValue(1);
+ settings->setValue("Audio/Threads",ui->sbCPUCores->value());
+
+ settings->setValue("Audio/AutoBS",settings->value("Audio/AutoBS",1));
+ ui->cbAutoBS->setChecked(settings->value("Audio/AutoBS",1).toInt());
+ ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode");
+
+ selected=-1;
+ for(int i=0;i<ui->cbBSMode->count();++i)
+ if(ui->cbBSMode->itemText(i)==settings->value("Audio/BankSelect","GS").toString())
+ {selected=i;break;}
+ if(~selected)ui->cbBSMode->setCurrentIndex(selected);
+ settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText());
+ settings->setValue("Audio/Gain",settings->value("Audio/Gain",50));
+
+ int sfc=settings->value("SoundFonts/SFCount",0).toInt();
+ ui->lwSoundfont->clear();for(int i=1;i<=sfc;++i)
+ ui->lwSoundfont->addItem(settings->value("SoundFonts/SF"+QString::number(i),"").toString());
+ settings->setValue("SoundFonts/SFCount",sfc);
+
+ settings->setValue("Behavior/RestorePlaylist",settings->value("Behavior/RestorePlaylist",0));
+ ui->cbRestorePlaylist->setChecked(settings->value("Behavior/RestorePlaylist",0).toInt());
+
+ settings->setValue("Behavior/LoadFolder",settings->value("Behavior/LoadFolder",0));
+ ui->cbLoadFolder->setChecked(settings->value("Behavior/LoadFolder",0).toInt());
+
+ settings->setValue("Behavior/DialogStatus",settings->value("Behavior/DialogStatus",1));
+ ui->cbDialogStatus->setChecked(settings->value("Behavior/DialogStatus",1).toInt());
+
+ settings->setValue("Behavior/SaveEfxParam",settings->value("Behavior/SaveEfxParam",1));
+ ui->cbSaveEfxParam->setChecked(settings->value("Behavior/SaveEfxParam",1).toInt());
+
+ settings->setValue("Behavior/SingleInstance",settings->value("Behavior/SingleInstance",0));
+ ui->cbPersistentfs->setChecked(settings->value("Behavior/SingleInstance",0).toInt());
+
+ settings->sync();
+ delete_fluid_settings(fsettings);
+}
+
+void qmpSettingsWindow::settingsUpdate()
+{
+ settings->setValue("Midi/DefaultOutput",settings->value("Midi/DefaultOutput","Internal FluidSynth"));
+ //this item is still a stub...
+
+ settings->setValue("Midi/DisableMapping",ui->cbDisableMapping->isChecked()?1:0);
+
+ settings->setValue("Midi/SendSysEx",ui->cbSendSysx->isChecked()?1:0);
+
+ settings->setValue("Midi/WaitVoice",ui->cbWaitVoice->isChecked()?1:0);
+
+ settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText());
+
+ settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText());
+
+ settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt());
+
+ settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt());
+
+ settings->setValue("Audio/Format",ui->cbFormat->currentText());
+
+ settings->setValue("Audio/Frequency",ui->cbFrequency->currentText());
+
+ settings->setValue("Audio/Polyphony",ui->sbPolyphony->value());
+
+ settings->setValue("Audio/Threads",ui->sbCPUCores->value());
+
+ settings->setValue("Audio/AutoBS",ui->cbAutoBS->isChecked()?1:0);
+
+ settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText());
+
+ settings->setValue("SoundFonts/SFCount",ui->lwSoundfont->count());
+ for(int i=0;i<ui->lwSoundfont->count();++i)
+ settings->setValue("SoundFonts/SF"+QString::number(i+1),ui->lwSoundfont->item(i)->text());
+
+ settings->setValue("Behavior/RestorePlaylist",ui->cbRestorePlaylist->isChecked()?1:0);
+
+ settings->setValue("Behavior/LoadFolder",ui->cbLoadFolder->isChecked()?1:0);
+
+ settings->setValue("Behavior/DialogStatus",ui->cbDialogStatus->isChecked()?1:0);
+ if(!ui->cbDialogStatus->isChecked())
+ {
+ settings->remove("DialogStatus/MainW");
+ settings->remove("DialogStatus/PListW");
+ settings->remove("DialogStatus/PListWShown");
+ settings->remove("DialogStatus/ChnlW");
+ settings->remove("DialogStatus/ChnlWShown");
+ settings->remove("DialogStatus/EfxW");
+ settings->remove("DialogStatus/EfxWShown");
+ settings->remove("DialogStatus/FileDialogPath");
+ }
+
+ settings->setValue("Behavior/SaveEfxParam",ui->cbSaveEfxParam->isChecked()?1:0);
+ if(!ui->cbSaveEfxParam->isChecked())
+ {
+ settings->remove("Effects/ChorusEnabled");
+ settings->remove("Effects/ReverbEnabled");
+ settings->remove("Effects/ReverbRoom");
+ settings->remove("Effects/ReverbDamp");
+ settings->remove("Effects/ReverbWidth");
+ settings->remove("Effects/ReverbLevel");
+
+ settings->remove("Effects/ChorusFeedbk");
+ settings->remove("Effects/ChorusLevel");
+ settings->remove("Effects/ChorusRate");
+ settings->remove("Effects/ChorusDepth");
+ settings->remove("Effects/ChorusType");
+ }
+
+ settings->setValue("Behavior/SingleInstance",ui->cbPersistentfs->isChecked()?1:0);
+ settings->sync();
+}
+
+void qmpSettingsWindow::on_cbBufSize_currentTextChanged(const QString &s)
+{
+ if(s.toInt()<64||s.toInt()>8192)ui->cbBufSize->setCurrentIndex(1);
+}
+
+void qmpSettingsWindow::on_cbBufCnt_currentTextChanged(const QString &s)
+{
+ if(s.toInt()<2||s.toInt()>64)ui->cbBufCnt->setCurrentIndex(1);
+}
+
+void qmpSettingsWindow::on_pbAdd_clicked()
+{
+ QStringList sl=QFileDialog::getOpenFileNames(this,"Add File","","SoundFont files (*.sf2)");
+ for(int i=0;i<sl.size();++i)
+ {
+ ui->lwSoundfont->addItem(new QListWidgetItem(sl.at(i)));
+ }
+}
+
+void qmpSettingsWindow::on_pbRemove_clicked()
+{
+ QList<QListWidgetItem*> sl=ui->lwSoundfont->selectedItems();
+ for(int i=0;i<sl.size();++i)
+ {
+ ui->lwSoundfont->removeItemWidget(sl.at(i));
+ delete sl.at(i);
+ }
+}
+
+void qmpSettingsWindow::on_pbUp_clicked()
+{
+ int cid=ui->lwSoundfont->currentRow();
+ QListWidgetItem *ci=ui->lwSoundfont->takeItem(cid);
+ ui->lwSoundfont->insertItem(cid-1,ci);
+ ui->lwSoundfont->setCurrentRow(cid-1);
+}
+
+void qmpSettingsWindow::on_pbDown_clicked()
+{
+ int cid=ui->lwSoundfont->currentRow();
+ QListWidgetItem *ci=ui->lwSoundfont->takeItem(cid);
+ ui->lwSoundfont->insertItem(cid+1,ci);
+ ui->lwSoundfont->setCurrentRow(cid+1);
+}
+
+void qmpSettingsWindow::on_cbAutoBS_stateChanged()
+{
+ ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode");
+}
diff --git a/qmidiplayer-desktop/qmpsettingswindow.hpp b/qmidiplayer-desktop/qmpsettingswindow.hpp
new file mode 100644
index 0000000..c506de4
--- /dev/null
+++ b/qmidiplayer-desktop/qmpsettingswindow.hpp
@@ -0,0 +1,47 @@
+#ifndef QMPSETTINGSWINDOW_H
+#define QMPSETTINGSWINDOW_H
+
+#include <QDialog>
+#include <QCloseEvent>
+#include <QSettings>
+#include <QListWidget>
+
+namespace Ui {
+ class qmpSettingsWindow;
+}
+
+class qmpSettingsWindow:public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit qmpSettingsWindow(QWidget *parent=0);
+ ~qmpSettingsWindow();
+ void closeEvent(QCloseEvent *event);
+ void settingsInit();
+ QListWidget* getSFWidget();
+ signals:
+ void dialogClosing();
+
+ private slots:
+ void on_buttonBox_accepted();
+ void on_buttonBox_rejected();
+
+ void on_cbBufSize_currentTextChanged(const QString &s);
+ void on_cbBufCnt_currentTextChanged(const QString &s);
+
+ void on_pbAdd_clicked();
+ void on_pbRemove_clicked();
+ void on_pbUp_clicked();
+ void on_pbDown_clicked();
+
+ void on_cbAutoBS_stateChanged();
+
+ private:
+ Ui::qmpSettingsWindow *ui;
+ void settingsUpdate();
+ static QSettings *settings;
+ public: static QSettings* getSettingsIntf(){return settings;}
+};
+
+#endif // QMPSETTINGSWINDOW_H
diff --git a/qmidiplayer-desktop/qmpsettingswindow.ui b/qmidiplayer-desktop/qmpsettingswindow.ui
new file mode 100644
index 0000000..330afa2
--- /dev/null
+++ b/qmidiplayer-desktop/qmpsettingswindow.ui
@@ -0,0 +1,761 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpSettingsWindow</class>
+ <widget class="QDialog" name="qmpSettingsWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>494</width>
+ <height>445</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>494</width>
+ <height>445</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Settings</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Midi</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="lbOutputDevice">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Default Output Device</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cbOutputDevice">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>Internal FluidSynth</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbDisableMapping">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Disable Midi Mapping</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbSendSysx">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Send SysEx</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbWaitVoice">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Wait for remaining voices before stopping</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QLabel" name="lbEncoding">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Text Encoding</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cbEncoding">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>Unicode</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Big5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Big5-HKSCS</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>CP949</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>EUC-JP</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>EUC-KR</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>GB18030</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>KOI8-R</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>KOI8-U</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Macintosh</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Shift-JIS</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Synth</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="2" column="0">
+ <widget class="QLabel" name="lbBufCnt">
+ <property name="text">
+ <string>Audio Buffer Count</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="lbBufSize">
+ <property name="text">
+ <string>Audio Buffer Size</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="cbBufSize">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>64</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>128</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>256</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>512</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>1024</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2048</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>4096</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>8192</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="lbFrequency">
+ <property name="text">
+ <string>Audio Frequency</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="cbBufCnt">
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <item>
+ <property name="text">
+ <string>2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>8</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>16</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>32</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>64</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="lbAudioDrv">
+ <property name="text">
+ <string>Audio Driver</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="cbFormat">
+ <item>
+ <property name="text">
+ <string>16bits</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>float</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cbAudioDrv"/>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="cbFrequency">
+ <property name="currentIndex">
+ <number>2</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>22050</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>44100</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>48000</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>96000</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="lbFormat">
+ <property name="text">
+ <string>Audio Format</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QSpinBox" name="sbPolyphony">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ <property name="value">
+ <number>2048</number>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="lbPolyphony">
+ <property name="text">
+ <string>Max Polyphony</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QCheckBox" name="cbAutoBS">
+ <property name="text">
+ <string>Auto bank select mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="lbBSMode">
+ <property name="text">
+ <string>Bank select mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QComboBox" name="cbBSMode">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Ignored</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>CC#0</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>CC#32</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>CC#0*128+CC#32</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="lbCPUCores">
+ <property name="text">
+ <string>CPU Cores</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QSpinBox" name="sbCPUCores">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>256</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>Soundfonts</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QListWidget" name="lwSoundfont">
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::InternalMove</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="pbAdd">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/add.png</normaloff>:/img/add.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbRemove">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/remove.png</normaloff>:/img/remove.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbUp">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/up.png</normaloff>:/img/up.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbDown">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/img/down.png</normaloff>:/img/down.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_4">
+ <attribute name="title">
+ <string>Behavior</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QCheckBox" name="cbRestorePlaylist">
+ <property name="text">
+ <string>Restore last playlist on startup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbLoadFolder">
+ <property name="text">
+ <string>Load files in the same folder</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbDialogStatus">
+ <property name="text">
+ <string>Save dialog status</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbSaveEfxParam">
+ <property name="text">
+ <string>Save parameters in effects window</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cbPersistentfs">
+ <property name="text">
+ <string>Persistent fluidsynth instance</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="lbVisualMode">
+ <property name="text">
+ <string>Visualization Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cbVisualMode"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="lbViewDist">
+ <property name="text">
+ <string>View distance</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>50</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSlider" name="hsViewDist">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>60</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbViewDist"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="lbNoteStretch">
+ <property name="text">
+ <string>Note stretch</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSlider" name="hsNoteStretch">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>60</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbNoteStretch"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="lbFog">
+ <property name="text">
+ <string>Fog Start</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>82</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSlider" name="hsFog">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>60</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbFog"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>qmpSettingsWindow</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>qmpSettingsWindow</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/qmidiplayer-desktop/resources.qrc b/qmidiplayer-desktop/resources.qrc
new file mode 100644
index 0000000..351d2fa
--- /dev/null
+++ b/qmidiplayer-desktop/resources.qrc
@@ -0,0 +1,36 @@
+<RCC>
+ <qresource prefix="/">
+ <file>../img/add.png</file>
+ <file>../img/list.png</file>
+ <file>../img/addfolder.png</file>
+ <file>../img/channel.png</file>
+ <file>../img/prev.png</file>
+ <file>../img/qmidiplyr.png</file>
+ <file>../img/remove.png</file>
+ <file>../img/clear.png</file>
+ <file>../img/down.png</file>
+ <file>../img/effects.png</file>
+ <file>../img/repeat-all.png</file>
+ <file>../img/repeat-base.png</file>
+ <file>../img/repeat-non.png</file>
+ <file>../img/load.png</file>
+ <file>../img/next.png</file>
+ <file>../img/repeat-one.png</file>
+ <file>../img/save.png</file>
+ <file>../img/settings.png</file>
+ <file>../img/pause.png</file>
+ <file>../img/play.png</file>
+ <file>../img/shuffle-off.png</file>
+ <file>../img/shuffle.png</file>
+ <file>../img/stop.png</file>
+ <file>../img/up.png</file>
+ <file>../img/visualization.png</file>
+ <file>../img/mainw.png</file>
+ <file>../img/chanw.png</file>
+ <file>../doc/index.html</file>
+ <file>../doc/version.html</file>
+ <file>../doc/license.html</file>
+ <file>../doc/mainwindow.html</file>
+ <file>../doc/channeldialog.html</file>
+ </qresource>
+</RCC>