drumstick  1.0.0
netmidioutput.cpp
1 /*
2  Drumstick RT (realtime MIDI In/Out)
3  Copyright (C) 2009-2014 Pedro Lopez-Cabanillas <plcl@users.sf.net>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 #include <QDebug>
21 #include <QUdpSocket>
22 #include <QNetworkInterface>
23 #include <QSettings>
24 #include "netmidioutput.h"
25 
26 namespace drumstick {
27 namespace rt {
28 
29 static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI Out"));
30 
31 class NetMIDIOutput::NetMIDIOutputPrivate
32 {
33 public:
34  QUdpSocket *m_socket;
35  quint16 m_port;
36  QString m_publicName;
37  QHostAddress m_groupAddress;
38  QString m_currentOutput;
39  QStringList m_outputDevices;
40  QStringList m_excludedNames;
41  QNetworkInterface m_iface;
42 
43  NetMIDIOutputPrivate() :
44  m_socket(0),
45  m_port(0),
46  m_publicName(DEFAULT_PUBLIC_NAME),
47  m_groupAddress(QHostAddress(STR_ADDRESS))
48  {
49  for(int i=MULTICAST_PORT; i<LAST_PORT; ++i) {
50  m_outputDevices << QString::number(i);
51  }
52  }
53 
54  ~NetMIDIOutputPrivate()
55  {
56  close();
57  }
58 
59  void initialize(QSettings* settings)
60  {
61  if (settings != 0) {
62  settings->beginGroup("Network");
63  QString ifaceName = settings->value("interface", QString()).toString();
64  QString address = settings->value("address", STR_ADDRESS).toString();
65  settings->endGroup();
66  if (!ifaceName.isEmpty()) {
67  m_iface = QNetworkInterface::interfaceFromName(ifaceName);
68  }
69  if (!address.isEmpty()) {
70  m_groupAddress.setAddress(address);
71  }
72  }
73  }
74 
75  void open(QString portName)
76  {
77  int p = m_outputDevices.indexOf(portName);
78  if (p > -1)
79  {
80  m_socket = new QUdpSocket();
81  m_port = MULTICAST_PORT + p;
82  m_currentOutput = portName;
83  if (m_iface.isValid()) {
84  m_socket->setMulticastInterface(m_iface);
85  }
86  //qDebug() << Q_FUNC_INFO << portName;
87  }
88  }
89 
90  void close()
91  {
92  delete m_socket;
93  m_socket = 0;
94  m_currentOutput.clear();
95  }
96 
97  void sendMessage(int m0)
98  {
99  QByteArray m;
100  m.resize(1);
101  m[0] = m0;
102  sendMessage(m);
103  }
104 
105  void sendMessage(int m0, int m1)
106  {
107  QByteArray m;
108  m.resize(2);
109  m[0] = m0;
110  m[1] = m1;
111  sendMessage(m);
112  }
113 
114  void sendMessage(int m0, int m1, int m2)
115  {
116  QByteArray m;
117  m.resize(3);
118  m[0] = m0;
119  m[1] = m1;
120  m[2] = m2;
121  sendMessage(m);
122  }
123 
124  void sendMessage(const QByteArray& message )
125  {
126  if (m_socket == 0) {
127  qDebug() << "udp socket is null";
128  return;
129  }
130  m_socket->writeDatagram(message, m_groupAddress, m_port);
131  }
132 };
133 
134 NetMIDIOutput::NetMIDIOutput(QObject *parent) : MIDIOutput(parent),
135  d(new NetMIDIOutputPrivate)
136 { }
137 
138 NetMIDIOutput::~NetMIDIOutput()
139 {
140  delete d;
141 }
142 
143 void NetMIDIOutput::initialize(QSettings *settings)
144 {
145  d->initialize(settings);
146 }
147 
148 QString NetMIDIOutput::backendName()
149 {
150  return QLatin1String("Network");
151 }
152 
153 QString NetMIDIOutput::publicName()
154 {
155  return d->m_publicName;
156 }
157 
158 void NetMIDIOutput::setPublicName(QString name)
159 {
160  d->m_publicName = name;
161 }
162 
163 QStringList NetMIDIOutput::connections(bool advanced)
164 {
165  Q_UNUSED(advanced)
166  return d->m_outputDevices;
167 }
168 
169 void NetMIDIOutput::setExcludedConnections(QStringList conns)
170 {
171  Q_UNUSED(conns)
172 }
173 
174 void NetMIDIOutput::open(QString name)
175 {
176  d->open(name);
177 }
178 
179 void NetMIDIOutput::close()
180 {
181  d->close();
182 }
183 
184 QString NetMIDIOutput::currentConnection()
185 {
186  return d->m_currentOutput;
187 }
188 
189 void NetMIDIOutput::sendNoteOff(int chan, int note, int vel)
190 {
191  d->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel);
192 }
193 
194 void NetMIDIOutput::sendNoteOn(int chan, int note, int vel)
195 {
196  d->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel);
197 }
198 
199 void NetMIDIOutput::sendKeyPressure(int chan, int note, int value)
200 {
201  d->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value);
202 }
203 
204 void NetMIDIOutput::sendController(int chan, int control, int value)
205 {
206  d->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value);
207 }
208 
209 void NetMIDIOutput::sendProgram(int chan, int program)
210 {
211  d->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program);
212 }
213 
214 void NetMIDIOutput::sendChannelPressure(int chan, int value)
215 {
216  d->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value);
217 }
218 
219 void NetMIDIOutput::sendPitchBend(int chan, int value)
220 {
221  d->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value));
222 }
223 
224 void NetMIDIOutput::sendSysex(const QByteArray &data)
225 {
226  d->sendMessage(data);
227 }
228 
229 void NetMIDIOutput::sendSystemMsg(const int status)
230 {
231  d->sendMessage(status);
232 }
233 
234 }}
The QObject class is the base class of all Qt objects.