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$
  • $\begingroup$ What do the resamplers give if the input is a pure sinusoid? $\endgroup$ – AnonSubmitter85 Feb 14 '18 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 Feb 15 '18 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 Feb 15 '18 at 11:20
  • $\begingroup$ Got it. I posted the solution as an answer now so OP can accept it. $\endgroup$ – hulappa Feb 15 '18 at 20:22
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, privacy policy and cookie policy

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