You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何指定AVAudioSourceNode的采样率以匹配音频硬件48kHz?

解决AVAudioSourceNode指定48kHz运行速率的问题

这个问题的核心在于AVAudioSourceNode的运行采样率是由初始化时指定的格式决定的,而不是连接节点时的格式参数。你之前用的是无格式参数的初始化方法,系统默认使用了44100Hz的通用格式,才导致采样读取速率和硬件输出不匹配。

下面是具体的解决步骤:

  1. 创建目标48kHz音频格式
    先根据你的采样数组参数(通道数、位深等),创建对应的AVAudioFormat实例。比如你的采样是单声道32位浮点PCM:

    guard let targetFormat = AVAudioFormat(
        standardFormatWithSampleRate: 48000.0,
        channels: 1
    ) else {
        fatalError("无法创建指定的48kHz音频格式")
    }
    
  2. 用指定格式初始化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
    }
    
  3. 连接节点并启动引擎
    后续的附加和连接操作可以直接使用上面创建的目标格式,或者直接调用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

火山引擎 最新活动