<jupyter_start><jupyter_text>Initial Implementation Library ImportsHere, the necessary libraries are imported<jupyter_code>import matplotlib.pyplot as plt
import numpy as np
from scipy.io import wavfile<jupyter_output><empty_output><jupyter_text>FilenameThis declares the filename variable for the sample wavefile. It is a recording of an Bass E string strum, from [this recording](https://freesound.org/people/Kyster/sounds/117677/) on freesound.org.<jupyter_code>FILE = "E_string_sample.wav"<jupyter_output><empty_output><jupyter_text>Reading the fileHere the file is read using the scipy.io.wavefile.read() function, which pulls the sample rate and the raw data.<jupyter_code>def read_wav(filename):
    return wavfile.read(filename)<jupyter_output><empty_output><jupyter_text>Plotting wavefileThis function plots the data that was read from the wavefile.<jupyter_code>def plot_wav(sample_rate, data):
    length = data.shape[0] / sample_rate
    
    # prints the information from the file
    print(f"Recording length: {length:.3f}s")
    print(f"Sample Rate: {sample_rate}Hz")
    
    # creates a time array for plotting
    time = np.linspace(0., length, data.shape[0])
    
    # uses matplot.lib for plotting functions, plotting both audio channels
    plt.plot(time, data[:, 0], label="Left channel")
    plt.plot(time, data[:, 1], label="Right channel")
    plt.legend()
    plt.xlabel("Time [s]")
    plt.ylabel("Amplitude")
    plt.show()<jupyter_output><empty_output><jupyter_text>Perform FFTThis uses the numpy real FFT function to do a real-FFT on the data inputted to the function.<jupyter_code>def do_fft(signal, sample_rate):
    fft_spectrum = np.fft.rfft(signal)
    freq = np.fft.rfftfreq(signal.size, d=1./sample_rate)  # get frequency values of FFT
    fft_spectrum_abs = np.abs(fft_spectrum)  # compute absolute value of FFT plot
    return freq, fft_spectrum_abs<jupyter_output><empty_output><jupyter_text>Plot FFTThis function takes in the frequency and FFT datasets and plots them using the matplot.lib functions.<jupyter_code>def plot_fft(freq_array, fft_array):
    plt.plot(freq_array, fft_array)
    plt.xlabel("frequency, Hz")
    plt.ylabel("Amplitude, units")
    plt.show()<jupyter_output><empty_output><jupyter_text>Get Max frequencyThis function returns the frequency (in Hz) of the maximum amplitude from the FFT dataset and looking it up in the frequency dataset.<jupyter_code>def get_freq(freq_array, fft_array):
    i = np.where(fft_array == max(fft_array))
    return float(freq_array[i[0]])<jupyter_output><empty_output><jupyter_text>Get Closest NoteThis function returns the string of the closest note depending on the pitch frequency given.<jupyter_code>def get_note(pitch_freq):
    CONCERT_PITCH = 440 # tuning standard in music
    ALL_NOTES = ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"] # musical notes arranged properly
    i = int(np.round(np.log2(pitch_freq/CONCERT_PITCH)*12))
    return ALL_NOTES[i % 12] + str(4 + (i + 9) // 12)<jupyter_output><empty_output><jupyter_text>Run for timeitThis function runs all the function without the plots in order for software implementation timing.<jupyter_code>def run_timed():
    sample_rate, data = read_wav(FILE)
    freq, fft = do_fft(data[:sample_rate,0], sample_rate) # only use one channel, 1 second of data
    wav_freq = get_freq(freq, fft)
    note = get_note(wav_freq)
%timeit run_timed()<jupyter_output>10 loops, best of 3: 85.8 ms per loop<jupyter_text>RunThis function runs the all the functions with the plots for visualization of the data.<jupyter_code>def run():
    sample_rate, data = read_wav(FILE)
    plot_wav(sample_rate, data)
    freq, fft = do_fft(data[:sample_rate,0], sample_rate) # only use one channel, 1 second of data
    plot_fft(freq[:10000], fft[:10000])
    wav_freq = get_freq(freq[:10000], fft[:10000])
    print(f"Recording Frequency: {wav_freq:.3f}Hz")
    note = get_note(wav_freq)
    print("Recording Note: " + note)
run()<jupyter_output>Recording length: 9.102s
Sample Rate: 48000Hz
{'fraction_non_alphanumeric': 0.109375, 'fraction_numerical': 0.01636904761904762, 'mean_word_length': 5.341194968553459, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '356738', 'license': 'MIT', 'n_tokens_mistral': 1439, 'n_tokens_neox': 1364, 'n_words': 361, 'path': 'jupyter_notebooks/Algorithm - Initial.ipynb', 'repo_name': 'db00lean/triad_finder', 'size': '4032'}