2017-04-25 2 views
0

Je travaille sur une application Swift, où j'utilise le signal MIDI d'un spécifique et de travailler avec elle. Un exemple est: Je veux déplacer la valeur d'un NSSlider autour du signal d'entrée. Donc, ce que j'ai fait était de créer un flux d'entrée MIDI (qui fonctionne) et ce que je dois faire maintenant, est de prendre la valeur et de le mettre à self.wave_mode_slider?.integerValue.Casting auto à UnsafeMutablePointer <Void> résultats dans EXC_BAD_INSTRUCTION

Ma méthode d'où je fais la connexion d'entrée est la suivante:

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

Comme vous pouvez le voir, j'ai la variable d'observateur fait comme ceci:

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

Ce que je puis passer à la fermeture et j'essaie d'utiliser comme ceci:

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

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

Cependant, cela conduit à EXC_BAD_INSTRUCTION sur la ligne où est déclaré mySelf.

J'ai également essayé d'utiliser les variantes retained, mais cela a conduit à la même EXC_BAD_INSTRUCTION.

Maintenant, je ne suis pas un développeur rapide chevronné, et surtout pas quand il s'agit de ce genre de choses, donc il se peut que j'ai manqué quelque chose d'évident, alors quelqu'un sait-il pourquoi cela arrive?

Merci

---- Modifier Comme suggéré, j'ai changé le code légèrement,

MIDIPortConnectSource(inPort, self.source, &observer) 

est devenu

MIDIPortConnectSource(inPort, self.source, observer) 

Ce qui m'a fait changer la variable observer à un UnsafeMutableRawPointer

+0

Il devrait être 'MIDIPortConnectSource (InPort, self.source, observateur)', sans '' et - comme je l'ai suggéré à http://stackoverflow.com/questions/43589188/access-self-from- ac-style-pointeur # comment74230252_43589188 :) –

+0

@MartinR Haha raté ça! Je mettrai à jour le code puisque le problème reste pour moi, –

+0

Bien sûr, cela fait une différence si vous transmettez le contenu de 'observer' ou l'adresse de cette variable. –

Répondre

0

Sur Swift 4 (réception 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!") 
     } 
    } 
}