重新创建网络音频 API GainNode 行为

Recreating Web Audio API GainNode behaviour

我正在叠加一堆音频片段,并希望能够将 (1, 1, 1, 0.5, 0...) 形式的值元组传递给我的函数,每个数字都是段的体积应缩放到的比率。 0 应该是绝对静音,而 1 应该是未修改的原始音量,而 0.5 正好是一半。据我了解,这是 the behavior of the GainNode "gain" property.

到目前为止我试过这些:

def adjust_volume(audio_segment, ratio):
    decibel = pydub.utils.ratio_to_db(audio_segment.rms)
    return audio_segment - decibel * (1 - ratio)

SILENCE_THRESHOLD = -120.00
def adjust_volume(audio_segment, ratio):
    difference = SILENCE_THRESHOLD - audio_segment.dBFS
    return audio_segment + (difference - (difference * ratio))

不幸的是,两者都无法正常工作,这意味着它们无法完全复制浏览器 (Mozilla Firefox) 的行为。使用第一个,即使我传入仅包含 0 的元组,也可以通过我的音频播放器 (foobar2000) 听到声音,而第二个使用正确的静音阈值设法使整个片段静音,例如使用 0.3 创建音频比我在浏览器中使用相同值观察到的级别低得多。

请注意,我的音频技术知识非常有限。这些仅仅是由不同的音频设备、音频实现细节等造成的技术错误吗?如果是这样的话,有人可以建议我最 "correct" 的缩放方法吗?

我的第一个问题是 0.5 到底是什么意思。声音的响度是对数的(每次你将信号的振幅、高度加倍,它听起来的音量就相等)

也就是说,简单的0.5是不是把振幅减半了?如果是这样,那会安静大约 6dB(我想!我总是混淆振幅和功率计算哈哈)。 OR 是静音和最大响度之间的 0.5 中间值?

无论如何,如果你想在 pydub 中保持静音,将音量降低 120dB 就可以了。人类能听到的最大动态范围是140dB,但CD音频(16位)大约是90dB。

pydub 提供了两个卷之间的淡入淡出以及仅应用增益的辅助函数:

from pydub import AudioSegment
from pydub.utils import ratio_to_db, db_to_float

sound = AudioSegment.from_file('/your/file.wav')

# this is roughly -6.0
half_amplitude_in_db = ratio_to_db(0.5)

# these are all roughly the same result
half_amplitude1 = sound.apply_gain(half_amplitude_in_db)
half_amplitude2 = sound.apply_gain(-6.0)
half_amplitude3 = sound - 6.0

# Assuming 16-bit sound, that’s ~90dB dynamic range.
# so -45dB is half way to silent.
# Note: that is A LOT quieter
half_way_to_silent = sound - 45.0

希望这对您有所帮助。

注意:查看规范我认为您需要这样做:

web_API_gain_value = 0.5

gain_in_db = ratio_to_db(web_API_gain_value)

sound_after_gain = sound.apply_gain(gain_in_db)