1
$\begingroup$

I've tried both using scikit.samplerate.resample and scipy.signal.resample. With neither of them can I achieve the result I want.

Scipy.samplerate:

file1 = '../machine_learning/voice_snippets_stepvoices/t10_9steps.wav'
file2 = '../random_data/t10_9steps.wav'

sr, y = scipy.io.wavfile.read(file1)

secs = len(y)/sr # Number of seconds in signal X

samps = secs*16000 # Number of samples to downsample
Y = scipy.signal.resample(y, samps)

scipy.io.wavfile.write(file2, 16000, Y)
#librosa.output.write_wav(file2, Y, 16000)

With both the outputs from scipy/librosa-write_wav() I can't listen to the file. So I assume the file is corrupted and this would be a result of the scipy.resample step. Yet I cannot work out why. I have no error logs to go off. I've tried plotting y and Y on wavplots and they are both the same except for different length x-axis(samples).

Any ideas?

Scikit.resample:

file = '../machine_learning/voice_snippets_stepvoices/t10_9steps.wav'
new_file = '../testing/random_data/t10_9steps.wav'
ratio = 16000/48000

sr, y = scipy.io.wavfile.read(file)
y_new = resample(y, ratio, 'sinc_best', True)
scipy.io.wavfile.write(new_file, 16000, y_new)

In this one I do get an output but it changes somewhat noisy audio of someone speaking to what sounds like Skrillex... (Joking. but look at the graphs).

after resampling before resampling

I didn't expect the resampling to have this effect especially since scikit.resample is supposed to be the best resampling tool for python. (and yes it does apply anti-aliasing).

Anyone have any idea why these techniques aren't working?

Thanks a lot (:


EDIT:

Thanks @hulappa for the solution. It was related to the output I got from scipy.io.wavfile.read. I used this code to solve:

 # scale to -1.0 -- 1.0 - https://stackoverflow.com/questions/2060628/reading-wav-files-in-python

if y.dtype == 'int16':
    nb_bits = 16 # -> 16-bit wav files
elif y.dtype == 'int32':
    nb_bits = 32 # -> 32-bit wav files
max_nb_bit = float(2 ** (nb_bits - 1))
samples = y / (max_nb_bit + 1.0) # samples is a numpy array of float representing

#--------------

Alas, this only worked for scikit.samplerate.resample(). I still get an unreadable file from using scipy.signal.resample().

I have tried running scipy.signal.resample() on a sine wave like so:

fs = 48000 # sample rate 
f = 5 # the frequency of the signal
x = np.arange(fs) # the points on the x axis for plotting
# compute the value (amplitude) of the sin wave at the for each sample
y = [ np.sin(2*np.pi*f * (i/float(fs))) for i in x]

secs = len(y)/fs # Number of seconds in signal X
samps = secs*16000 # Number of samples to downsample
Y = scipy.signal.resample(y, samps)


file1 = '../random_data/sine48000.wav'
file2 = '../random_data/sine16000.wav'

scipy.io.wavfile.write(file2, 16000, Y)
scipy.io.wavfile.write(file1, 48000, np.array(y))

I cannot listen to both the resampled wav file or the sine wav file. I assume this is a careless error but I will put this here in case an answer helps future readers.

$\endgroup$
4
  • $\begingroup$ What do the resamplers give if the input is a pure sinusoid? $\endgroup$ Commented Feb 14, 2018 at 15:55
  • 1
    $\begingroup$ Could it be related to the fact that scipy.io.wavfile.read typically returns an array of integers, depending on the data type used in the file? You could try converting y to a floating point representation before applying resampling. For a N bit signed wav file that would be something along the lines of: y_float = y / 2.0**(N-1). $\endgroup$
    – hulappa
    Commented Feb 15, 2018 at 1:12
  • $\begingroup$ Can I please ask you to post the solution as a "self-answer" and accept it too, so the question is closed gracefully and it does not get re-cycled in the system as "un-answered" (?). (Or, @hulappa does it maybe (?)) $\endgroup$
    – A_A
    Commented Feb 15, 2018 at 11:20
  • $\begingroup$ Got it. I posted the solution as an answer now so OP can accept it. $\endgroup$
    – hulappa
    Commented Feb 15, 2018 at 20:22

1 Answer 1

0
$\begingroup$

The problem is that if your wav file stores samples as integers (typically 16 bit signed), $\texttt{scipy.io.wavfile.read()}$ returns an array of integers. If this is the case, you want to convert your signal into a floating point representation before applying resampling. For a wav file which stores values as N bit signed integers, this can be done by:

// Convert y to float array, with values in the interval [-1.0,1.0]
y_float = float(y / (2.0**(N-1) + 1))
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.