【发布时间】:2017-04-24 13:17:35
【问题描述】:
我正在开发一个使用 MIDI 设备的应用程序。在操场上玩了一些 CoreMIDI 之后,我找到了如何获取 MIDI 输入信号,所以我实现了这个:
func makeInputSource() {
var midiClient : MIDIClientRef = 0
var inPort : MIDIPortRef = 0
MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient)
MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, {
(pktList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in
let packetList : MIDIPacketList = pktList.pointee
var packet : MIDIPacket = packetList.packet
for _ in 1...packetList.numPackets {
let bytes = Mirror(reflecting: packet.data).children
var params : [UInt64] = []
var i = packet.length
for (_, attr) in bytes.enumerated() {
let string = String(format: "%02X ", attr.value as! UInt8)
params.append(UInt64(strtoul(string, nil, 16)))
i -= 1
if (i <= 0) {
break
}
}
packet = MIDIPacketNext(&packet).pointee
}
}, nil, &inPort)
MIDIPortConnectSource(inPort, self.source, &self.source)
}
这就像使用信号的魅力。现在,我想使用信号来编辑NSSlider 的值,所以很自然地,我想出的是这样的:
self.slider_one?.integerValue = params[2]
但是,当我尝试这样做时,我收到以下错误:
A C function pointer cannot be formed from a closure that captures context
所以我想知道的是,有没有一种方法可以从该闭包内部访问self,还是有其他方法可以快速使用 MIDI 输入?
谢谢。
--- 编辑: 如题,我修改后的代码:
func makeInputSource() {
var midiClient : MIDIClientRef = 0
var inPort : MIDIPortRef = 0
var observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient)
MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, {
(pktList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in
let packetList : MIDIPacketList = pktList.pointee
var packet : MIDIPacket = packetList.packet
for _ in 1...packetList.numPackets {
let bytes = Mirror(reflecting: packet.data).children
var params : [UInt64] = []
var i = packet.length
for (_, attr) in bytes.enumerated() {
let string = String(format: "%02X ", attr.value as! UInt8)
params.append(UInt64(strtoul(string, nil, 16)))
i -= 1
if (i <= 0) {
break
}
}
let mySelf = Unmanaged<Wob>.fromOpaque(observer).takeUnretainedValue()
mySelf.slider_one?.integerValue = 25 // 25 is a test value
packet = MIDIPacketNext(&packet).pointee
}
}, &observer, &inPort)
MIDIPortConnectSource(inPort, self.source, &self.source)
}
【问题讨论】:
-
@MartinR 尝试这样做:
UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())但是,我仍然遇到同样的错误 -
你不能在闭包内使用
self,你必须从上下文指针重建它,参见链接到答案中的let mySelf = Unmanaged ...。 -
我从来没有直接引用
self,我使用了let mySelf = Unmanaged...,之后我尝试使用mySelf变量@MartinR -
您可以将修改后的代码添加到您的问题中吗?我相当确定它有效。
标签: swift macos cocoa midi coremidi