1 |
/*************************************************************************** |
/*************************************************************************** |
2 |
* * |
* * |
3 |
* Copyright (C) 2004, 2005 Grame * |
* Copyright (C) 2004, 2005 Grame * |
4 |
* Copyright (C) 2005 - 2014 Christian Schoenebeck * |
* Copyright (C) 2005 - 2015 Christian Schoenebeck * |
5 |
* * |
* * |
6 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
7 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
147 |
str = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8); |
str = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8); |
148 |
MIDIDestinationCreate(pDevice->hCoreMidiClient, str, ReadProc, this, &pDestination); |
MIDIDestinationCreate(pDevice->hCoreMidiClient, str, ReadProc, this, &pDestination); |
149 |
/* */ |
/* */ |
150 |
|
CFRelease(str); |
151 |
|
|
152 |
if (!pDestination) throw MidiInputException("Error creating CoreMidi virtual destination"); |
if (!pDestination) throw MidiInputException("Error creating CoreMidi virtual destination"); |
153 |
this->portNumber = pPortID++; |
this->portNumber = pPortID++; |
225 |
} |
} |
226 |
} |
} |
227 |
|
|
228 |
|
void MidiInputDeviceCoreMidi::MidiInputPortCoreMidi::onCoreMIDIDeviceAppeared(MIDIDeviceRef device) { |
229 |
|
ItemCount entityCount = MIDIDeviceGetNumberOfEntities(device); |
230 |
|
for (ItemCount e = 0; e < entityCount; ++e) { |
231 |
|
MIDIEntityRef entity = MIDIDeviceGetEntity(device, e); |
232 |
|
onCoreMIDIEntityAppeared(entity); |
233 |
|
} |
234 |
|
} |
235 |
|
|
236 |
|
void MidiInputDeviceCoreMidi::MidiInputPortCoreMidi::onCoreMIDIDeviceDisappeared(MIDIDeviceRef device) { |
237 |
|
ItemCount entityCount = MIDIDeviceGetNumberOfEntities(device); |
238 |
|
for (ItemCount e = 0; e < entityCount; ++e) { |
239 |
|
MIDIEntityRef entity = MIDIDeviceGetEntity(device, e); |
240 |
|
onCoreMIDIEntityDisappeared(entity); |
241 |
|
} |
242 |
|
} |
243 |
|
|
244 |
|
void MidiInputDeviceCoreMidi::MidiInputPortCoreMidi::onCoreMIDIEntityAppeared(MIDIEntityRef entity) { |
245 |
|
ItemCount sourceCount = MIDIEntityGetNumberOfSources(entity); |
246 |
|
for (ItemCount s = 0; s < sourceCount; ++s) { |
247 |
|
MIDIEndpointRef source = MIDIEntityGetSource(entity, s); |
248 |
|
onNewSourceAppeared(source); |
249 |
|
} |
250 |
|
} |
251 |
|
|
252 |
|
void MidiInputDeviceCoreMidi::MidiInputPortCoreMidi::onCoreMIDIEntityDisappeared(MIDIEntityRef entity) { |
253 |
|
ItemCount sourceCount = MIDIEntityGetNumberOfSources(entity); |
254 |
|
for (ItemCount s = 0; s < sourceCount; ++s) { |
255 |
|
MIDIEndpointRef source = MIDIEntityGetSource(entity, s); |
256 |
|
onNewSourceDisappeared(source); |
257 |
|
} |
258 |
|
} |
259 |
|
|
260 |
|
|
261 |
// *************** MidiInputDeviceCoreMidi *************** |
// *************** MidiInputDeviceCoreMidi *************** |
262 |
// * |
// * |
307 |
switch (message->messageID) { |
switch (message->messageID) { |
308 |
case kMIDIMsgObjectAdded: { |
case kMIDIMsgObjectAdded: { |
309 |
MIDIObjectAddRemoveNotification* notification = (MIDIObjectAddRemoveNotification*) message; |
MIDIObjectAddRemoveNotification* notification = (MIDIObjectAddRemoveNotification*) message; |
310 |
if (notification->childType == kMIDIObjectType_Source) { |
switch (notification->childType) { |
311 |
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
case kMIDIObjectType_Device: { |
312 |
iter != pDevice->Ports.end(); ++iter) |
MIDIDeviceRef device = (MIDIDeviceRef) notification->child; |
313 |
{ |
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
314 |
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
iter != pDevice->Ports.end(); ++iter) |
315 |
|
{ |
316 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
317 |
|
pPort->onCoreMIDIDeviceAppeared(device); |
318 |
|
} |
319 |
|
break; |
320 |
|
} |
321 |
|
case kMIDIObjectType_Entity: { |
322 |
|
MIDIEntityRef entity = (MIDIEntityRef) notification->child; |
323 |
|
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
324 |
|
iter != pDevice->Ports.end(); ++iter) |
325 |
|
{ |
326 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
327 |
|
pPort->onCoreMIDIEntityAppeared(entity); |
328 |
|
} |
329 |
|
break; |
330 |
|
} |
331 |
|
case kMIDIObjectType_Source: { |
332 |
MIDIEndpointRef source = (MIDIEndpointRef) notification->child; |
MIDIEndpointRef source = (MIDIEndpointRef) notification->child; |
333 |
pPort->onNewSourceAppeared(source); |
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
334 |
|
iter != pDevice->Ports.end(); ++iter) |
335 |
|
{ |
336 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
337 |
|
pPort->onNewSourceAppeared(source); |
338 |
|
} |
339 |
|
break; |
340 |
} |
} |
341 |
|
default: |
342 |
|
break; |
343 |
} |
} |
344 |
break; |
break; |
345 |
} |
} |
346 |
|
|
347 |
case kMIDIMsgObjectRemoved: { |
case kMIDIMsgObjectRemoved: { |
348 |
MIDIObjectAddRemoveNotification* notification = (MIDIObjectAddRemoveNotification*) message; |
MIDIObjectAddRemoveNotification* notification = (MIDIObjectAddRemoveNotification*) message; |
349 |
if (notification->childType == kMIDIObjectType_Source) { |
switch (notification->childType) { |
350 |
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
case kMIDIObjectType_Device: { |
351 |
iter != pDevice->Ports.end(); ++iter) |
MIDIDeviceRef device = (MIDIDeviceRef) notification->child; |
352 |
{ |
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
353 |
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
iter != pDevice->Ports.end(); ++iter) |
354 |
|
{ |
355 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
356 |
|
pPort->onCoreMIDIDeviceDisappeared(device); |
357 |
|
} |
358 |
|
break; |
359 |
|
} |
360 |
|
case kMIDIObjectType_Entity: { |
361 |
|
MIDIEntityRef entity = (MIDIEntityRef) notification->child; |
362 |
|
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
363 |
|
iter != pDevice->Ports.end(); ++iter) |
364 |
|
{ |
365 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
366 |
|
pPort->onCoreMIDIEntityDisappeared(entity); |
367 |
|
} |
368 |
|
break; |
369 |
|
} |
370 |
|
case kMIDIObjectType_Source: { |
371 |
MIDIEndpointRef source = (MIDIEndpointRef) notification->child; |
MIDIEndpointRef source = (MIDIEndpointRef) notification->child; |
372 |
pPort->onNewSourceDisappeared(source); |
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
373 |
|
iter != pDevice->Ports.end(); ++iter) |
374 |
|
{ |
375 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
376 |
|
pPort->onNewSourceDisappeared(source); |
377 |
|
} |
378 |
|
break; |
379 |
} |
} |
380 |
|
default: |
381 |
|
break; |
382 |
} |
} |
383 |
break; |
break; |
384 |
} |
} |
385 |
|
|
386 |
|
case kMIDIMsgPropertyChanged: { |
387 |
|
MIDIObjectPropertyChangeNotification* notification = (MIDIObjectPropertyChangeNotification*) message; |
388 |
|
if (notification->propertyName == kMIDIPropertyOffline) { |
389 |
|
SInt32 offline = 0; |
390 |
|
MIDIObjectGetIntegerProperty(notification->object, kMIDIPropertyOffline, &offline); |
391 |
|
switch (notification->objectType) { |
392 |
|
case kMIDIObjectType_Device: { |
393 |
|
MIDIDeviceRef device = (MIDIDeviceRef) notification->object; |
394 |
|
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
395 |
|
iter != pDevice->Ports.end(); ++iter) |
396 |
|
{ |
397 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
398 |
|
if (offline) |
399 |
|
pPort->onCoreMIDIDeviceDisappeared(device); |
400 |
|
else |
401 |
|
pPort->onCoreMIDIDeviceAppeared(device); |
402 |
|
} |
403 |
|
break; |
404 |
|
} |
405 |
|
case kMIDIObjectType_Entity: { |
406 |
|
MIDIEntityRef entity = (MIDIEntityRef) notification->object; |
407 |
|
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
408 |
|
iter != pDevice->Ports.end(); ++iter) |
409 |
|
{ |
410 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
411 |
|
if (offline) |
412 |
|
pPort->onCoreMIDIEntityDisappeared(entity); |
413 |
|
else |
414 |
|
pPort->onCoreMIDIEntityAppeared(entity); |
415 |
|
} |
416 |
|
break; |
417 |
|
} |
418 |
|
case kMIDIObjectType_Source: { |
419 |
|
MIDIEndpointRef endpoint = (MIDIEndpointRef) notification->object; |
420 |
|
for (std::map<int,MidiInputPort*>::iterator iter = pDevice->Ports.begin(); |
421 |
|
iter != pDevice->Ports.end(); ++iter) |
422 |
|
{ |
423 |
|
MidiInputPortCoreMidi* pPort = (MidiInputPortCoreMidi*) iter->second; |
424 |
|
if (offline) |
425 |
|
pPort->onNewSourceDisappeared(endpoint); |
426 |
|
else |
427 |
|
pPort->onNewSourceAppeared(endpoint); |
428 |
|
} |
429 |
|
break; |
430 |
|
} |
431 |
|
default: |
432 |
|
break; |
433 |
|
} |
434 |
|
} |
435 |
|
break; |
436 |
|
} |
437 |
|
|
438 |
case kMIDIMsgSetupChanged: |
case kMIDIMsgSetupChanged: |
|
case kMIDIMsgPropertyChanged: |
|
439 |
case kMIDIMsgThruConnectionsChanged: |
case kMIDIMsgThruConnectionsChanged: |
440 |
case kMIDIMsgSerialPortOwnerChanged: |
case kMIDIMsgSerialPortOwnerChanged: |
441 |
case kMIDIMsgIOError: |
case kMIDIMsgIOError: |