【问题标题】:convert numpy int16 audio array to float32将 numpy int16 音频数组转换为 float32
【发布时间】:2017-07-21 13:02:59
【问题描述】:

我有原始二进制 int16 数据,我正在使用

将其转换为 numpy 数组

audio = np.fromstring(raw_data, dtype=np.int16)

数据是音频数据。当我将数据转换为 float32 时,音频会失真:

audio = audio.astype(np.float32, order='C')

我正在将音频保存到磁盘以使用 SoundFile 收听:

soundfile.write('out.wav', audio, sample_rate)

如果我直接将音频写入磁盘而不执行astype操作,则不会失真(即);

# no distortion
audio = np.fromstring(raw_data, dtype=np.int16)
soundfile.write('out.wav', audio, sample_rate)

# distortion
audio = np.fromstring(raw_data, dtype=np.int16)
audio = audio.astype(np.float32, order='C')
soundfile.write('out.wav', audio, sample_rate)

这里转换数据类型的正确方法是什么?

【问题讨论】:

    标签: python numpy audio


    【解决方案1】:

    按照惯例,浮点音频数据被标准化为 [-1.0,1.0] 的范围,您可以通过缩放来做到这一点:

    audio = audio.astype(np.float32, order='C') / 32768.0
    

    这可能会为您解决问题,但您需要确保 soundfile.write 写入指示 float32 的 wav 标头。它可能会根据数组的 dtype 自动执行此操作。

    【讨论】:

    • 带符号的int范围从-32768到32767。我们不必在转换过程中以某种方式平衡范围吗?或者我们可以假设 0 是真正的零并且有符号的 int 表示只是不平衡的(可以表示 -32768 但不能表示 32767)?
    • @fodma1。是的,0 是中心。我从不写出带有 -32768 的文件,但是在阅读时我不喜欢假设其他人没有,因此 /32768.0.只有0.00026 dB的差异,不值得有溢出的机会。
    • 这个方法有两个证明:1) FFmpeg source: s->scale = 1. / (1 << (avctx->bits_per_coded_sample - 1)); 2) soundfile test: numpy.array_equal(soundfile.read('file.wav', dtype='int16')[0] / 32768, soundfile.read('file.wav', dtype='float32')[0])
    猜你喜欢
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2023-03-11
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    相关资源
    最近更新 更多