So I've been self studying signal processing, and been trying to use Python to get quality spectrograms, quality spectrogram like the one that would be produced with audacity etc. The steps I have done are:
Me saying 'computer', was recorded on my mac in .m4a, then I used ffmpeg converting it into .wav
$ ffmpeg -i computer.m4a -acodec pcm_s16le -ac 1 -ar 16000 computer.wav
Imported into Python via:
sample_rate, samples = wavfile.read('/path/to/computer.wav')
Now I just do a quick plot of the samples:
plt.plot(samples)
and I get this kinda graph:
Why are my peaks capped?
Anyway, I carry on and as I understand it, I perform a Fourier transform that will take my signal, decompose it into the sine waves of different amplitudes and frequencies, and then get the real part of the complex numbers that are generated:
samples_fft = np.fft.rfft(samples) frequencies = np.abs(samples_fft)
I now plot a graph of frequencies:
This is what I guessed would be like, as vocal frequencies are typically around the range of 100 to a thousand, right?
A spectrogram is when I divide my samples into a certain amount of windows, and then take the Fourier transform of each of the windows, resulting in a time frequency graph.
last_wind = 0 windows = np.linspace(0,len(samples),1000) spectrogram = [] for window in windows: if window != 0: samples_in_range = samples[last_wind:int(window)] samples_in_range_fft = np.fft.rfft(samples_in_range) frequencies_in_range = np.abs(samples_in_range_fft) spectrogram.append(list(frequencies_in_range)) last_wind = int(window) spectrogram2 = np.asarray(spectrogram).T
Plot the spectrogram:
audio_length = len(samples)/sample_rate audio_time_intervals = np.linspace(0,audio_length,999) tempfreq = np.linspace(0,1,19) plt.pcolormesh(audio_time_intervals, tempfreq, spectrogram2)
So now I have a spectrogram, but of very poor quality. but I've been watching youtube videos such as this one, how do I get better resolution and clarity so as to read stuff such as formants in vowels, i tried changing the size of my partitions, but still get very similar results, more windows get less data of frequencies in each window, and less windows get poor time resolution.
I am very new to signal processing, so any help would be greatly appreciated, such as a point in the right direction or pointers as to what I'm doing wrong, in order to get clear spectrograms so as to study.
Note, I have tried python packages such signal.spectrogram
, but the results are very poor aswell. Plus I'd rather get to know the nitty gritties so I really understand what is going on.