AudioKit 4.2将自定义音序器连接到AKMIDISampler的端点

时间:2018-05-04 20:07:14

标签: swift audiokit

从4.1升级到4.2打破了我们的音序器和AKMIDISampler之间的连接。似乎端口现在是私有的(这是有意义的),但我如何连接到它?

1 个答案:

答案 0 :(得分:2)

好的,我通过扩展程序快速修复,但如果有任何AK人有更好的建议,我全都耳朵! (我还对传递给“handle(event :)”的“事件”添加了一个完整性检查,因为我们有用户事件,其中internalData.count< 3.。)

import Foundation
import AudioKit

extension AKMIDISampler {
    private func handle(event: AKMIDIEvent) throws {
    // This implementation assumes internatlData.count >= 3. If you have user events on the port it may just crash (i.e., if internalData.count < 3). No fun. We've added a little sanity check, just in case.
        if event.internalData.count > 2 {
            try self.handleMIDI(data1: event.internalData[0],
                            data2: event.internalData[1],
                            data3: event.internalData[2])
        }
    }

    // Had to just replicate this, due to protection levels... I guess this is a kludge, but it works!
    func handleMIDI(data1: MIDIByte, data2: MIDIByte, data3: MIDIByte) throws {
        let status = data1 >> 4
        let channel = data1 & 0xF

        if Int(status) == AKMIDIStatus.noteOn.rawValue && data3 > 0 {

            try play(noteNumber: MIDINoteNumber(data2),
                 velocity: MIDIVelocity(data3),
                 channel: MIDIChannel(channel))

        } else if Int(status) == AKMIDIStatus.noteOn.rawValue && data3 == 0 {

            try stop(noteNumber: MIDINoteNumber(data2), channel: MIDIChannel(channel))

        } else if Int(status) == AKMIDIStatus.controllerChange.rawValue {

            midiCC(data2, value: data3, channel: channel)

        }
    }

    // Again, just replicating AK's internal code, but allowing the user to show the port long enough to connect a (custom) sequencer, then hide it again after.
    func showVirtualMIDIPort() {
        MIDIObjectSetIntegerProperty(midiIn, kMIDIPropertyPrivate, 0)
    }
    func hideVirtualMIDIPort() {
        MIDIObjectSetIntegerProperty(midiIn, kMIDIPropertyPrivate, 1)
    }
}