wavfile.write:相同的数组,但只有一个工作

时间:2018-05-20 03:04:37

标签: python audio fft wav

我有两个完全相同的阵列(设计因为我通过FFT然后对第一个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)

我得到True,这意味着两个数组是相同的。唯一的区别是,有一个" 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 个答案:

答案 0 :(得分:2)

那只"唯一的区别"是一个巨大的差异。

默认情况下,

The WAV format将样本存储为带符号的little-endian 16位整数。因此,当您将int16值数组作为原始数据写入时,您将获得可播放的WAV文件(至少在小端系统上)。

但是当你写一个int32值的数组时,你会得到无意义的 - 每个数字变成2个样本,其中一个是数据的高位字,下一个是低位字。因此,您可以以半速获取原始音频样本,并与有效随机噪声交错。

或者,您也可以使用非默认的WAV格式。你没有显示足够的代码来展示你如何处理它,但你可以用各种不同的格式编写WAV文件,从8位无符号整数到32位浮点数,32-位签名的int是有效的格式。 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)