如何使用scipy或常用替代方法读取和写入24位wav文件?

时间:2013-05-23 16:42:39

标签: python audio numpy scipy wav

通常,wav文件是或者需要24位,但我没有看到使用scipy模块写入或读取24位wav文件的方法。 wavfile.write()的文档指出wav文件的分辨率由数据类型决定。这必须意味着不支持24位,因为我不知道24位整数数据类型。如果需要替代方案,那么如果它很常见就可以很容易地交换文件,而不需要其他人用scipy安装额外的模块。

import numpy as np
import scipy.io.wavfile as wavfile

fs=48000
t=1
nc=2
nbits=24
x = np.random.rand(t*fs,nc) * 2 - 1
wavfile.write('white.wav', fs, (x*(2**(nbits-1)-1)).astype(np.int32))

2 个答案:

答案 0 :(得分:3)

使用PySoundFile

非常容易
import soundfile as sf

x = ...
fs = ...

sf.write('white.wav', x, fs, subtype='PCM_24')

从浮点到PCM的转换是自动完成的。

另见my other answer

更新:

在PySoundFile版本0.8.0中,sf.write()的参数顺序已更改。 现在文件名首先出现,数据数组是第二个参数。我在上面的示例中对此进行了更改。

答案 1 :(得分:0)

我也遇到过这个问题。我有一个包含所有32位带符号样本的缓冲区,而在每个样本中,只使用24位(最高8位是0填充,即使数字为负)。我的解决方案是:

    samples_4byte = self.buffer.tobytes()
    byte_format = ('%ds %dx ' % (3, 1)) * self.sample_len * 2
    samples_3byte = b''.join(struct.unpack(byte_format, samples_4byte))

现在我有一个可以写入wave文件的bytearray:

with wave.open(file_abs, 'wb') as wav_file:
        # Set the number of channels
        wav_file.setnchannels(2)
        # Set the sample width to 3 bytes
        wav_file.setsampwidth(3)
        # Set the frame rate to sample_rate
        wav_file.setframerate(self.sample_rate)
        # Set the number of frames to sample_len
        wav_file.setnframes(self.sample_len)
        # Set the compression type and description
        wav_file.setcomptype('NONE', "not compressed")
        # Write data
        wav_file.writeframes(samples_3byte)