首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改AKSequencer的长度:奇怪的行为

更改AKSequencer的长度:奇怪的行为
EN

Stack Overflow用户
提问于 2018-06-02 18:35:46
回答 1查看 178关注 0票数 3

我有一个支持循环的aksequencer,我想在回放时改变长度。我已经用setLength()和setLoopInfo()尝试过了,但它们似乎都不能正常工作。

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

实际行为:好坏参半。当我使用setLength(结束节拍)时,它只是删除结束节拍之后的midi事件,但循环仍然是16个节拍。当我调用setLoopInfo(duration,numloops)时,它缩短了循环,但从错误的一端开始。因此,它不是1-12,而是4-16。当我第一次更改循环持续时间时,它也会出现一些奇怪的卡顿现象。

任何关于如何实现这一点的建议都将不胜感激!我也看过支持苹果MusicSequence的文档,但数量很少。

我的代码大致如下所示:

代码语言:javascript
复制
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和偏移量吗?)。但是当我改变序列长度时,我仍然会遇到播放卡顿的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-02 22:32:57

在调用setLength()之后,您需要通过调用enableLooping()来重新断言循环行为(或者您可以使用setloopInfo,它可以在一个步骤中完成这两项工作)。但基本上在定序器运行时改变循环长度将是一个问题。

重要的是要理解,AKSequencer本质上是CoreMIDI的MusicSequence的快速包装器,所以它基本上继承了MusicSequence的大多数怪癖和限制。这些限制之一是,尽管你可以设置循环范围的“左侧”,但你不能设置“右侧”-它总是循环回MusicTimeStamp 0。调用setLoopinfo (或者调用setLength(),然后调用enableLooping())实际上并不会像您所说的那样从错误的一端缩短循环(尽管我一开始也认为它是这样做的)。它不仅正确地设置了循环长度,而且还将播放头传送到一个“新循环长度”的位置,而不是“旧循环长度”。因此,如果您将16节拍循环更改为12节拍循环,MusicSequence将从0循环到12,但它会将播放头移动到节拍4 (16 - 12 = 4)。它不会从4到16播放,但是从4到12,它们从0循环到12。有时你可以work around this你可以在你玩的时候做这个工作,但大多数情况下这是一种痛苦。最好的解决方案是在更改循环长度时停止播放。CoreMIDI'a MusicSequence不太擅长动态处理变化。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50655994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档