Sample-rate conversion in Python
Resampling is not a trivial task. Simple ‘zero order hold’ or ‘linear interpolation’ produces bad result.
This article discusses how to perform sample rate conversion using Python-SoXR in Python.
Resampling NumPy array
Example for converting ndrray
’s samplerate:
import numpy as np
import soxr
SOURCE_RATE = 2400
TARGET_RATE = 1500
LEN = 1000
# generate source signal
ch1 = np.sin(np.pi / 120 * np.arange(LEN))
ch2 = np.sin(np.pi / 180 * np.arange(LEN))
x = np.asarray([ch1, ch2]).T
print(f'source: {x.shape}')
# Resample signal
y = soxr.resample(x, SOURCE_RATE, TARGET_RATE)
print(f'resampled: {y.shape}')
Result:
source: (1000, 2)
resampled: (625, 2)
Note that soxr uses channel-last format.
Audio file sample rate conversion
To convert audio file’s samplerate and save as new file:
import soundfile as sf
import soxr
TARGET_RATE = 16000
# Load the audio file
x, source_rate = sf.read('input.mp3')
# Resample the audio
y = soxr.resample(x, source_rate, TARGET_RATE)
# Save the resampled audio
sf.write('output.wav', y, TARGET_RATE)
Resampled audio will be saved to output.wav
.
Audio file sample rate conversion (streaming)
Use ResampleStream
for real-time processing or very long signal.
import soundfile as sf
import soxr
TARGET_RATE = 16000
CHUNK_SIZE = 96000
# Open input audio file
in_file = sf.SoundFile('input_too_long_to_fit_in_memory.flac', 'r')
source_rate = in_file.samplerate
channels = in_file.channels
# Config ResampleStream
resampler = soxr.ResampleStream(source_rate, TARGET_RATE, channels, dtype='float32')
# Open output audio file
with sf.SoundFile('output.flac', 'w', TARGET_RATE, channels) as out_file:
while True:
# Read chunk of audio
x = in_file.read(CHUNK_SIZE, dtype='float32')
is_last = (in_file.tell() == in_file.frames)
# Resample the chunk
y = resampler.resample_chunk(x, last=is_last)
# Write to output file
out_file.write(y)
if is_last:
break
in_file.close()
That’s it!
Now you can resample any 1-D data in Python.