Ios AVAudioPlayerNode-计划缓冲区和段之间的混合

Ios AVAudioPlayerNode-计划缓冲区和段之间的混合,ios,avaudioengine,avaudioplayernode,Ios,Avaudioengine,Avaudioplayernode,我正在写一个应用程序,我应该播放部分音频文件。每个音频文件包含单独曲目的音频数据。 这些部分是有开始时间和结束时间的部分,我试着按照我选择的顺序播放这些部分 例如,假设我有4个部分: A-B-C-D 我激活B和D,我想玩,B,然后D,然后再B,然后D,等等 为了在播放中实现平滑的“跳跃”,我认为淡入/淡出开始/结束部分很重要 因此,我有一个基本的AVAudioEngine设置,带有AVAudioPlayerNode,还有一个混音器。 对于每个音频部分,我都会缓存一些信息: 部分中第一个样本的缓

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

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

A-B-C-D

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

为了在播放中实现平滑的“跳跃”,我认为淡入/淡出开始/结束部分很重要

因此,我有一个基本的
AVAudioEngine
设置,带有
AVAudioPlayerNode
,还有一个混音器。 对于每个音频部分,我都会缓存一些信息:

  • 部分中第一个样本的缓冲区(我手动淡入)
  • 中间段的
    AVAudioFramePosition
    AVAudioFrameCount
    的元组
  • 音频部分中用于结束采样的缓冲区(我手动淡出)
现在,当我安排播放一节时,我会说
AVAudioPlayerNode

  • 计划开始缓冲区(
    scheduleBuffer(uuquo:completionHandler:)
    no选项)
  • 计划中间段(
    scheduleSecgment(uu:startingFrame:frameCount:at:completionHandler:)
  • 最后,计划结束缓冲区(
    scheduleBuffer(uquo:completionHandler:)
    no选项)
全部在“时间”
nil

这里的问题是我能听到clic和音频部分边界的糟糕声音,我看不出哪里做错了。 我的第一个想法是手动淡入淡出(基本上是将采样值乘以体积因子),但不这样做的结果相同。 我以为我没有及时安排,但提前安排部分,例如A-B-C,也有同样的结果。 然后我尝试了不同的帧位置计算,使用音频格式设置,结果相同

所以我在这里没有主意了,也许我没有把时间表安排好

有人能确认我可以在
AVAudioPlayerNode
中混合调度缓冲区和段吗?或者我应该只调度缓冲区或段吗? 我可以确认,只安排片段工作,播放是完全好的

关于我如何缓存音频部分信息的一点背景。。 在下面的代码中,
文件
属于从
URL
加载到磁盘上的
AVAudioFile
类型,
开始
结束
时间间隔
值,代表我的音频部分的开始/结束

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
的采样率

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