3

I use this code to send midi sysEx. It s perfect for sending "fix" data but now i need to send data with different size.

            var midiPacket:MIDIPacket = MIDIPacket()
            midiPacket.length = 6
            midiPacket.data.0 = data[0]
            midiPacket.data.1 = data[1]
            midiPacket.data.2 = data[2]
            midiPacket.data.3 = data[3]
            midiPacket.data.4 = data[4]
            midiPacket.data.5 = data[5]
            //... 
            //MIDISend...

Now imagine i have a String name "TROLL" but the name can change. I need something like this :

            var name:String = "TOTO"
            var nameSplit = name.components(separatedBy: "")
            var size:Int = name.count

            midiPacket.length = UInt16(size)

            for i in 0...size{
                midiPacket.data.i = nameSplit[i]
            }
            //...
            //MIDISend...

But this code don t work because i can t use "i" like this with a tuple. If someone knows how to do that.

Thanks in advance. KasaiJo

Vladyslav Zavalykhatko
  • 15,202
  • 8
  • 65
  • 100
KasaiJo
  • 130
  • 1
  • 12
  • where's the tuple you are talking about ? Seems nameSplit is an array, accessing with an index like you do should work – Damien Oct 27 '17 at 09:57
  • yeah i know, the tuple is "data" a parameter of midiPacket so i can access him with ...data.1 or ...data.2 but not with ...data.i cause is a tuple. – KasaiJo Oct 27 '17 at 10:02
  • This is the documentation : https://developer.apple.com/documentation/coremidi/midipacket – KasaiJo Oct 27 '17 at 10:08
  • You might find something usefull in this question https://stackoverflow.com/questions/24746397/how-can-i-convert-an-array-to-a-tuple – Damien Oct 27 '17 at 10:24

2 Answers2

4

C arrays are imported to Swift as tuples. But the Swift compiler preserves the memory layout of imported C structures (source), therefore you can rebind a pointer to the tuple to an pointer to UInt8:

withUnsafeMutablePointer(to: &midiPacket.data) {
    $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: midiPacket.data)) {
        dataPtr in // `dataPtr` is an `UnsafeMutablePointer<UInt8>`

        for i in 0..<size {
            dataPtr[i] = ...
        }
    }
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
1

I don't know any proper way to do that, as tuples are compound type and can't be extended to add additional functionality.

One way of improving it I can think about is extracting it to a func like:

    func setMidiPacket(_ midi: MIDIPacket fromArray array: [ProbablyInt]) {
        midiPacket.length = 6
        midiPacket.data.0 = data[0]
        midiPacket.data.1 = data[1]
        midiPacket.data.2 = data[2]
        midiPacket.data.3 = data[3]
        midiPacket.data.4 = data[4]
        midiPacket.data.5 = data[5]
    }

setMidiPacket(midi, data)
Vladyslav Zavalykhatko
  • 15,202
  • 8
  • 65
  • 100