diff options
author | sotech117 <michael_foiani@brown.edu> | 2023-05-08 17:04:32 -0400 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2023-05-08 17:04:32 -0400 |
commit | afe87c35aac78ac9e8d0c0b711a0323356e29bb3 (patch) | |
tree | 0ab48d1ba29e7c366e5b9eb04052d28a4f67632a | |
parent | f73f94ed6b7a6f2c1452e50e846bf3316b317cac (diff) |
initial upload of first iteration of documents. readme with explanation to come.
-rw-r--r-- | ai.py | 0 | ||||
-rw-r--r-- | before_train.py | 120 | ||||
-rw-r--r-- | oscilloscope.py | 120 |
3 files changed, 240 insertions, 0 deletions
diff --git a/before_train.py b/before_train.py new file mode 100644 index 0000000..64e5487 --- /dev/null +++ b/before_train.py @@ -0,0 +1,120 @@ +# This is a sample Python script. +import struct + +# Press ⌃R to execute it or replace it with your code. +# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. + +from scipy.fftpack import fft +import numpy as np +import pyaudio +import matplotlib.pyplot as plt + + +class Test(object): + + def __init__(self): + # stream constants + self.CHUNK = 2048 * 2 + self.FORMAT = pyaudio.paInt32 + self.CHANNELS = 1 + self.RATE = 44100 + self.pause = False + + # stream object + self.p = pyaudio.PyAudio() + self.stream = self.p.open( + format=self.FORMAT, + channels=self.CHANNELS, + rate=self.RATE, + input=True, + output=True, + frames_per_buffer=self.CHUNK, + ) + + self.seenvalues = set() + + # goal: returns the max frequency of waveform + def get_fundamental_frequency(self, audio_waveform): + spectrum = fft(audio_waveform) + + # scale the spectrum + scaled_spectrum = np.abs(spectrum[0:self.CHUNK]) / (128 * self.CHUNK) + + # clean the nullish first and last values + cleaned_scaled_spectrum = scaled_spectrum[10:-10] + + # get the index of the max + np_max = max(cleaned_scaled_spectrum) + max_index = np.where(scaled_spectrum == np_max)[0][0] + + # the index corresponds to the following linspace + index_to_freq = np.linspace(0, self.RATE, self.CHUNK) + return index_to_freq[max_index], scaled_spectrum + + def read_audio_stream(self): + data = self.stream.read(self.CHUNK, exception_on_overflow=False) + data_int = struct.unpack(str(4 * self.CHUNK) + 'B', data) + return data_int + + def open_loop(self, graphics=True): + self.init_plots() + while not self.pause: + waveform = self.read_audio_stream() + freq_max, scaled_spectrum = self.get_fundamental_frequency(waveform) + if 250 < freq_max < 550: + if freq_max not in self.seenvalues: + print(freq_max) + self.seenvalues.add(freq_max) + + # update figure canvas if wanted + if graphics: + # set top graph + data_np = np.array(waveform, dtype='b')[::4] + 128 + self.line.set_ydata(data_np) + # set bottom graph + self.line_fft.set_ydata(scaled_spectrum) + + # update figures + self.fig.canvas.draw() + self.fig.canvas.flush_events() + + def init_plots(self): + + # x variables for plotting + x = np.arange(0, 2 * self.CHUNK, 2) + xf = np.linspace(0, self.RATE, self.CHUNK) + + # create matplotlib figure and axes + self.fig, (ax1, ax2) = plt.subplots(2, figsize=(15, 7)) + + # create a line object with random data + self.line, = ax1.plot(x, np.random.rand(self.CHUNK), '-', lw=2) + + # create semilogx line for spectrum + self.line_fft, = ax2.semilogx( + xf, np.random.rand(self.CHUNK), '-', lw=2) + + # format waveform axes + ax1.set_title('AUDIO WAVEFORM') + ax1.set_xlabel('samples') + ax1.set_ylabel('volume') + ax1.set_ylim(0, 255) + ax1.set_xlim(0, 2 * self.CHUNK) + plt.setp( + ax1, yticks=[0, 128, 255], + xticks=[0, self.CHUNK, 2 * self.CHUNK], + ) + plt.setp(ax2, yticks=[0, 1], ) + + # format spectrum axes + ax2.set_xlim(20, self.RATE / 2) + + # show axes + thismanager = plt.get_current_fig_manager() + # thismanager.window.setGeometry(5, 120, 1910, 1070) + plt.show(block=False) + + +if __name__ == '__main__': + t = Test() + t.open_loop() diff --git a/oscilloscope.py b/oscilloscope.py new file mode 100644 index 0000000..50f6a91 --- /dev/null +++ b/oscilloscope.py @@ -0,0 +1,120 @@ +# This is a sample Python script. +import struct + +# Press ⌃R to execute it or replace it with your code. +# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. + +from scipy.fftpack import fft +import numpy as np +import pyaudio +import matplotlib.pyplot as plt + + +class Test(object): + + def __init__(self): + # stream constants + self.CHUNK = 2048 * 2 + self.FORMAT = pyaudio.paInt32 + self.CHANNELS = 1 + self.RATE = 44100 + self.pause = False + + # stream object + self.p = pyaudio.PyAudio() + self.stream = self.p.open( + format=self.FORMAT, + channels=self.CHANNELS, + rate=self.RATE, + input=True, + output=True, + frames_per_buffer=self.CHUNK, + ) + + self.seenvalues = set() + + self.sample_divs = 4 + + # goal: returns the max frequency of waveform + def get_fundamental_frequency(self, audio_waveform): + spectrum = fft(audio_waveform) + + # scale and normalize the spectrum, some are imaginary + scaled_spectrum = np.abs(spectrum) + scaled_spectrum = scaled_spectrum / (np.linalg.norm(scaled_spectrum) + 1e-16) + + # get the index of the max + np_max = max(scaled_spectrum) + max_index = np.where(scaled_spectrum == np_max)[0][0] + + # the index corresponds to the following linspace + index_to_freq = np.linspace(0, self.RATE, self.CHUNK) + return index_to_freq[max_index], scaled_spectrum + + def read_audio_stream(self): + data = self.stream.read(self.CHUNK) + data_int = struct.unpack(str(self.CHUNK) + 'i', data) + return data_int + + def open_loop(self, graphics=True): + self.init_plots() + while not self.pause: + waveform = self.read_audio_stream() + freq_max, scaled_spectrum = self.get_fundamental_frequency(waveform) + if 250 < freq_max < 550: + if freq_max not in self.seenvalues: + print(freq_max) + self.seenvalues.add(freq_max) + + # update figure canvas if wanted + if graphics: + # set top graph + data_np = np.array(waveform) / (np.linalg.norm(waveform) + 1e-16) * 10 + self.line.set_ydata(data_np[0:len(data_np)// self.sample_divs]) + # set bottom graph + self.line_fft.set_ydata(scaled_spectrum) + + # update figures + self.fig.canvas.draw() + self.fig.canvas.flush_events() + + def init_plots(self): + + # x variables for plotting + x = np.arange(0, self.CHUNK * 2 // self.sample_divs, 2) + xf = np.linspace(0, self.RATE, self.CHUNK) + + # create matplotlib figure and axes + self.fig, (ax1, ax2) = plt.subplots(2, figsize=(15, 7)) + + # create a line object with random data + self.line, = ax1.plot(x, np.random.rand(self.CHUNK // self.sample_divs), '-', lw=2) + + # create semilogx line for spectrum + self.line_fft, = ax2.semilogx( + xf, np.random.rand(self.CHUNK), '-', lw=2) + + # format waveform axes + ax1.set_title('AUDIO WAVEFORM') + ax1.set_xlabel('samples') + ax1.set_ylabel('volume') + ax1.set_ylim(-1, 1) + ax1.set_xlim(0, self.CHUNK // self.sample_divs) + plt.setp( + ax1, + xticks=[0, self.CHUNK // self.sample_divs, self.CHUNK * 2 // self.sample_divs], + ) + plt.setp(ax2, yticks=[0, 1], ) + + # format spectrum axes + ax2.set_xlim(20, self.RATE / 2) + + # show axes + thismanager = plt.get_current_fig_manager() + # thismanager.window.setGeometry(5, 120, 1910, 1070) + plt.show(block=False) + + +if __name__ == '__main__': + t = Test() + t.open_loop() |