我有两个完全相同的阵列(设计因为我通过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文件的格式?
答案 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)