create offiplayergui.py & update offitracker.py

Adds a GUI for easy usage
This commit is contained in:
Emanulator 2024-01-02 20:25:31 +00:00
parent 0af3446706
commit ba2c5a6e39
2 changed files with 122 additions and 67 deletions

45
offiplayergui.py Normal file
View File

@ -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()

View File

@ -1,67 +1,77 @@
import sys
import csv
import numpy as np
import sounddevice as sd
# OffiTracker, the tracker that no one asked for but I made it anyways :3
# Usage: Make a CSV table in Excel or LibreOffice with the following format:
# Frequency1 Effect1 Frequency2 Effect2 .... Noise Duration
# You can make as many channels as you want.
# Effect = pulse width from 0 to 100
# Frequency = tone in Hz.
# Noise = noise amplitude from 0 to 10
# Duration = tone duration in ms
# (c) 2024 mueller_minki, Feel free to modify or share.
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)
# 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)
combined_wave = np.sum(waves, axis=0)
combined_wave = combined_wave.astype(np.float32)
output_stream.write(combined_wave)
def play_csv_file(file_path):
with open(file_path, 'r') as csv_file:
csv_reader = csv.DictReader(csv_file)
header = csv_reader.fieldnames
num_columns = len(header)
num_pairs = (num_columns - 1) // 2
with sd.OutputStream(channels=1) as output_stream:
for row in csv_reader:
frequencies = [float(row[f'Frequency{i}']) for i in range(1, num_pairs + 1)]
effects = [float(row[f'Effect{i}']) for i in range(1, num_pairs + 1)]
duration = float(row['Duration'])
# 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 __name__ == "__main__":
print(' ')
print(' Mueller\'s Software Domain proudly presents:')
print('________ _____ _____._____________ __ ')
print('\_____ \_/ ____\/ ____\__\__ ___/___________ ____ | | __ ___________ ')
print(' / | \ __\\\\ __\| | | | \_ __ \__ \ _/ ___\| |/ // __ \_ __ \\')
print('/ | \ | | | | | | | | | \// __ \\\\ \___| <\ ___/| | \/')
print('\_______ /__| |__| |__| |____| |__| (____ /\___ >__|_ \\\\___ >__| ')
print(' \/ \/ \/ \/ \/ ')
print(' Version 1.1')
if len(sys.argv) > 1:
csv_file_path = sys.argv[1]
else:
csv_file_path = input("Choose a CSV file: ")
play_csv_file(csv_file_path)
import sys
import csv
import numpy as np
import sounddevice as sd
import time
# OffiTracker, the tracker that no one asked for but I made it anyways :3
# Usage: Make a CSV table in Excel or LibreOffice with the following format:
# Frequency1 Effect1 Frequency2 Effect2 .... Noise Duration
# You can make as many channels as you want.
# Effect = pulse width from 0 to 100
# Frequency = tone in Hz.
# 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 stop_playback():
stop_signal = True
def play_square_waves(output_stream, frequencies, effects, duration, amplitude=1, noise_amplitude=0, sample_rate=44100):
if stop_signal == True:
output_stream.stop()
pass
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)]
# 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 = combined_wave.astype(np.float32)
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
num_columns = len(header)
num_pairs = (num_columns - 1) // 2
with sd.OutputStream(channels=1) as output_stream:
for row in csv_reader:
frequencies = [float(row[f'Frequency{i}']) for i in range(1, num_pairs + 1)]
effects = [float(row[f'Effect{i}']) for i in range(1, num_pairs + 1)]
duration = float(row['Duration'])
# Check if 'Noise' column exists in the CSV file
noise_amplitude = float(row.get('Noise', 0))
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:')
print('________ _____ _____._____________ __ ')
print('\_____ \_/ ____\/ ____\__\__ ___/___________ ____ | | __ ___________ ')
print(' / | \ __\\\\ __\| | | | \_ __ \__ \ _/ ___\| |/ // __ \_ __ \\')
print('/ | \ | | | | | | | | | \// __ \\\\ \___| <\ ___/| | \/')
print('\_______ /__| |__| |__| |____| |__| (____ /\___ >__|_ \\\\___ >__| ')
print(' \/ \/ \/ \/ \/ ')
print(' Version 1.1')
if len(sys.argv) > 1:
csv_file_path = sys.argv[1]
else:
csv_file_path = input("Choose a CSV file: ")
play_csv_file(csv_file_path)