drumstick  1.0.2
netmidioutput.cpp
00001 /*
00002     Drumstick RT (realtime MIDI In/Out)
00003     Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl@users.sf.net>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License along
00016     with this program; if not, write to the Free Software Foundation, Inc.,
00017     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 */
00019 
00020 #include <QDebug>
00021 #include <QUdpSocket>
00022 #include <QNetworkInterface>
00023 #include <QSettings>
00024 #include "netmidioutput.h"
00025 
00026 namespace drumstick {
00027 namespace rt {
00028 
00029 static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI Out"));
00030 
00031 class NetMIDIOutput::NetMIDIOutputPrivate
00032 {
00033 public:
00034     QUdpSocket *m_socket;
00035     quint16 m_port;
00036     QString m_publicName;
00037     QHostAddress m_groupAddress;
00038     QString m_currentOutput;
00039     QStringList m_outputDevices;
00040     QStringList m_excludedNames;
00041     QNetworkInterface m_iface;
00042 
00043     NetMIDIOutputPrivate() :
00044         m_socket(0),
00045         m_port(0),
00046         m_publicName(DEFAULT_PUBLIC_NAME),
00047         m_groupAddress(QHostAddress(STR_ADDRESS))
00048     {
00049         for(int i=MULTICAST_PORT; i<LAST_PORT; ++i) {
00050             m_outputDevices << QString::number(i);
00051         }
00052     }
00053 
00054     ~NetMIDIOutputPrivate()
00055     {
00056         close();
00057     }
00058 
00059     void initialize(QSettings* settings)
00060     {
00061         if (settings != 0) {
00062             settings->beginGroup("Network");
00063             QString ifaceName = settings->value("interface", QString()).toString();
00064             QString address = settings->value("address", STR_ADDRESS).toString();
00065             settings->endGroup();
00066             if (!ifaceName.isEmpty()) {
00067                 m_iface = QNetworkInterface::interfaceFromName(ifaceName);
00068             }
00069             if (!address.isEmpty()) {
00070                 m_groupAddress.setAddress(address);
00071             }
00072         }
00073     }
00074 
00075     void open(QString portName)
00076     {
00077         int p = m_outputDevices.indexOf(portName);
00078         if (p > -1)
00079         {
00080             m_socket = new QUdpSocket();
00081             m_port = MULTICAST_PORT + p;
00082             m_currentOutput = portName;
00083             if (m_iface.isValid()) {
00084                 m_socket->setMulticastInterface(m_iface);
00085             }
00086             //qDebug() << Q_FUNC_INFO << portName;
00087         }
00088     }
00089 
00090     void close()
00091     {
00092         delete m_socket;
00093         m_socket = 0;
00094         m_currentOutput.clear();
00095     }
00096 
00097     void sendMessage(int m0)
00098     {
00099         QByteArray m;
00100         m.resize(1);
00101         m[0] = m0;
00102         sendMessage(m);
00103     }
00104 
00105     void sendMessage(int m0, int m1)
00106     {
00107         QByteArray m;
00108         m.resize(2);
00109         m[0] = m0;
00110         m[1] = m1;
00111         sendMessage(m);
00112     }
00113 
00114     void sendMessage(int m0, int m1, int m2)
00115     {
00116         QByteArray m;
00117         m.resize(3);
00118         m[0] = m0;
00119         m[1] = m1;
00120         m[2] = m2;
00121         sendMessage(m);
00122     }
00123 
00124     void sendMessage(const QByteArray& message )
00125     {
00126         if (m_socket == 0) {
00127             qDebug() << "udp socket is null";
00128             return;
00129         }
00130         m_socket->writeDatagram(message, m_groupAddress, m_port);
00131     }
00132 };
00133 
00134 NetMIDIOutput::NetMIDIOutput(QObject *parent) : MIDIOutput(parent),
00135   d(new NetMIDIOutputPrivate)
00136 { }
00137 
00138 NetMIDIOutput::~NetMIDIOutput()
00139 {
00140     delete d;
00141 }
00142 
00143 void NetMIDIOutput::initialize(QSettings *settings)
00144 {
00145     d->initialize(settings);
00146 }
00147 
00148 QString NetMIDIOutput::backendName()
00149 {
00150     return QLatin1String("Network");
00151 }
00152 
00153 QString NetMIDIOutput::publicName()
00154 {
00155     return d->m_publicName;
00156 }
00157 
00158 void NetMIDIOutput::setPublicName(QString name)
00159 {
00160     d->m_publicName = name;
00161 }
00162 
00163 QStringList NetMIDIOutput::connections(bool advanced)
00164 {
00165     Q_UNUSED(advanced)
00166     return d->m_outputDevices;
00167 }
00168 
00169 void NetMIDIOutput::setExcludedConnections(QStringList conns)
00170 {
00171     Q_UNUSED(conns)
00172 }
00173 
00174 void NetMIDIOutput::open(QString name)
00175 {
00176     d->open(name);
00177 }
00178 
00179 void NetMIDIOutput::close()
00180 {
00181     d->close();
00182 }
00183 
00184 QString NetMIDIOutput::currentConnection()
00185 {
00186     return d->m_currentOutput;
00187 }
00188 
00189 void NetMIDIOutput::sendNoteOff(int chan, int note, int vel)
00190 {
00191     d->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel);
00192 }
00193 
00194 void NetMIDIOutput::sendNoteOn(int chan, int note, int vel)
00195 {
00196     d->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel);
00197 }
00198 
00199 void NetMIDIOutput::sendKeyPressure(int chan, int note, int value)
00200 {
00201     d->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value);
00202 }
00203 
00204 void NetMIDIOutput::sendController(int chan, int control, int value)
00205 {
00206     d->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value);
00207 }
00208 
00209 void NetMIDIOutput::sendProgram(int chan, int program)
00210 {
00211     d->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program);
00212 }
00213 
00214 void NetMIDIOutput::sendChannelPressure(int chan, int value)
00215 {
00216     d->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value);
00217 }
00218 
00219 void NetMIDIOutput::sendPitchBend(int chan, int value)
00220 {
00221     d->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value));
00222 }
00223 
00224 void NetMIDIOutput::sendSysex(const QByteArray &data)
00225 {
00226     d->sendMessage(data);
00227 }
00228 
00229 void NetMIDIOutput::sendSystemMsg(const int status)
00230 {
00231     d->sendMessage(status);
00232 }
00233 
00234 }}