20 #include "macmidioutput.h" 21 #include "maccommon.h" 26 #include <QStringList> 28 #include <QVarLengthArray> 30 #include <CoreFoundation/CoreFoundation.h> 31 #include <CoreMIDI/MIDIServices.h> 36 static CFStringRef DEFAULT_PUBLIC_NAME CFSTR(
"MIDI Out");
38 class MacMIDIOutput::MacMIDIOutputPrivate {
40 MIDIClientRef m_client;
42 MIDIEndpointRef m_endpoint;
43 MIDIEndpointRef m_destination;
46 QString m_currentOutput;
48 QStringList m_excludedNames;
49 QStringList m_outputDevices;
51 MacMIDIOutputPrivate():
57 m_publicName(QString::fromCFString(DEFAULT_PUBLIC_NAME))
59 internalCreate(DEFAULT_PUBLIC_NAME);
62 void internalCreate(CFStringRef name)
64 OSStatus result = noErr;
65 result = MIDIClientCreate( name, NULL, NULL, &m_client );
66 if ( result != noErr ) {
67 qDebug() <<
"MIDIClientCreate() error:" << result;
70 result = MIDISourceCreate( m_client, name, &m_endpoint );
71 if ( result != noErr ) {
72 qDebug() <<
"MIDISourceCreate() error:" << result;
75 result = MIDIOutputPortCreate( m_client, name, &m_port );
76 if (result != noErr) {
77 qDebug() <<
"MIDIOutputPortCreate() error:" << result;
80 reloadDeviceList(
true);
83 virtual ~MacMIDIOutputPrivate()
88 void internalDispose()
90 OSStatus result = noErr;
92 result = MIDIPortDispose( m_port );
93 if (result != noErr) {
94 qDebug() <<
"MIDIPortDispose() error:" << result;
98 if (m_endpoint != 0) {
99 result = MIDIEndpointDispose( m_endpoint );
100 if (result != noErr) {
101 qDebug() <<
"MIDIEndpointDispose() err:" << result;
106 result = MIDIClientDispose( m_client );
107 if (result != noErr) {
108 qDebug() <<
"MIDIClientDispose() error:" << result;
114 void setPublicName(QString name)
116 if (m_publicName != name) {
118 internalCreate(name.toCFString());
123 void reloadDeviceList(
bool advanced)
125 int num = MIDIGetNumberOfDestinations();
126 m_clientFilter = !advanced;
127 m_outputDevices.clear();
128 for (
int i = 0; i < num; ++i) {
129 bool excluded =
false;
130 MIDIEndpointRef dest = MIDIGetDestination( i );
132 QString name = getEndpointName(dest);
133 if ( m_clientFilter &&
134 name.contains(QLatin1String(
"IAC"), Qt::CaseSensitive) )
136 if ( name.contains (m_publicName) )
138 foreach (
const QString& n, m_excludedNames ) {
139 if ( name.contains(n) ) {
145 m_outputDevices << name;
148 if (!m_currentOutput.isEmpty() && m_destination != 0 &&
149 !m_outputDevices.contains(m_currentOutput)) {
150 m_currentOutput.clear();
155 void sendEvents(
const MIDIPacketList* events )
157 MIDIReceived(m_endpoint, events);
158 if (m_destination != 0)
159 MIDISend(m_port, m_destination, events);
162 bool open(
const QString &name)
165 QStringList allOutputDevices;
166 int num = MIDIGetNumberOfDestinations();
167 for (
int i = 0; i < num; ++i) {
168 MIDIEndpointRef dest = MIDIGetDestination( i );
170 allOutputDevices << getEndpointName( dest );
172 index = allOutputDevices.indexOf(name);
175 m_destination = MIDIGetDestination( index );
176 m_currentOutput = name;
183 m_currentOutput.clear();
187 MacMIDIOutput::MacMIDIOutput(
QObject *parent) :
188 MIDIOutput(parent), d(new MacMIDIOutputPrivate)
192 MacMIDIOutput::~MacMIDIOutput()
197 void MacMIDIOutput::initialize(QSettings *settings)
202 QString MacMIDIOutput::backendName()
204 return QLatin1Literal(
"CoreMIDI");
207 QString MacMIDIOutput::publicName()
209 return d->m_publicName;
212 void MacMIDIOutput::setPublicName(QString name)
214 d->setPublicName(name);
217 QStringList MacMIDIOutput::connections(
bool advanced)
219 d->reloadDeviceList(advanced);
220 return d->m_outputDevices;
223 void MacMIDIOutput::setExcludedConnections(QStringList conns)
225 d->m_excludedNames = conns;
228 void MacMIDIOutput::open(QString name)
233 void MacMIDIOutput::close()
238 QString MacMIDIOutput::currentConnection()
240 return d->m_currentOutput;
290 void MacMIDIOutput::sendNoteOn(
int chan,
int note,
int vel)
293 MIDIPacketList pktlist ;
294 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
295 data[0] = MIDI_STATUS_NOTEON | (chan & 0x0f);
298 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
301 d->sendEvents(&pktlist);
304 void MacMIDIOutput::sendNoteOff(
int chan,
int note,
int vel)
307 MIDIPacketList pktlist ;
308 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
309 data[0] = MIDI_STATUS_NOTEOFF | (chan & 0x0f);
312 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
315 d->sendEvents(&pktlist);
318 void MacMIDIOutput::sendController(
int chan,
int control,
int value)
321 MIDIPacketList pktlist ;
322 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
323 data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & 0x0f);
326 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
329 d->sendEvents(&pktlist);
332 void MacMIDIOutput::sendKeyPressure(
int chan,
int note,
int value)
335 MIDIPacketList pktlist ;
336 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
337 data[0] = MIDI_STATUS_KEYPRESURE | (chan & 0x0f);
340 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
343 d->sendEvents(&pktlist);
346 void MacMIDIOutput::sendProgram(
int chan,
int program)
349 MIDIPacketList pktlist ;
350 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
351 data[0] = MIDI_STATUS_PROGRAMCHANGE | (chan & 0x0f);
353 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
356 d->sendEvents(&pktlist);
359 void MacMIDIOutput::sendChannelPressure(
int chan,
int value)
362 MIDIPacketList pktlist ;
363 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
364 data[0] = MIDI_STATUS_CHANNELPRESSURE | (chan & 0x0f);
366 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
369 d->sendEvents(&pktlist);
372 void MacMIDIOutput::sendPitchBend(
int chan,
int value)
374 quint16 val = value + 8192;
376 MIDIPacketList pktlist ;
377 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
378 data[0] = MIDI_STATUS_PITCHBEND | (chan & 0x0f);
379 data[1] = MIDI_LSB(val);
380 data[2] = MIDI_MSB(val);
381 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
384 d->sendEvents(&pktlist);
387 void MacMIDIOutput::sendSysex(
const QByteArray& data)
390 if (data.size() > 4096)
392 MIDIPacketList* pktlist = (MIDIPacketList*) &buf;
393 MIDIPacket* packet = MIDIPacketListInit(pktlist);
394 packet = MIDIPacketListAdd(pktlist,
sizeof(buf), packet, 0,
395 data.size(), (
const Byte*)data.data());
397 d->sendEvents(pktlist);
400 void MacMIDIOutput::sendSystemMsg(
const int status)
403 MIDIPacketList pktlist;
404 MIDIPacket* packet = MIDIPacketListInit(&pktlist);
406 packet = MIDIPacketListAdd(&pktlist,
sizeof(pktlist), packet, 0,
407 sizeof(data), &data);
409 d->sendEvents(&pktlist);
The QObject class is the base class of all Qt objects.