首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVAudioPlayerNode lastRenderTime

AVAudioPlayerNode lastRenderTime
EN

Stack Overflow用户
提问于 2017-02-22 08:41:40
回答 1查看 1.5K关注 0票数 23

我在AVAudioEngine中使用多个AVAudioEngine来混合音频文件以进行回放。一旦所有设置完成(引擎准备就绪,启动,音频文件段排定),我将调用每个播放器节点上的play()方法来开始播放。

由于遍历所有player节点需要花费时间,所以我对第一个节点的lastRenderTime值进行了快照,并使用它计算节点play(at:)方法的启动时间,以保持节点之间的同步播放:

代码语言:javascript
复制
let delay = 0.0
let startSampleTime = time.sampleTime     // time is the snapshot value    
let sampleRate = player.outputFormat(forBus: 0).sampleRate
let startTime = AVAudioTime(
        sampleTime: startSampleTime + AVAudioFramePosition(delay * sampleRate),
        atRate: sampleRate)
player.play(at: startTime)

问题在于当前的播放时间.

我使用这个计算来获得值,其中seekTime是我跟踪的值,以防我们寻找播放器。这是刚开始的0.0

代码语言:javascript
复制
private var _currentTime: TimeInterval {
    guard player.engine != nil,
          let lastRenderTime = player.lastRenderTime,
          lastRenderTime.isSampleTimeValid,
          lastRenderTime.isHostTimeValid else {
        return seekTime
    }

    let sampleRate = player.outputFormat(forBus: 0).sampleRate
    let sampleTime = player.playerTime(forNodeTime: lastRenderTime)?.sampleTime ?? 0
    if sampleTime > 0 && sampleRate != 0 {
        return seekTime + (Double(sampleTime) / sampleRate)
    }
    return seekTime
}

虽然这会产生一个相对正确的值,但我可以听到我演奏的时间和我听到的第一个声音之间的延迟。因为一旦我调用了lastRenderTimeplay(at:)就立即开始前进,并且必须有某种处理/缓冲时间偏移。

值得注意的延迟是大约100毫秒,这是非常大的,我需要一个精确的当前时间值来做平行的视觉渲染。

这可能并不重要,但每个音频文件都是AAC音频,我在播放器节点中安排它们的片段,我不直接使用缓冲区。片段的长度可能会变化。我还调用了每个播放器节点的prepare(withFrameCount:),一旦我有预定的音频数据。

所以我的问题是,我观察到的延迟是一个缓冲的问题吗?(我的意思是,我是否应该安排更短的片段),是否有一种方法可以精确地计算这个值,以便调整当前的播放时间计算?

当我在一个AVAudioPlayerNode上安装一个tap块时,用一个长度为4410的缓冲区调用这个块,并且采样率是44100 Hz,这意味着0.1s的音频数据。我应该依赖这个来计算延迟吗?

我想知道我是否可以信任我在tap块中得到的缓冲区的长度。或者,我试图计算我的音频图形的总延迟。有人能提供关于如何精确地确定这个价值的见解吗?

EN

回答 1

Stack Overflow用户

发布于 2021-01-08 04:07:57

类似的孩子在苹果开发者论坛上发表的一篇文章

在系统上,延迟是通过以下方法来衡量的:

音频设备I/O缓冲帧大小+输出安全偏移+输出流延迟+输出设备延迟

如果您试图计算往返总延迟,可以添加:

输入延迟+输入安全偏移到上面。

在呈现过程中看到的时间戳。计算缓冲区帧大小和安全偏移量,但流和设备延迟不计在内。

iOS允许您通过AVAudioSession访问上述最重要的信息,正如前面提到的,您还可以使用“首选”会话设置- setPreferredIOBufferDurationpreferredIOBufferDuration进行进一步控制。

代码语言:javascript
复制
/ The current hardware input latency in seconds. */
@property(readonly) NSTimeInterval inputLatency  NS_AVAILABLE_IOS(6_0);
/ The current hardware output latency in seconds. */
@property(readonly) NSTimeInterval outputLatency  NS_AVAILABLE_IOS(6_0);
/ The current hardware IO buffer duration in seconds. */
@property(readonly) NSTimeInterval IOBufferDuration  NS_AVAILABLE_IOS(6_0);

音频单元还具有可以查询的kAudioUnitProperty_Latency属性。

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

https://stackoverflow.com/questions/42386497

复制
相关文章

相似问题

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