From 70fd2d85c1bd6fb8732e680e8fda9d36c317c732 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Wed, 6 Apr 2016 16:54:29 +0800 Subject: Too young too simple. --- qmidiplayer-desktop/main.cpp | 29 ++ qmidiplayer-desktop/qdialskulpturestyle.cpp | 437 ++++++++++++++++ qmidiplayer-desktop/qdialskulpturestyle.hpp | 39 ++ qmidiplayer-desktop/qmidiplayer-desktop.pro | 64 +++ qmidiplayer-desktop/qmpchanneleditor.cpp | 193 +++++++ qmidiplayer-desktop/qmpchanneleditor.hpp | 42 ++ qmidiplayer-desktop/qmpchanneleditor.ui | 602 ++++++++++++++++++++++ qmidiplayer-desktop/qmpchannelswindow.cpp | 132 +++++ qmidiplayer-desktop/qmpchannelswindow.hpp | 71 +++ qmidiplayer-desktop/qmpchannelswindow.ui | 146 ++++++ qmidiplayer-desktop/qmpefxwindow.cpp | 198 ++++++++ qmidiplayer-desktop/qmpefxwindow.hpp | 62 +++ qmidiplayer-desktop/qmpefxwindow.ui | 478 +++++++++++++++++ qmidiplayer-desktop/qmphelpwindow.cpp | 31 ++ qmidiplayer-desktop/qmphelpwindow.hpp | 26 + qmidiplayer-desktop/qmphelpwindow.ui | 34 ++ qmidiplayer-desktop/qmpimidimapper.hpp | 16 + qmidiplayer-desktop/qmpinfowindow.cpp | 57 +++ qmidiplayer-desktop/qmpinfowindow.hpp | 24 + qmidiplayer-desktop/qmpinfowindow.ui | 91 ++++ qmidiplayer-desktop/qmpmainwindow.cpp | 510 +++++++++++++++++++ qmidiplayer-desktop/qmpmainwindow.hpp | 90 ++++ qmidiplayer-desktop/qmpmainwindow.ui | 413 +++++++++++++++ qmidiplayer-desktop/qmpplistwindow.cpp | 308 +++++++++++ qmidiplayer-desktop/qmpplistwindow.hpp | 57 +++ qmidiplayer-desktop/qmpplistwindow.ui | 263 ++++++++++ qmidiplayer-desktop/qmppresetselect.cpp | 99 ++++ qmidiplayer-desktop/qmppresetselect.hpp | 36 ++ qmidiplayer-desktop/qmppresetselect.ui | 106 ++++ qmidiplayer-desktop/qmpsettingswindow.cpp | 289 +++++++++++ qmidiplayer-desktop/qmpsettingswindow.hpp | 47 ++ qmidiplayer-desktop/qmpsettingswindow.ui | 761 ++++++++++++++++++++++++++++ qmidiplayer-desktop/resources.qrc | 36 ++ 33 files changed, 5787 insertions(+) create mode 100644 qmidiplayer-desktop/main.cpp create mode 100644 qmidiplayer-desktop/qdialskulpturestyle.cpp create mode 100644 qmidiplayer-desktop/qdialskulpturestyle.hpp create mode 100644 qmidiplayer-desktop/qmidiplayer-desktop.pro create mode 100644 qmidiplayer-desktop/qmpchanneleditor.cpp create mode 100644 qmidiplayer-desktop/qmpchanneleditor.hpp create mode 100644 qmidiplayer-desktop/qmpchanneleditor.ui create mode 100644 qmidiplayer-desktop/qmpchannelswindow.cpp create mode 100644 qmidiplayer-desktop/qmpchannelswindow.hpp create mode 100644 qmidiplayer-desktop/qmpchannelswindow.ui create mode 100644 qmidiplayer-desktop/qmpefxwindow.cpp create mode 100644 qmidiplayer-desktop/qmpefxwindow.hpp create mode 100644 qmidiplayer-desktop/qmpefxwindow.ui create mode 100644 qmidiplayer-desktop/qmphelpwindow.cpp create mode 100644 qmidiplayer-desktop/qmphelpwindow.hpp create mode 100644 qmidiplayer-desktop/qmphelpwindow.ui create mode 100644 qmidiplayer-desktop/qmpimidimapper.hpp create mode 100644 qmidiplayer-desktop/qmpinfowindow.cpp create mode 100644 qmidiplayer-desktop/qmpinfowindow.hpp create mode 100644 qmidiplayer-desktop/qmpinfowindow.ui create mode 100644 qmidiplayer-desktop/qmpmainwindow.cpp create mode 100644 qmidiplayer-desktop/qmpmainwindow.hpp create mode 100644 qmidiplayer-desktop/qmpmainwindow.ui create mode 100644 qmidiplayer-desktop/qmpplistwindow.cpp create mode 100644 qmidiplayer-desktop/qmpplistwindow.hpp create mode 100644 qmidiplayer-desktop/qmpplistwindow.ui create mode 100644 qmidiplayer-desktop/qmppresetselect.cpp create mode 100644 qmidiplayer-desktop/qmppresetselect.hpp create mode 100644 qmidiplayer-desktop/qmppresetselect.ui create mode 100644 qmidiplayer-desktop/qmpsettingswindow.cpp create mode 100644 qmidiplayer-desktop/qmpsettingswindow.hpp create mode 100644 qmidiplayer-desktop/qmpsettingswindow.ui create mode 100644 qmidiplayer-desktop/resources.qrc (limited to 'qmidiplayer-desktop') 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 . + */ +#include "qmpmainwindow.hpp" +#include +#include + +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 + + 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 +#include +#include +#include + +#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(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(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 + + 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 + +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 +#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 dials=findChildren(); + for(int i=0;isetStyle(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 +#include +#include +#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 @@ + + + qmpChannelEditor + + + + 0 + 0 + 422 + 300 + + + + + 422 + 300 + + + + + 422 + 300 + + + + Dialog + + + + + 10 + 10 + 21 + 21 + + + + < + + + + + + 30 + 10 + 21 + 20 + + + + 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 50 + 10 + 21 + 21 + + + + > + + + + + + 90 + 10 + 261 + 51 + + + + + 16 + + + + Yamaha Grand Piano + + + + + + 10 + 30 + 81 + 20 + + + + BK: 0 + + + + + + 10 + 50 + 81 + 20 + + + + PC: 0 + + + + + + 0 + 70 + 141 + 101 + + + + Filters + + + + + 70 + 80 + 66 + 20 + + + + Res. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Cut. 64 + + + Qt::AlignCenter + + + + + + + 140 + 70 + 141 + 101 + + + + Effects + + + + + 70 + 80 + 66 + 20 + + + + Chr. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Rev. 64 + + + Qt::AlignCenter + + + + + + + 0 + 170 + 211 + 101 + + + + Envelope + + + + + 70 + 80 + 66 + 20 + + + + Dec. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Atk. 64 + + + Qt::AlignCenter + + + + + + 150 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 140 + 80 + 66 + 20 + + + + Rel. 64 + + + Qt::AlignCenter + + + + + + + 210 + 170 + 211 + 101 + + + + Vibrato + + + + + 70 + 80 + 66 + 20 + + + + Dep. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Rate 64 + + + Qt::AlignCenter + + + + + + 150 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 140 + 80 + 66 + 20 + + + + Del. 64 + + + Qt::AlignCenter + + + + + + + 280 + 70 + 141 + 101 + + + + Mixer + + + + + 70 + 80 + 66 + 20 + + + + Pan. C + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 66 + 20 + + + + Vol. 127 + + + Qt::AlignCenter + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 127 + + + true + + + + + + + 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 +#include +#include +#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 +#include +#include +#include +#include +#include +#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 @@ + + + qmpChannelsWindow + + + + 0 + 0 + 580 + 410 + + + + + 580 + 410 + + + + + 580 + 16777215 + + + + Channels + + + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::NoSelection + + + false + + + 16 + + + 5 + + + + + + + + + + + + + + + + + + + + M + + + + + S + + + + + Device + + + + + Preset + + + + + ... + + + + + + + + + + + + + + + + + Save + + + + 16 + 16 + + + + + + + + Load + + + + + + + Unmute All + + + + + + + Unsolo All + + + + + + + + + + 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 +#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 dials=findChildren(); + for(int i=0;isetStyle(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 +#include +#include +#include + +#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 @@ + + + qmpEfxWindow + + + + 0 + 0 + 546 + 177 + + + + + 546 + 177 + + + + + 546 + 177 + + + + Effects + + + + + + Reverb + + + + + 80 + 4 + 21 + 24 + + + + + + + + + + 10 + 30 + 50 + 51 + + + + 120 + + + true + + + + + + 200 + 30 + 50 + 51 + + + + 100 + + + true + + + + + + 10 + 103 + 50 + 51 + + + + 100 + + + true + + + + + + 200 + 103 + 50 + 51 + + + + 100 + + + true + + + + + + 60 + 30 + 41 + 20 + + + + Room + + + + + + 60 + 50 + 51 + 21 + + + + 120 + + + + + + 140 + 30 + 51 + 20 + + + + Damp + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 140 + 50 + 56 + 21 + + + + 100 + + + + + + 60 + 100 + 51 + 20 + + + + Width + + + + + + 60 + 120 + 56 + 21 + + + + 100 + + + + + + 145 + 100 + 51 + 20 + + + + Level + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 140 + 120 + 56 + 21 + + + + 100 + + + + + + + + Chorus + + + + + 80 + 4 + 21 + 24 + + + + + + + + + + 10 + 30 + 50 + 51 + + + + 99 + + + true + + + + + + 200 + 30 + 50 + 51 + + + + 29 + + + 500 + + + 29 + + + true + + + + + + 10 + 103 + 50 + 51 + + + + 210 + + + true + + + + + + 200 + 103 + 50 + 51 + + + + 100 + + + true + + + + + + 60 + 30 + 71 + 20 + + + + Feedback + + + + + + 60 + 50 + 51 + 21 + + + + 99 + + + + + + 140 + 30 + 51 + 20 + + + + Rate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 60 + 100 + 51 + 20 + + + + Depth + + + + + + 145 + 100 + 51 + 20 + + + + Level + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 140 + 120 + 56 + 21 + + + + 100 + + + + + + 137 + 50 + 61 + 21 + + + + 0.290000000000000 + + + 5.000000000000000 + + + 0.100000000000000 + + + + + + 35 + 77 + 41 + 20 + + + + LFO + + + + + + 70 + 77 + 61 + 20 + + + + Sine + + + + + + 145 + 77 + 91 + 20 + + + + Trian&gle + + + + + + 60 + 120 + 51 + 21 + + + + 1 + + + 21.000000000000000 + + + 0.100000000000000 + + + + + + + + + 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 +#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 +#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 @@ + + + qmpHelpWindow + + + + 0 + 0 + 640 + 360 + + + + + 640 + 360 + + + + Help + + + + + + true + + + + + + + + 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 +#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 + +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 @@ + + + qmpInfoWindow + + + + 0 + 0 + 400 + 142 + + + + + 400 + 142 + + + + File Information + + + + + + File name: + + + + + + + + + Tempo: + + + + + + + Key Sig.: + + + + + + + Time Sig.: + + + + + + + + + Title: + + + + + + + Copyright: + + + + + + + + + Note count: + + + + + + + File standard: + + + + + + + + + + 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 +#include +#include +#include +#include +#include "qmpmainwindow.hpp" +#include "ui_qmpmainwindow.h" +#include "../core/qmpmidiplay.hpp" +#ifdef _WIN32 +#include +#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;iemptyList();} + 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 l=event->mimeData()->urls(); + QStringList sl; + for(int i=0;iinsertItems(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 elapsed= + std::chrono::duration_cast>(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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 @@ + + + qmpMainWindow + + + + 0 + 0 + 435 + 245 + + + + + 435 + 245 + + + + + 435 + 245 + + + + true + + + QMidiPlayer + + + + :/img/qmidiplyr.png:/img/qmidiplyr.png + + + + + + 30 + 20 + 311 + 41 + + + + + 18 + + + + Qt::CustomContextMenu + + + somefile.mid + + + Qt::AlignCenter + + + + + + 20 + 90 + 321 + 20 + + + + 100 + + + 0 + + + Qt::Horizontal + + + + + + 20 + 110 + 61 + 36 + + + + + + + + :/img/play.png:/img/play.png + + + + 32 + 32 + + + + + + + 80 + 110 + 61 + 36 + + + + + + + + :/img/stop.png:/img/stop.png + + + + 32 + 32 + + + + + + + 140 + 110 + 61 + 36 + + + + + + + + :/img/prev.png:/img/prev.png + + + + 32 + 32 + + + + + + + 200 + 110 + 61 + 36 + + + + + + + + :/img/next.png:/img/next.png + + + + 32 + 32 + + + + + + + 280 + 110 + 61 + 36 + + + + + + + + :/img/settings.png:/img/settings.png + + + + 32 + 32 + + + + true + + + + + + 20 + 160 + 151 + 36 + + + + text-align:left + + + Channels + + + + :/img/channel.png:/img/channel.png + + + + 32 + 32 + + + + true + + + + + + 190 + 160 + 151 + 36 + + + + text-align:left + + + Playlist + + + + :/img/list.png:/img/list.png + + + + 32 + 32 + + + + true + + + false + + + false + + + + + + 20 + 200 + 151 + 36 + + + + text-align:left + + + Effects + + + + :/img/effects.png:/img/effects.png + + + + 32 + 32 + + + + true + + + + + + 190 + 200 + 151 + 36 + + + + text-align:left + + + Visualization + + + + :/img/visualization.png:/img/visualization.png + + + + 32 + 32 + + + + + + + 320 + 20 + 111 + 20 + + + + <html><head/><body><p>Poly: 0/0</p></body></html> + + + Qt::AlignCenter + + + + + + 370 + 50 + 20 + 160 + + + + 100 + + + 50 + + + Qt::Vertical + + + + + + 360 + 210 + 61 + 20 + + + + Master + + + + + + 20 + 70 + 66 + 20 + + + + 00:00 + + + + + + 270 + 70 + 66 + 20 + + + + 00:00 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 0 + 0 + 21 + 21 + + + + ? + + + + + + + + + + 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 +#include +#include +#include +#include +#include +#include +#include +#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;ilwFiles->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 l=event->mimeData()->urls(); + QStringList sl; + for(int i=0;imimeData()->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;ilwFiles->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 sl=ui->lwFiles->selectedItems(); + for(int i=0;ilwFiles->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;ilwFiles->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 +#include +#include +#include +#include +#include +#include + +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 @@ + + + qmpPlistWindow + + + + 0 + 0 + 530 + 321 + + + + + 530 + 321 + + + + + 530 + 321 + + + + true + + + Playlist + + + + + 10 + 280 + 121 + 36 + + + + text-align:left + + + Add + + + + :/img/add.png:/img/add.png + + + + 32 + 32 + + + + + + + 140 + 280 + 121 + 36 + + + + text-align:left + + + Add Folder + + + + :/img/addfolder.png:/img/addfolder.png + + + + 32 + 32 + + + + + + + 270 + 240 + 121 + 36 + + + + text-align:left + + + Repeat Off + + + + :/img/repeat-non.png:/img/repeat-non.png + + + + 32 + 32 + + + + + + + 400 + 240 + 121 + 36 + + + + text-align:left + + + Shuffle Off + + + + :/img/shuffle-off.png:/img/shuffle-off.png + + + + 32 + 32 + + + + + + + 10 + 240 + 121 + 36 + + + + text-align:left + + + Save + + + + :/img/save.png:/img/save.png + + + + 32 + 32 + + + + + + + 140 + 240 + 121 + 36 + + + + text-align:left + + + Load + + + + :/img/load.png:/img/load.png + + + + 32 + 32 + + + + + + + 270 + 280 + 121 + 36 + + + + text-align:left + + + Remove + + + + :/img/remove.png:/img/remove.png + + + + 32 + 32 + + + + + + + 400 + 280 + 121 + 36 + + + + text-align:left + + + Clear + + + + :/img/clear.png:/img/clear.png + + + + 32 + 32 + + + + + + + 10 + 10 + 511 + 221 + + + + false + + + true + + + QAbstractItemView::InternalMove + + + + + + + + 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 +#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;ilwBankSelect->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 +#include + +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 @@ + + + qmpPresetSelector + + + + 0 + 0 + 404 + 300 + + + + + 404 + 300 + + + + + 404 + 300 + + + + Preset Selection + + + true + + + + + 10 + 30 + 71 + 221 + + + + + + + 90 + 30 + 301 + 221 + + + + + + + 10 + 10 + 66 + 20 + + + + Bank + + + + + + 90 + 10 + 66 + 20 + + + + Preset + + + + + + 300 + 260 + 97 + 36 + + + + OK + + + + + + 190 + 260 + 97 + 36 + + + + Cancel + + + + + + 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 +#include +#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;icbEncoding->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;icbAudioDrv->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;icbBufSize->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;icbBufCnt->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;icbFormat->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;icbFrequency->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;icbBSMode->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;ilwSoundfont->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;ilwSoundfont->addItem(new QListWidgetItem(sl.at(i))); + } +} + +void qmpSettingsWindow::on_pbRemove_clicked() +{ + QList sl=ui->lwSoundfont->selectedItems(); + for(int i=0;ilwSoundfont->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 +#include +#include +#include + +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 @@ + + + qmpSettingsWindow + + + + 0 + 0 + 494 + 445 + + + + + 494 + 445 + + + + Settings + + + + + + 0 + + + + Midi + + + + + + + + + 0 + 0 + + + + Default Output Device + + + + + + + + 0 + 0 + + + + + Internal FluidSynth + + + + + + + + + + + 0 + 0 + + + + Disable Midi Mapping + + + + + + + + 0 + 0 + + + + Send SysEx + + + + + + + + 0 + 0 + + + + Wait for remaining voices before stopping + + + + + + + + + + 0 + 0 + + + + Text Encoding + + + + + + + + 0 + 0 + + + + + Unicode + + + + + Big5 + + + + + Big5-HKSCS + + + + + CP949 + + + + + EUC-JP + + + + + EUC-KR + + + + + GB18030 + + + + + KOI8-R + + + + + KOI8-U + + + + + Macintosh + + + + + Shift-JIS + + + + + + + + + + + Synth + + + + + + Audio Buffer Count + + + + + + + Audio Buffer Size + + + + + + + true + + + 1 + + + + 64 + + + + + 128 + + + + + 256 + + + + + 512 + + + + + 1024 + + + + + 2048 + + + + + 4096 + + + + + 8192 + + + + + + + + Audio Frequency + + + + + + + true + + + + 2 + + + + + 4 + + + + + 8 + + + + + 16 + + + + + 32 + + + + + 64 + + + + + + + + Audio Driver + + + + + + + + 16bits + + + + + float + + + + + + + + + + + 2 + + + + 22050 + + + + + 44100 + + + + + 48000 + + + + + 96000 + + + + + + + + Audio Format + + + + + + + 1 + + + 65535 + + + 2048 + + + + + + + Max Polyphony + + + + + + + Auto bank select mode + + + + + + + Bank select mode + + + + + + + 1 + + + + Ignored + + + + + CC#0 + + + + + CC#32 + + + + + CC#0*128+CC#32 + + + + + + + + CPU Cores + + + + + + + 1 + + + 256 + + + + + + + + Soundfonts + + + + + + QAbstractItemView::InternalMove + + + + + + + + + + + + + :/img/add.png:/img/add.png + + + + 24 + 24 + + + + + + + + + + + + :/img/remove.png:/img/remove.png + + + + 24 + 24 + + + + + + + + + + + + :/img/up.png:/img/up.png + + + + 24 + 24 + + + + + + + + + + + + :/img/down.png:/img/down.png + + + + 24 + 24 + + + + + + + + + + + Behavior + + + + + + Restore last playlist on startup + + + + + + + Load files in the same folder + + + + + + + Save dialog status + + + + + + + Save parameters in effects window + + + + + + + Persistent fluidsynth instance + + + + + + + + + Visualization Mode + + + + + + + + + + + + + + View distance + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 50 + 20 + + + + + + + + + 60 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + + + Note stretch + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 60 + 20 + + + + + + + + + 60 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + + + Fog Start + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 82 + 20 + + + + + + + + + 60 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + qmpSettingsWindow + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + qmpSettingsWindow + reject() + + + 316 + 260 + + + 286 + 274 + + + + + 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 @@ + + + ../img/add.png + ../img/list.png + ../img/addfolder.png + ../img/channel.png + ../img/prev.png + ../img/qmidiplyr.png + ../img/remove.png + ../img/clear.png + ../img/down.png + ../img/effects.png + ../img/repeat-all.png + ../img/repeat-base.png + ../img/repeat-non.png + ../img/load.png + ../img/next.png + ../img/repeat-one.png + ../img/save.png + ../img/settings.png + ../img/pause.png + ../img/play.png + ../img/shuffle-off.png + ../img/shuffle.png + ../img/stop.png + ../img/up.png + ../img/visualization.png + ../img/mainw.png + ../img/chanw.png + ../doc/index.html + ../doc/version.html + ../doc/license.html + ../doc/mainwindow.html + ../doc/channeldialog.html + + -- cgit v1.2.3