Ios AVAudioPlayerNode-计划缓冲区和段之间的混合
我正在写一个应用程序,我应该播放部分音频文件。每个音频文件包含单独曲目的音频数据。 这些部分是有开始时间和结束时间的部分,我试着按照我选择的顺序播放这些部分 例如,假设我有4个部分: A-B-C-D 我激活B和D,我想玩,B,然后D,然后再B,然后D,等等 为了在播放中实现平滑的“跳跃”,我认为淡入/淡出开始/结束部分很重要 因此,我有一个基本的Ios AVAudioPlayerNode-计划缓冲区和段之间的混合,ios,avaudioengine,avaudioplayernode,Ios,Avaudioengine,Avaudioplayernode,我正在写一个应用程序,我应该播放部分音频文件。每个音频文件包含单独曲目的音频数据。 这些部分是有开始时间和结束时间的部分,我试着按照我选择的顺序播放这些部分 例如,假设我有4个部分: A-B-C-D 我激活B和D,我想玩,B,然后D,然后再B,然后D,等等 为了在播放中实现平滑的“跳跃”,我认为淡入/淡出开始/结束部分很重要 因此,我有一个基本的AVAudioEngine设置,带有AVAudioPlayerNode,还有一个混音器。 对于每个音频部分,我都会缓存一些信息: 部分中第一个样本的缓
AVAudioEngine
设置,带有AVAudioPlayerNode
,还有一个混音器。
对于每个音频部分,我都会缓存一些信息:
- 部分中第一个样本的缓冲区(我手动淡入)
- 中间段的
和AVAudioFramePosition
的元组AVAudioFrameCount
- 音频部分中用于结束采样的缓冲区(我手动淡出)
AVAudioPlayerNode
:
- 计划开始缓冲区(
no选项)scheduleBuffer(uuquo:completionHandler:)
- 计划中间段(
)scheduleSecgment(uu:startingFrame:frameCount:at:completionHandler:)
- 最后,计划结束缓冲区(
no选项)scheduleBuffer(uquo:completionHandler:)
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
的采样率
我为每个音频分区缓存这些信息,但我会听到分区边界的点击,无论我是否提前安排它们。
我也尝试在调度时不混合缓冲区和段,但我没有改变任何东西,所以我开始认为我做了错误的帧计算