mirror of
https://github.com/Anjok07/ultimatevocalremovergui.git
synced 2024-12-01 02:27:21 +01:00
parent
531a9c9802
commit
3a16689c8e
302
VocalRemover.py
302
VocalRemover.py
@ -4,7 +4,6 @@ import tkinter.ttk as ttk
|
|||||||
import tkinter.messagebox
|
import tkinter.messagebox
|
||||||
import tkinter.filedialog
|
import tkinter.filedialog
|
||||||
import tkinter.font
|
import tkinter.font
|
||||||
from tkinterdnd2 import TkinterDnD, DND_FILES # Enable Drag & Drop
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
# Images
|
# Images
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -36,7 +35,6 @@ else:
|
|||||||
os.chdir(base_path) # Change the current working directory to the base path
|
os.chdir(base_path) # Change the current working directory to the base path
|
||||||
|
|
||||||
instrumentalModels_dir = os.path.join(base_path, 'models')
|
instrumentalModels_dir = os.path.join(base_path, 'models')
|
||||||
vocalModels_dir = os.path.join(base_path, 'models')
|
|
||||||
stackedModels_dir = os.path.join(base_path, 'models')
|
stackedModels_dir = os.path.join(base_path, 'models')
|
||||||
logo_path = os.path.join(base_path, 'img', 'UVR-logo.png')
|
logo_path = os.path.join(base_path, 'img', 'UVR-logo.png')
|
||||||
refresh_path = os.path.join(base_path, 'img', 'refresh.png')
|
refresh_path = os.path.join(base_path, 'img', 'refresh.png')
|
||||||
@ -170,30 +168,6 @@ def get_model_values(model_name):
|
|||||||
return model_values
|
return model_values
|
||||||
|
|
||||||
|
|
||||||
def drop(var, event, accept_mode: str = 'files'):
|
|
||||||
"""
|
|
||||||
Drag & Drop verification process
|
|
||||||
"""
|
|
||||||
path = event.data
|
|
||||||
|
|
||||||
if accept_mode == 'folder':
|
|
||||||
path = path.replace('{', '').replace('}', '')
|
|
||||||
if not os.path.isdir(path):
|
|
||||||
tk.messagebox.showerror(title='Invalid Folder',
|
|
||||||
message='Your given export path is not a valid folder!')
|
|
||||||
return
|
|
||||||
elif accept_mode == 'files':
|
|
||||||
# Clean path text and set path to the list of paths
|
|
||||||
path = path[:-1]
|
|
||||||
path = path.replace('{', '')
|
|
||||||
path = path.split('} ')
|
|
||||||
else:
|
|
||||||
# Invalid accept mode
|
|
||||||
return
|
|
||||||
|
|
||||||
var.set(path)
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadSafeConsole(tk.Text):
|
class ThreadSafeConsole(tk.Text):
|
||||||
"""
|
"""
|
||||||
Text Widget which is thread safe for tkinter
|
Text Widget which is thread safe for tkinter
|
||||||
@ -227,23 +201,23 @@ class ThreadSafeConsole(tk.Text):
|
|||||||
self.after(100, self.update_me)
|
self.after(100, self.update_me)
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(TkinterDnD.Tk):
|
class MainWindow(tk.Tk):
|
||||||
# --Constants--
|
# --Constants--
|
||||||
# Layout
|
# Layout
|
||||||
IMAGE_HEIGHT = 140
|
IMAGE_HEIGHT = 140
|
||||||
FILEPATHS_HEIGHT = 90
|
FILEPATHS_HEIGHT = 90
|
||||||
OPTIONS_HEIGHT = 280
|
OPTIONS_HEIGHT = 240
|
||||||
CONVERSIONBUTTON_HEIGHT = 35
|
CONVERSIONBUTTON_HEIGHT = 35
|
||||||
COMMAND_HEIGHT = 200
|
COMMAND_HEIGHT = 200
|
||||||
PROGRESS_HEIGHT = 26
|
PROGRESS_HEIGHT = 26
|
||||||
PADDING = 10
|
PADDING = 10
|
||||||
|
|
||||||
COL1_ROWS = 10
|
COL1_ROWS = 8
|
||||||
COL2_ROWS = 8
|
COL2_ROWS = 7
|
||||||
COL3_ROWS = 7
|
COL3_ROWS = 5
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Run the __init__ method on the TkinterDnD.Tk class
|
# Run the __init__ method on the tk.Tk class
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# Calculate window height
|
# Calculate window height
|
||||||
height = self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT
|
height = self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT
|
||||||
@ -259,7 +233,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
xpad=int(self.winfo_screenwidth()/2 - 550/2),
|
xpad=int(self.winfo_screenwidth()/2 - 550/2),
|
||||||
ypad=int(self.winfo_screenheight()/2 - height/2 - 30)))
|
ypad=int(self.winfo_screenheight()/2 - height/2 - 30)))
|
||||||
self.configure(bg='#000000') # Set background color to black
|
self.configure(bg='#000000') # Set background color to black
|
||||||
self.protocol("WM_DELETE_WINDOW", self.save_values)
|
|
||||||
self.resizable(False, False)
|
self.resizable(False, False)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
@ -269,25 +242,21 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
self.refresh_img = open_image(path=refresh_path,
|
self.refresh_img = open_image(path=refresh_path,
|
||||||
size=(20, 20))
|
size=(20, 20))
|
||||||
self.instrumentalLabel_to_path = defaultdict(lambda: '')
|
self.instrumentalLabel_to_path = defaultdict(lambda: '')
|
||||||
self.vocalLabel_to_path = defaultdict(lambda: '')
|
|
||||||
self.stackedLabel_to_path = defaultdict(lambda: '')
|
self.stackedLabel_to_path = defaultdict(lambda: '')
|
||||||
self.lastInstrumentalModels = []
|
self.lastInstrumentalModels = []
|
||||||
self.lastVocalModels = []
|
|
||||||
self.lastStackedModels = []
|
self.lastStackedModels = []
|
||||||
# -Tkinter Value Holders-
|
# -Tkinter Value Holders-
|
||||||
data = load_data()
|
data = load_data()
|
||||||
# Paths
|
# Paths
|
||||||
self.exportPath_var = tk.StringVar(value=data['export_path'])
|
self.exportPath_var = tk.StringVar(value=data['export_path'])
|
||||||
self.inputPaths_var = tk.StringVar(value='')
|
self.inputPaths = []
|
||||||
# Processing Options
|
# Processing Options
|
||||||
self.gpuConversion_var = tk.BooleanVar(value=data['gpu'])
|
self.gpuConversion_var = tk.BooleanVar(value=data['gpu'])
|
||||||
self.postprocessing_var = tk.BooleanVar(value=data['postprocess'])
|
self.postprocessing_var = tk.BooleanVar(value=data['postprocess'])
|
||||||
self.tta_var = tk.BooleanVar(value=data['tta'])
|
self.tta_var = tk.BooleanVar(value=data['tta'])
|
||||||
self.outputImage_var = tk.BooleanVar(value=data['output_image'])
|
self.outputImage_var = tk.BooleanVar(value=data['output_image'])
|
||||||
# Models
|
# Models
|
||||||
self.useModel_var = tk.StringVar(value=data['useModel'])
|
|
||||||
self.instrumentalModel_var = tk.StringVar(value='')
|
self.instrumentalModel_var = tk.StringVar(value='')
|
||||||
self.vocalModel_var = tk.StringVar(value='')
|
|
||||||
self.stackedModel_var = tk.StringVar(value='')
|
self.stackedModel_var = tk.StringVar(value='')
|
||||||
# Stacked Options
|
# Stacked Options
|
||||||
self.stack_var = tk.BooleanVar(value=data['stack'])
|
self.stack_var = tk.BooleanVar(value=data['stack'])
|
||||||
@ -311,7 +280,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
# --Widgets--
|
# --Widgets--
|
||||||
self.create_widgets()
|
self.create_widgets()
|
||||||
self.configure_widgets()
|
self.configure_widgets()
|
||||||
self.bind_widgets()
|
|
||||||
self.place_widgets()
|
self.place_widgets()
|
||||||
|
|
||||||
self.update_available_models()
|
self.update_available_models()
|
||||||
@ -353,21 +321,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
font=self.font, foreground='white')
|
font=self.font, foreground='white')
|
||||||
ttk.Style().configure('T', font=self.font, foreground='white')
|
ttk.Style().configure('T', font=self.font, foreground='white')
|
||||||
|
|
||||||
def bind_widgets(self):
|
|
||||||
"""Bind widgets to the drag & drop mechanic"""
|
|
||||||
self.filePaths_saveTo_Button.drop_target_register(DND_FILES)
|
|
||||||
self.filePaths_saveTo_Entry.drop_target_register(DND_FILES)
|
|
||||||
self.filePaths_musicFile_Button.drop_target_register(DND_FILES)
|
|
||||||
self.filePaths_musicFile_Entry.drop_target_register(DND_FILES)
|
|
||||||
self.filePaths_saveTo_Button.dnd_bind('<<Drop>>',
|
|
||||||
lambda e, var=self.exportPath_var: drop(var, e, accept_mode='folder'))
|
|
||||||
self.filePaths_saveTo_Entry.dnd_bind('<<Drop>>',
|
|
||||||
lambda e, var=self.exportPath_var: drop(var, e, accept_mode='folder'))
|
|
||||||
self.filePaths_musicFile_Button.dnd_bind('<<Drop>>',
|
|
||||||
lambda e, var=self.inputPaths_var: drop(var, e, accept_mode='files'))
|
|
||||||
self.filePaths_musicFile_Entry.dnd_bind('<<Drop>>',
|
|
||||||
lambda e, var=self.inputPaths_var: drop(var, e, accept_mode='files'))
|
|
||||||
|
|
||||||
def place_widgets(self):
|
def place_widgets(self):
|
||||||
"""Place main widgets"""
|
"""Place main widgets"""
|
||||||
self.title_Label.place(x=-2, y=-2)
|
self.title_Label.place(x=-2, y=-2)
|
||||||
@ -401,7 +354,7 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
text='Select Your Audio File(s)',
|
text='Select Your Audio File(s)',
|
||||||
command=self.open_file_filedialog)
|
command=self.open_file_filedialog)
|
||||||
self.filePaths_musicFile_Entry = ttk.Entry(master=self.filePaths_Frame,
|
self.filePaths_musicFile_Entry = ttk.Entry(master=self.filePaths_Frame,
|
||||||
textvariable=self.inputPaths_var,
|
text=self.inputPaths,
|
||||||
state=tk.DISABLED
|
state=tk.DISABLED
|
||||||
)
|
)
|
||||||
# -Place Widgets-
|
# -Place Widgets-
|
||||||
@ -440,18 +393,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
text='Output Image',
|
text='Output Image',
|
||||||
variable=self.outputImage_var,
|
variable=self.outputImage_var,
|
||||||
)
|
)
|
||||||
# Use Instrumental Model
|
|
||||||
self.options_instrumental_Radiobutton = ttk.Radiobutton(master=self.options_Frame,
|
|
||||||
text='Use Instrumental Model',
|
|
||||||
variable=self.useModel_var,
|
|
||||||
value='instrumental',
|
|
||||||
)
|
|
||||||
# Use Vocal Model
|
|
||||||
self.options_vocal_Radiobutton = ttk.Radiobutton(master=self.options_Frame,
|
|
||||||
text='Use Vocal Model',
|
|
||||||
variable=self.useModel_var,
|
|
||||||
value='vocal',
|
|
||||||
)
|
|
||||||
# Stack Loops
|
# Stack Loops
|
||||||
self.options_stack_Checkbutton = ttk.Checkbutton(master=self.options_Frame,
|
self.options_stack_Checkbutton = ttk.Checkbutton(master=self.options_Frame,
|
||||||
text='Stack Passes',
|
text='Stack Passes',
|
||||||
@ -516,12 +457,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
background='#a7a7a7', font=self.font, relief="ridge")
|
background='#a7a7a7', font=self.font, relief="ridge")
|
||||||
self.options_instrumentalModel_Optionmenu = ttk.OptionMenu(self.options_Frame,
|
self.options_instrumentalModel_Optionmenu = ttk.OptionMenu(self.options_Frame,
|
||||||
self.instrumentalModel_var)
|
self.instrumentalModel_var)
|
||||||
# Choose Vocal Model
|
|
||||||
self.options_vocalModel_Label = tk.Label(master=self.options_Frame,
|
|
||||||
text='Choose Vocal Model',
|
|
||||||
background='#a7a7a7', font=self.font, relief="ridge")
|
|
||||||
self.options_vocalModel_Optionmenu = ttk.OptionMenu(self.options_Frame,
|
|
||||||
self.vocalModel_var)
|
|
||||||
# Choose Stacked Model
|
# Choose Stacked Model
|
||||||
self.options_stackedModel_Label = tk.Label(master=self.options_Frame,
|
self.options_stackedModel_Label = tk.Label(master=self.options_Frame,
|
||||||
text='Choose Stacked Model',
|
text='Choose Stacked Model',
|
||||||
@ -542,23 +477,18 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
relx=0, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
relx=0, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
||||||
self.options_image_Checkbutton.place(x=0, y=0, width=0, height=0,
|
self.options_image_Checkbutton.place(x=0, y=0, width=0, height=0,
|
||||||
relx=0, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
relx=0, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
||||||
# Model
|
|
||||||
self.options_instrumental_Radiobutton.place(x=0, y=0, width=0, height=0,
|
|
||||||
relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
|
||||||
self.options_vocal_Radiobutton.place(x=0, y=0, width=0, height=0,
|
|
||||||
relx=0, rely=5/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
|
||||||
# Stacks
|
# Stacks
|
||||||
self.options_stack_Checkbutton.place(x=0, y=0, width=0, height=0,
|
self.options_stack_Checkbutton.place(x=0, y=0, width=0, height=0,
|
||||||
relx=0, rely=6/self.COL1_ROWS, relwidth=1/3/4*3, relheight=1/self.COL1_ROWS)
|
relx=0, rely=4/self.COL1_ROWS, relwidth=1/3/4*3, relheight=1/self.COL1_ROWS)
|
||||||
self.options_stack_Entry.place(x=0, y=3, width=0, height=-6,
|
self.options_stack_Entry.place(x=0, y=3, width=0, height=-6,
|
||||||
relx=1/3/4*2.4, rely=6/self.COL1_ROWS, relwidth=1/3/4*0.9, relheight=1/self.COL1_ROWS)
|
relx=1/3/4*2.4, rely=4/self.COL1_ROWS, relwidth=1/3/4*0.9, relheight=1/self.COL1_ROWS)
|
||||||
self.options_stackOnly_Checkbutton.place(x=0, y=0, width=0, height=0,
|
self.options_stackOnly_Checkbutton.place(x=0, y=0, width=0, height=0,
|
||||||
relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
relx=0, rely=5/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
||||||
self.options_saveStack_Checkbutton.place(x=0, y=0, width=0, height=0,
|
self.options_saveStack_Checkbutton.place(x=0, y=0, width=0, height=0,
|
||||||
relx=0, rely=8/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
relx=0, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
||||||
# Model Folder
|
# Model Folder
|
||||||
self.options_modelFolder_Checkbutton.place(x=0, y=0, width=0, height=0,
|
self.options_modelFolder_Checkbutton.place(x=0, y=0, width=0, height=0,
|
||||||
relx=0, rely=9/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
||||||
# -Column 2-
|
# -Column 2-
|
||||||
# SR
|
# SR
|
||||||
self.options_sr_Label.place(x=5, y=4, width=5, height=-8,
|
self.options_sr_Label.place(x=5, y=4, width=5, height=-8,
|
||||||
@ -581,40 +511,32 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
self.options_nfft_Entry.place(x=15, y=4, width=5, height=-8,
|
self.options_nfft_Entry.place(x=15, y=4, width=5, height=-8,
|
||||||
relx=1/3 + 1/3/2, rely=3/self.COL2_ROWS, relwidth=1/3/4, relheight=1/self.COL2_ROWS)
|
relx=1/3 + 1/3/2, rely=3/self.COL2_ROWS, relwidth=1/3/4, relheight=1/self.COL2_ROWS)
|
||||||
# AI model
|
# AI model
|
||||||
self.options_aiModel_Label.place(x=5, y=4, width=-30, height=-8,
|
self.options_aiModel_Label.place(x=5, y=-5, width=-30, height=-8,
|
||||||
relx=1/3, rely=5/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
|
relx=1/3, rely=5/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
|
||||||
self.options_aiModel_Optionmenu.place(x=5, y=4, width=-30, height=-8,
|
self.options_aiModel_Optionmenu.place(x=5, y=-5, width=-30, height=-8,
|
||||||
relx=1/3, rely=6/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
|
relx=1/3, rely=6/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
|
||||||
|
|
||||||
# -Column 3-
|
# -Column 3-
|
||||||
# Choose Model
|
# Choose Model
|
||||||
self.options_instrumentalModel_Label.place(x=0, y=-5, width=0, height=-10,
|
self.options_instrumentalModel_Label.place(x=0, y=0, width=0, height=-10,
|
||||||
relx=2/3, rely=0, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
relx=2/3, rely=0, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
||||||
self.options_instrumentalModel_Optionmenu.place(x=15, y=-10, width=-30, height=-2,
|
self.options_instrumentalModel_Optionmenu.place(x=15, y=-4, width=-30, height=-13,
|
||||||
relx=2/3, rely=1/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
relx=2/3, rely=1/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
||||||
self.options_vocalModel_Label.place(x=0, y=-5, width=0, height=-10,
|
self.options_stackedModel_Label.place(x=0, y=0, width=0, height=-10,
|
||||||
relx=2/3, rely=2/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
relx=2/3, rely=2/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
||||||
self.options_vocalModel_Optionmenu.place(x=15, y=-10, width=-30, height=-2,
|
self.options_stackedModel_Optionmenu.place(x=15, y=-4, width=-30, height=-13,
|
||||||
relx=2/3, rely=3/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
relx=2/3, rely=3/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
||||||
self.options_stackedModel_Label.place(x=0, y=-5, width=0, height=-10,
|
self.options_model_Button.place(x=15, y=3, width=-30, height=-8,
|
||||||
relx=2/3, rely=4/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
relx=2/3, rely=4/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
||||||
self.options_stackedModel_Optionmenu.place(x=15, y=-10, width=-30, height=-2,
|
|
||||||
relx=2/3, rely=5/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
|
||||||
self.options_model_Button.place(x=15, y=0, width=-30, height=1,
|
|
||||||
relx=2/3, rely=6/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS)
|
|
||||||
|
|
||||||
# -Update Binds-
|
# -Update Binds-
|
||||||
self.options_stackOnly_Checkbutton.configure(command=self.update_states) # nopep8
|
self.options_stackOnly_Checkbutton.configure(command=self.update_states) # nopep8
|
||||||
self.options_stack_Checkbutton.configure(command=self.update_states) # nopep8
|
self.options_stack_Checkbutton.configure(command=self.update_states) # nopep8
|
||||||
self.options_stack_Entry.bind('<FocusOut>',
|
self.options_stack_Entry.bind('<FocusOut>',
|
||||||
lambda e: self.update_states())
|
lambda e: self.update_states())
|
||||||
self.options_instrumental_Radiobutton.configure(command=self.update_states) # nopep8
|
|
||||||
self.options_vocal_Radiobutton.configure(command=self.update_states)
|
|
||||||
# Model name decoding
|
# Model name decoding
|
||||||
self.instrumentalModel_var.trace_add('write',
|
self.instrumentalModel_var.trace_add('write',
|
||||||
lambda *args: self.decode_modelNames())
|
lambda *args: self.decode_modelNames())
|
||||||
self.vocalModel_var.trace_add('write',
|
|
||||||
lambda *args: self.decode_modelNames())
|
|
||||||
self.stackedModel_var.trace_add('write',
|
self.stackedModel_var.trace_add('write',
|
||||||
lambda *args: self.decode_modelNames())
|
lambda *args: self.decode_modelNames())
|
||||||
# Model deselect
|
# Model deselect
|
||||||
@ -635,8 +557,13 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
initialdir=self.lastDir,
|
initialdir=self.lastDir,
|
||||||
)
|
)
|
||||||
if paths: # Path selected
|
if paths: # Path selected
|
||||||
|
self.inputPaths = paths
|
||||||
|
# Change the entry text
|
||||||
|
self.filePaths_musicFile_Entry.configure(state=tk.NORMAL)
|
||||||
|
self.filePaths_musicFile_Entry.delete(0, tk.END)
|
||||||
|
self.filePaths_musicFile_Entry.insert(0, self.inputPaths)
|
||||||
|
self.filePaths_musicFile_Entry.configure(state=tk.DISABLED)
|
||||||
|
|
||||||
self.inputPaths_var.set(paths)
|
|
||||||
self.lastDir = os.path.dirname(paths[0])
|
self.lastDir = os.path.dirname(paths[0])
|
||||||
|
|
||||||
def open_export_filedialog(self):
|
def open_export_filedialog(self):
|
||||||
@ -657,16 +584,13 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
"""
|
"""
|
||||||
# -Get all variables-
|
# -Get all variables-
|
||||||
export_path = self.exportPath_var.get()
|
export_path = self.exportPath_var.get()
|
||||||
input_paths = self.inputPaths_var.get()
|
|
||||||
instrumentalModel_path = self.instrumentalLabel_to_path[self.instrumentalModel_var.get()] # nopep8
|
instrumentalModel_path = self.instrumentalLabel_to_path[self.instrumentalModel_var.get()] # nopep8
|
||||||
vocalModel_path = self.vocalLabel_to_path[self.vocalModel_var.get()]
|
|
||||||
stackedModel_path = self.stackedLabel_to_path[self.stackedModel_var.get()] # nopep8
|
stackedModel_path = self.stackedLabel_to_path[self.stackedModel_var.get()] # nopep8
|
||||||
# Get constants
|
# Get constants
|
||||||
instrumental = get_model_values(self.instrumentalModel_var.get())
|
instrumental = get_model_values(self.instrumentalModel_var.get())
|
||||||
vocal = get_model_values(self.vocalModel_var.get())
|
|
||||||
stacked = get_model_values(self.stackedModel_var.get())
|
stacked = get_model_values(self.stackedModel_var.get())
|
||||||
try:
|
try:
|
||||||
if [bool(instrumental), bool(vocal), bool(stacked)].count(True) == 2:
|
if [bool(instrumental), bool(stacked)].count(True) == 2:
|
||||||
sr = DEFAULT_DATA['sr']
|
sr = DEFAULT_DATA['sr']
|
||||||
hop_length = DEFAULT_DATA['hop_length']
|
hop_length = DEFAULT_DATA['hop_length']
|
||||||
window_size = DEFAULT_DATA['window_size']
|
window_size = DEFAULT_DATA['window_size']
|
||||||
@ -689,12 +613,11 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# -Check for invalid inputs-
|
# -Check for invalid inputs-
|
||||||
for path in input_paths:
|
if not any([(os.path.isfile(path) and path.endswith(('.mp3', '.mp4', '.m4a', '.flac', '.wav')))
|
||||||
if not os.path.isfile(path):
|
for path in self.inputPaths]):
|
||||||
tk.messagebox.showwarning(master=self,
|
tk.messagebox.showwarning(master=self,
|
||||||
title='Invalid Music File',
|
title='Invalid Music File',
|
||||||
message='You have selected an invalid music file! Please make sure that the file still exists!',
|
message='You have selected an invalid music file!\nPlease make sure that your files still exist and ends with either ".mp3", ".mp4", ".m4a", ".flac", ".wav"')
|
||||||
detail=f'File path: {path}')
|
|
||||||
return
|
return
|
||||||
if not os.path.isdir(export_path):
|
if not os.path.isdir(export_path):
|
||||||
tk.messagebox.showwarning(master=self,
|
tk.messagebox.showwarning(master=self,
|
||||||
@ -702,21 +625,11 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
message='You have selected an invalid export directory!\nPlease make sure that your directory still exists!')
|
message='You have selected an invalid export directory!\nPlease make sure that your directory still exists!')
|
||||||
return
|
return
|
||||||
if not self.stackOnly_var.get():
|
if not self.stackOnly_var.get():
|
||||||
if self.useModel_var.get() == 'instrumental':
|
|
||||||
if not os.path.isfile(instrumentalModel_path):
|
if not os.path.isfile(instrumentalModel_path):
|
||||||
tk.messagebox.showwarning(master=self,
|
tk.messagebox.showwarning(master=self,
|
||||||
title='Invalid Instrumental Model File',
|
title='Invalid Instrumental Model File',
|
||||||
message='You have selected an invalid instrumental model file!\nPlease make sure that your model file still exists!')
|
message='You have selected an invalid instrumental model file!\nPlease make sure that your model file still exists!')
|
||||||
return
|
return
|
||||||
elif self.useModel_var.get() == 'vocal':
|
|
||||||
if not os.path.isfile(vocalModel_path):
|
|
||||||
tk.messagebox.showwarning(master=self,
|
|
||||||
title='Invalid Vocal Model File',
|
|
||||||
message='You have selected an invalid vocal model file!\nPlease make sure that your model file still exists!')
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
print('THIS SHOULD NOT HAPPEN')
|
|
||||||
exit()
|
|
||||||
if (self.stackOnly_var.get() or
|
if (self.stackOnly_var.get() or
|
||||||
stackPasses > 0):
|
stackPasses > 0):
|
||||||
if not os.path.isfile(stackedModel_path):
|
if not os.path.isfile(stackedModel_path):
|
||||||
@ -725,6 +638,27 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
message='You have selected an invalid stacked model file!\nPlease make sure that your model file still exists!')
|
message='You have selected an invalid stacked model file!\nPlease make sure that your model file still exists!')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# -Save Data-
|
||||||
|
save_data(data={
|
||||||
|
'export_path': export_path,
|
||||||
|
'gpu': self.gpuConversion_var.get(),
|
||||||
|
'postprocess': self.postprocessing_var.get(),
|
||||||
|
'tta': self.tta_var.get(),
|
||||||
|
'output_image': self.outputImage_var.get(),
|
||||||
|
'stack': self.stack_var.get(),
|
||||||
|
'stackOnly': self.stackOnly_var.get(),
|
||||||
|
'stackPasses': stackPasses,
|
||||||
|
'saveAllStacked': self.saveAllStacked_var.get(),
|
||||||
|
'sr': sr,
|
||||||
|
'hop_length': hop_length,
|
||||||
|
'window_size': window_size,
|
||||||
|
'n_fft': n_fft,
|
||||||
|
'useModel': 'instrumental', # Always instrumental
|
||||||
|
'lastDir': self.lastDir,
|
||||||
|
'modelFolder': self.modelFolder_var.get(),
|
||||||
|
'aiModel': self.aiModel_var.get(),
|
||||||
|
})
|
||||||
|
|
||||||
if self.aiModel_var.get() == 'v2':
|
if self.aiModel_var.get() == 'v2':
|
||||||
inference = inference_v2
|
inference = inference_v2
|
||||||
elif self.aiModel_var.get() == 'v4':
|
elif self.aiModel_var.get() == 'v4':
|
||||||
@ -736,7 +670,7 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
threading.Thread(target=inference.main,
|
threading.Thread(target=inference.main,
|
||||||
kwargs={
|
kwargs={
|
||||||
# Paths
|
# Paths
|
||||||
'input_paths': input_paths,
|
'input_paths': self.inputPaths,
|
||||||
'export_path': export_path,
|
'export_path': export_path,
|
||||||
# Processing Options
|
# Processing Options
|
||||||
'gpu': 0 if self.gpuConversion_var.get() else -1,
|
'gpu': 0 if self.gpuConversion_var.get() else -1,
|
||||||
@ -745,9 +679,9 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
'output_image': self.outputImage_var.get(),
|
'output_image': self.outputImage_var.get(),
|
||||||
# Models
|
# Models
|
||||||
'instrumentalModel': instrumentalModel_path,
|
'instrumentalModel': instrumentalModel_path,
|
||||||
'vocalModel': vocalModel_path,
|
'vocalModel': '', # Always not needed
|
||||||
'stackModel': stackedModel_path,
|
'stackModel': stackedModel_path,
|
||||||
'useModel': self.useModel_var.get(),
|
'useModel': 'instrumental', # Always instrumental
|
||||||
# Stack Options
|
# Stack Options
|
||||||
'stackPasses': stackPasses,
|
'stackPasses': stackPasses,
|
||||||
'stackOnly': self.stackOnly_var.get(),
|
'stackOnly': self.stackOnly_var.get(),
|
||||||
@ -775,12 +709,10 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
"""
|
"""
|
||||||
# Check state of model selectors
|
# Check state of model selectors
|
||||||
instrumental_selectable = bool(str(self.options_instrumentalModel_Optionmenu.cget('state')) == 'normal')
|
instrumental_selectable = bool(str(self.options_instrumentalModel_Optionmenu.cget('state')) == 'normal')
|
||||||
vocal_selectable = bool(str(self.options_vocalModel_Optionmenu.cget('state')) == 'normal')
|
|
||||||
stacked_selectable = bool(str(self.options_stackedModel_Optionmenu.cget('state')) == 'normal')
|
stacked_selectable = bool(str(self.options_stackedModel_Optionmenu.cget('state')) == 'normal')
|
||||||
|
|
||||||
# Extract data from models name
|
# Extract data from models name
|
||||||
instrumental = get_model_values(self.instrumentalModel_var.get())
|
instrumental = get_model_values(self.instrumentalModel_var.get())
|
||||||
vocal = get_model_values(self.vocalModel_var.get())
|
|
||||||
stacked = get_model_values(self.stackedModel_var.get())
|
stacked = get_model_values(self.stackedModel_var.get())
|
||||||
|
|
||||||
# Assign widgets to constants
|
# Assign widgets to constants
|
||||||
@ -790,33 +722,32 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
'window_size': [self.options_winSize_Entry, self.winSize_var],
|
'window_size': [self.options_winSize_Entry, self.winSize_var],
|
||||||
'n_fft': [self.options_nfft_Entry, self.nfft_var],
|
'n_fft': [self.options_nfft_Entry, self.nfft_var],
|
||||||
}
|
}
|
||||||
# Obtain data from instrumental or vocal (based on what is selected)
|
|
||||||
modelData = instrumental if bool(instrumental) else vocal
|
|
||||||
modelData_selectable = (instrumental_selectable or vocal_selectable)
|
|
||||||
|
|
||||||
# Loop through each constant (key) and its widgets
|
# Loop through each constant (key) and its widgets
|
||||||
for key, (widget, var) in widgetsVars.items():
|
for key, (widget, var) in widgetsVars.items():
|
||||||
if stacked_selectable:
|
if stacked_selectable:
|
||||||
if modelData_selectable:
|
# Stacked model can be selected
|
||||||
if (key in modelData.keys() and
|
|
||||||
key in stacked.keys()):
|
|
||||||
# Both models have set constants
|
|
||||||
widget.configure(state=tk.DISABLED)
|
|
||||||
var.set('%d/%d' % (modelData[key], stacked[key]))
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if key in stacked.keys():
|
if key in stacked.keys():
|
||||||
|
if (key in stacked.keys() and
|
||||||
|
not instrumental_selectable):
|
||||||
# Only stacked selectable
|
# Only stacked selectable
|
||||||
widget.configure(state=tk.DISABLED)
|
widget.configure(state=tk.DISABLED)
|
||||||
var.set(stacked[key])
|
var.set(stacked[key])
|
||||||
continue
|
continue
|
||||||
|
elif (key in instrumental.keys() and
|
||||||
|
instrumental_selectable):
|
||||||
|
# Both models have set constants
|
||||||
|
widget.configure(state=tk.DISABLED)
|
||||||
|
var.set('%d/%d' % (instrumental[key], stacked[key]))
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
# Stacked model can not be selected
|
# Stacked model can not be selected
|
||||||
if (key in modelData.keys() and
|
if (key in instrumental.keys() and
|
||||||
modelData_selectable):
|
instrumental_selectable):
|
||||||
widget.configure(state=tk.DISABLED)
|
widget.configure(state=tk.DISABLED)
|
||||||
var.set(modelData[key])
|
var.set(instrumental[key])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If widget is already enabled, no need to reset the value
|
# If widget is already enabled, no need to reset the value
|
||||||
if str(widget.cget('state')) != 'normal':
|
if str(widget.cget('state')) != 'normal':
|
||||||
widget.configure(state=tk.NORMAL)
|
widget.configure(state=tk.NORMAL)
|
||||||
@ -834,7 +765,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
and add to the select your model list
|
and add to the select your model list
|
||||||
"""
|
"""
|
||||||
temp_instrumentalModels_dir = os.path.join(instrumentalModels_dir, self.aiModel_var.get(), 'Instrumental Models') # nopep8
|
temp_instrumentalModels_dir = os.path.join(instrumentalModels_dir, self.aiModel_var.get(), 'Instrumental Models') # nopep8
|
||||||
temp_vocalModels_dir = os.path.join(vocalModels_dir, self.aiModel_var.get(), 'Vocal Models')
|
|
||||||
temp_stackedModels_dir = os.path.join(stackedModels_dir, self.aiModel_var.get(), 'Stacked Models')
|
temp_stackedModels_dir = os.path.join(stackedModels_dir, self.aiModel_var.get(), 'Stacked Models')
|
||||||
# Instrumental models
|
# Instrumental models
|
||||||
new_InstrumentalModels = os.listdir(temp_instrumentalModels_dir)
|
new_InstrumentalModels = os.listdir(temp_instrumentalModels_dir)
|
||||||
@ -849,19 +779,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
# Link the files name to its absolute path
|
# Link the files name to its absolute path
|
||||||
self.instrumentalLabel_to_path[file_name] = os.path.join(temp_instrumentalModels_dir, file_name) # nopep8
|
self.instrumentalLabel_to_path[file_name] = os.path.join(temp_instrumentalModels_dir, file_name) # nopep8
|
||||||
self.lastInstrumentalModels = new_InstrumentalModels
|
self.lastInstrumentalModels = new_InstrumentalModels
|
||||||
# Vocal models
|
|
||||||
new_VocalModels = os.listdir(temp_vocalModels_dir)
|
|
||||||
if new_VocalModels != self.lastVocalModels:
|
|
||||||
self.vocalLabel_to_path.clear()
|
|
||||||
self.options_vocalModel_Optionmenu['menu'].delete(0, 'end')
|
|
||||||
for file_name in new_VocalModels:
|
|
||||||
if file_name.endswith('.pth'):
|
|
||||||
# Add Radiobutton to the Options Menu
|
|
||||||
self.options_vocalModel_Optionmenu['menu'].add_radiobutton(label=file_name,
|
|
||||||
command=tk._setit(self.vocalModel_var, file_name))
|
|
||||||
# Link the files name to its absolute path
|
|
||||||
self.vocalLabel_to_path[file_name] = os.path.join(temp_vocalModels_dir, file_name) # nopep8
|
|
||||||
self.lastVocalModels = new_VocalModels
|
|
||||||
# Stacked models
|
# Stacked models
|
||||||
new_stackedModels = os.listdir(temp_stackedModels_dir)
|
new_stackedModels = os.listdir(temp_stackedModels_dir)
|
||||||
if new_stackedModels != self.lastStackedModels:
|
if new_stackedModels != self.lastStackedModels:
|
||||||
@ -897,14 +814,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
self.stackLoops_var.set(0)
|
self.stackLoops_var.set(0)
|
||||||
stackLoops = 0
|
stackLoops = 0
|
||||||
|
|
||||||
# Radiobuttons
|
|
||||||
if self.stackOnly_var.get():
|
|
||||||
self.options_instrumental_Radiobutton.configure(text='Stack Instrumental')
|
|
||||||
self.options_vocal_Radiobutton.configure(text='Stack Vocal')
|
|
||||||
else:
|
|
||||||
self.options_instrumental_Radiobutton.configure(text='Use Instrumental Model')
|
|
||||||
self.options_vocal_Radiobutton.configure(text='Use Vocal Model')
|
|
||||||
|
|
||||||
# Stack Only and Save All Outputs
|
# Stack Only and Save All Outputs
|
||||||
if stackLoops > 0:
|
if stackLoops > 0:
|
||||||
self.options_stackOnly_Checkbutton.configure(state=tk.NORMAL)
|
self.options_stackOnly_Checkbutton.configure(state=tk.NORMAL)
|
||||||
@ -921,37 +830,15 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
self.options_instrumentalModel_Label.configure(foreground='#777')
|
self.options_instrumentalModel_Label.configure(foreground='#777')
|
||||||
self.options_instrumentalModel_Optionmenu.configure(state=tk.DISABLED) # nopep8
|
self.options_instrumentalModel_Optionmenu.configure(state=tk.DISABLED) # nopep8
|
||||||
self.instrumentalModel_var.set('')
|
self.instrumentalModel_var.set('')
|
||||||
# Vocal Model
|
|
||||||
self.options_vocalModel_Label.configure(foreground='#777')
|
|
||||||
self.options_vocalModel_Optionmenu.configure(state=tk.DISABLED)
|
|
||||||
self.vocalModel_var.set('')
|
|
||||||
# Stack Model
|
# Stack Model
|
||||||
self.options_stackedModel_Label.configure(foreground='#000')
|
self.options_stackedModel_Label.configure(foreground='#000')
|
||||||
self.options_stackedModel_Optionmenu.configure(state=tk.NORMAL) # nopep8
|
self.options_stackedModel_Optionmenu.configure(state=tk.NORMAL) # nopep8
|
||||||
elif self.useModel_var.get() == 'instrumental':
|
else:
|
||||||
# Instrumental Model
|
# Instrumental Model
|
||||||
self.options_instrumentalModel_Label.configure(foreground='#000')
|
self.options_instrumentalModel_Label.configure(foreground='#000')
|
||||||
self.options_instrumentalModel_Optionmenu.configure(state=tk.NORMAL) # nopep8
|
self.options_instrumentalModel_Optionmenu.configure(state=tk.NORMAL) # nopep8
|
||||||
# Vocal Model
|
|
||||||
self.options_vocalModel_Label.configure(foreground='#777')
|
|
||||||
self.options_vocalModel_Optionmenu.configure(state=tk.DISABLED)
|
|
||||||
self.vocalModel_var.set('')
|
|
||||||
# Stack Model
|
|
||||||
if stackLoops > 0:
|
|
||||||
self.options_stackedModel_Label.configure(foreground='#000')
|
|
||||||
self.options_stackedModel_Optionmenu.configure(state=tk.NORMAL) # nopep8
|
|
||||||
else:
|
|
||||||
self.options_stackedModel_Label.configure(foreground='#777')
|
|
||||||
self.options_stackedModel_Optionmenu.configure(state=tk.DISABLED) # nopep8
|
|
||||||
self.stackedModel_var.set('')
|
|
||||||
else:
|
|
||||||
# Instrumental Model
|
|
||||||
self.options_instrumentalModel_Label.configure(foreground='#777')
|
|
||||||
self.options_instrumentalModel_Optionmenu.configure(state=tk.DISABLED) # nopep8
|
|
||||||
self.instrumentalModel_var.set('')
|
self.instrumentalModel_var.set('')
|
||||||
# Vocal Model
|
|
||||||
self.options_vocalModel_Label.configure(foreground='#000')
|
|
||||||
self.options_vocalModel_Optionmenu.configure(state=tk.NORMAL)
|
|
||||||
# Stack Model
|
# Stack Model
|
||||||
if stackLoops > 0:
|
if stackLoops > 0:
|
||||||
self.options_stackedModel_Label.configure(foreground='#000')
|
self.options_stackedModel_Label.configure(foreground='#000')
|
||||||
@ -984,7 +871,6 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
self.last_aiModel = self.aiModel_var.get()
|
self.last_aiModel = self.aiModel_var.get()
|
||||||
|
|
||||||
self.instrumentalModel_var.set('')
|
self.instrumentalModel_var.set('')
|
||||||
self.vocalModel_var.set('')
|
|
||||||
self.stackedModel_var.set('')
|
self.stackedModel_var.set('')
|
||||||
|
|
||||||
self.srValue_var.set(DEFAULT_DATA['sr'])
|
self.srValue_var.set(DEFAULT_DATA['sr'])
|
||||||
@ -999,56 +885,12 @@ class MainWindow(TkinterDnD.Tk):
|
|||||||
"""
|
"""
|
||||||
Restart the application after asking for confirmation
|
Restart the application after asking for confirmation
|
||||||
"""
|
"""
|
||||||
save = tk.messagebox.askyesno(title='Confirmation',
|
proceed = tk.messagebox.askyesno(title='Confirmation',
|
||||||
message='The application will restart. Do you want to save the data?')
|
message='The application will restart and lose unsaved data. Do you wish to proceed?')
|
||||||
if save:
|
if proceed:
|
||||||
self.save_values()
|
|
||||||
subprocess.Popen(f'python "{__file__}"', shell=True)
|
subprocess.Popen(f'python "{__file__}"', shell=True)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
def save_values(self):
|
|
||||||
"""
|
|
||||||
Save the data of the application
|
|
||||||
"""
|
|
||||||
export_path = self.exportPath_var.get()
|
|
||||||
# Get constants
|
|
||||||
instrumental = get_model_values(self.instrumentalModel_var.get())
|
|
||||||
vocal = get_model_values(self.vocalModel_var.get())
|
|
||||||
stacked = get_model_values(self.stackedModel_var.get())
|
|
||||||
if [bool(instrumental), bool(vocal), bool(stacked)].count(True) == 2:
|
|
||||||
sr = DEFAULT_DATA['sr']
|
|
||||||
hop_length = DEFAULT_DATA['hop_length']
|
|
||||||
window_size = DEFAULT_DATA['window_size']
|
|
||||||
n_fft = DEFAULT_DATA['n_fft']
|
|
||||||
else:
|
|
||||||
sr = self.srValue_var.get()
|
|
||||||
hop_length = self.hopValue_var.get()
|
|
||||||
window_size = self.winSize_var.get()
|
|
||||||
n_fft = self.nfft_var.get()
|
|
||||||
|
|
||||||
# -Save Data-
|
|
||||||
save_data(data={
|
|
||||||
'export_path': export_path,
|
|
||||||
'gpu': self.gpuConversion_var.get(),
|
|
||||||
'postprocess': self.postprocessing_var.get(),
|
|
||||||
'tta': self.tta_var.get(),
|
|
||||||
'output_image': self.outputImage_var.get(),
|
|
||||||
'stack': self.stack_var.get(),
|
|
||||||
'stackOnly': self.stackOnly_var.get(),
|
|
||||||
'stackPasses': self.stackLoops_var.get(),
|
|
||||||
'saveAllStacked': self.saveAllStacked_var.get(),
|
|
||||||
'sr': sr,
|
|
||||||
'hop_length': hop_length,
|
|
||||||
'window_size': window_size,
|
|
||||||
'n_fft': n_fft,
|
|
||||||
'useModel': self.useModel_var.get(),
|
|
||||||
'lastDir': self.lastDir,
|
|
||||||
'modelFolder': self.modelFolder_var.get(),
|
|
||||||
'aiModel': self.aiModel_var.get(),
|
|
||||||
})
|
|
||||||
|
|
||||||
self.destroy()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
root = MainWindow()
|
root = MainWindow()
|
||||||
|
Loading…
Reference in New Issue
Block a user