AVAudioPlayerNode - 在计划缓冲区和段

时间:2017-03-31 07:07:47

标签: ios avaudioengine avaudioplayernode

我正在编写一个我应该播放部分音频文件的应用程序。每个音频文件包含单独轨道的音频数据。 这些部分是包含开始时间和结束时间的部分,我尝试按照我选择的顺序播放这些部分。

例如,假设我有4个部分:

A - B - C - D

我激活B和D,我想玩,B,然后D,然后B再次,然后D,等等。

顺利跳跃"在回放中我认为淡入/淡出开始/结束部分缓冲区非常重要。

所以,我有一个基本的AVAudioEngine设置,AVAudioPlayerNode和一个调音台。 对于每个音频部分,我缓存一些信息:

  • 该部分中第一个样本的缓冲区(我手动淡入)
  • AVAudioFramePosition的元组和中段的AVAudioFrameCount元组
  • 音频部分中的最终样本的缓冲区(我手动淡出)

现在,当我安排一个部分进行游戏时,我会说AVAudioPlayerNode

  • 安排启动缓冲区(scheduleBuffer(_:completionHandler:)无选项)
  • 安排中段(scheduleSegment(_:startingFrame:frameCount:at:completionHandler:)
  • 最后安排结束缓冲区(scheduleBuffer(_:completionHandler:)无选项)

所有在"时间" nil

这里的问题是我可以听到声音部分界限处的声音和蹩脚的声音,我无法看到我做错的地方。 我的第一个想法是我手动淡化(基本上将样本值乘以体积因子),但不这样做的结果相同。 我以为我没有及时安排,但事先安排部分,例如A - B - C预先有相同的结果。 然后,我尝试了不同的帧位置计算,音频格式设置,结果相同。

所以我在这里没有想法,也许我没有正确的计划机制。

任何人都可以确认我可以在AVAudioPlayerNode中混合调度缓冲区和段吗?或者我应该只安排缓冲区或段? 我可以确认只安排分段工作,播放完全没问题。

关于如何缓存音频部分信息的一些背景信息.. 在下面的代码中,从fileAVAudioFileURL begin值加载到磁盘上的end类型为TimeInterval,并代表我的音频部分的开头/结尾。

let format = file.processingFormat

let startBufferFrameCount: AVAudioFrameCount = 4096
let endBufferFrameCount: AVAudioFrameCount = 4096

let audioSectionStartFrame = framePosition(at: begin, format: format)
let audioSectionEndFrame = framePosition(at: end, format: format)

let segmentStartFrame = audioSectionStartFrame + AVAudioFramePosition(startBufferFrameCount)
let segmentEndFrame = audioSectionEndFrame - AVAudioFramePosition(endBufferFrameCount)

startBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: startBufferFrameCount)
endBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: endBufferFrameCount)

file.framePosition = audioSectionStartFrame
try file.read(into: startBuffer)

file.framePosition = segmentEndFrame
try file.read(into: endBuffer)

middleSegment = (segmentStartFrame, AVAudioFrameCount(segmentEndFrame - segmentStartFrame))
frameCount = AVAudioFrameCount(audioSectionEndFrame - audioSectionStartFrame)

此外,framePosition(at:format:)TimeInterval值乘以传入的AVAudioFormat的采样率。

我为每个音频部分缓存此信息,但无论是否提前安排,我都会听到部分边界的点击。 我还尝试在调度时不要混用缓冲区和段,但我没有改变任何东西,所以我开始认为我做错了帧计算。

0 个答案:

没有答案