soundfile (PySoundFile)
The `soundfile` module (also known as PySoundFile) is a Python library for reading and writing sound files, built upon the C library `libsndfile`, CFFI, and NumPy. It provides a simple, high-level interface to handle various audio formats as NumPy arrays, making it ideal for audio processing and scientific applications. It is actively maintained with regular releases.
Warnings
- breaking The primary import name changed from `pysoundfile` to `soundfile` in version 0.7. Using the old import will result in an `ImportError`.
- breaking The default value of the `always_2d` parameter in `sf.read()` changed from `True` to `False` in version 0.8.0. This affects the shape of the returned NumPy array for mono files (1D instead of 2D).
- breaking The argument order for `sf.write()` changed in version 0.8.0 from `write(data, file, ...)` to `write(file, data, ...)`. Calling with the old order will likely cause `TypeError` or incorrect data writing.
- gotcha When reading or writing from in-memory file-like objects (e.g., `io.BytesIO`), it's crucial to `seek(0)` to the beginning of the stream after writing and before attempting to read, otherwise `libsndfile` will report an 'unknown format' error.
- gotcha The load order for the `libsndfile` C library changed in version 0.12.0. Packaged `libsndfile` (included in binary wheels) is now preferred over any system-installed version. This might affect applications relying on a specific system `libsndfile` version.
- gotcha Reading RAW (un-headered) audio files requires explicitly specifying `channels`, `samplerate`, and `subtype` in `sf.read()`, as the format cannot be auto-detected.
Install
-
pip install soundfile -
pip install soundfile --no-binary :all: sudo apt install libsndfile1 # on Debian/Ubuntu
Imports
- soundfile
import soundfile as sf
Quickstart
import soundfile as sf
import numpy as np
import os
# Create dummy audio data (mono, 44.1 kHz)
samplerate = 44100 # samples per second
duration = 1.0 # seconds
f_hz = 440 # sine wave frequency
t = np.linspace(0., duration, int(samplerate * duration), endpoint=False)
data = 0.5 * np.sin(2 * np.pi * f_hz * t)
output_filename = 'dummy_audio.wav'
# Write the audio data to a WAV file
sf.write(output_filename, data, samplerate)
print(f"Audio written to {output_filename}")
# Read the audio data back from the file
read_data, read_samplerate = sf.read(output_filename)
print(f"Audio read from {output_filename} with sample rate {read_samplerate}")
print(f"Read data shape: {read_data.shape}")
# Verify data
assert np.allclose(data, read_data[:len(data)])
assert samplerate == read_samplerate
# Clean up the dummy file
os.remove(output_filename)
print(f"Cleaned up {output_filename}")