AudioKit AKPlayer 无法回环到 setPosition 开头

问题描述 投票:0回答:2

在 v4 中,如果您将

AKPlayer
与循环一起使用并使用
setPosition
API,则播放器会在
setPosition
设置的位置和播放器总持续时间之间循环。我需要的是从
setPosition
API 设置的位置开始,并在循环发生时循环到开头。我不确定这是否是有意的,但我需要能够找到播放器中的某个点并循环到开头,目前看来这不是 AudioKit 中的功能。 有没有办法或解决方法来实现这一目标?我需要按照要求完成此任务。 此处重现的是一个完整的游乐场示例:

import AudioKitPlaygrounds
import AudioKit

let file = try AKAudioFile(readFileName: "3.aac")

//: Set up a player to the loop the file's playback
var player = AKPlayer(audioFile: file)
player.isLooping = true
player.buffering = .always

AKManager.output = player
try AKManager.start()


player.setPosition(player.duration - 2)
player.play(at: AVAudioTime.now())
// player loops between player.duration - 2, player.duration  forever. I want it to loop between 0, player.duration

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

预期行为 我预计它会回到开头。

详情:

  • AudioKit 版本 4.11.2
ios audiokit
2个回答
2
投票

如果您打算开发某种循环应用程序,我认为方法是使用音序器来协调音频文件的播放。在声音应开始播放的每个位置,您都可以向序列中添加一个事件。

定序器可以连接到回调工具,回调工具是将事件传递给用户定义函数的节点。在回调函数中,您将开始播放该事件指示的音频文件。

这是应该做什么的概述:

  1. 使用 AKSequenceraddTrack 方法创建一个轨道来包含播放事件。将此轨道连接到AKCallbackInstrument。请参阅此答案,了解如何将 AKCallbackInstrument 连接到 AKSequencer 轨道。将音序器和曲目的
    length
    设置为歌曲的总持续时间(请注意,这些属性以节拍而不是秒表示)。根据需要设置音序器的
    loopEnabled
  2. 将播放事件添加到轨道中您希望每个声音播放的时间位置。由于您将使用回调函数自己解释事件,因此使用什么类型的事件并不重要。您可以简单地使用
    Note On
  3. 在回调函数中,收到该事件时开始播放相应的声音。

您需要几个类来表示有关每个样本在歌曲中出现位置的一些基本信息:

class Beat {
    var sample: Sample!
    var onsetTime: Double

    var endTime {
        get {
            return onsetTime + sample.duration
        }
    }
}

class Sample {
    var url: URL!
    var duration: Double
}

class ViewController: UIViewController {
    var samples: [Sample] = []
    var beats: [Beat] = []

    var player: AKPlayer!
    var sequencer: AKSequencer!
}

在音符的音高上,您可以存储要播放的样本的索引。这就是你的回调函数的样子:

func playCallback(status:UInt8, note:MIDINoteNumber, vel:MIDIVelocity) -> () {
    guard let status = AKMIDIStatus(byte: status),
        let type = status.type,
        type == .noteOn else { return }
    DispatchQueue.main.async {
        player.load(samples[note].url)
        player.play()
    }
}

您可以使用

AKSequencer
seek
方法在任意位置开始播放歌曲。

有一种特殊情况,音序器在节拍中间开始播放。在这种情况下,您必须手动开始播放该样本。

func play(at time: Double = 0) {
    sequencer.seek(time)
    sequencer.play()
    for beat in beats {
        if beat.onsetTime < time && time < beat.endTime {
            player.load(beat.sample.url)
            player.play(from: time - beat.onsetTime)
        }
    }
}

0
投票

AKPlayer 还能用吗?看起来它已从 AudioKit 中删除。

© www.soinside.com 2019 - 2024. All rights reserved.