Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift中的CoreMIDI回调_Swift_Midi_Swift Playground_Coremidi - Fatal编程技术网

Swift中的CoreMIDI回调

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

我使用以下代码在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)
}
导入可可粉
进口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, &param)
    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)提交了一份错误报告。希望当更多的人这样做时,这会让事情进展顺利。