2017-04-25 38 views
0

我正在使用Swift应用程序,在该应用程序中,我利用特定的MIDI信号并使用它。一个例子是:我想根据输入信号移动NSSlider的值。所以,我所做的是创建一个MIDI输入流(可行),我现在需要做的是取值并将其设置为self.wave_mode_slider?.integerValue将自我投射到UnsafeMutablePointer <Void>产生EXC_BAD_INSTRUCTION

我从那里我使输入连接如下方法:

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?) -> Void in 
     let packetList : MIDIPacketList = pktList.pointee 
     var packet : MIDIPacket = packetList.packet 
     let mySelf = Unmanaged<Wob>.fromOpaque(readProcRefCon!).takeUnretainedValue() 

     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 
       } 
      } 

      mySelf.wave_mode_slider?.integerValue = ("\(params[2])" as NSString).integerValue 
      packet = MIDIPacketNext(&packet).pointee 
     } 

    }, nil, &inPort) 

    MIDIPortConnectSource(inPort, self.source, &observer) 
} 

正如你所看到的,我有这样做出的观测变量:

var observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())

然后我传递到封闭,我尝试使用像这样:

let mySelf = Unmanaged<Wob>.fromOpaque(readProcRefCon!).takeUnretainedValue() 

mySelf.wave_mode_slider?.integerValue = ("\(params[2])" as NSString).integerValue 

然而,这导致EXC_BAD_INSTRUCTIONmySelf宣布的行上。

我也试过使用retained变种,但是这导致了相同的EXC_BAD_INSTRUCTION

现在,我不是一个经验丰富的快速开发人员,特别是当涉及到这个东西时,所以可能是我错过了一些明显的东西,所以有人知道为什么会发生这种情况?

感谢

编辑----至于建议,我略微改变的代码,

MIDIPortConnectSource(inPort, self.source, &observer) 

成为

MIDIPortConnectSource(inPort, self.source, observer) 

这也让我observer变量更改为UnsafeMutableRawPointer

+0

它应该是'MIDIPortConnectSource(运行轨迹,self.source,观察者)',而'&' - 我建议在http://stackoverflow.com/questions/43589188/access-self-from-交流风格指针#comment74230252_43589188 :) –

+0

@MartinR哈哈错过了!我将更新代码,因为问题仍然存在, –

+0

当然,如果您传递“observer”的内容或该变量的地址,它会有所不同。 –

回答

0

在Swift 4上(收到cc):

@objc func receiveMIDI(_ sender: UIButton) { 

    let observer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) 
    MIDIClientCreate(s, nil, nil, &midiClient); 
    MIDIInputPortCreate(midiClient, p, { 
    (pktList: UnsafePointer<MIDIPacketList>, 
     readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in 
      // callback block 
      let packetList:MIDIPacketList = pktList.pointee 
      var packet:MIDIPacket = packetList.packet 

      for _ in 1...packetList.numPackets{ 
       let bytes = Mirror(reflecting: packet.data).children 
       var dumpStr = "" 


       var i = packet.length 
       for (_, attr) in bytes.enumerated(){ 
         dumpStr += String(format:"%02d ", attr.value as! UInt8) 
         i -= 1 
         if (i <= 0) 
         { 
          break 
         } 
       } 
       let midi = dumpStr.split(separator: " ", maxSplits: 2, omittingEmptySubsequences: true) 
       var midiIntValues = [Int(midi[0]),Int(midi[1]),Int(midi[2].trimmingCharacters(in: .whitespaces))] 
       if let src = srcConnRefCon{ 
        let mySelf = Unmanaged<DetailViewController>.fromOpaque(src).takeUnretainedValue() 
        if let v = midiIntValues[2]{ 
         // print("control \(midiIntValues[1]) has \(v) value") 
        } 

       } 
       packet = MIDIPacketNext(&packet).pointee 
      } 
      // end callback block 
     }, nil, &inputPort); 

    let sourceCount = MIDIGetNumberOfSources() 
    print("source count \(sourceCount)") 

    for srcIndex in 0 ..< sourceCount { 
     var source = MIDIGetSource(srcIndex) 
     let status = MIDIPortConnectSource(inputPort,source,observer) 
     if status == noErr { 
      print("Connected to inputPort") 
     } else { 
      print("There was an error connecting the ports!") 
     } 
    } 
} 
相关问题