如何指定AVAudioSourceNode的采样率以匹配音频硬件48kHz?
解决AVAudioSourceNode指定48kHz运行速率的问题
这个问题的核心在于AVAudioSourceNode的运行采样率是由初始化时指定的格式决定的,而不是连接节点时的格式参数。你之前用的是无格式参数的初始化方法,系统默认使用了44100Hz的通用格式,才导致采样读取速率和硬件输出不匹配。
下面是具体的解决步骤:
创建目标48kHz音频格式
先根据你的采样数组参数(通道数、位深等),创建对应的AVAudioFormat实例。比如你的采样是单声道32位浮点PCM:guard let targetFormat = AVAudioFormat( standardFormatWithSampleRate: 48000.0, channels: 1 ) else { fatalError("无法创建指定的48kHz音频格式") }用指定格式初始化AVAudioSourceNode
使用带format参数的初始化方法创建SourceNode,这样它就会以48kHz的速率运行:let srcNode = AVAudioSourceNode(format: targetFormat) { _, timeStamp, frameCount, audioBufferList -> OSStatus in let ablPointer = UnsafeMutableAudioBufferListPointer(audioBufferList) // 在这里填充你的48kHz采样数据 // 示例逻辑(根据你的实际采样数组调整): for buffer in ablPointer { let samples = buffer.mAudioData.assumingMemoryBound(to: Float.self) // 将预先生成的48kHz采样数组复制到samples中,注意frameCount的限制 // ... 你的采样填充代码 ... } return noErr }连接节点并启动引擎
后续的附加和连接操作可以直接使用上面创建的目标格式,或者直接调用SourceNode的输出格式:let engine = AVAudioEngine() engine.attach(srcNode) engine.connect(srcNode, to: engine.mainMixerNode, format: targetFormat) do { try engine.start() } catch { print("引擎启动失败:\(error.localizedDescription)") }
关键说明
- 初始化时指定的
format参数直接决定了SourceNode内部的运行采样率,这样它读取你预先生成的48kHz采样时,速率就和硬件输出一致,不会出现播放时长被拉伸的问题。 - 连接节点时的
format参数仅用于定义两个节点之间的音频转换格式,不会改变SourceNode自身的运行速率,这也是你之前修改connect格式无效的原因。 - 确保你的预生成采样数组的格式(采样率、通道数、数据类型)和
targetFormat完全匹配,否则填充采样时会出现音频失真或错误。
内容的提问来源于stack exchange,提问作者samp17




