加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift中的CoreMIDI回调

发布时间:2020-12-14 04:55:30 所属栏目:百科 来源:网络整理
导读:我使用以下代码在 Swift Playground中接收MIDI事件: import Cocoaimport CoreMIDIimport XCPlaygroundXCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)func notifyCallback(message:UnsafePointerMIDINotification,refCon:UnsafeMut
我使用以下代码在 Swift Playground中接收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])),&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/找到

解决方法

与早期版本相比,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,&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,&packetList)
    print("Note off sent to (destName)")
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读