scipy.io : 不能写 wavfile [英] scipy.io : can't write wavfile

查看:65
本文介绍了scipy.io : 不能写 wavfile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将 2d numpy 数组写入波形文件(音频)时遇到问题

I have an issue writing a 2d numpy array as a wave file (audio)

根据文档,我应该编写一个 2d int16 numpy 数组

According to the doc I should write a 2d int16 numpy array

https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.io.wavfile.write.html

16-bit PCM  -32768  +32767  int16

作为 float32 格式的范围 (-1,1) 中的 numpy 数组,我首先将其转换为 16 位 int

As my numpy array in range (-1,1) in float32 format I first convert it to 16 bits int

stereoAudio = ((stereoAudio * bits16max)).astype('int16')

print "argmax : " + str(np.amax(stereoAudio))
print "argmin : " + str(np.amin(stereoAudio))

outWaveFileName = "out/file.wav"
print "writing " + outWaveFileName
wavfile.write(outWaveFileName,44100,stereoAudio)

我得到以下输出:

argmax : 4389
argmin : -4381
writing out/file.wav
Traceback (most recent call last):
  File "/Users/me/file.py", line 132, in <module>
wavfile.write(outWaveFileName,44100,stereoAudio)
  File "//anaconda/lib/python2.7/site-packages/scipy/io/wavfile.py", line 353, in write
    bytes_per_second, block_align, bit_depth)
error: ushort format requires 0 <= number <= USHRT_MAX

因为我的值在 16 位格式的 -4391 和 4389 之间,所以应该没问题.但我的数据看起来被解释为 ushort

as my values are between -4391 and 4389 in 16bits format it should be ok. but my data looks interpreted as ushort

推荐答案

write scipy.io.wavfile 函数期望输入数组具有 (num_samples, num_channels).我怀疑您的数组具有 (num_channels, num_samples) 形状.然后 write 尝试将 num_samples 放在写入 WAV 文件的结构中的 16 位字段中,但是 num_samples 的值太高了对于 16 位值来说很大.(请注意,如果 num_samples 足够小,则不会出现错误,但文件的格式将不正确.)

The write function in scipy.io.wavfile expects the input array to have the shape (num_samples, num_channels). I suspect your array has shape (num_channels, num_samples). Then write tries to put num_samples in a 16 bit field in a structure that gets written to the WAV file, but the value of num_samples is too big for a 16 bit value. (Note that if num_samples were small enough, you would not get an error, but the file would not have the correct format.)

快速解决方法是编写数组的转置:

A quick fix is to write the transpose of your array:

wavfile.write(outWaveFileName, 44100, stereoAudio.T)

例如,这里是一些演示错误的代码;xy 的形状为 (2, 40000):

For example, here is some code that demonstrates the error; x and y have shape (2, 40000):

In [12]: x = (2*np.random.rand(2, 40000) - 1).astype(np.float32)

In [13]: y = (x*32767).astype('int16')

In [14]: from scipy.io import wavfile

In [15]: wavfile.write('foo.wav', 44100, y)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-15-36b8cd0e729c> in <module>()
----> 1 wavfile.write('foo.wav', 44100, y)

/Users/warren/anaconda/lib/python2.7/site-packages/scipy/io/wavfile.pyc in write(filename, rate, data)
    351 
    352         fmt_chunk_data = struct.pack('<HHIIHH', format_tag, channels, fs,
--> 353                                      bytes_per_second, block_align, bit_depth)
    354         if not (dkind == 'i' or dkind == 'u'):
    355             # add cbSize field for non-PCM files

error: ushort format requires 0 <= number <= USHRT_MAX

转置数组,使 wavfile.write 的输入具有预期的形状:

Transpose the array so the input to wavfile.write has the expected shape:

In [16]: wavfile.write('foo.wav', 44100, y.T)

回读数据以验证它是否按预期工作:

Read back the data to verify that it worked as expected:

In [22]: fs, z = wavfile.read('foo.wav')

In [23]: np.allclose(z, y.T)
Out[23]: True

这篇关于scipy.io : 不能写 wavfile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆