Swift中的CoreMIDI回调
我使用以下代码在Swift游乐场接收MIDI事件:Swift中的CoreMIDI回调,swift,midi,swift-playground,coremidi,Swift,Midi,Swift Playground,Coremidi,我使用以下代码在Swift游乐场接收MIDI事件: import Cocoa import CoreMIDI import XCPlayground XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true) func notifyCallback(message:UnsafePointer<MIDINotification>,refCon:UnsafeMutablePointer<Void&g
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)
}
导入可可粉
进口CoreMIDI
导入运动场
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely:true)
func notifyCallback(消息:UnsafePointer,refCon:UnsafeMutablePointer)
{
println(“MIDI通知”)
}
func eventCallback(pktlist:UnsafePointer、refCon:UnsafeMutablePointer、conrefcon:UnsafeMutablePointer)
{
println(“MIDI读取”)
}
var client=MIDIClientRef()
midclientcreate(“核心MIDI回调演示”如NSString、MIDINotifyProc(COpaquePointer([notifyCallback])、nil和client)
var inPort=MIDIPortRef()
MIDInputPortCreate(客户端,“输入端口”、MIDIReadProc(COpaquePointer([eventCallback])、nil和inPort)
让sourceCount=MIDIGetNumberOfSources()
对于var计数:UInt=0;计数<源计数++计数
{
让src:MIDIEndpointRef=MIDIGetSource(计数)
MIDIPortConnectSource(输入端口、src、nil)
}
我是通过将Objective-C代码翻译成我认为正确的Swift版本来实现这一点的
它编译并运行良好,直到其中一个回调触发,例如,当我拔下MIDI设备或按下它的一个键时。我总是有一个糟糕的执行官
任何想法如何使这项工作,或是迅速只是没有准备好的一些博客文章在网络上的状态。我忽略了苹果公司的任何官方信息,清楚地表明斯威夫特尚未准备好CoreMIDI回调
更新2015-03-10:相应的Objective-C代码可在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)")
}
导入可可粉
进口CoreMIDI
导入PlaygroundSupport
//从MIDIObjectRef提取显示名称的帮助器方法
func midiObjectDisplayName(j:MIDIObjectRef)->字符串{
变量参数:非托管?
var capturedName=“错误”
让err=MIDIObjectGetStringProperty(obj、kMIDIPropertyDisplayName和param)
如果err==OSStatus(noErr){
capturedName=param!.takeRetainedValue()作为字符串
}
返回capturedName
}
//方法收集可用MIDI目标的显示名称
func midDestinationNames()->[字符串]{
变量名称:[字符串]=[]
让计数:Int=MIDIGetNumberOfDestinations()
因为我在0..0{
//建立一个MIDI客户机和输出端口,并发送一个note on/off对。
变量midiClient:MIDIClientRef=0
变量输出端口:MIDIPortRef=0
midclientcreate(“Swift3测试客户端”作为CFString、nil、nil和midclient)
MIDIOutputPortCreate(midiClient,“Swift3测试输出端口”作为CFString,&OutPort)
设destNum=0
让destName=destinationNames[destNum]
var dest:MIDIEndpointRef=MIDIGetDestination(destNum)
var midiPacket:midiPacket=midiPacket()
midiPacket.timeStamp=0
midiPacket.length=3
midiPacket.data.0=0x90+0//事件通道1上的注释
midiPacket.data.1=0x3D//Note Db
midiPacket.data.2=100//Velocity
var packetList:MIDIPacketList=MIDIPacketList(numPackets:1,packet:midiPacket)
打印(“将注释发送到\(destName)”)
MIDISend(输出端口、目的地和打包列表)
midiPacket.data.0=0x80+0//Note off事件通道1
midiPacket.data.2=0//Velocity
睡眠(1)
packetList=MIDIPacketList(numPackets:1,packet:midiPacket)
MIDISend(输出端口、目的地和打包列表)
打印(“通知发送到\(destName)”)
}
类似的问题:,。我猜C函数回调是不受支持的(目前)在Swift中。是的,但我不确定从那以后关于Swift的变化有多大。它似乎真的还没有被支持,也发现了这篇非常好的帖子:。谢谢你的评论,Tobias。我刚刚在本周推出的Swift 1.2测试版中再试了一次。仍然没有运气。也许如果我们都与苹果就函数指针问题展开讨论,这将是一个好消息激励他们?我知道这是显而易见的,但回调问题适用于所有C API,而不仅仅是核心MIDI。CGPathApplierFunction是另一个在Swift中还无法实现的示例。非常感谢,Gene。我们已经向Apple(20185404)提交了一份错误报告。希望当更多的人这样做时,这会让事情进展顺利。