diff --git a/README.md b/README.md index 06df4ea..50d4fb4 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ Assuming `python3` is already installed, you can use the following command to in pip3 install csv numpy sounddevice ``` +If you need the GUI, additionally install PySimpleGui: + +```bash +pip3 install PySimpleGui +``` + After that, simply run `python3 offitracker.py` and enjoy. The command can also take a path to a file as a parameter if you wish to use your shells autocompletion. ____ diff --git a/offiplayergui.py b/offiplayergui.py new file mode 100644 index 0000000..2c76f6a --- /dev/null +++ b/offiplayergui.py @@ -0,0 +1,45 @@ +import PySimpleGUI as sg +import glob +import offitracker as offi +import sys +import csv +import numpy as np +import sounddevice as sd +import threading + +names = glob.glob("./**/*.csv", recursive=True) +toplay = "" + +layout = [[sg.Text('Search')], + [sg.Input(size=(200, 1), enable_events=True, key='-INPUT-')], + [sg.Listbox(names, size=(200, 10), enable_events=True, key='-LIST-')], + [sg.Button('Play'), sg.Button('Stop'), sg.Text("",key="file")]] + +window = sg.Window('OffiPlayer', layout,size=(480, 320)) + +def playthread(window): + offi.stop_signal = False + offi.play_csv_file(toplay) + window.write_event_value(('-THREAD-', '** DONE **'), 'Done!') + +while True: + event, values = window.read() + if event in (sg.WIN_CLOSED, 'Exit'): + break + if values['-INPUT-'] != '': + search = values['-INPUT-'] + new_values = [x for x in names if search in x] + window['-LIST-'].update(new_values) + else: + window['-LIST-'].update(names) + if event == '-LIST-' and len(values['-LIST-']): + toplay = values['-LIST-'][0] + window['file'].update(toplay) + if event == 'Play': + window.start_thread(lambda: playthread(window), ('-THREAD-', '-THEAD ENDED-')) + if event == 'Stop': + offi.stop_signal = True +window.close() + + + diff --git a/offitracker.py b/offitracker.py index ecd240f..ba8190c 100644 --- a/offitracker.py +++ b/offitracker.py @@ -12,26 +12,32 @@ import sounddevice as sd # Noise = noise amplitude from 0 to 10 # Duration = tone duration in ms # (c) 2024 mueller_minki, Feel free to modify or share. +stop_signal = False def play_square_waves(output_stream, frequencies, effects, duration, amplitude=1, noise_amplitude=0, sample_rate=44100): - num_waves = len(frequencies) - t = np.linspace(0, duration / 1000, int(sample_rate * duration / 1000), endpoint=False) + if stop_signal == True: + output_stream.stop() + else: + num_waves = len(frequencies) + t = np.linspace(0, duration / 1000, int(sample_rate * duration / 1000), endpoint=False) - # Generate and sum square waves for each frequency with corresponding effects - waves = [amplitude * (effect / 100) * np.sign(np.sin(2 * np.pi * freq * t)) for freq, effect in zip(frequencies, effects)] + # Generate and sum square waves for each frequency with corresponding effects + waves = [amplitude * (effect / 100) * np.sign(np.sin(2 * np.pi * freq * t)) for freq, effect in zip(frequencies, effects)] - # Add optional noise channel - if noise_amplitude > 0: - noise = noise_amplitude * np.random.uniform(-1, 1, len(t)) - waves.append(noise) + # Add optional noise channel + if noise_amplitude > 0: + noise = noise_amplitude * np.random.uniform(-1, 1, len(t)) + waves.append(noise) - combined_wave = np.sum(waves, axis=0) + combined_wave = np.sum(waves, axis=0) - combined_wave = combined_wave.astype(np.float32) + combined_wave = combined_wave.astype(np.float32) - output_stream.write(combined_wave) + output_stream.write(combined_wave) def play_csv_file(file_path): + stop_signal = False + with open(file_path, 'r') as csv_file: csv_reader = csv.DictReader(csv_file) header = csv_reader.fieldnames @@ -46,9 +52,9 @@ def play_csv_file(file_path): # Check if 'Noise' column exists in the CSV file noise_amplitude = float(row.get('Noise', 0)) - - play_square_waves(output_stream, frequencies, effects, duration, noise_amplitude=noise_amplitude) - + if stop_signal == False: + play_square_waves(output_stream, frequencies, effects, duration, noise_amplitude=noise_amplitude) + if __name__ == "__main__": print(' ') print(' Mueller\'s Software Domain proudly presents:') @@ -58,7 +64,7 @@ if __name__ == "__main__": print('/ | \ | | | | | | | | | \// __ \\\\ \___| <\ ___/| | \/') print('\_______ /__| |__| |__| |____| |__| (____ /\___ >__|_ \\\\___ >__| ') print(' \/ \/ \/ \/ \/ ') - print(' Version 1.1') + print(' Version 1.2') if len(sys.argv) > 1: csv_file_path = sys.argv[1] else: