如何提升AVAudioPCMBuffer生成音频的分贝等级?
调整AVAudioPCMBuffer音频分贝的方法
要提升或调整音频缓冲区的分贝等级,核心是理解分贝(dBFS,全刻度分贝)与音频样本振幅的数学关系,再结合你的代码实现动态计算。
核心原理
dBFS是音频领域描述数字音量的标准,以满刻度(样本值最大为1.0)为0dBFS基准,两者的换算公式为:
振幅 = 10^(dBFS / 20)
举几个对应关系:
- 0dBFS(最大无失真音量)→ 振幅1.0
- -6dBFS → 振幅0.5
- -12dBFS(你当前默认值)→ 振幅0.25
- -20dBFS → 振幅0.1
超过0dBFS的振幅会导致音频削波(失真),所以必须限制dBFS不大于0。
代码修改实现
你可以直接新增dbFS属性来控制分贝,替代原有的amplitude变量(或让amplitude由dbFS驱动),以下是修改后的完整代码:
import Foundation import AVFoundation class AVTonePlayerUnit: AVAudioPlayerNode { let bufferCapacity: AVAudioFrameCount = 512 let sampleRate: Double = 44_100.0 var frequency: Double = 440.0 // 新增dBFS属性,默认-12dBFS(对应原振幅0.25) var dbFS: Double = -12.0 { didSet { // 限制合法范围:0dBFS为最大无失真值,-96dBFS接近静音 dbFS = max(min(dbFS, 0.0), -96.0) } } private var theta: Double = 0.0 private var audioFormat: AVAudioFormat! override init() { super.init() audioFormat = AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: 1) } func prepareBuffer() -> AVAudioPCMBuffer { let buffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: bufferCapacity)! fillBuffer(buffer) return buffer } func fillBuffer(_ buffer: AVAudioPCMBuffer) { guard let data = buffer.floatChannelData?[0] else { return } let numberFrames = buffer.frameCapacity var theta = self.theta let theta_increment = 2.0 * .pi * self.frequency / self.sampleRate // 根据当前dBFS计算对应的振幅 let amplitude = pow(10, dbFS / 20) for frame in 0..<Int(numberFrames) { data[frame] = Float32(sin(theta) * amplitude) theta += theta_increment if theta > 2.0 * .pi { theta -= 2.0 * .pi } } buffer.frameLength = numberFrames self.theta = theta } func scheduleBuffer() { let buffer = prepareBuffer() self.scheduleBuffer(buffer) { if self.isPlaying { self.scheduleBuffer() } } } func preparePlaying() { scheduleBuffer() scheduleBuffer() scheduleBuffer() scheduleBuffer() } }
使用方式
直接设置dbFS值即可调整音量:
- 要设置最大无失真音量:
player.dbFS = 0.0 - 要提升到-6dBFS(比原音量大1倍):
player.dbFS = -6.0 - 要降低到-20dBFS:
player.dbFS = -20.0
内容的提问来源于stack exchange,提问作者Sudeep P H
相关产品推荐
相关产品推荐

