我使用以下代码在Swift游乐场接收MIDI事件:
import Cocoa
import CoreMIDI
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
func notifyCallback(message:UnsafePointer<MIDINotification>,refCon:UnsafeMutablePointer<Void>)
{
println("MIDI Notify")
}
func eventCallback(pktlist:UnsafePointer<MIDIPacketList>, refCon:UnsafeMutablePointer<Void>, connRefCon:UnsafeMutablePointer<Void>)
{
println("MIDI Read")
}
var client = MIDIClientRef()
MIDIClientCreate("Core MIDI Callback Demo" as NSString, MIDINotifyProc(COpaquePointer([notifyCallback])), nil, &client)
var inPort = MIDIPortRef()
MIDIInputPortCreate(client, "Input port",MIDIReadProc(COpaquePointer([eventCallback])), nil, &inPort)
let sourceCount = MIDIGetNumberOfSources()
for var count:UInt = 0; count < sourceCount; ++count
{
let src:MIDIEndpointRef = MIDIGetSource(count)
MIDIPortConnectSource(inPort, src, nil)
}我通过将Objective-C代码翻译成我认为正确的Swift版本得到了这一点。
它编译和运行良好,直到一个回调触发,例如,当我拔出MIDI设备或按下它的一个键。我总是得到一台BAD_EXEC。
有没有什么办法可以做到这一点,或者是Swift还没有准备好在网络上发布一些博客文章。我忽略了苹果的任何官方消息,明确表示Swift还没有准备好接受CoreMIDI回调?
更新2015-03-10:相应的Objective-C代码可以在http://www.digital-aud.io/blog/2015/03/10/on-coremidi-callbacks/上找到
Update 2021-06-25:我已经写了一个关于如何在苹果设备https://twissmueller.medium.com/midi-listener-in-swift-b6e5fb277406上接收MIDI消息的编程教程
发布于 2017-01-03 06:24:19
与早期版本相比,Swift3似乎对CoreMIDI有更好的支持。下面显示的示例游乐场演示展示了一些基本的CoreMIDI调用。
import Cocoa
import CoreMIDI
import PlaygroundSupport
// helper method to extract the display name from a MIDIObjectRef
func midiObjectDisplayName(_ obj: MIDIObjectRef) -> String {
var param: Unmanaged<CFString>?
var capturedName = "Error"
let err = MIDIObjectGetStringProperty(obj, kMIDIPropertyDisplayName, ¶m)
if err == OSStatus(noErr) {
capturedName = param!.takeRetainedValue() as String
}
return capturedName
}
// method to collect display names of available MIDI destinations
func midiDestinationNames() -> [String] {
var names:[String] = []
let count:Int = MIDIGetNumberOfDestinations()
for i in 0..<count {
let endpoint:MIDIEndpointRef = MIDIGetDestination(i)
if endpoint != 0 {
names.append(midiObjectDisplayName(endpoint))
}
}
return names
}
let destinationNames = midiDestinationNames()
// check if we have any available MIDI destinations.
if destinationNames.count > 0 {
// establish a MIDI client and output port, and send a note on/off pair.
var midiClient:MIDIClientRef = 0
var outPort:MIDIPortRef = 0
MIDIClientCreate("Swift3 Test Client" as CFString, nil, nil, &midiClient)
MIDIOutputPortCreate(midiClient, "Swift3 Test OutPort" as CFString, &outPort)
let destNum = 0
let destName = destinationNames[destNum]
var dest:MIDIEndpointRef = MIDIGetDestination(destNum)
var midiPacket:MIDIPacket = MIDIPacket()
midiPacket.timeStamp = 0
midiPacket.length = 3
midiPacket.data.0 = 0x90 + 0 // Note On event channel 1
midiPacket.data.1 = 0x3D // Note Db
midiPacket.data.2 = 100 // Velocity
var packetList:MIDIPacketList = MIDIPacketList(numPackets: 1, packet: midiPacket)
print("Sending note on to \(destName)")
MIDISend(outPort, dest, &packetList)
midiPacket.data.0 = 0x80 + 0 // Note off event channel 1
midiPacket.data.2 = 0 // Velocity
sleep(1)
packetList = MIDIPacketList(numPackets: 1, packet: midiPacket)
MIDISend(outPort, dest, &packetList)
print("Note off sent to \(destName)")
} https://stackoverflow.com/questions/28924831
复制相似问题