Swift - AudioKit AKMidi 到 AKSequencer

Posted

技术标签:

【中文标题】Swift - AudioKit AKMidi 到 AKSequencer【英文标题】:Swift - AudioKit AKMidi to AKSequencer 【发布时间】:2018-09-03 11:59:03 【问题描述】:

我目前有一个应用程序,它使用 AKKeyboard 通过振荡器创建声音。每当弹奏键盘时,我也会得到 MIDI 数据。我想做的是根据收到的 MIDI 数据创建一个 AKSequence。

任何建议或指点将不胜感激,谢谢。

这是我的部分代码:

var bank = AKOscillatorBank()
var midi: AKMIDI!
let sequencer = AKSequencer()
let sequenceLength = AKDuration(beats: 8.0)

func configureBank() 
    AudioKit.output = bank

    do 
        try AudioKit.start()
     catch 
        AKLog("AudioKit couldn't be started")
    

    midi = AudioKit.midi
    midi.addListener(self)
    midi.openInput()


// AKKeyboard Protocol methods
func noteOn(note: MIDINoteNumber) 
    let event = AKMIDIEvent(noteOn: note, velocity: 80, channel: 5)
    midi.sendEvent(event)
    bank.play(noteNumber: note, velocity: 100)


func noteOff(note: MIDINoteNumber) 
    let event = AKMIDIEvent(noteOff: note, velocity: 0, channel: 5)
    midi.sendEvent(event)
    bank.stop(noteNumber: note)


// AKMIDIListener Protocol methods..
func receivedMIDINoteOff(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel) 
    print("ReceivedMIDINoteOff: \(noteNumber), velocity: \(velocity), channel: \(channel)")

【问题讨论】:

【参考方案1】:

您实际上不需要直接从 AKMIDIEvents 构建序列。只需在调用 AKKeyboardView 的 noteOn 和 noteOff 方法时查询序列的 currentPosition,并基于此以编程方式将事件添加到音序器轨道。

流程基本与此相同(当然是最后一步除外):https://***.com/a/50071028/2717159

编辑 - 获取 noteOn 和 noteOff 时间和持续时间:

// store notes and times in a dictionary:
var noteDict = [MIDINoteNumber: MIDITimeStamp]()

// when you get a noteOn, note the time
noteDict[currentMIDINote] = seq.currentPosition.beats

// when you get a noteOff
let endTime = seq.currentPosition.beats
if let startTime = noteDict[currentMIDINote] 
    let durationInBeats = endTime - startTime
    // use the startTime, duration and currentMIDINote to add event to track
    noteDict[currentMIDINote] = nil

【讨论】:

谢谢你,这个参考肯定有帮助。你能解释一下我如何用 currentPosition 计算 timeAtNoteOn 和 timeAtNoteOff 吗?我现在被困住了。 另外,当我想播放音序器来听所有的 MIDI 时,我只有一两个音序器吗?我问这个是因为当我创建音序器时我必须播放它才能看到当前位置,希望从 AKKeyboard 录制 MIDI 并通过单击按钮将其回放给用户。 在您的第一条评论中添加了代码。关于第二个,你可以只用一个音序器来做。只需将要写入事件的轨道的输出设置为触发外部 MIDI 事件的 AKCallbackInstrument(就像在上面的 AKKeyboardDelegate 中所做的那样)。 github.com/AudioKit/AudioKit/tree/master/Examples/ios/… 的自述文件提供了一个设置示例。所以 AKKeyboardDelegate 方法会触发实时事件,而音序器轨道会触发录制的事件。 感谢您在这方面的帮助,您真的是 AudioKit 之王。我很可能会提出另一个可能与 Audiobus 有关的问题,但现在我有一个问题(至少我认为这是一个问题)。当我查询 currentPosition.beats 时,我总是收到 0.0。 我如何将 MIDITimestamp 转换为 AKDuration?

以上是关于Swift - AudioKit AKMidi 到 AKSequencer的主要内容,如果未能解决你的问题,请参考以下文章

Swift:声音输出和麦克风输入 |使用 AudioKit |

Audiokit 4.9.5 在 xcode 11.4 + swift 5.2 中崩溃,没有有用的错误消息

Swift - 带有振荡器的 AudioKit 音序器(AKOscillatorBank).频率不会在更高的范围内播放(MidiNote 120+)

MIDI 信息成倍增加

AudioKit (iOS) - 为频率/幅度变化添加观察者

如何使用 Swift 创建 MIDI 文件? [关闭]