In [1]:
import matplotlib.pyplot as plt
%matplotlib inline
import math
import numpy as np
In [2]:
class GuitarProfile:
def __init__(self, pitch_profile, sampling_freq, decay_factor):
self.pitch_profile = pitch_profile
self.sampling_freq = sampling_freq
self.decay_factor = decay_factor
def get_note_profile(self, pitch):
levels_to_return = []
freq_to_return = []
for i in range(0,len(self.pitch_profile)):
levels_to_return.append(self.pitch_profile[i])
temp = (pitch - 69)/12.
temp = math.exp(temp)
temp *= 440
temp *= (i+1)
freq_to_return.append(temp)
return levels_to_return, freq_to_return
def create_aggregate_sample(self, period, pitch):
sample_container = np.zeros((period))
amplitudes, freqs = self.get_note_profile(pitch)
for i in range(0, len(freqs)):
single_frequency_container = np.zeros((period))
sampling_period = 1./self.sampling_freq
for j in range(0, period):
single_frequency_container[j] = sampling_period * j
single_frequency_container = np.cos(freqs[i] * 2 * math.pi * single_frequency_container)
single_frequency_container *= amplitudes[i]
sample_container += single_frequency_container
return sample_container
def create_aggregate_sample_with_decay(self, period, pitch):
sample_container = np.zeros((period))
amplitudes, freqs = self.get_note_profile(pitch)
for i in range(0, len(freqs)):
single_frequency_container = np.zeros((period))
sampling_period = 1./self.sampling_freq
for j in range(0, period):
single_frequency_container[j] = sampling_period * j
decay = single_frequency_container
single_frequency_container = np.cos(freqs[i] * 2 * math.pi * single_frequency_container)
decay = amplitudes[i]*np.exp(-self.decay_factor*decay)
single_frequency_container *= decay
sample_container += single_frequency_container
return sample_container
def acf(container):
results = []
for i in range(1, int(container.shape[0]/2)):
results.append(acf_helper(container, i))
return results
def acf_helper(container, lag):
result = 0
for i in range(0, int(container.shape[0]/2)):
result += container[i] * container[i + lag]
return result
def detect_peak(container, start):
for i in range(start, container.shape[0]):
if container[i - 1] < container[i] and container[i + 1] < container[i]:
return i
def get_freq(peak, frequency):
return frequency / peak
In [3]:
profile1 = GuitarProfile([1., 0.5, 0.3, 0.4, 0.2, 0.1], 96000, 500.)
profile2 = GuitarProfile([1.], 96000, 500.)
In [4]:
amp, freq = profile1.get_note_profile(60)
for i in range(0, len(amp)):
print "Amplitude:", amp[i], "Frequency:", freq[i]
In [5]:
plt.plot(profile1.create_aggregate_sample(2048, 60))
plt.show()
In [6]:
plt.plot(profile1.create_aggregate_sample_with_decay(2048, 60))
plt.show()
In [7]:
sample = profile1.create_aggregate_sample(2048, 60)
sample_simple = profile2.create_aggregate_sample(2048, 60)
sample_decay = profile1.create_aggregate_sample_with_decay(2048, 60)
plt.plot(acf(sample))
plt.show()
plt.plot(acf(sample_decay))
plt.show()
plt.plot(acf(sample_simple))
plt.show()
In [8]:
print get_freq(detect_peak(sample_simple, 1), profile2.sampling_freq)
print get_freq(detect_peak(sample, 1), profile1.sampling_freq)
print get_freq(detect_peak(sample_decay, 2), profile1.sampling_freq)
In [9]:
fft_stuff = np.absolute(np.fft.rfft(sample))
fft_stuff = fft_stuff / np.amax(fft_stuff)
freq = np.fft.rfftfreq(2048, d=1./profile1.sampling_freq)
plt.plot(freq[0:25], fft_stuff[0:25])
plt.show()
fft_stuff = np.absolute(np.fft.rfft(sample_simple))
fft_stuff = fft_stuff / np.amax(fft_stuff)
freq = np.fft.rfftfreq(2048, d=1./profile1.sampling_freq)
plt.plot(freq[0:25], fft_stuff[0:25])
plt.show()
fft_stuff = np.absolute(np.fft.rfft(sample_decay))
fft_stuff = fft_stuff / np.amax(fft_stuff)
freq = np.fft.rfftfreq(2048, d=1./profile1.sampling_freq)
plt.plot(freq[0:25], fft_stuff[0:25])
plt.show()
In [11]:
import scipy.signal
filter_object = scipy.signal.bilinear(50, 2*math.pi/207)
In [18]:
simple_peaks = scipy.signal.find_peaks_cwt(acf(sample_simple), np.arange(1,10))
In [19]:
peaks2 = scipy.signal.find_peaks_cwt(acf(sample), np.arange(1,10))
In [20]:
simple_peaks2 = scipy.signal.find_peaks_cwt(acf(sample_decay), np.arange(1,10))
In [22]:
for i in simple_peaks:
print get_freq(i, profile1.sampling_freq)
In [23]:
for i in peaks2:
print get_freq(i, profile1.sampling_freq)
In [24]:
for i in simple_peaks2:
print get_freq(i, profile1.sampling_freq)
In [ ]: