mirror of
https://github.com/Anjok07/ultimatevocalremovergui.git
synced 2025-02-20 04:21:03 +01:00
Update UVR.py
This commit is contained in:
parent
82769c7acd
commit
ac0435bcfc
360
UVR.py
360
UVR.py
@ -57,6 +57,7 @@ import sys
|
||||
import yaml
|
||||
from ml_collections import ConfigDict
|
||||
from collections import Counter
|
||||
from os.path import expanduser
|
||||
|
||||
if not is_macos:
|
||||
import torch_directml
|
||||
@ -253,7 +254,16 @@ SETTINGS_CACHE_DIR = os.path.join(BASE_PATH, 'gui_data', 'saved_settings')
|
||||
VR_PARAM_DIR = os.path.join(BASE_PATH, 'lib_v5', 'vr_network', 'modelparams')
|
||||
SAMPLE_CLIP_PATH = os.path.join(BASE_PATH, 'temp_sample_clips')
|
||||
ENSEMBLE_TEMP_PATH = os.path.join(BASE_PATH, 'ensemble_temps')
|
||||
DOWNLOAD_MODEL_CACHE = os.path.join(BASE_PATH, 'gui_data', 'model_manual_download.json')
|
||||
DOWNLOAD_MODEL_CACHE = os.path.join(BASE_PATH, 'gui_data', 'model_manual_download.json')#
|
||||
|
||||
# if is_macos:
|
||||
APP_DIR_DATA = os.path.join(expanduser("~"), "UVR Conversions")
|
||||
DEFAULT_SAVE_PATH = os.path.join(APP_DIR_DATA)
|
||||
# else:
|
||||
# DEFAULT_SAVE_PATH = os.path.join(BASE_PATH, 'completed')
|
||||
|
||||
if not os.path.isdir(DEFAULT_SAVE_PATH):
|
||||
os.mkdir(DEFAULT_SAVE_PATH)
|
||||
|
||||
#CR Text
|
||||
CR_TEXT = os.path.join(BASE_PATH, 'gui_data', 'cr_text.txt')
|
||||
@ -311,7 +321,15 @@ def drop(event, accept_mode: str = 'files'):
|
||||
title=INVALID_FOLDER_ERROR_TEXT[0],
|
||||
message=INVALID_FOLDER_ERROR_TEXT[1])
|
||||
return
|
||||
|
||||
if not can_write_to_directory(path):
|
||||
messagebox.showerror(parent=root,
|
||||
title=INVALID_FOLDER_ERROR_UNWRITABLE_TEXT[0],
|
||||
message=INVALID_FOLDER_ERROR_UNWRITABLE_TEXT[1])
|
||||
return
|
||||
|
||||
root.export_path_var.set(path)
|
||||
root.last_export_path_var.set(path)
|
||||
elif accept_mode in ['files', FILE_1, FILE_2, FILE_1_LB, FILE_2_LB]:
|
||||
path = path.replace("{", "").replace("}", "")
|
||||
for dnd_file in dnd_path_check:
|
||||
@ -323,6 +341,7 @@ def drop(event, accept_mode: str = 'files'):
|
||||
root.inputPaths = tuple(path)
|
||||
root.process_input_selections()
|
||||
root.update_inputPaths()
|
||||
root.switch_export_dir()
|
||||
elif accept_mode in [FILE_1, FILE_2]:
|
||||
if len(path) == 2:
|
||||
root.select_audiofile(path[0])
|
||||
@ -447,6 +466,7 @@ class ModelData():
|
||||
self.is_inst_only_voc_splitter = root.check_only_selection_stem(INST_STEM_ONLY)
|
||||
self.is_save_vocal_only = root.check_only_selection_stem(IS_SAVE_VOC_ONLY)
|
||||
self.is_roformer = False
|
||||
self.is_target_instrument = False
|
||||
|
||||
if selected_process_method == ENSEMBLE_MODE:
|
||||
self.process_method, _, self.model_name = model_name.partition(ENSEMBLE_PARTITION)
|
||||
@ -478,6 +498,7 @@ class ModelData():
|
||||
self.model_path = os.path.join(VR_MODELS_DIR, f"{self.model_name}.pth")
|
||||
self.get_model_hash()
|
||||
if self.model_hash:
|
||||
print(self.model_hash)
|
||||
self.model_hash_dir = os.path.join(VR_HASH_DIR, f"{self.model_hash}.json")
|
||||
if is_change_def:
|
||||
self.model_data = self.change_model_data()
|
||||
@ -525,6 +546,7 @@ class ModelData():
|
||||
self.mdx_c_configs = config
|
||||
|
||||
if self.mdx_c_configs.training.target_instrument:
|
||||
self.is_target_instrument = True
|
||||
# Use target_instrument as the primary stem and set 4-stem ensemble to False
|
||||
target = self.mdx_c_configs.training.target_instrument
|
||||
self.mdx_model_stems = [target]
|
||||
@ -533,6 +555,8 @@ class ModelData():
|
||||
if self.is_roformer and self.mdx_c_configs.training.target_instrument == VOCAL_STEM and self.is_ensemble_mode:
|
||||
self.mdxnet_stem_select = self.ensemble_primary_stem
|
||||
|
||||
print("self.primary_stem target", self.primary_stem)
|
||||
|
||||
else:
|
||||
# If no specific target_instrument, use all instruments in the training config
|
||||
self.mdx_model_stems = self.mdx_c_configs.training.instruments
|
||||
@ -547,7 +571,6 @@ class ModelData():
|
||||
# Update mdxnet_stem_select based on ensemble mode
|
||||
if self.is_ensemble_mode:
|
||||
self.mdxnet_stem_select = self.ensemble_primary_stem
|
||||
|
||||
else:
|
||||
self.model_status = False
|
||||
else:
|
||||
@ -559,6 +582,8 @@ class ModelData():
|
||||
self.primary_stem_native = self.model_data["primary_stem"]
|
||||
self.check_if_karaokee_model()
|
||||
|
||||
|
||||
print("self.primary_stem final", self.primary_stem)
|
||||
self.secondary_stem = secondary_stem(self.primary_stem)
|
||||
else:
|
||||
self.model_status = False
|
||||
@ -769,18 +794,18 @@ class ModelData():
|
||||
#print(self.model_name," - ", self.model_hash)
|
||||
|
||||
class Ensembler():
|
||||
def __init__(self, is_manual_ensemble=False):
|
||||
def __init__(self, is_manual_ensemble=False, is_save_input_dir=False):
|
||||
self.is_save_all_outputs_ensemble = root.is_save_all_outputs_ensemble_var.get()
|
||||
chosen_ensemble_name = '{}'.format(root.chosen_ensemble_var.get().replace(" ", "_")) if not root.chosen_ensemble_var.get() == CHOOSE_ENSEMBLE_OPTION else 'Ensembled'
|
||||
self.chosen_ensemble_name = '{}'.format(root.chosen_ensemble_var.get().replace(" ", "_")) if not root.chosen_ensemble_var.get() == CHOOSE_ENSEMBLE_OPTION else 'Ensembled'
|
||||
ensemble_algorithm = root.ensemble_type_var.get().partition("/")
|
||||
ensemble_main_stem_pair = root.ensemble_main_stem_var.get().partition("/")
|
||||
time_stamp = round(time.time())
|
||||
self.time_stamp = round(time.time())
|
||||
self.audio_tool = MANUAL_ENSEMBLE
|
||||
self.main_export_path = Path(root.export_path_var.get())
|
||||
self.chosen_ensemble = f"_{chosen_ensemble_name}" if root.is_append_ensemble_name_var.get() else ''
|
||||
self.chosen_ensemble = f"_{self.chosen_ensemble_name}" if root.is_append_ensemble_name_var.get() else ''
|
||||
ensemble_folder_name = self.main_export_path if self.is_save_all_outputs_ensemble else ENSEMBLE_TEMP_PATH
|
||||
self.ensemble_folder_name = os.path.join(ensemble_folder_name, '{}_Outputs_{}'.format(chosen_ensemble_name, time_stamp))
|
||||
self.is_testing_audio = f"{time_stamp}_" if root.is_testing_audio_var.get() else ''
|
||||
self.ensemble_folder_name = os.path.join(ensemble_folder_name, '{}_Outputs_{}'.format(self.chosen_ensemble_name, self.time_stamp))
|
||||
self.is_testing_audio = f"{self.time_stamp}_" if root.is_testing_audio_var.get() else ''
|
||||
self.primary_algorithm = ensemble_algorithm[0]
|
||||
self.secondary_algorithm = ensemble_algorithm[2]
|
||||
self.ensemble_primary_stem = ensemble_main_stem_pair[0]
|
||||
@ -790,9 +815,22 @@ class Ensembler():
|
||||
self.wav_type_set = root.wav_type_set
|
||||
self.mp3_bit_set = root.mp3_bit_set_var.get()
|
||||
self.save_format = root.save_format_var.get()
|
||||
if not is_manual_ensemble:
|
||||
self.is_manual_ensemble = is_manual_ensemble
|
||||
|
||||
if not is_manual_ensemble and not is_save_input_dir:
|
||||
os.mkdir(self.ensemble_folder_name)
|
||||
|
||||
def save_to_input_dir_ensemble(self, new_path):
|
||||
|
||||
self.main_export_path = Path(new_path)
|
||||
ensemble_folder_name = self.main_export_path if self.is_save_all_outputs_ensemble else ENSEMBLE_TEMP_PATH
|
||||
self.ensemble_folder_name = os.path.join(ensemble_folder_name, '{}_Outputs_{}'.format(self.chosen_ensemble_name, self.time_stamp))
|
||||
|
||||
if not self.is_manual_ensemble and not os.path.isdir(self.ensemble_folder_name):
|
||||
os.mkdir(self.ensemble_folder_name)
|
||||
|
||||
return self.ensemble_folder_name
|
||||
|
||||
def ensemble_outputs(self, audio_file_base, export_path, stem, is_4_stem=False, is_inst_mix=False):
|
||||
"""Processes the given outputs and ensembles them with the chosen algorithm"""
|
||||
|
||||
@ -810,10 +848,11 @@ class Ensembler():
|
||||
stem_outputs = self.get_files_to_ensemble(folder=export_path, prefix=audio_file_base, suffix=f"_({stem_tag}).wav")
|
||||
audio_file_output = f"{self.is_testing_audio}{audio_file_base}{self.chosen_ensemble}_({stem_tag})"
|
||||
stem_save_path = os.path.join('{}'.format(self.main_export_path),'{}.wav'.format(audio_file_output))
|
||||
|
||||
#print("get_files_to_ensemble: ", stem_outputs)
|
||||
|
||||
|
||||
if len(stem_outputs) > 1:
|
||||
if os.path.isfile(stem_save_path):
|
||||
stem_save_path = stem_save_path.replace(".wav", f"_{self.time_stamp}.wav")
|
||||
|
||||
spec_utils.ensemble_inputs(stem_outputs, algorithm, self.is_normalization, self.wav_type_set, stem_save_path, is_wave=self.is_wav_ensemble)
|
||||
save_format(stem_save_path, self.save_format, self.mp3_bit_set)
|
||||
|
||||
@ -850,6 +889,10 @@ class Ensembler():
|
||||
algorithm = root.choose_algorithm_var.get()
|
||||
algorithm_text = "" if is_bulk else f"_({root.choose_algorithm_var.get()})"
|
||||
stem_save_path = os.path.join('{}'.format(self.main_export_path),'{}{}{}.wav'.format(self.is_testing_audio, audio_file_base, algorithm_text))
|
||||
|
||||
if os.path.isfile(stem_save_path):
|
||||
stem_save_path = stem_save_path.replace(".wav", f"_{self.time_stamp}.wav")
|
||||
|
||||
spec_utils.ensemble_inputs(audio_inputs, algorithm, self.is_normalization, self.wav_type_set, stem_save_path, is_wave=self.is_wav_ensemble)
|
||||
save_format(stem_save_path, self.save_format, self.mp3_bit_set)
|
||||
|
||||
@ -867,12 +910,12 @@ class Ensembler():
|
||||
|
||||
class AudioTools():
|
||||
def __init__(self, audio_tool):
|
||||
time_stamp = round(time.time())
|
||||
self.time_stamp = round(time.time())
|
||||
self.audio_tool = audio_tool
|
||||
self.main_export_path = Path(root.export_path_var.get())
|
||||
self.wav_type_set = root.wav_type_set
|
||||
self.is_normalization = root.is_normalization_var.get()
|
||||
self.is_testing_audio = f"{time_stamp}_" if root.is_testing_audio_var.get() else ''
|
||||
self.is_testing_audio = f"{self.time_stamp}_" if root.is_testing_audio_var.get() else ''
|
||||
self.save_format = lambda save_path:save_format(save_path, root.save_format_var.get(), root.mp3_bit_set_var.get())
|
||||
self.align_window = TIME_WINDOW_MAPPER[root.time_window_var.get()]
|
||||
self.align_intro_val = INTRO_MAPPER[root.intro_analysis_var.get()]
|
||||
@ -891,6 +934,12 @@ class AudioTools():
|
||||
aligned_path = os.path.join('{}'.format(self.main_export_path),'{}_(Aligned).wav'.format(audio_file_2_base))
|
||||
inverted_path = os.path.join('{}'.format(self.main_export_path),'{}_(Inverted).wav'.format(audio_file_base))
|
||||
|
||||
if os.path.isfile(aligned_path):
|
||||
aligned_path = aligned_path.replace(".wav", f"_{self.time_stamp}.wav")
|
||||
|
||||
if os.path.isfile(inverted_path):
|
||||
inverted_path = inverted_path.replace(".wav", f"_{self.time_stamp}.wav")
|
||||
|
||||
spec_utils.align_audio(audio_inputs[0],
|
||||
audio_inputs[1],
|
||||
aligned_path,
|
||||
@ -917,6 +966,9 @@ class AudioTools():
|
||||
|
||||
save_path = os.path.join('{}'.format(self.main_export_path),'{}_(Matched).wav'.format(f"{self.is_testing_audio}{audio_file_base}"))
|
||||
|
||||
if os.path.isfile(save_path):
|
||||
save_path = save_path.replace(".wav", f"_{self.time_stamp}.wav")
|
||||
|
||||
match.process(
|
||||
target=target,
|
||||
reference=reference,
|
||||
@ -940,6 +992,10 @@ class AudioTools():
|
||||
is_time_correction = True if root.is_time_correction_var.get() else False
|
||||
file_text = TIME_TEXT if self.audio_tool == TIME_STRETCH else PITCH_TEXT
|
||||
save_path = os.path.join(self.main_export_path, f"{self.is_testing_audio}{audio_file_base}{file_text}.wav")
|
||||
|
||||
if os.path.isfile(save_path):
|
||||
save_path = save_path.replace(".wav", f"_{self.time_stamp}.wav")
|
||||
|
||||
spec_utils.augment_audio(save_path, audio_file, rate, self.is_normalization, self.wav_type_set, self.save_format, is_pitch=is_pitch, is_time_correction=is_time_correction)
|
||||
|
||||
class ToolTip(object):
|
||||
@ -1135,6 +1191,7 @@ class ComboBoxEditableMenu(ttk.Combobox):
|
||||
super().__init__(master, **kw)
|
||||
|
||||
self.textvariable = kw.get('textvariable', tk.StringVar())
|
||||
self.master = master
|
||||
self.pattern = pattern
|
||||
self.test = 1
|
||||
self.tooltip = ToolTip(self)
|
||||
@ -1152,11 +1209,17 @@ class ComboBoxEditableMenu(ttk.Combobox):
|
||||
if width:
|
||||
self.configure(width=width)
|
||||
|
||||
#self.lock_horizontal_scrolling()
|
||||
|
||||
def menu_combobox_configure(self):
|
||||
self.bind('<<ComboboxSelected>>', self.check_input)
|
||||
self.bind('<Button-1>', lambda e:self.focus())
|
||||
self.bind('<Button-1>', self.reset_scroll)
|
||||
self.bind('<FocusIn>', self.focusin)
|
||||
self.bind('<FocusOut>', lambda e: self.var_validation(is_focus_only=True))
|
||||
self.bind('<MouseWheel>', lambda e: "break")
|
||||
#self.bind('<MouseWheel>', lambda e: print("Scrolling"))
|
||||
# self.bind('<Shift-MouseWheel>', lambda e: "break")
|
||||
# self.bind('<Control-MouseWheel>', lambda e: "break")
|
||||
|
||||
if is_macos:
|
||||
self.bind('<Enter>', lambda e:self.button_released())
|
||||
@ -1183,6 +1246,20 @@ class ComboBoxEditableMenu(ttk.Combobox):
|
||||
|
||||
self.textvariable.set(self.default)
|
||||
|
||||
def reset_scroll(self, event=None):
|
||||
self.focus()
|
||||
|
||||
try:
|
||||
# Open the dropdown menu
|
||||
self.tk.call("ttk::combobox::Post", self)
|
||||
|
||||
# Access the popdown widget
|
||||
popdown_window = self.tk.call("ttk::combobox::PopdownWindow", self)
|
||||
listbox_path = f"{popdown_window}.f.l"
|
||||
self.tk.call(listbox_path, "xview", "moveto", 0.0)
|
||||
except Exception as e:
|
||||
print(f"Error resetting dropdown scroll: {e}")
|
||||
|
||||
def button_released(self, e=None):
|
||||
self.event_generate('<Button-3>')
|
||||
self.event_generate('<ButtonRelease-3>')
|
||||
@ -1208,6 +1285,7 @@ class ComboBoxMenu(ttk.Combobox):
|
||||
|
||||
def menu_combobox_configure(self, is_download_menu=False, command=None, width=None):
|
||||
self.bind('<FocusIn>', self.focusin)
|
||||
self.bind('<Button-1>', self.reset_scroll)
|
||||
self.bind('<MouseWheel>', lambda e:"break")
|
||||
|
||||
if is_macos:
|
||||
@ -1235,6 +1313,20 @@ class ComboBoxMenu(ttk.Combobox):
|
||||
if is_macos:
|
||||
self.event_generate('<Leave>')
|
||||
|
||||
def reset_scroll(self, event=None):
|
||||
self.focus()
|
||||
|
||||
try:
|
||||
# Open the dropdown menu
|
||||
self.tk.call("ttk::combobox::Post", self)
|
||||
|
||||
# Access the popdown widget
|
||||
popdown_window = self.tk.call("ttk::combobox::PopdownWindow", self)
|
||||
listbox_path = f"{popdown_window}.f.l"
|
||||
self.tk.call(listbox_path, "xview", "moveto", 0.0)
|
||||
except Exception as e:
|
||||
print(f"Error resetting dropdown scroll: {e}")
|
||||
|
||||
def update_dropdown_size(self, option_list, dropdown_name, offset=185, command=None):
|
||||
dropdown_style = f"{dropdown_name}.TCombobox"
|
||||
if option_list:
|
||||
@ -1553,6 +1645,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.update_idletasks()
|
||||
self.fill_gpu_list()
|
||||
self.online_data_refresh(user_refresh=False, is_start_up=True)
|
||||
self.switch_export_dir()
|
||||
|
||||
# Menu Functions
|
||||
def main_window_LABEL_SET(self, master, text):return ttk.Label(master=master, text=text, background=BG_COLOR, font=self.font_set, foreground=FG_COLOR, anchor=tk.CENTER)
|
||||
@ -1721,6 +1814,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.filePaths_saveTo_Entry.place(x=SAVETO_ENTRY_X, y=SAVETO_BUTTON_Y, width=SAVETO_ENTRY_WIDTH, height=SAVETO_ENTRY_HEIGHT, relx=0.3, rely=0.5, relwidth=0.7, relheight=0.5)
|
||||
self.filePaths_saveTo_Open = ttk.Button(master=self.filePaths_Frame, image=self.efile_img, command=lambda:OPEN_FILE_func(Path(self.export_path_var.get())) if os.path.isdir(self.export_path_var.get()) else self.error_dialoge(INVALID_EXPORT))
|
||||
self.filePaths_saveTo_Open.place(x=OPEN_BUTTON_X, y=SAVETO_BUTTON_Y, width=OPEN_BUTTON_WIDTH, height=SAVETO_ENTRY_HEIGHT, relx=0.3, rely=0.5, relwidth=0.7, relheight=0.5)
|
||||
|
||||
self.filePaths_saveTo_Entry.configure(cursor="hand2")
|
||||
self.help_hints(self.filePaths_saveTo_Button, text=OUTPUT_FOLDER_ENTRY_HELP)
|
||||
self.help_hints(self.filePaths_saveTo_Open, text=OUTPUT_FOLDER_BUTTON_HELP)
|
||||
|
||||
@ -1885,11 +1980,21 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.ensemble_listbox_Label_place = lambda:self.ensemble_listbox_Label.place(x=MAIN_ROW_2_X[0], y=MAIN_ROW_2_Y[1], width=0, height=LABEL_HEIGHT, relx=2/3, rely=5/11, relwidth=1/3, relheight=1/self.COL1_ROWS)
|
||||
self.ensemble_listbox_Frame = tk.Frame(self.options_Frame, highlightbackground='#04332c', highlightcolor='#04332c', highlightthicknes=1)
|
||||
self.ensemble_listbox_Option = tk.Listbox(self.ensemble_listbox_Frame, selectmode=tk.MULTIPLE, activestyle='dotbox', font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), background='#070708', exportselection=0, relief=tk.SOLID, borderwidth=0)
|
||||
|
||||
|
||||
self.ensemble_listbox_scroll = ttk.Scrollbar(self.options_Frame, orient=tk.VERTICAL)
|
||||
self.ensemble_listbox_Option.config(yscrollcommand=self.ensemble_listbox_scroll.set)
|
||||
self.ensemble_listbox_scroll.configure(command=self.ensemble_listbox_Option.yview)
|
||||
|
||||
self.ensemble_listbox_hscroll = ttk.Scrollbar(self.options_Frame, orient=tk.HORIZONTAL)
|
||||
self.ensemble_listbox_Option.config(xscrollcommand=self.ensemble_listbox_hscroll.set)
|
||||
self.ensemble_listbox_hscroll.configure(command=self.ensemble_listbox_Option.xview)
|
||||
|
||||
|
||||
self.ensemble_listbox_Option_place = lambda: (self.ensemble_listbox_Frame.place(x=ENSEMBLE_LISTBOX_FRAME_X, y=ENSEMBLE_LISTBOX_FRAME_Y, width=ENSEMBLE_LISTBOX_FRAME_WIDTH, height=ENSEMBLE_LISTBOX_FRAME_HEIGHT, relx=2/3, rely=6/11, relwidth=1/3, relheight=1/self.COL1_ROWS),
|
||||
self.ensemble_listbox_scroll.place(x=ENSEMBLE_LISTBOX_SCROLL_X, y=ENSEMBLE_LISTBOX_SCROLL_Y, width=ENSEMBLE_LISTBOX_SCROLL_WIDTH, height=ENSEMBLE_LISTBOX_SCROLL_HEIGHT, relx=2/3, rely=6/11, relwidth=1/10, relheight=1/self.COL1_ROWS))
|
||||
self.ensemble_listbox_scroll.place(x=ENSEMBLE_LISTBOX_SCROLL_X, y=ENSEMBLE_LISTBOX_SCROLL_Y, width=ENSEMBLE_LISTBOX_SCROLL_WIDTH, height=ENSEMBLE_LISTBOX_SCROLL_HEIGHT, relx=2/3, rely=6/11, relwidth=1/10, relheight=1/self.COL1_ROWS),
|
||||
self.ensemble_listbox_hscroll.place(x=-27, y=48, width=159, height=-12, relx=2/3, rely=7/11, relwidth=1/10, relheight=1/self.COL1_ROWS))
|
||||
|
||||
self.ensemble_listbox_Option_pack = lambda:self.ensemble_listbox_Option.pack(fill=tk.BOTH, expand=1)
|
||||
self.help_hints(self.ensemble_listbox_Label, text=ENSEMBLE_LISTBOX_HELP)
|
||||
|
||||
@ -2048,6 +2153,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.ensemble_listbox_Frame,
|
||||
self.ensemble_listbox_Option,
|
||||
self.ensemble_listbox_scroll,
|
||||
self.ensemble_listbox_hscroll,
|
||||
self.chosen_audio_tool_Label,
|
||||
self.chosen_audio_tool_Option,
|
||||
self.choose_algorithm_Label,
|
||||
@ -2110,7 +2216,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
def focus_out_widgets(self, all_widgets, frame):
|
||||
for option in all_widgets:
|
||||
if not type(option) is ComboBoxEditableMenu:
|
||||
if not type(option) is ComboBoxEditableMenu and not type(option) is ComboBoxMenu:
|
||||
option.bind('<Button-1>', lambda e:(option.focus(), self.combo_box_selection_clear(frame)))
|
||||
|
||||
def bind_widgets(self):
|
||||
@ -2138,6 +2244,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.options_Frame.bind(right_click_button, lambda e:(self.right_click_menu_popup(e, main_menu=True), self.options_Frame.focus()))
|
||||
self.filePaths_musicFile_Entry.bind(right_click_button, lambda e:(self.input_right_click_menu(e), self.filePaths_musicFile_Entry.focus()))
|
||||
self.filePaths_musicFile_Entry.bind('<Button-1>', lambda e:(self.check_is_menu_open(INPUTS_MENU), self.filePaths_musicFile_Entry.focus()))
|
||||
self.filePaths_saveTo_Entry.bind(right_click_button, lambda e:(self.output_right_click_menu(e), self.filePaths_saveTo_Entry.focus()))
|
||||
self.filePaths_saveTo_Entry.bind('<Button-1>', lambda e:(self.output_right_click_menu(e), self.filePaths_saveTo_Entry.focus()))
|
||||
|
||||
self.fileOne_Entry.bind('<Button-1>', lambda e:self.menu_batch_dual())
|
||||
self.fileTwo_Entry.bind('<Button-1>', lambda e:self.menu_batch_dual())
|
||||
@ -2214,6 +2322,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
self.process_input_selections()
|
||||
self.update_inputPaths()
|
||||
self.switch_export_dir()
|
||||
|
||||
def export_select_filedialog(self):
|
||||
"""Make user select a folder to export the converted files in"""
|
||||
@ -2223,8 +2332,12 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
path = self.show_file_dialog(dialoge_type=CHOOSE_EXPORT_FIR)
|
||||
|
||||
if path: # Path selected
|
||||
self.export_path_var.set(path)
|
||||
export_path = self.export_path_var.get()
|
||||
if not can_write_to_directory(path):
|
||||
self.error_dialoge(INVALID_FOLDER_ERROR_UNWRITABLE_TEXT)
|
||||
else:
|
||||
self.export_path_var.set(path)
|
||||
self.last_export_path_var.set(path)
|
||||
export_path = self.export_path_var.get()
|
||||
|
||||
return export_path
|
||||
|
||||
@ -2423,6 +2536,31 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
finally:
|
||||
right_click_menu.grab_release()
|
||||
|
||||
def output_right_click_menu(self, event):
|
||||
|
||||
label_text = "Disable Save to Input Path" if self.is_save_to_input_path_var.get() else "Enable Save to Input Path"
|
||||
is_enabled = self.is_save_to_input_path_var.get()
|
||||
|
||||
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
|
||||
right_click_menu.add_command(label=label_text, command=lambda:self.switch_export_menu_selection(is_enabled))
|
||||
|
||||
try:
|
||||
right_click_menu.tk_popup(event.x_root,event.y_root)
|
||||
right_click_release_linux(right_click_menu)
|
||||
finally:
|
||||
right_click_menu.grab_release()
|
||||
|
||||
def switch_export_menu_selection(self, is_enabled):
|
||||
self.is_save_to_input_path_var.set(False if is_enabled else True)
|
||||
self.switch_export_dir()
|
||||
|
||||
def switch_export_dir(self):
|
||||
if self.is_save_to_input_path_var.get():
|
||||
self.export_path_var.set(os.path.dirname(self.inputPaths[0]) if self.inputPaths else '')
|
||||
else:
|
||||
self.export_path_var.set(self.last_export_path_var.get() if self.last_export_path_var.get() else DEFAULT_SAVE_PATH)
|
||||
self.last_export_path_var.set(self.export_path_var.get())
|
||||
|
||||
def input_dual_right_click_menu(self, event, is_primary:bool):
|
||||
input_path = self.fileOneEntry_Full_var.get() if is_primary else self.fileTwoEntry_Full_var.get()
|
||||
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
|
||||
@ -2549,6 +2687,12 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
return audio_sample
|
||||
|
||||
def verify_default_save_path_exists(self):
|
||||
if not os.path.isdir(DEFAULT_SAVE_PATH):
|
||||
os.mkdir(DEFAULT_SAVE_PATH)
|
||||
|
||||
return DEFAULT_SAVE_PATH
|
||||
|
||||
#--Right Click Menu Pop-Ups--
|
||||
|
||||
def right_click_select_settings_sub(self, parent_menu, process_method):
|
||||
@ -3258,7 +3402,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.model_sample_mode_duration_var.set(value)
|
||||
self.model_sample_mode_duration_checkbox_var.set(SAMPLE_MODE_CHECKBOX(value))
|
||||
self.model_sample_mode_duration_label_var.set(f'{value} {SECONDS_TEXT}')
|
||||
|
||||
|
||||
#Settings Tab 1
|
||||
settings_menu_main_Frame = self.menu_FRAME_SET(tab1)
|
||||
settings_menu_main_Frame.grid(row=0)
|
||||
@ -3331,6 +3475,10 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
audio_format_title_Label = self.menu_title_LABEL_SET(settings_menu_format_Frame, GENERAL_PROCESS_SETTINGS_TEXT)
|
||||
audio_format_title_Label.grid(pady=MENU_PADDING_2)
|
||||
|
||||
is_save_to_input_path_Option = ttk.Checkbutton(settings_menu_format_Frame, text=SAVE_TO_INPUT_PATH_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_save_to_input_path_var, command=self.switch_export_dir)
|
||||
is_save_to_input_path_Option.grid()
|
||||
self.help_hints(is_save_to_input_path_Option, text=IS_SAVE_TO_INPUT_HELP)
|
||||
|
||||
is_testing_audio_Option = ttk.Checkbutton(settings_menu_format_Frame, text=SETTINGS_TEST_MODE_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_testing_audio_var)
|
||||
is_testing_audio_Option.grid()
|
||||
self.help_hints(is_testing_audio_Option, text=IS_TESTING_AUDIO_HELP)
|
||||
@ -4228,6 +4376,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
mdx_download_list = model_data["mdx_download_list"]
|
||||
demucs_download_list = model_data["demucs_download_list"]
|
||||
mdx_download_list.update(model_data["mdx23c_download_list"])
|
||||
mdx_download_list.update(model_data["other_network_list"])
|
||||
#print(model_data["roformer_download_list_fixed"])
|
||||
|
||||
def create_link(link):
|
||||
final_link = lambda:webbrowser.open_new_tab(link)
|
||||
@ -4238,27 +4388,31 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
widgets.destroy()
|
||||
|
||||
main_selection = model_selection_var.get()
|
||||
is_defined_link = False
|
||||
|
||||
MAIN_ROW = 0
|
||||
|
||||
|
||||
self.menu_sub_LABEL_SET(manual_downloads_link_Frame, 'Download Link(s)').grid(row=0,column=0,padx=0,pady=MENU_PADDING_4)
|
||||
|
||||
if VR_ARCH_TYPE in main_selection:
|
||||
main_selection = vr_download_list[main_selection]
|
||||
model_dir = VR_MODELS_DIR
|
||||
elif MDX_ARCH_TYPE in main_selection or MDX_23_NAME in main_selection:
|
||||
elif DEMUCS_ARCH_TYPE in main_selection:
|
||||
model_dir = DEMUCS_NEWER_REPO_DIR if 'v3' in main_selection or 'v4' in main_selection else DEMUCS_MODELS_DIR
|
||||
main_selection = demucs_download_list[main_selection]
|
||||
else:
|
||||
if isinstance(mdx_download_list[main_selection], dict):
|
||||
main_selection = mdx_download_list[main_selection]
|
||||
main_selection = list(main_selection.keys())[0]
|
||||
main_selection_list = list(main_selection.keys())
|
||||
if len(main_selection_list) == 1:
|
||||
main_selection = main_selection_list[0]
|
||||
else:
|
||||
main_selection, is_defined_link = main_selection[main_selection_list[0]], True
|
||||
else:
|
||||
main_selection = mdx_download_list[main_selection]
|
||||
|
||||
model_dir = MDX_MODELS_DIR
|
||||
|
||||
elif DEMUCS_ARCH_TYPE in main_selection:
|
||||
model_dir = DEMUCS_NEWER_REPO_DIR if 'v3' in main_selection or 'v4' in main_selection else DEMUCS_MODELS_DIR
|
||||
main_selection = demucs_download_list[main_selection]
|
||||
|
||||
|
||||
if type(main_selection) is dict:
|
||||
for links in main_selection.values():
|
||||
MAIN_ROW += 1
|
||||
@ -4266,7 +4420,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
link = create_link(links)
|
||||
link_button = ttk.Button(manual_downloads_link_Frame, text=f"Open Link to Model{button_text}", command=link).grid(row=MAIN_ROW,column=0,padx=0,pady=MENU_PADDING_1)
|
||||
else:
|
||||
link = f"{NORMAL_REPO}{main_selection}"
|
||||
link = f"{'' if is_defined_link else NORMAL_REPO}{main_selection}"
|
||||
link_button = ttk.Button(manual_downloads_link_Frame, text=OPEN_LINK_TO_MODEL_TEXT, command=lambda:webbrowser.open_new_tab(link))
|
||||
link_button.grid(row=1,column=0,padx=0,pady=MENU_PADDING_2)
|
||||
|
||||
@ -4300,11 +4454,16 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
for model_selection_mdx in mdx_download_list.keys():
|
||||
|
||||
model_name = mdx_download_list[model_selection_mdx]
|
||||
|
||||
|
||||
if isinstance(model_name, dict):
|
||||
items_list = list(model_name.items())
|
||||
model_name, config = items_list[0]
|
||||
config_link = f"{MDX23_CONFIG_CHECKS}{config}"
|
||||
if len(items_list) == 1:
|
||||
model_name, config = items_list[0]
|
||||
config_link = f"{MDX23_CONFIG_CHECKS}{config}"
|
||||
else:
|
||||
model_name, model_link = items_list[0]
|
||||
config, config_link = items_list[1]
|
||||
|
||||
config_local = os.path.join(MDX_C_CONFIG_PATH, config)
|
||||
if not os.path.isfile(config_local):
|
||||
try:
|
||||
@ -4312,9 +4471,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
with open(config_local, 'wb') as out_file:
|
||||
out_file.write(response.read())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
model_name = None
|
||||
|
||||
#print(model_name)
|
||||
|
||||
if model_name:
|
||||
if not os.path.isfile(os.path.join(MDX_MODELS_DIR, model_name)):
|
||||
@ -4408,12 +4566,19 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
is_new_update = self.online_data_refresh(confirmation_box=True)
|
||||
is_download_in_app_var = tk.BooleanVar(value=False)
|
||||
is_rollback = True if ROLLBACK_FOUND_TEXT in self.app_update_button_Text_var.get() else False
|
||||
menu_title = ROLLBACK_FOUND_TEXT if is_rollback else UPDATE_FOUND_TEXT
|
||||
|
||||
def update_type():
|
||||
if is_download_in_app_var.get():
|
||||
self.download_item(is_update_app=True)
|
||||
else:
|
||||
webbrowser.open_new_tab(self.download_update_link_var.get())
|
||||
if is_rollback:
|
||||
url = self.online_data["roll_back_macos_arm64_url" if SYSTEM_PROC == ARM or ARM in SYSTEM_ARCH else "roll_back_macos_x86_64_url"] if is_macos else self.online_data["roll_back_win_url"]
|
||||
else:
|
||||
url = self.download_update_link_var.get()
|
||||
|
||||
webbrowser.open_new_tab(url)
|
||||
|
||||
update_confirmation_win.destroy()
|
||||
|
||||
@ -4424,7 +4589,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
update_confirmation_Frame = self.menu_FRAME_SET(update_confirmation_win)
|
||||
update_confirmation_Frame.grid(row=0)
|
||||
|
||||
update_found_label = self.menu_title_LABEL_SET(update_confirmation_Frame, UPDATE_FOUND_TEXT, width=15)
|
||||
update_found_label = self.menu_title_LABEL_SET(update_confirmation_Frame, menu_title, width=15)
|
||||
update_found_label.grid(row=0,column=0,padx=0,pady=MENU_PADDING_2)
|
||||
|
||||
confirm_update_label = self.menu_sub_LABEL_SET(update_confirmation_Frame, UPDATE_CONFIRMATION_TEXT, font_size=FONT_SIZE_3)
|
||||
@ -4436,7 +4601,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
no_button = ttk.Button(update_confirmation_Frame, text=NO_TEXT, command=lambda:(update_confirmation_win.destroy()))
|
||||
no_button.grid(row=3,column=0,padx=0,pady=MENU_PADDING_1)
|
||||
|
||||
if is_windows:
|
||||
if is_windows and not is_rollback:
|
||||
download_outside_application_button = ttk.Checkbutton(update_confirmation_Frame, variable=is_download_in_app_var, text='Download Update in Application')
|
||||
download_outside_application_button.grid(row=4,column=0,padx=0,pady=MENU_PADDING_1)
|
||||
|
||||
@ -5207,7 +5372,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
if not is_start_up:
|
||||
if is_beta_version:
|
||||
self.app_update_status_Text_var.set(f"Roll Back: {self.lastest_version}")
|
||||
self.app_update_status_Text_var.set(f"{ROLLBACK_FOUND_TEXT}: {self.lastest_version}")
|
||||
self.app_update_button_Text_var.set(ROLL_BACK_TEXT)
|
||||
else:
|
||||
self.app_update_status_Text_var.set(f"Update Found: {self.lastest_version}")
|
||||
@ -5225,7 +5390,6 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
if not is_beta_version and not self.lastest_version == current_patch:
|
||||
self.command_Text.write(NEW_UPDATE_FOUND_TEXT(self.lastest_version))
|
||||
|
||||
|
||||
is_update_params = self.is_auto_update_model_params if is_start_up else self.is_auto_update_model_params_var.get()
|
||||
|
||||
if is_update_params and is_start_up or is_download_complete:
|
||||
@ -5304,7 +5468,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.mdx_download_list = self.online_data["mdx_download_list"]
|
||||
self.demucs_download_list = self.online_data["demucs_download_list"]
|
||||
self.mdx_download_list.update(self.online_data["mdx23c_download_list"])
|
||||
self.mdx_download_list.update(self.online_data["roformer_download_list"])
|
||||
self.mdx_download_list.update(self.online_data["other_network_list"])
|
||||
|
||||
if not self.decoded_vip_link is NO_CODE:
|
||||
self.vr_download_list.update(self.online_data["vr_download_vip_list"])
|
||||
@ -5328,8 +5492,14 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
for (selectable, model) in self.mdx_download_list.items():
|
||||
if isinstance(model, dict):
|
||||
items_list = list(model.items())
|
||||
model_name, config = items_list[0]
|
||||
config_link = f"{MDX23_CONFIG_CHECKS}{config}"
|
||||
|
||||
if len(items_list) == 1:
|
||||
model_name, config = items_list[0]
|
||||
config_link = f"{MDX23_CONFIG_CHECKS}{config}"
|
||||
else:
|
||||
model_name, model_link = items_list[0]
|
||||
config, config_link = items_list[1]
|
||||
|
||||
config_local = os.path.join(MDX_C_CONFIG_PATH, config)
|
||||
if not os.path.isfile(config_local):
|
||||
with urllib.request.urlopen(config_link) as response:
|
||||
@ -5449,10 +5619,13 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
for selected_model in self.mdx_download_list.items():
|
||||
if selection in selected_model:
|
||||
if isinstance(selected_model[1], dict):
|
||||
model_name = list(selected_model[1].keys())[0]
|
||||
model_dict_keys = list(selected_model[1].keys())
|
||||
model_name = model_dict_keys[0]
|
||||
model_link = "{}{}".format(model_repo, model_name) if len(model_dict_keys) == 1 else selected_model[1][model_name]
|
||||
else:
|
||||
model_name = str(selected_model[1])
|
||||
self.download_link_path_var.set("{}{}".format(model_repo, model_name))
|
||||
model_link = "{}{}".format(model_repo, model_name)
|
||||
self.download_link_path_var.set(model_link)
|
||||
self.download_save_path_var.set(os.path.join(MDX_MODELS_DIR, model_name))
|
||||
break
|
||||
|
||||
@ -5848,26 +6021,26 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
"""Updates the available stems for selected Demucs model"""
|
||||
|
||||
model_stems = [stem for stem in model_stems]
|
||||
|
||||
primary_stem = model_stems[0]
|
||||
secondary_stem = model_stems[1] if len(model_stems) == 2 else None
|
||||
|
||||
if len(model_stems) >= 3:
|
||||
model_stems.insert(0, ALL_STEMS)
|
||||
self.mdxnet_stems_var.set(ALL_STEMS)
|
||||
else:
|
||||
self.mdxnet_stems_var.set(model_stems[0])
|
||||
self.mdxnet_stems_var.set(primary_stem)
|
||||
|
||||
if self.mdxnet_stems_var.get() == ALL_STEMS:
|
||||
self.update_stem_checkbox_labels(PRIMARY_STEM, disable_boxes=True)
|
||||
elif self.mdxnet_stems_var.get() == VOCAL_STEM:
|
||||
self.update_stem_checkbox_labels(VOCAL_STEM)
|
||||
self.is_stem_only_Options_Enable()
|
||||
else:
|
||||
self.update_stem_checkbox_labels(primary_stem, defined_secondary_stem=secondary_stem)
|
||||
self.is_stem_only_Options_Enable()
|
||||
|
||||
if not self.mdx_net_model_var.get() == CHOOSE_MODEL:
|
||||
self.mdxnet_stems_Option['values'] = model_stems
|
||||
self.mdxnet_stems_Option.command(lambda e:self.update_stem_checkbox_labels(self.mdxnet_stems_var.get()))
|
||||
|
||||
def update_stem_checkbox_labels(self, selection, demucs=False, disable_boxes=False, is_disable_demucs_boxes=True):
|
||||
def update_stem_checkbox_labels(self, selection, demucs=False, disable_boxes=False, is_disable_demucs_boxes=True, defined_secondary_stem=None):
|
||||
"""Updates the "save only" checkboxes based on the model selected"""
|
||||
|
||||
stem_text = self.is_primary_stem_only_Text_var, self.is_secondary_stem_only_Text_var
|
||||
@ -5900,7 +6073,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.is_secondary_stem_only_Demucs_Option.configure(state=tk.NORMAL)
|
||||
|
||||
stem_text[0].set(f"{selection} Only")
|
||||
stem_text[1].set(f"{secondary_stem(selection)} Only")
|
||||
stem_text[1].set(f"{defined_secondary_stem if defined_secondary_stem else secondary_stem(selection)} Only")
|
||||
|
||||
def update_ensemble_algorithm_menu(self, is_4_stem=False):
|
||||
options = ENSEMBLE_TYPE_4_STEM if is_4_stem else ENSEMBLE_TYPE
|
||||
@ -5985,7 +6158,12 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.mdx_segment_size_Option_place()
|
||||
self.overlap_mdx_Label_place()
|
||||
self.overlap_mdx23_Option_place()
|
||||
self.update_button_states_mdx(model_data.mdx_model_stems)
|
||||
|
||||
if model_data.is_target_instrument:
|
||||
self.update_stem_checkbox_labels(model_data.primary_stem)
|
||||
else:
|
||||
self.update_button_states_mdx(model_data.mdx_model_stems)
|
||||
#elif model_data.is_target_instrument and
|
||||
else:
|
||||
if ai_type == MDX_ARCH_TYPE:
|
||||
self.mdx_segment_size_Label_place()
|
||||
@ -6213,6 +6391,10 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
def process_initialize(self):
|
||||
"""Verifies the input/output directories are valid and prepares to thread the main process."""
|
||||
|
||||
#self.is_save_to_input_path = True
|
||||
|
||||
is_audio_tools = False if self.chosen_process_method_var.get() != AUDIO_TOOLS else True
|
||||
|
||||
if not (
|
||||
self.chosen_process_method_var.get() == AUDIO_TOOLS
|
||||
and self.chosen_audio_tool_var.get() in [ALIGN_INPUTS, MATCH_INPUTS]
|
||||
@ -6224,23 +6406,26 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.error_dialoge(INVALID_INPUT)
|
||||
return
|
||||
|
||||
|
||||
if not os.path.isdir(self.export_path_var.get()):
|
||||
if not os.path.isdir(self.export_path_var.get()) and not self.is_save_to_input_path_var.get():
|
||||
self.error_dialoge(INVALID_EXPORT)
|
||||
return
|
||||
|
||||
if not can_write_to_directory(self.export_path_var.get()) and not self.is_save_to_input_path_var.get():
|
||||
self.error_dialoge(INVALID_FOLDER_ERROR_UNWRITABLE_TEXT)
|
||||
return
|
||||
|
||||
if not self.process_storage_check():
|
||||
return
|
||||
|
||||
if self.chosen_process_method_var.get() != AUDIO_TOOLS:
|
||||
if is_audio_tools:
|
||||
target_function = self.process_tool_start
|
||||
else:
|
||||
if not self.process_preliminary_checks():
|
||||
error_msg = INVALID_ENSEMBLE if self.chosen_process_method_var.get() == ENSEMBLE_MODE else INVALID_MODEL
|
||||
self.error_dialoge(error_msg)
|
||||
return
|
||||
target_function = self.process_start
|
||||
else:
|
||||
target_function = self.process_tool_start
|
||||
|
||||
|
||||
self.active_processing_thread = KThread(target=target_function)
|
||||
self.active_processing_thread.start()
|
||||
|
||||
@ -6364,6 +6549,9 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.true_model_count = 1
|
||||
self.process_check_wav_type()
|
||||
process_complete_text = PROCESS_COMPLETE
|
||||
is_save_to_input_path = self.is_save_to_input_path_var.get()
|
||||
is_manual_ensemble = False
|
||||
is_output_path_writable = True
|
||||
|
||||
if self.chosen_audio_tool_var.get() in [ALIGN_INPUTS, MATCH_INPUTS]:
|
||||
if self.DualBatch_inputPaths:
|
||||
@ -6385,19 +6573,37 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
audio_tool = AudioTools(CHANGE_PITCH)
|
||||
self.progress_bar_main_var.set(2)
|
||||
elif self.chosen_audio_tool_var.get() == MANUAL_ENSEMBLE:
|
||||
if self.chosen_audio_tool_var.get() == MANUAL_ENSEMBLE:
|
||||
audio_tool = Ensembler(is_manual_ensemble=True)
|
||||
is_manual_ensemble = True
|
||||
audio_tool = Ensembler(is_manual_ensemble=is_manual_ensemble)
|
||||
multiple_files = True
|
||||
if total_files <= 1:
|
||||
self.command_Text.write(NOT_ENOUGH_ERROR_TEXT)
|
||||
self.process_end()
|
||||
return
|
||||
if can_write_to_directory(inputPaths[0]):
|
||||
export_dir = os.path.dirname(inputPaths[0])
|
||||
else:
|
||||
is_output_path_writable = False
|
||||
export_dir = self.last_export_path_var.get() if can_write_to_directory(self.last_export_path_var.get()) else self.verify_default_save_path_exists()
|
||||
self.export_path_var.set(export_dir)
|
||||
elif self.chosen_audio_tool_var.get() in [ALIGN_INPUTS, MATCH_INPUTS]:
|
||||
audio_tool = AudioTools(self.chosen_audio_tool_var.get())
|
||||
self.progress_bar_main_var.set(2)
|
||||
is_dual = True
|
||||
|
||||
for file_num, audio_file in enumerate(inputPaths, start=1):
|
||||
audio_tool_action = audio_tool.audio_tool
|
||||
if is_save_to_input_path:
|
||||
if not is_manual_ensemble:
|
||||
export_dir = os.path.dirname(audio_file[0] if audio_tool_action in [ALIGN_INPUTS, MATCH_INPUTS] else audio_file)
|
||||
if can_write_to_directory(export_dir):
|
||||
export_dir = export_dir
|
||||
else:
|
||||
is_output_path_writable = False
|
||||
export_dir = self.last_export_path_var.get() if can_write_to_directory(self.last_export_path_var.get()) else self.verify_default_save_path_exists()
|
||||
|
||||
self.export_path_var.set(export_dir)
|
||||
audio_tool.main_export_path = export_dir
|
||||
self.iteration += 1
|
||||
base = (100 / total_files)
|
||||
audio_file_base = get_audio_file_base(audio_file)
|
||||
@ -6412,8 +6618,10 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.command_Text.write(f'\n{error_text_console}')
|
||||
is_verified_audio = False
|
||||
continue
|
||||
|
||||
if not is_output_path_writable:
|
||||
self.command_Text.write(f'{self.base_text}: {INPUT_DIR_FAIL_TEXT}')
|
||||
|
||||
audio_tool_action = audio_tool.audio_tool
|
||||
if audio_tool_action not in [MANUAL_ENSEMBLE, ALIGN_INPUTS, MATCH_INPUTS]:
|
||||
audio_file = self.create_sample(audio_file) if is_model_sample_mode else audio_file
|
||||
self.command_Text.write(f'{NEW_LINE if file_num != 1 else NO_LINE}{self.base_text}"{os.path.basename(audio_file)}\".{NEW_LINES}')
|
||||
@ -6586,6 +6794,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
inputPaths = self.inputPaths
|
||||
inputPath_total_len = len(inputPaths)
|
||||
is_model_sample_mode = self.model_sample_mode_var.get()
|
||||
is_save_to_input_path = self.is_save_to_input_path_var.get()
|
||||
|
||||
try:
|
||||
if self.chosen_process_method_var.get() == ENSEMBLE_MODE:
|
||||
@ -6604,12 +6813,11 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
true_model_pre_proc_model_count = sum(2 if m.pre_proc_model_activated else 0 for m in model)
|
||||
self.true_model_count = sum(2 if m.is_secondary_model_activated else 1 for m in model) + true_model_4_stem_count + true_model_pre_proc_model_count + self.determine_voc_split(model)
|
||||
|
||||
#print("self.true_model_count", self.true_model_count)
|
||||
|
||||
for file_num, audio_file in enumerate(inputPaths, start=1):
|
||||
self.cached_sources_clear()
|
||||
base_text = self.process_get_baseText(total_files=inputPath_total_len, file_num=file_num)
|
||||
|
||||
audiofile_path = os.path.dirname(audio_file)
|
||||
|
||||
if self.verify_audio(audio_file):
|
||||
audio_file = self.create_sample(audio_file) if is_model_sample_mode else audio_file
|
||||
self.command_Text.write(f'{NEW_LINE if not file_num ==1 else NO_LINE}{base_text}"{os.path.basename(audio_file)}\".{NEW_LINES}')
|
||||
@ -6621,6 +6829,17 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
is_verified_audio = False
|
||||
continue
|
||||
|
||||
if is_save_to_input_path:
|
||||
if not can_write_to_directory(audiofile_path):
|
||||
audiofile_path = self.last_export_path_var.get() if can_write_to_directory(self.last_export_path_var.get()) else self.verify_default_save_path_exists()
|
||||
self.command_Text.write(base_text + f'{INPUT_DIR_FAIL_TEXT}')
|
||||
|
||||
export_path = audiofile_path
|
||||
self.export_path_var.set(export_path)
|
||||
|
||||
if is_ensemble:
|
||||
export_path = ensemble.save_to_input_dir_ensemble(export_path)
|
||||
|
||||
for current_model_num, current_model in enumerate(model, start=1):
|
||||
self.iteration += 1
|
||||
|
||||
@ -6641,7 +6860,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
if self.is_create_model_folder_var.get() and not is_ensemble:
|
||||
export_path = os.path.join(Path(self.export_path_var.get()), current_model.model_basename, os.path.splitext(os.path.basename(audio_file))[0])
|
||||
if not os.path.isdir(export_path):os.makedirs(export_path)
|
||||
if not os.path.isdir(export_path):
|
||||
os.makedirs(export_path)
|
||||
|
||||
process_data = {
|
||||
'model_data': current_model,
|
||||
@ -6693,7 +6913,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
|
||||
clear_gpu_cache()
|
||||
|
||||
shutil.rmtree(export_path) if is_ensemble and len(os.listdir(export_path)) == 0 else None
|
||||
if is_ensemble and len(os.listdir(export_path)) == 0:
|
||||
shutil.rmtree(export_path)
|
||||
|
||||
if inputPath_total_len == 1 and not is_verified_audio:
|
||||
self.command_Text.write(f'{error_text_console}\n{PROCESS_FAILED}')
|
||||
@ -6875,8 +7096,10 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.set_vocal_splitter_var = tk.StringVar(value=data['set_vocal_splitter'])
|
||||
self.is_set_vocal_splitter_var = tk.BooleanVar(value=data['is_set_vocal_splitter'])#
|
||||
self.is_save_inst_set_vocal_splitter_var = tk.BooleanVar(value=data['is_save_inst_set_vocal_splitter'])#
|
||||
self.is_save_to_input_path_var = tk.BooleanVar(value=data['is_save_to_input_path'])#
|
||||
|
||||
#Path Vars
|
||||
self.last_export_path_var = tk.StringVar(value=data['last_export_path'])
|
||||
self.export_path_var = tk.StringVar(value=data['export_path'])
|
||||
self.inputPaths = data['input_paths']
|
||||
self.lastDir = data['lastDir']
|
||||
@ -6991,6 +7214,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
self.is_auto_update_model_params_var.set(loaded_setting['is_auto_update_model_params'])
|
||||
self.is_add_model_name_var.set(loaded_setting['is_add_model_name'])
|
||||
self.is_accept_any_input_var.set(loaded_setting["is_accept_any_input"])
|
||||
self.is_save_to_input_path_var.set(loaded_setting["is_save_to_input_path"])
|
||||
self.last_export_path_var.set(loaded_setting["last_export_path"])
|
||||
self.is_task_complete_var.set(loaded_setting['is_task_complete'])
|
||||
self.is_create_model_folder_var.set(loaded_setting['is_create_model_folder'])
|
||||
self.mp3_bit_set_var.set(loaded_setting['mp3_bit_set'])
|
||||
@ -7124,6 +7349,8 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
'is_auto_update_model_params': self.is_auto_update_model_params_var.get(),
|
||||
'is_add_model_name': self.is_add_model_name_var.get(),
|
||||
'is_accept_any_input': self.is_accept_any_input_var.get(),
|
||||
'is_save_to_input_path': self.is_save_to_input_path_var.get(),
|
||||
#is_save_to_input_path
|
||||
'is_task_complete': self.is_task_complete_var.get(),
|
||||
'is_normalization': self.is_normalization_var.get(),#
|
||||
'is_use_opencl': self.is_use_opencl_var.get(),#
|
||||
@ -7144,6 +7371,7 @@ class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
|
||||
}
|
||||
|
||||
other_data = {
|
||||
'last_export_path': self.last_export_path_var.get(),
|
||||
'chosen_process_method': self.chosen_process_method_var.get(),
|
||||
'input_paths': self.inputPaths,
|
||||
'lastDir': self.lastDir,
|
||||
|
Loading…
x
Reference in New Issue
Block a user