首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用重复随机结果调用AKSequencer中的随机AKSequencer

用重复随机结果调用AKSequencer中的随机AKSequencer
EN

Stack Overflow用户
提问于 2018-09-13 23:39:14
回答 1查看 77关注 0票数 0

这是一个多音频播放项目,我目前正在工作,其中多个AKPlayers随机播放顺序,通过AKSequencer。

首先,我有一个文件名数组:

代码语言:javascript
复制
Let filenames = [“1.mp3”, “2.mp3, “3.mp3”, … “10.mp3”]

这将单独加载到AKPlayer上,以便稍后以随机顺序调用它:

代码语言:javascript
复制
Let players: [AKPlayer] = {
    Do {
        Let filenames = [“1.mp3”, “2.mp3, “3.mp3”, … “10.mp3”]
        Return try filenames.map { AKPlayer(audioFile: try AKAudioFile(readRileName: $0)) }
    } catch {
        fatalError()
    }
}()

然后,通过AKsequencer调用AKsequencer,通过‘playRandom’函数触发它:

代码语言:javascript
复制
Let sequencer = AKSequencer()
Let callbackInst = AKCallbackInstrument()

func playRandom() {
    let playerIndex = Int(arc4random_uniform(UInt32(players.count)))
    players[playerIndex].play()
}

func addTracks() {
    let track = sequencer.newTrack()!
    track.add(noteNumber: 48, velocity: 127, position: AKDuration(beats: 0), duration: AKDuration(beats: 16), channel: 0)
    track.setMIDIOutput(callbackInst.midiIn)
    callbackInst.callback = { status, note, vel in
        guard status == .noteOn else { return }
        self.playRandom()
        }
    }

最后,我将AKPlayer设置为AudioKit.output,并启动了排序器。到目前为止,这是成功的!排序器按随机顺序无缝地播放AKPlayer。

但我想尝试不同的随机性:重复随机选择的播放器2或3次。(如2,2,3,3,3,1,1,5,5,5,5,9,9,…)现在,‘playRandom’只是在每个重复中选择不同的AKPlayer。

作为一种解决方案,多亏了StackOverFlow母版,我尝试了这样的方法:

代码语言:javascript
复制
class RandomWithRepeats {
var range: ClosedRange<Int>
var repeatRange: ClosedRange<Int>
var repeatCount = 0
var value = 0

init(range: ClosedRange<Int>, repeatRange: ClosedRange<Int>) {
    self.range = range
    self.repeatRange = repeatRange
}

// generate a random number in a range
// Just use Int.random(in:) with Swift 4.2 and later
func random(in range: ClosedRange<Int>) -> Int {
    return Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound + 1))) + range.lowerBound
}

func nextValue() -> Int {
    // if repeatCount is 0, its time to generate a new value and
    // a new repeatCount
    if repeatCount == 0 {
        // For Swift 4.2, just use Int.random(in:) instead
        value = self.random(in: range)
        repeatCount = self.random(in: repeatRange)
    }

    repeatCount -= 1
    return value
}
}

然后我对playRandom函数进行了如下修改:

代码语言:javascript
复制
func playRandom() {
    Let rand = randomWithRepeats(range: 1…players.count, repeatRange: 2…3)
    Do { players[rand.nextValue()].play() }
}

结果是,这是完全相同的结果,因为playRandom函数本身(由AKSequencer触发)每个重复,因此它实际上不会‘重复’随机AKPlayer 2或3次。我能用不同的方式解决这个问题吗?非常感谢。<3

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-14 00:31:09

RandomWithRepeats类的任务是跟踪何时传递不同的AKPlayer实例,但是每次调用playRandom()时都要创建RandomWithRepeats的新实例,因此它无法跟踪任何内容。

在创建播放机数组并在RandomWithRepeats方法中使用此实例时,创建一个playRandom()实例。

代码语言:javascript
复制
let rand = RandomWithRepeats(range: 0 ... players.count, repeatRange: 2 ... 3)

func playRandom() {
     try? players[rand.nextValue()].play() 
}

为了获得更清晰的解决方案,您可以将RandomWithRepeats的逻辑与AKPlayer数组封装到一个类中,例如RandomlyRepeatingPlayer类。

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

https://stackoverflow.com/questions/52323117

复制
相关文章

相似问题

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