Multiple files can now be loaded. Fixed GUI becoming unresponsive while a song is playing.
This commit is contained in:
parent
66a3b9f542
commit
c55da23e2d
1 changed files with 53 additions and 6 deletions
59
main.py
59
main.py
|
@ -25,8 +25,10 @@
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
from tkinter import filedialog as fd
|
from tkinter import filedialog as fd
|
||||||
|
from tkinter import messagebox as mb
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
import os
|
import os
|
||||||
|
import threading
|
||||||
|
|
||||||
class MidiPort:
|
class MidiPort:
|
||||||
|
|
||||||
|
@ -45,6 +47,11 @@ class App(ttk.Frame):
|
||||||
self.devices = self.get_midi_list()
|
self.devices = self.get_midi_list()
|
||||||
self.create_widgets()
|
self.create_widgets()
|
||||||
self.midi_port_var.set(str(self.devices[0]))
|
self.midi_port_var.set(str(self.devices[0]))
|
||||||
|
# play control
|
||||||
|
self.play_mutex = threading.Lock()
|
||||||
|
self.is_playing = False
|
||||||
|
self.stop_after = False
|
||||||
|
self.files = ()
|
||||||
|
|
||||||
def create_widgets(self):
|
def create_widgets(self):
|
||||||
self.midi_port_label = ttk.Label(self, text="Midi Device")
|
self.midi_port_label = ttk.Label(self, text="Midi Device")
|
||||||
|
@ -58,16 +65,24 @@ class App(ttk.Frame):
|
||||||
self.midi_file_label = ttk.Label(self, text="File")
|
self.midi_file_label = ttk.Label(self, text="File")
|
||||||
self.midi_file_label.grid(column=0, row=1)
|
self.midi_file_label.grid(column=0, row=1)
|
||||||
self.midi_file_var = StringVar()
|
self.midi_file_var = StringVar()
|
||||||
self.midi_file_text = ttk.Entry(self, textvariable=self.midi_file_var, width=80)
|
self.midi_file_text = Listbox(self, listvariable=self.midi_file_var, width=80, height=20, selectmode="extended")
|
||||||
self.midi_file_text.grid(column=1, row=1)
|
self.midi_file_text.grid(column=1, row=1)
|
||||||
self.midi_file_button = ttk.Button(self,
|
self.midi_file_button = ttk.Button(self,
|
||||||
text="Open...",
|
text="Open...",
|
||||||
command=lambda: self.midi_file_var.set(fd.askopenfilename(defaultextension=".mid", filetypes=[("MIDI", ".mid")], initialdir=os.environ['HOME'])))
|
command=self.open_file)
|
||||||
self.midi_file_button.grid(column=2, row=1, sticky=(E, W))
|
self.midi_file_button.grid(column=3, row=1, sticky=(E, W))
|
||||||
|
self.midi_file_scroll = ttk.Scrollbar(self, orient=VERTICAL, command=self.midi_file_text.yview)
|
||||||
|
self.midi_file_text.configure(yscrollcommand=self.midi_file_scroll.set)
|
||||||
|
self.midi_file_scroll.grid(column=2, row=1, sticky=(N, S, W))
|
||||||
|
|
||||||
self.play_button = ttk.Button(self, text="Play", command=self.play_midi)
|
self.play_button = ttk.Button(self, text="Play", command=self.play_midi)
|
||||||
self.play_button.grid(column=1, row=2)
|
self.play_button.grid(column=1, row=2)
|
||||||
|
|
||||||
|
self.stop_after_var = StringVar()
|
||||||
|
self.stop_after_var.set("go")
|
||||||
|
self.stop_after_button = ttk.Checkbutton(self, text="Stop after current", command=self.stop_after_current, variable=self.stop_after_var, onvalue="stop", offvalue="go")
|
||||||
|
self.stop_after_button.grid(column=2, row=2, columnspan=2)
|
||||||
|
|
||||||
self.columnconfigure(1, weight=1)
|
self.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -79,14 +94,46 @@ class App(ttk.Frame):
|
||||||
port_name_start = devices[0].find("Port name")
|
port_name_start = devices[0].find("Port name")
|
||||||
return [MidiPort(i[port_start:client_name_start].strip(), i[client_name_start:port_name_start].strip(), i[port_name_start:].strip()) for i in devices[1:]]
|
return [MidiPort(i[port_start:client_name_start].strip(), i[client_name_start:port_name_start].strip(), i[port_name_start:].strip()) for i in devices[1:]]
|
||||||
|
|
||||||
|
def stop_after_current(self):
|
||||||
|
self.play_mutex.acquire()
|
||||||
|
self.stop_after = self.stop_after_var.get() == "stop"
|
||||||
|
self.play_mutex.release()
|
||||||
|
|
||||||
def play_midi(self):
|
def play_midi(self):
|
||||||
sp.run(["aplaymidi", "-p", self.devices[self.midi_port_selector.current()].port, self.midi_file_var.get()])
|
self.play_mutex.acquire()
|
||||||
|
if self.is_playing:
|
||||||
|
self.play_mutex.release()
|
||||||
|
mb.showinfo(message="Another song cannot play until the previous song is finished playing.")
|
||||||
|
else:
|
||||||
|
self.play_mutex.release()
|
||||||
|
port = self.devices[self.midi_port_selector.current()].port
|
||||||
|
midis = [self.files[f] for f in self.midi_file_text.curselection()]
|
||||||
|
if len(midis) == 0:
|
||||||
|
midis = self.files
|
||||||
|
play_thread = threading.Thread(target=self.play_thread, args=(port, midis))
|
||||||
|
play_thread.start()
|
||||||
|
|
||||||
|
def play_thread(self, port: str, midis: list):
|
||||||
|
self.play_mutex.acquire()
|
||||||
|
self.is_playing = True
|
||||||
|
self.play_mutex.release()
|
||||||
|
for midi in midis:
|
||||||
|
sp.run(["aplaymidi", "-p", port, midi])
|
||||||
|
self.play_mutex.acquire()
|
||||||
|
if self.stop_after:
|
||||||
|
self.play_mutex.release()
|
||||||
|
break;
|
||||||
|
self.play_mutex.release()
|
||||||
|
self.play_mutex.acquire()
|
||||||
|
self.is_playing = False
|
||||||
|
self.play_mutex.release()
|
||||||
|
|
||||||
def open_file(self):
|
def open_file(self):
|
||||||
initial_dir = os.pwd()
|
initial_dir = os.getcwd()
|
||||||
if 'HOME' in os.environ:
|
if 'HOME' in os.environ:
|
||||||
initial_dir = os.environ['HOME']
|
initial_dir = os.environ['HOME']
|
||||||
self.midi_file_var.set(fd.askopenfilename(defaultextension=".mid", filetypes=[("MIDI", ".mid")], initialdir=initial_dir))
|
self.files = fd.askopenfilename(defaultextension=".mid", filetypes=[("MIDI", ".mid")], initialdir=initial_dir, multiple=True)
|
||||||
|
self.midi_file_var.set(self.files)
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
root = Tk()
|
root = Tk()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue