drumstick  1.1.0
vpiano.cpp

A Virtual Piano Keyboard GUI application. See another one at http://vmpk.sf.net

/*
Virtual Piano test using the MIDI Sequencer C++ library
Copyright (C) 2006-2016, Pedro Lopez-Cabanillas <plcl@users.sf.net>
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 VPIANO_H
#define VPIANO_H
#include <QMainWindow>
#include <QCloseEvent>
#include "ui_vpiano.h"
#include "vpianoabout.h"
#include "connections.h"
#include "preferences.h"
#include "rtmidiinput.h"
#include "rtmidioutput.h"
using namespace drumstick::rt;
class VPiano : public QMainWindow
{
Q_OBJECT
public:
VPiano( QWidget * parent = 0, Qt::WindowFlags flags = 0 );
virtual ~VPiano();
void closeEvent(QCloseEvent *event);
void findInput(QString name, QList<MIDIInput*> &inputs);
void findOutput(QString name, QList<MIDIOutput*> &outputs);
public slots:
void readSettings();
void writeSettings();
void slotAbout();
void slotAboutQt();
void slotConnections();
void slotPreferences();
void slotNoteOn(const int midiNote, const int vel);
void slotNoteOn(const int chan, const int note, const int vel);
void slotNoteOff(const int midiNote, const int vel);
void slotNoteOff(const int chan, const int note, const int vel);
private:
MIDIInput * m_midiIn;
MIDIOutput* m_midiOut;
QString m_lastInputBackend;
QString m_lastOutputBackend;
QString m_lastInputConnection;
QString m_lastOutputConnection;
bool m_midiThru;
bool m_advanced;
Ui::VPiano ui;
About dlgAbout;
Connections dlgConnections;
Preferences dlgPreferences;
QString m_nativeInput;
QString m_nativeOutput;
QString m_defaultInput;
QString m_defaultOutput;
};
#endif // VPIANO_H
/*
Virtual Piano test using the MIDI Sequencer C++ library
Copyright (C) 2006-2016, Pedro Lopez-Cabanillas <plcl@users.sf.net>
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 <QDebug>
#include "vpiano.h"
#include "backendmanager.h"
VPiano::VPiano( QWidget * parent, Qt::WindowFlags flags )
: QMainWindow(parent, flags),
m_midiIn(0),
m_midiOut(0)
{
m_nativeInput = QLatin1Literal("Network");
m_defaultInput = QLatin1Literal("21928");
#if defined(Q_OS_LINUX)
m_nativeOutput = QLatin1Literal("SonivoxEAS");
m_defaultOutput = QLatin1Literal("SonivoxEAS");
#elif defined(Q_OS_OSX)
m_nativeOutput = QLatin1Literal("DLS Synth");
m_defaultOutput = QLatin1Literal("DLS Synth");
#elif defined(Q_OS_WIN)
m_nativeOutput = QLatin1Literal("Windows MM");
m_defaultOutput = QLatin1Literal("Microsoft GS Wavetable Synth");
#else
m_nativeOutput = m_nativeInput;
m_defaultOutput = m_defaultInput;
#endif
ui.setupUi(this);
ui.statusBar->hide();
readSettings();
QSettings settings;
BackendManager man;
man.refresh(&settings);
QList<MIDIInput*> inputs = man.availableInputs();
QList<MIDIOutput*> outputs = man.availableOutputs();
findInput(m_lastInputBackend, inputs);
if (m_midiIn == 0) {
findInput(m_nativeInput, inputs);
}
findOutput(m_lastOutputBackend, outputs);
if (m_midiOut == 0) {
findOutput(m_nativeOutput, outputs);
}
connect(ui.actionExit, SIGNAL(triggered()), SLOT(close()));
connect(ui.actionAbout, SIGNAL(triggered()), SLOT(slotAbout()));
connect(ui.actionAbout_Qt, SIGNAL(triggered()), SLOT(slotAboutQt()));
connect(ui.actionConnections, SIGNAL(triggered()), SLOT(slotConnections()));
connect(ui.actionPreferences, SIGNAL(triggered()), SLOT(slotPreferences()));
connect(ui.pianokeybd, SIGNAL(noteOn(int,int)), SLOT(slotNoteOn(int,int)));
connect(ui.pianokeybd, SIGNAL(noteOff(int,int)), SLOT(slotNoteOff(int,int)));
dlgConnections.setInputs(inputs);
dlgConnections.setOutputs(outputs);
dlgConnections.setInput(m_midiIn);
dlgConnections.setOutput(m_midiOut);
dlgConnections.setMidiThru(m_midiThru);
dlgConnections.setAdvanced(m_advanced);
if (m_midiIn != 0) {
connect(m_midiIn, SIGNAL(midiNoteOn(int,int,int)), SLOT(slotNoteOn(int,int,int)));
connect(m_midiIn, SIGNAL(midiNoteOff(int,int,int)), SLOT(slotNoteOff(int,int,int)));
if (!m_lastInputConnection.isEmpty()) {
m_midiIn->initialize(&settings);
m_midiIn->open(m_lastInputConnection);
}
}
if (m_midiOut != 0 && !m_lastOutputConnection.isEmpty()) {
m_midiOut->initialize(&settings);
m_midiOut->open(m_lastOutputConnection);
if (m_midiIn != 0) {
m_midiIn->setMIDIThruDevice(m_midiOut);
m_midiIn->enableMIDIThru(m_midiThru);
}
}
}
VPiano::~VPiano()
{
//qDebug() << Q_FUNC_INFO;
m_midiIn->close();
m_midiOut->close();
qDebug() << "Cheers!";
}
void VPiano::slotNoteOn(const int midiNote, const int vel)
{
int chan = dlgPreferences.getOutChannel();
m_midiOut->sendNoteOn(chan, midiNote, vel);
}
void VPiano::slotNoteOff(const int midiNote, const int vel)
{
int chan = dlgPreferences.getOutChannel();
m_midiOut->sendNoteOff(chan, midiNote, vel);
}
void VPiano::slotNoteOn(const int chan, const int note, const int vel)
{
if (dlgPreferences.getInChannel() == chan) {
if (vel > 0)
ui.pianokeybd->getPianoScene()->showNoteOn(note);
else
ui.pianokeybd->getPianoScene()->showNoteOff(note);
}
}
void VPiano::slotNoteOff(const int chan, const int note, const int vel)
{
Q_UNUSED(vel)
if (dlgPreferences.getInChannel() == chan) {
ui.pianokeybd->getPianoScene()->showNoteOff(note);
}
}
void VPiano::slotAbout()
{
dlgAbout.exec();
}
void VPiano::slotAboutQt()
{
qApp->aboutQt();
}
void VPiano::slotConnections()
{
dlgConnections.refresh();
if (dlgConnections.exec() == QDialog::Accepted) {
if (m_midiIn != 0) {
m_midiIn->disconnect();
}
if (m_midiOut != 0) {
m_midiOut->disconnect();
}
m_midiIn = dlgConnections.getInput();
m_midiOut = dlgConnections.getOutput();
if (m_midiIn != 0) {
connect(m_midiIn, SIGNAL(midiNoteOn(int,int,int)), SLOT(slotNoteOn(int,int,int)));
connect(m_midiIn, SIGNAL(midiNoteOff(int,int,int)), SLOT(slotNoteOff(int,int,int)));
}
m_midiThru = dlgConnections.midiThru();
m_advanced = dlgConnections.advanced();
}
}
void VPiano::slotPreferences()
{
if (dlgPreferences.exec() == QDialog::Accepted) {
if (ui.pianokeybd->baseOctave() != dlgPreferences.getBaseOctave()) {
ui.pianokeybd->setBaseOctave(dlgPreferences.getBaseOctave());
}
if (ui.pianokeybd->numKeys() != dlgPreferences.getNumKeys()) {
ui.pianokeybd->setNumKeys(dlgPreferences.getNumKeys());
}
if (ui.pianokeybd->startKey() != dlgPreferences.getStartingKey()) {
ui.pianokeybd->setNumKeys(dlgPreferences.getNumKeys(), dlgPreferences.getStartingKey());
}
}
}
void VPiano::closeEvent(QCloseEvent *event)
{
//qDebug() << Q_FUNC_INFO;
writeSettings();
event->accept();
}
void VPiano::writeSettings()
{
QSettings settings;
settings.beginGroup("Window");
settings.setValue("Geometry", saveGeometry());
settings.setValue("State", saveState());
settings.endGroup();
settings.beginGroup("Connections");
settings.setValue("inputBackend", m_midiIn->backendName());
settings.setValue("outputBackend", m_midiOut->backendName());
settings.setValue("inputConnection", m_midiIn->currentConnection());
settings.setValue("outputConnection", m_midiOut->currentConnection());
settings.setValue("midiThru", m_midiThru);
settings.setValue("advanced", m_advanced);
settings.endGroup();
settings.beginGroup("Preferences");
settings.setValue("inputChannel", dlgPreferences.getInChannel());
settings.setValue("outputChannel",dlgPreferences.getOutChannel());
settings.setValue("velocity", dlgPreferences. getVelocity());
settings.setValue("baseOctave", dlgPreferences.getBaseOctave());
settings.setValue("numKeys", dlgPreferences.getNumKeys());
settings.setValue("startingKey", dlgPreferences.getStartingKey());
settings.endGroup();
settings.sync();
}
void VPiano::readSettings()
{
QSettings settings;
settings.beginGroup("Window");
restoreGeometry(settings.value("Geometry").toByteArray());
restoreState(settings.value("State").toByteArray());
settings.endGroup();
settings.beginGroup("Connections");
m_lastInputBackend = settings.value("inputBackend", m_nativeInput).toString();
m_lastOutputBackend = settings.value("outputBackend", m_nativeOutput).toString();
m_lastInputConnection = settings.value("inputConnection", m_defaultInput).toString();
m_lastOutputConnection = settings.value("outputConnection", m_defaultOutput).toString();
m_midiThru = settings.value("midiThru", false).toBool();
m_advanced = settings.value("advanced", false).toBool();
settings.endGroup();
settings.beginGroup("Preferences");
dlgPreferences.setInChannel(settings.value("inputChannel", 0).toInt());
dlgPreferences.setOutChannel(settings.value("outputChannel", 0).toInt());
dlgPreferences.setVelocity(settings.value("velocity", 100).toInt());
dlgPreferences.setBaseOctave(settings.value("baseOctave", 1).toInt());
dlgPreferences.setNumKeys(settings.value("numKeys", 88).toInt());
dlgPreferences.setStartingKey(settings.value("startingKey", 9).toInt());
ui.pianokeybd->setBaseOctave(settings.value("baseOctave", 1).toInt());
ui.pianokeybd->setNumKeys(settings.value("numKeys", 88).toInt(), settings.value("startingKey", 9).toInt());
settings.endGroup();
}
void VPiano::findInput(QString name, QList<MIDIInput *> &inputs)
{
foreach(MIDIInput* input, inputs) {
if (m_midiIn == 0 && (input->backendName() == name)) {
m_midiIn = input;
break;
}
}
}
void VPiano::findOutput(QString name, QList<MIDIOutput *> &outputs)
{
foreach(MIDIOutput* output, outputs) {
if (m_midiOut == 0 && (output->backendName() == name)) {
m_midiOut = output;
break;
}
}
}