Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downsampling wav audio file

Tags:

I have to downsample a wav file from 44100Hz to 16000Hz without using any external Python libraries, so preferably wave and/or audioop. I tried just changing the wav files framerate to 16000 by using setframerate function but that just slows down the entire recording. How can I just downsample the audio file to 16kHz and maintain the same length of the audio?

like image 876
d3cr1pt0r Avatar asked Jun 03 '15 12:06

d3cr1pt0r


People also ask

How do I reduce the sample rate of a WAV file?

Click on the menu next to Import Using > WAV Encoder. Then click to change Setting > Custom and a new window will open. In the WAV Encoder window, change the Sample Rate to 44.100 kHz and Sample Size to 16-bit. Exit all windows by clicking OK until you are back to your iTunes library.

How do I make a WAV file smaller without losing quality?

The only way to reduce the size of a wav file is to resample it to a lower bit rate or use less bits per sample. Wav files don't have compression capabilities like mp3 or ogg.

How do I downsample a wav file in Python?

To downsample (also called decimate) your signal (it means to reduce the sampling rate), or upsample (increase the sampling rate) you need to interpolate between your data. The idea is that you need to somehow draw a curve between your points, and then take values from this curve at the new sampling rate.


2 Answers

You can use Librosa's load() function,

import librosa     y, s = librosa.load('test.wav', sr=8000) # Downsample 44.1kHz to 8kHz 

The extra effort to install Librosa is probably worth the peace of mind.

Pro-tip: when installing Librosa on Anaconda, you need to install ffmpeg as well, so

pip install librosa conda install -c conda-forge ffmpeg 

This saves you the NoBackendError() error.

like image 194
wafflecat Avatar answered Oct 06 '22 01:10

wafflecat


To downsample (also called decimate) your signal (it means to reduce the sampling rate), or upsample (increase the sampling rate) you need to interpolate between your data.

The idea is that you need to somehow draw a curve between your points, and then take values from this curve at the new sampling rate. This is because you want to know the value of the sound wave at some time that wasn't sampled, so you have to guess this value by one way or an other. The only case where subsampling would be easy is when you divide the sampling rate by an integer $k$. In this case, you just have to take buckets of $k$ samples and keep only the first one. But this won't answer your question. See the picture below where you have a curve sampled at two different scales.

Signal

You could do it by hand if you understand the principle, but I strongly recommend you to use a library. The reason is that interpolating the right way isn't easy or either obvious.

You could use a linear interpolation (connect points with a line) or a binomial interpolation (connect three points with a piece of polynom) or (sometimes the best for sound) use a Fourier transform and interpolate in the space of frequency. Since fourier transform isn't something you want to re-write by hand, if you want a good subsampling/supsampling, See the following picture for two curves of upsampling using a different algorithm from scipy. The "resampling" function use fourier transform. Resampling scipy

I was indeed in the case I was loading a 44100Hz wave file and required a 48000Hz sampled data, so I wrote the few following lines to load my data:

    # Imports     from scipy.io import wavfile     import scipy.signal as sps      # Your new sampling rate     new_rate = 48000      # Read file     sampling_rate, data = wavfile.read(path)      # Resample data     number_of_samples = round(len(data) * float(new_rate) / sampling_rate)     data = sps.resample(data, number_of_samples) 

Notice you can also use the method decimate in the case you are only doing downsampling and want something faster than fourier.

like image 37
Jeremy Cochoy Avatar answered Oct 05 '22 23:10

Jeremy Cochoy