AudioKit是否提供高精度计时器?

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

AudioKit是否提供high precision timer?我查看并发现了有关AKSheduledAction的信息,它基于Timer,并且似乎是唯一的默认选项:

https://github.com/AudioKit/Playgrounds/blob/master/iPad/AudioKit.playgroundbook/Contents/Modules/AudioKit.playgroundmodule/Internals/AKScheduledAction.swift

或者,对于Timer的用法,我写了一个在scheduler中运行的audio thread(*没看到波纹管),如果有错,请纠正我。我已经测试过了,它不是很精确,因为产生的时差会有所不同:

func schedule(timeOut: Double, onComplete: @escaping () -> Void) -> Void {
    do {
        let file = try AKAudioFile.silent(samples: Int64(defaultSampleRate * timeOut))
        let audioPlayer = try AKAudioPlayer(file: file)
        audioPlayer >>> self.mainMixer
        audioPlayer.completionHandler = {
            onComplete()
        }
        audioPlayer.play()
    } catch {
        print(error.localizedDescription)
    }
}

输出:

elapsedTime 4.715054468018934
elapsedTime 4.712334129028022
elapsedTime 4.71259418700356
elapsedTime 4.712263747991528

该测试通过以下方法在主线程中运行:

func test() {
    let info = ProcessInfo.processInfo
    let begin = info.systemUptime
    self.schedule(timeOut: 4.666667) {
        let elapsedTime = info.systemUptime - begin
        print("elapsedTime \(elapsedTime)")
    }
}

我将对.completionHandler的含义进行更多研究,但我首先假设为AVAudioPlayerNode.scheduleBuffer

AVAudioPlayerNode.scheduleBuffer(AVAudioPCMBuffer, at: nil, options: .interruptsAtLoop, completionHandler: nil)

查看completionHandler的源,即AKCallback,我们可以看到它在主线程(https://github.com/AudioKit/AudioKit/blob/master/AudioKit/Common/Nodes/Playback/Players/AKAudioPlayer.swift#L692)中运行:

/// Triggered when the player reaches the end of its playing range
fileprivate func internalCompletionHandler() {
    DispatchQueue.main.async {
        if self.isPlaying {
            self.stop()
            self.completionHandler?()
        }
    }
}

所以,我将尝试使用AVAudioPlayerNode.scheduleBuffer重写它,希望会有所帮助。

Ref:

https://developer.apple.com/documentation/foundation/timerhttps://developer.apple.com/library/archive/technotes/tn2169/_index.html

audiokit
1个回答
0
投票

我已经完成研究,很遗憾没有找到关于提供精确计时器的方法的太多信息。

我发现的最佳结果是基于以下技术,迄今为止,该技术保持了最佳结果*,audioFile的长度为4.666667

    let info = ProcessInfo.processInfo
    let begin = info.systemUptime
    self.audioBufferPlayerNode.scheduleBuffer(self.file.pcmBuffer, at: nil, options: .interruptsAtLoop, completionHandler: {
        let elapsedTime = info.systemUptime - begin
        print("elapsedTime \(elapsedTime)")
    })
    self.audioBufferPlayerNode.play()

输出:

elapsedTime 4.691985241952352
elapsedTime 4.662765832967125
elapsedTime 4.664656096952967
elapsedTime 4.664366245968267
elapsedTime 4.666537321987562
elapsedTime 4.666480115964077
elapsedTime 4.659072204027325
elapsedTime 4.665851002908312

[请记住,您需要计算AVAudioPlayerNode的初始化过程,并在通话时间之前将其连接到mixer,否则,如果您在一次通话中进行全部计算,则会得到:

elapsedTime 4.701177543029189
elapsedTime 4.7050989009439945
elapsedTime 4.702830816968344
elapsedTime 4.695075194002129
elapsedTime 4.708125164033845
elapsedTime 4.700082497904077
elapsedTime 4.695926539017819
elapsedTime 4.711938992026262

希望这对以后的人有所帮助!

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