AudioKit:将新的AKSequencer与各种回调工具一起使用 [英] AudioKit: Using the new AKSequencer with any variety of the callback instruments

查看:46
本文介绍了AudioKit:将新的AKSequencer与各种回调工具一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该主题已经无数次,我有在我以前的应用程序中,已成功将 AKMIDICallbackInstrument 与旧的 AKAppleSequencer 一起使用.

This topic has been covered Numerous Times, and I have successfully used a AKMIDICallbackInstrument with the old AKAppleSequencer in my previous apps.

我开始使用新的 AKSequencer ,它绝对是惊人的:优雅的界面,易于使用.但是,我一生都无法弄清楚如何使用它来处理回调事件.我需要使用回调函数,以便根据音序器的播放来触发GUI事件.

I am starting to use the new AKSequencer which is absolutely phenomenal: elegant interface, and easy to use. However, I cannot for my life figure out how to handle callback events with it. I need to use a callback in order to trigger GUI events based on the sequencer playing.

这是我的示例代码:

    private func setMetronome(bpm: BPM, beats:Int)
    {
        sequencer = AKSequencer(targetNode: metronomeSampler)
        sequencer.tempo = bpm
        sequencer.loopEnabled = false
        sequencer.length = Double(beats)

        metroCallback.callback = {status, noteNumber, velocity in
            if let midiStatus = AKMIDIStatus(byte: status), midiStatus.type != .noteOn { return }

            //Do callback stuff here
        }

        let metroCallbackTrack = sequencer.addTrack(for: metroCallback)

        for i in 0..<beats
        {
            if i == 0
            {
                sequencer.add(noteNumber: MIDINoteNumber(67), position: Double(i), duration: 1.0)
                metroCallbackTrack.add(noteNumber: MIDINoteNumber(67), position: Double(i), duration: 1.0)
            }
            else if (i % 4 == 0)
            {
                sequencer.add(noteNumber: MIDINoteNumber(67), position: Double(i), duration: 1.0)
                metroCallbackTrack.add(noteNumber: MIDINoteNumber(60), position: Double(i), duration: 1.0)
            }
            else
            {
                sequencer.add(noteNumber: MIDINoteNumber(60), position: Double(i), duration: 1.0)
                metroCallbackTrack.add(noteNumber: MIDINoteNumber(60), position: Double(i), duration: 1.0)
            }
            print("seq count:\(i)")
        }

        for track in sequencer.tracks
        {
            print("Adding track to mixer:\(track.length)")
            track >>> mixer
        }
    }

此代码正确地创建了一个 n 个拍子序列,并通过我的 AKSampler 进行播放,这一切都很好.除了没有回调事件发生外(使用打印语句进行确认)

This code correctly creates a sequence of n number of beats, it plays back through my AKSampler all is well in the world. Except that no callback events happen (using print statements to confirm)

思考过程

使用 AKAppleSequencer AKMIDICallbackInstrument ,可以将 globalMIDIOutput AKAppleSequencer 一起设置,并且将midi输入 AKMIDICallBackInstrument .

With AKAppleSequencer and AKMIDICallbackInstrument, you could set the globalMIDIOutput with the AKAppleSequencer with the midi input of AKMIDICallBackInstrument.

现在新的 AKSequencer AKCallbackInstrument 没有这些选项,新的 AKSequencerTrack (旧的 AKAppleSequencer 将使用 AKMusicTrack 对象来设置midi输入/输出).在查看新的 AKSequencer 的实现时,它是由 AKNode 对象驱动的, AKCallbackInstrument AKNode 对象,并且应该能够通过具有正确Midi数据的轨道来驱动.

Now the new AKSequencer and AKCallbackInstrument do not have these options, nor does the new AKSequencerTrack (the old AKAppleSequencer would use AKMusicTrack objects which could set midi input/output). In looking at the implementation of the new AKSequencer, it is driven by AKNode objects, AKCallbackInstrument is a AKNode object and should be able be driven by a track with the right midi data.

我向音序器添加了一个音轨,并从该音轨中添加了必要的midi数据,这些数据精确地复制了我要回调并执行GUI事件的midi事件.但是,使用这种方法,它似乎没有调用回调.

I add a track to my sequencer, and from that track, and the necessary midi data that duplicate exactly the midi events I want to callback on and perform my GUI events. However with this approach, it does not seem to call the callback.

有人知道如何在回调中使用这些新组件吗?我真的不想回到 AKAppleSequencer ,除非显然没有办法使用新的 AKSequencer 驱动回调.

Does anyone have any idea how to use these new components with a callback? I really don't want to go back to AKAppleSequencer unless there is clearly no way to drive callbacks with the new AKSequencer.

推荐答案

要使 AKCallbackInstrument 与新的 AKSequencer 一起使用,请尝试将回调工具连接到输出,例如,

To get AKCallbackInstrument working with the new AKSequencer, try connecting your callback instrument to your output, e.g.,

metroCallback >>> mixer

不明显,但是对我有用.

Not obvious, but has worked for me.

包含带有 AKCallbackInstrument

class SequencerWrapper {
    var seq: AKSequencer!
    var cbInst: AKCallbackInstrument!
    var mixer: AKMixer!

    init() {
        mixer = AKMixer()
        AudioKit.output = mixer
        seq = AKSequencer()
        cbInst = AKCallbackInstrument()

        // set up a track
        let track = seq.addTrack(for: cbInst)
        for i in 0 ..< 4 {
            track.add(noteNumber: 60, position: Double(i), duration: 0.5)
        }
        track.length = 4.0
        track.loopEnabled = true
        track >>> mixer  // must send track to mixer

        // set up the callback instrument
        cbInst.callback = { status, note, vel in
            guard let status = AKMIDIStatus(byte: status),
                let type = status.type,
                type == .noteOn else { return }
            print("note on: \(note)")
            // trigger sampler etc from here
        }
        cbInst >>> mixer // must send callbackInst to mixer
    }

    func play() {
        seq.playFromStart()
    }
}

这篇关于AudioKit:将新的AKSequencer与各种回调工具一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆