改变AKSequencer的长度:奇怪的行为

时间:2018-06-02 10:35:46

标签: audiokit

我有一个启用循环的aksequencer,我想在播放期间更改长度。我用setLength()和setLoopInfo()尝试过这个,但似乎没有一个能正常工作。

预期的行为:如果我有一个16拍的序列,并且我调用changeSequenceToLength(12),我希望循环从节拍1-12播放,然后重复。 (当然,我应该处理我在12号之后改变长度的情况,但你明白了。)

实际行为:混合包。当我使用setLength(endbeat)时,它只是删除endbeat之后的midi事件,但循环仍然是16次节拍。当我调用setLoopInfo(duration,numloops)时,它会缩短循环,但是从错误的一侧开始。所以不是打1-12而是打4-16。当我第一次改变循环持续时间时,它也会做一些奇怪的口吃。

如何处理此问题的任何建议将非常感谢!我也看过支持苹果MusicSequence的文档,但它非常稀疏。

我的代码大致如下:

import AudioKit
import AudioKitUI

final class Sequencer: AKSequencer {
    static let shared = Sequencer() //Singleton

    var numBeats = 16 // Number of spaces in the grid
    var beatLength = 1/4.0
    var sequenceDuration: AKDuration {
        get {
            return AKDuration(beats: (numBeats * beatLength))
        }
    }

    private override init() {
        super.init()
        setTempo(120.0)
        for _ in 0..<8 {
            let track = newTrack()
        }
        let callback = AKCallbackInstrument() { status, note, velocity in
            //send midi messages...
        }
        let midiNode = AKMIDINode(node: callback)
        setLength(sequenceDuration)
        AudioKit.output = midiNode
        AudioKit.start()
        midiNode.enableMIDI(Midi.shared.client, name: "midiNode midi in")
        enableLooping()
    }

    func changeSequenceToLength(length: Int) {
        numBeats = length
        setLength(sequenceDuration)
        //  setLoopInfo(sequenceDuration, numberOfLoops: 50)
    }
}

编辑:所以我找到了AKMusicTrack.setLengthSoft(),所以当我缩短序列时,我的midi序列不会被删除。我还读取了setLoopInfo的代码,它确实应该从结尾向后创建一个循环(不应该采用startTime和offset ??)。但是当我改变序列长度时,我仍然遇到播放卡顿问题。

1 个答案:

答案 0 :(得分:2)

调用setLength()后,您需要通过调用enableLooping()来重新声明循环行为(或者您可以使用setloopInfo来完成两个步骤)。但是,在顺控程序运行时基本上改变循环长度将是一个问题。

重要的是要理解AKSequencer本质上是围绕CoreMIDI的MusicSequence的Swift包装器,因此它基本上继承了MusicSequence的大部分怪癖和限制。其中一个限制是,尽管您可以设置循环范围的“左侧”,但您无法设置“右侧” - 它将始终循环回到MusicTimeStamp 0.调用setLoopinfo(或者调用{{ 1}}后跟setLength())实际上并没有像你说的那样从错误的一边缩短循环(虽然我起初也认为它是这样做的)。它正确设置循环长度,但也将播放头传送到“新循环长度”的位置,远离“旧循环长度”。因此,如果您将16拍循环更改为12拍循环,enableLooping()将从0循环到12,但它会将播放头移动到4(16 - 12 = 4)。它不会从4到16播放,但是从4到12,它们从0到12循环。有时你可以work around this在播放时你可以使这个工作,但大多数情况下它是一种痛苦。最佳解决方案是在更改循环长度时停止播放。 CoreMIDI'a MusicSequence不擅长动态处理变更。