soundfile
module¶There are many libraries for handling audio files with Python (see overview page), but the best one is probably the soundfile module.
Full documentation including installation instructions is available at http://pysoundfile.readthedocs.org/.
Advantages:
Disadvantages:
Installation:
python3 -m pip install soundfile
This is the quickest way to load a WAV file into a NumPy array (using soundfile.read()):
import soundfile as sf
sig, samplerate = sf.read('data/test_wav_pcm16.wav')
That's all. Easy, isn't it?
But let's have a closer look ...
The test file is not a very typical file, because it only has 15 frames but it has 7 channels:
sig.shape
samplerate
Let's check the contents of the file by plotting thw audio waveform:
import matplotlib.pyplot as plt
plt.plot(sig);
Looking good!
In most cases soundfile.read() is all you need, but for some advanced use cases, you might want to use a soundfile.SoundFile object instead:
f = sf.SoundFile('data/test_wav_pcm16.wav')
len(f), f.channels, f.samplerate
f.format, f.subtype, f.endian
test = f.read()
test.shape
plt.plot(test);
(test == sig).all()
As you can see, you get the same data as with sf.read()
.
# TODO: read mono file
# mono data is by default returned as one-dimensional NumPy array,
# this can be changed with always_2d=True
24-bit files work:
sig, samplerate = sf.read('data/test_wav_pcm24.wav')
plt.plot(sig);
WAVEX is supported:
sig, samplerate = sf.read('data/test_wavex_pcm16.wav')
plt.plot(sig);
sig, samplerate = sf.read('data/test_wavex_pcm24.wav')
plt.plot(sig);
32-bit float files work:
sig, samplerate = sf.read('data/test_wav_float32.wav')
plt.plot(sig);
sig, samplerate = sf.read('data/test_wavex_float32.wav')
plt.plot(sig);
Writing audio data to a file (using soundfile.write()) is as simple as reading from a file:
sf.write('my_pcm16_file.wav', sig, samplerate)
Let's check if this file has really been written:
!sndfile-info my_pcm16_file.wav
Note that by default, WAV files are written as 16-bit fixed point data (a.k.a. 'PCM_16'
).
You can find the default setting for each file format with soundfile.default_subtype():
sf.default_subtype('WAV')
If you want to save your file with a better quality setting (especially if you want to do further processing later), you can, for example, use the 32-bit floating point format:
sf.write('my_float_file.wav', sig, samplerate, subtype='FLOAT')
Let's check if this worked:
!sndfile-info my_float_file.wav
You can get all available subtypes for a given format with soundfile.available_subtypes():
sf.available_subtypes('WAV')
You can get all available formats with soundfile.available_formats():
sf.available_formats()
... and all available subtypes with soundfile.available_subtypes():
sf.available_subtypes()
print("PySoundFile version:", sf.__version__)
import sys
print("Python version:", sys.version)