pythonnumpypython-sounddevice

Python np array converted to list and back isn't the same


I made a voice recorder using python-sounddevice module but records are NumPy arrays so I convert them to lists and then back but it doesn't work:

import sounddevice as sd, numpy as np, scipy.io.wavfile as wavf
fs = 48000
sd.default.samplerate = fs
sd.default.channels = 2
r = sd.rec(2*fs)
sd.wait()

wavf.write("C:\\...\\r.wav", fs, r) # works
wavf.write("C:\\...\\r2.wav", fs, np.array(r.tolist())) # doesn't work

Solution

  • By default numpy.array creates an array of 64-bit floats (numpy.float64), however WAVE file format was not designed for 32-bit floats.

    You could use something like:

    np.array(r.tolist(), dtype=np.float32)
    

    Originally as of Multimedia Multimedia Programming Interface and Data Specifications 1.0 (1991), WAVE files supported only a handful of data formats, the one that was widely used was Microsoft Pulse Code Modulation (PCM) 16-bit fixed point encoding. The data points were represented as integers.

    In 1994 with New Multimedia Data Types and Data Techniques many new formats were introduced but still no floating point codecs were officially registered. Few years later in 1998 RFC 2361 already listed Wave Format 0x0003 (IEEE:float) though without implementation details.

    At present most audio players support 32-bit floating point sample encoding, yet very few support 64-bit floating point samples. Encoders such as ffmpeg or players such as MPlayer support 64-bit PCM encoding and should be able to convert and play your r2.wav without any modification.