使用AudioKit从MIDI文件中读取注释

8

我正在尝试构建一个可以从midi文件中渲染音符的序列器。

目前,我正在使用AudioKit进行音乐数据处理。想知道如何使用AudioKit从midi文件中获取音符数据/事件。

我已经尝试使用AKSequencer并输出到AKMIDINode来监听MIDI事件,但似乎无法从中获取任何内容。

class CustomMIDINode: AKMIDINode {

    override init(node: AKPolyphonicNode) {
        print("Node create") // OK
        super.init(node: node)
    }

    func receivedMIDINoteOff(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel) {
        print("midi note off") // Not printed
    }

    func receivedMIDISetupChange() {
        print("midi setup changed") // Not printed
    }

    override func receivedMIDINoteOn(_ noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel) {
        print("receivedMIDINoteOn") // Not printed
    }
}

func setupSynth() {
    oscBank.attackDuration = 0.05
    oscBank.decayDuration = 0.1
    oscBank.sustainLevel = 0.1
    oscBank.releaseDuration = 0.1
}


let seq = AKSequencer(filename: "music")
let oscBank = AKOscillatorBank()
var midi = AKMIDI()
let midiNode = CustomMIDINode(node: oscBank)

setupSynth()

midi.openInput()
midi.addListener(midiNode)
seq.tracks.forEach { (track) in
    track.setMIDIOutput(midiNode.midiIn)
}
AudioKit.output = midiNode
AudioKit.start()
seq.play()
2个回答

3
你看过任何可下载的Audio Kit示例项目吗?它们非常有用,可以用于解决AK相关问题。实际上,我发现比起文档(因为实现没有很好地解释),这些示例更好理解。
至于你的问题,你可以将midi监听器添加到事件中,此代码在模拟合成器X项目中提供了一个示例。
let midi = AKMIDI()
        midi.createVirtualPorts()
        midi.openInput("Session 1")
        midi.addListener(self)

如果你需要更完整的代码示例,可以参考此链接。不过需要注意,部分代码可能已经过时。


1

托尼,你是收不到MIDI事件还是只是print语句无法输出?

我同意Axemasta的回答,建议在类中添加AKMidiListener并查看AudioKit提供的MIDI代码示例。这个ROM玩家示例展示了如何使用AKMidiSampler节点播放外部MIDI文件:

https://github.com/AudioKit/ROMPlayer

为了使打印输出正常显示,请尝试将其包装在 DispatchQueue.main.async 中,以便它在主线程上运行。这里有一个关于AudioKit MIDI实现的问题,我在这里发布了一个代码示例:AudioKit iOS - receivedMIDINoteOn function。希望这可以帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接