I have an issue writing a 2d numpy array as a wave file (audio)
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
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)
I get the following output :
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
as my values are between -4391 and 4389 in 16bits format it should be ok. but my data looks interpreted as ushort
The function needs two parameters - first the file name and second the mode. The mode can be 'wb' for writing audio data or 'rb' for reading. A mode of 'rb' returns a Wave_read object, while a mode of 'wb' returns a Wave_write object. Close the file if it was opened by wave.
The documentation of scipy. io. wavfile. read says that it returns sample rate and data.
The Scipy.io (Input and Output) package provides a wide range of functions to work around with different format of files. Some of these formats are − Matlab. IDL.
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)
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With