代码之家  ›  专栏  ›  技术社区  ›  Rohit Pandey

wavfile。写入:相同的数组,但只有一个有效

  •  1
  • Rohit Pandey  · 技术社区  · 6 年前

    我有两个相同的阵列(通过设计,因为我通过FFT获得了第二个阵列,然后对第一个阵列进行逆FFT)。然而,当我写第一封信给。wav文件,我得到的是声音产生文件,而不是第二个文件。我听不到声音。这是我的代码:

    fs, data = wavfile.read(filename)
    a = data.T[0]
    c = fft(a)
    y2 = fftp.ifft(c)
    y2 = np.array([int(round(i)) for i in y2.real])
    

    现在当我尝试:

    sum(y2==a)==len(a)
    

    我明白了,这意味着这两个数组是相同的。唯一的区别是其中一个有“dtype=int16”:

    In [322]: a
    Out[322]: array([ 1,  1,  1, ..., 21, 20, 21], dtype=int16)
    In [321]: y2
    Out[321]: array([ 1,  1,  1, ..., 21, 20, 21])
    

    如何将第二个数组转换为生成有效数组的格式。还有wav文件吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   abarnert    6 年前

    “唯一的不同”是一个巨大的不同。

    The WAV format 默认情况下,将样本存储为带符号的小端16位整数。所以,当你写一个数组 int16 值作为原始数据,您将得到一个可播放的WAV文件(至少在一个小的endian系统上)。

    但是当你写一个数组 int32 值,则每个数字都会变成两个样本,其中一个是数据的高位字,下一个是低位字。所以,你已经以半速度获得了原始音频样本,并与有效的随机噪声交织。


    或者,也可以使用非默认WAV格式。你没有展示足够的代码来展示你是如何处理这个问题的,但是你可以用各种不同的格式编写WAV文件,从8位无符号整数到32位浮点,32位有符号整数是一种有效的格式。WAV文件甚至可以处理压缩(包括MP3)。

    但不太常见的格式可能并不适用于所有工具;许多程序假定WAV是16位整数,不知道如何处理其他任何东西。

    所以,你最好写16位整数。


    或者,也许你已经在用正确的头写32位int值了,也许你的播放器处理得很好。

    但是你写的是-32768和32767之间的32位int值。这意味着你只使用了动态范围的1/65536,所以一切都会非常安静。如果要写入32位int值,则需要将其规格化为32位int范围,而不是16位int范围。


    所有这些问题的最简单解决方案是:将值转换回 int16 在写之前:

    y3 = y2.astype(np.int16)