Rachel Sowa rsowa@umail.ucsb.edu
The goal of this project is to perform a Fourier transform on different instrument samples and find the most prominent frequency in each instrument's frequency spectrum.
%pylab inline
#rcParams['figure.figsize'] = (10, 4) #wide graphs by default
from __future__ import print_function
from __future__ import division
from scipy.io import wavfile
Populating the interactive namespace from numpy and matplotlib
# read in the three instrument wav files
glock_sr, glock = wavfile.read('glockenspiel.wav')
piano_sr, piano = wavfile.read('piano.wav')
tom_sr, tom = wavfile.read('tom.wav')
# defining a function to find a cutoff for the x-axis of the frequency spectrum so that it only shows
# the main part of the spectrum and ignores the high frequencies that only count for 5% of the entire spectrum
def cutoff(fft_mag_array):
sum_total = sum(fft_mag_array)
cur_sum = 0.0
i = 0
while cur_sum < 0.95*sum_total and i < len(fft_mag_array):
cur_sum += fft_mag_array[i]
i += 1
return i
# defining a function to plot the signal in time and frequency domains, and to find the most prominent
# frequency in the signal
def findmaxpeak(name, source, samp_rate):
plt.figure().suptitle(name,fontsize=25)
plt.gcf().set_size_inches(10,15)
subplots_adjust(hspace=0.3)
subplots_adjust(top=0.93)
# plot the original signal in the time domain
plt.subplot(311)
plt.title('Original signal in Time Domain')
plt.xlabel('Samples')
plt.ylabel('Amplitude')
src, = plt.plot(source)
plt.legend([src],['Source Signal'])
# perform real fft on source signal and extract the magnitudes of each frequency bin
source_fft_mag = abs(fft.rfft(source))
# calculate the frequency bin with the highest peak
max_freq = argmax(source_fft_mag)*(samp_rate / len(source))
# plot the transformed signal in the frequency domain, denoting the maximum peak with a vertical line
plt.subplot(312)
plt.title('Signal in the Frequency Domain')
plt.xlabel('Frequency bin')
plt.ylabel('Magnitude')
x_axis = arange(0,len(source_fft_mag)*samp_rate / len(source),(samp_rate / len(source)))
src, = plt.plot(x_axis,source_fft_mag, linewidth=1.5)
mx = plt.axvline(x=max_freq, linewidth=1, color='#fe9900')
plt.legend([src, mx], ['Magnitude Spectrum', 'Most Prominent Frequency = '+str(int(max_freq))+' Hz'])
# plot the transformed signal in the frequency domain, denoting the maximum peak with a vertical line
# this time use the cutoff function in order to "zoom in" on the main part of the spectrum
plt.subplot(313)
plt.title('Signal in the Frequency Domain (Zoomed in)')
plt.xlabel('Frequency bin')
plt.ylabel('Magnitude')
plt.axis([0, cutoff(source_fft_mag), 0, max(source_fft_mag)*1.3])
src, = plt.plot(x_axis,source_fft_mag, linewidth=1.5)
mx = plt.axvline(x=max_freq, linewidth=1, color='#fe9900')
plt.legend([src, mx], ['Magnitude Spectrum', 'Most Prominent Frequency = '+str(int(max_freq))+' Hz'])
findmaxpeak('Glockenspiel',glock, glock_sr)
findmaxpeak('Piano',piano, piano_sr)
findmaxpeak('Tom Tom',tom, tom_sr)