Core MIDI is a C API which provides capabilities not found elsewhere.
When the user's MIDI setup changes (e.g. you plugged in a device), there is a notification.
This is the type of the function that is called.
typealias MIDINotifyProc = CFunctionPointer<((UnsafePointer<MIDINotification>, UnsafeMutablePointer<Void>) -> Void)>
The first parameter is a MIDINotification struct which looks like this:
struct MIDINotification {
var messageID: MIDINotificationMessageID
var messageSize: UInt32
}
You might implement the callback like this:
func MyMIDINotifyProc (np:UnsafePointer<MIDINotification>, refCon:UnsafeMutablePointer<Void>) {
var notification = np.memory
switch (notification.messageID) {
case MIDINotificationMessageID(kMIDIMsgObjectAdded):
// In Objective-C you would just do a cast here
// This is the problem line
var m = np.memory as MIDIObjectAddRemoveNotification
You would look at the messageID member to see what kind of notification you just received. There are several (I'm showing just one). For each kind of notification, you will get a different struct passed in. This is the struct you get when a device has been added or removed:
struct MIDIObjectAddRemoveNotification {
var messageID: MIDINotificationMessageID
var messageSize: UInt32
var parent: MIDIObjectRef
var parentType: MIDIObjectType
var child: MIDIObjectRef
var childType: MIDIObjectType
}
As you see, this struct has additional info. The "child" might be an endpoint to a device for example, so you need these fields.
The problem is casting from the MIDINotification struct (required by the callback signature) to MIDIObjectAddRemoveNotification. The line I've shown using "as" does not work.
Do you have any suggestions for this sort of "downcasting"?
As Vatsal Manot suggested, since MIDINotification
and MIDIObjectAddRemoveNotification
are not related by any inheritance or contract, Swift cannot perform any safe casting between those structures.
You'll need to cast it explicitly using unsafeBitCast
function:
case MIDINotificationMessageID(kMIDIMsgObjectAdded):
let m = unsafeBitCast(np.memory, MIDIObjectAddRemoveNotification.self)
Note that this function can always be used in Swift to perform casts, but it is extremely unsafe and you should use it only as the last possible solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With