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