ultimatevocalremovergui/UVR.py

7216 lines
399 KiB
Python
Raw Normal View History

2022-12-19 04:18:56 +01:00
# GUI modules
2023-09-26 00:11:08 +02:00
import time
#start_time = time.time()
2022-12-19 04:18:56 +01:00
import audioread
import gui_data.sv_ttk
import hashlib
import json
import librosa
import math
import natsort
import os
2023-09-26 00:11:08 +02:00
import pickle
2022-12-19 04:18:56 +01:00
import psutil
2023-09-27 06:41:47 +02:00
from pyglet import font as pyglet_font
2022-12-19 04:18:56 +01:00
import pyperclip
import base64
import queue
import shutil
import subprocess
import soundfile as sf
import torch
import urllib.request
import webbrowser
import wget
import traceback
2023-09-26 00:11:08 +02:00
import matchering as match
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.font import Font
from tkinter import filedialog
from tkinter import messagebox
from collections import Counter
2022-12-30 04:07:23 +01:00
from __version__ import VERSION, PATCH, PATCH_MAC, PATCH_LINUX
2022-12-19 04:18:56 +01:00
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from datetime import datetime
from gui_data.constants import *
2023-09-26 00:11:08 +02:00
from gui_data.app_size_values import *
2022-12-19 04:18:56 +01:00
from gui_data.error_handling import error_text, error_dialouge
from gui_data.old_data_check import file_check, remove_unneeded_yamls, remove_temps
2022-12-28 10:52:35 +01:00
from gui_data.tkinterdnd2 import TkinterDnD, DND_FILES
2022-12-19 04:18:56 +01:00
from lib_v5.vr_network.model_param_init import ModelParameters
from kthread import KThread
from lib_v5 import spec_utils
from pathlib import Path
2023-09-26 00:11:08 +02:00
from separate import SeperateDemucs, SeperateMDX, SeperateMDXC, SeperateVR, save_format
2022-12-19 04:18:56 +01:00
from playsound import playsound
from typing import List
2023-09-26 00:11:08 +02:00
import onnx
import re
2023-03-31 12:15:39 +02:00
import sys
2023-09-26 00:11:08 +02:00
import yaml
from ml_collections import ConfigDict
from collections import Counter
# Change the current working directory to the directory
# this file sits in
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the PyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
BASE_PATH = sys._MEIPASS
else:
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
os.chdir(BASE_PATH) # Change the current working directory to the base path
SPLASH_DOC = os.path.join(BASE_PATH, 'tmp', 'splash.txt')
if os.path.isfile(SPLASH_DOC):
os.remove(SPLASH_DOC)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def get_execution_time(function, name):
start = time.time()
function()
end = time.time()
time_difference = end - start
print(f'{name} Execution Time: ', time_difference)
2022-12-19 04:18:56 +01:00
2023-10-07 02:05:25 +02:00
PREVIOUS_PATCH_WIN = 'UVR_Patch_10_6_23_4_27'
2023-03-31 12:15:39 +02:00
2022-12-29 00:48:28 +01:00
is_dnd_compatible = True
2022-12-30 04:07:23 +01:00
banner_placement = -2
2022-12-29 00:48:28 +01:00
2022-12-27 11:31:41 +01:00
if OPERATING_SYSTEM=="Darwin":
OPEN_FILE_func = lambda input_string:subprocess.Popen(["open", input_string])
2022-12-30 04:07:23 +01:00
dnd_path_check = MAC_DND_CHECK
banner_placement = -8
current_patch = PATCH_MAC
2022-12-27 11:31:41 +01:00
is_windows = False
2023-09-26 00:11:08 +02:00
is_macos = True
2022-12-27 11:31:41 +01:00
right_click_button = '<Button-2>'
2022-12-30 04:07:23 +01:00
application_extension = ".dmg"
2022-12-27 11:31:41 +01:00
elif OPERATING_SYSTEM=="Linux":
2023-09-29 09:08:14 +02:00
OPEN_FILE_func = lambda input_string:subprocess.Popen(["xdg-open", input_string])
2022-12-30 04:07:23 +01:00
dnd_path_check = LINUX_DND_CHECK
current_patch = PATCH_LINUX
2022-12-27 11:31:41 +01:00
is_windows = False
2023-09-26 00:11:08 +02:00
is_macos = False
2022-12-27 11:31:41 +01:00
right_click_button = '<Button-3>'
application_extension = ".zip"
elif OPERATING_SYSTEM=="Windows":
OPEN_FILE_func = lambda input_string:os.startfile(input_string)
2022-12-30 04:07:23 +01:00
dnd_path_check = WINDOWS_DND_CHECK
current_patch = PATCH
2022-12-27 11:31:41 +01:00
is_windows = True
2023-09-26 00:11:08 +02:00
is_macos = False
2022-12-27 11:31:41 +01:00
right_click_button = '<Button-3>'
application_extension = ".exe"
2023-10-07 02:05:25 +02:00
2023-10-12 06:30:24 +02:00
if is_macos:
from torch.mps import empty_cache
else:
from torch.cuda import empty_cache
clear_gpu_cache = empty_cache
2022-12-30 12:49:26 +01:00
def right_click_release_linux(window, top_win=None):
if OPERATING_SYSTEM=="Linux":
root.bind('<Button-1>', lambda e:window.destroy())
if top_win:
top_win.bind('<Button-1>', lambda e:window.destroy())
2022-12-27 11:31:41 +01:00
if not is_windows:
2023-09-26 00:11:08 +02:00
import ssl
2022-12-27 11:31:41 +01:00
ssl._create_default_https_context = ssl._create_unverified_context
2023-09-26 00:11:08 +02:00
else:
from ctypes import windll, wintypes
def close_process(q:queue.Queue):
def close_splash():
name = "UVR_Launcher.exe"
for process in psutil.process_iter(attrs=["name"]):
process_name = process.info.get("name")
if process_name == name:
try:
process.terminate()
q.put(f"{name} terminated.") # Push message to queue
break
except psutil.NoSuchProcess as e:
q.put(f"Error terminating {name}: {e}") # Push error to queue
try:
with open(SPLASH_DOC, 'w') as f:
f.write('1')
except:
print('No splash screen.')
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
thread = KThread(target=close_splash)
thread.start()
2022-12-19 04:18:56 +01:00
def save_data(data):
"""
Saves given data as a .pkl (pickle) file
Paramters:
data(dict):
Dictionary containing all the necessary data to save
"""
# Open data file, create it if it does not exist
with open('data.pkl', 'wb') as data_file:
pickle.dump(data, data_file)
def load_data() -> dict:
"""
Loads saved pkl file and returns the stored data
Returns(dict):
Dictionary containing all the saved data
"""
try:
with open('data.pkl', 'rb') as data_file: # Open data file
data = pickle.load(data_file)
return data
except (ValueError, FileNotFoundError):
# Data File is corrupted or not found so recreate it
save_data(data=DEFAULT_DATA)
return load_data()
def load_model_hash_data(dictionary):
'''Get the model hash dictionary'''
2023-09-26 00:11:08 +02:00
with open(dictionary, 'r') as d:
return json.load(d)
2023-01-02 03:16:12 +01:00
2023-09-26 00:11:08 +02:00
def font_checker(font_file):
chosen_font_name = None
chosen_font_file = None
try:
if os.path.isfile(font_file):
with open(font_file, 'r') as d:
chosen_font = json.load(d)
chosen_font_name = chosen_font["font_name"]
if chosen_font["font_file"]:
chosen_font_file = os.path.join(OTHER_FONT_PATH, chosen_font["font_file"])
chosen_font_file = chosen_font_file if os.path.isfile(chosen_font_file) else None
except Exception as e:
print(e)
chosen_font = chosen_font_name, chosen_font_file
return chosen_font
2022-12-19 04:18:56 +01:00
debugger = []
#--Constants--
#Models
MODELS_DIR = os.path.join(BASE_PATH, 'models')
VR_MODELS_DIR = os.path.join(MODELS_DIR, 'VR_Models')
MDX_MODELS_DIR = os.path.join(MODELS_DIR, 'MDX_Net_Models')
DEMUCS_MODELS_DIR = os.path.join(MODELS_DIR, 'Demucs_Models')
DEMUCS_NEWER_REPO_DIR = os.path.join(DEMUCS_MODELS_DIR, 'v3_v4_repo')
2023-03-31 12:15:39 +02:00
MDX_MIXER_PATH = os.path.join(BASE_PATH, 'lib_v5', 'mixer.ckpt')
2022-12-19 04:18:56 +01:00
#Cache & Parameters
VR_HASH_DIR = os.path.join(VR_MODELS_DIR, 'model_data')
VR_HASH_JSON = os.path.join(VR_MODELS_DIR, 'model_data', 'model_data.json')
MDX_HASH_DIR = os.path.join(MDX_MODELS_DIR, 'model_data')
2023-09-26 00:11:08 +02:00
MDX_HASH_JSON = os.path.join(MDX_HASH_DIR, 'model_data.json')
MDX_C_CONFIG_PATH = os.path.join(MDX_HASH_DIR, 'mdx_c_configs')
2023-03-31 12:15:39 +02:00
DEMUCS_MODEL_NAME_SELECT = os.path.join(DEMUCS_MODELS_DIR, 'model_data', 'model_name_mapper.json')
MDX_MODEL_NAME_SELECT = os.path.join(MDX_MODELS_DIR, 'model_data', 'model_name_mapper.json')
2022-12-19 04:18:56 +01:00
ENSEMBLE_CACHE_DIR = os.path.join(BASE_PATH, 'gui_data', 'saved_ensembles')
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')
2023-09-26 00:11:08 +02:00
DOWNLOAD_MODEL_CACHE = os.path.join(BASE_PATH, 'gui_data', 'model_manual_download.json')
#CR Text
CR_TEXT = os.path.join(BASE_PATH, 'gui_data', 'cr_text.txt')
2022-12-19 04:18:56 +01:00
#Style
2022-12-27 11:31:41 +01:00
ICON_IMG_PATH = os.path.join(BASE_PATH, 'gui_data', 'img', 'GUI-Icon.ico')
if not is_windows:
MAIN_ICON_IMG_PATH = os.path.join(BASE_PATH, 'gui_data', 'img', 'GUI-Icon.png')
2023-09-26 00:11:08 +02:00
OWN_FONT_PATH = os.path.join(BASE_PATH, 'gui_data', 'own_font.json')
MAIN_FONT_NAME = 'Montserrat'
SEC_FONT_NAME = 'Century Gothic'
FONT_PATH = os.path.join(BASE_PATH, 'gui_data', 'fonts', 'Montserrat', 'Montserrat.ttf')#
SEC_FONT_PATH = os.path.join(BASE_PATH, 'gui_data', 'fonts', 'centurygothic', 'GOTHIC.ttf')#
OTHER_FONT_PATH = os.path.join(BASE_PATH, 'gui_data', 'fonts', 'other')#
FONT_MAPPER = {MAIN_FONT_NAME:FONT_PATH,
SEC_FONT_NAME:SEC_FONT_PATH}
2022-12-19 04:18:56 +01:00
#Other
COMPLETE_CHIME = os.path.join(BASE_PATH, 'gui_data', 'complete_chime.wav')
FAIL_CHIME = os.path.join(BASE_PATH, 'gui_data', 'fail_chime.wav')
CHANGE_LOG = os.path.join(BASE_PATH, 'gui_data', 'change_log.txt')
2023-09-26 00:11:08 +02:00
DENOISER_MODEL_PATH = os.path.join(VR_MODELS_DIR, 'UVR-DeNoise-Lite.pth')
DEVERBER_MODEL_PATH = os.path.join(VR_MODELS_DIR, 'UVR-DeEcho-DeReverb.pth')
MODEL_DATA_URLS = [VR_MODEL_DATA_LINK, MDX_MODEL_DATA_LINK, MDX_MODEL_NAME_DATA_LINK, DEMUCS_MODEL_NAME_DATA_LINK]
MODEL_DATA_FILES = [VR_HASH_JSON, MDX_HASH_JSON, MDX_MODEL_NAME_SELECT, DEMUCS_MODEL_NAME_SELECT]
2022-12-19 04:18:56 +01:00
file_check(os.path.join(MODELS_DIR, 'Main_Models'), VR_MODELS_DIR)
file_check(os.path.join(DEMUCS_MODELS_DIR, 'v3_repo'), DEMUCS_NEWER_REPO_DIR)
remove_unneeded_yamls(DEMUCS_MODELS_DIR)
remove_temps(ENSEMBLE_TEMP_PATH)
remove_temps(SAMPLE_CLIP_PATH)
remove_temps(os.path.join(BASE_PATH, 'img'))
if not os.path.isdir(ENSEMBLE_TEMP_PATH):
os.mkdir(ENSEMBLE_TEMP_PATH)
if not os.path.isdir(SAMPLE_CLIP_PATH):
os.mkdir(SAMPLE_CLIP_PATH)
model_hash_table = {}
data = load_data()
def drop(event, accept_mode: str = 'files'):
path = event.data
if accept_mode == 'folder':
path = path.replace('{', '').replace('}', '')
if not os.path.isdir(path):
2023-09-26 00:11:08 +02:00
messagebox.showerror(parent=root,
title=INVALID_FOLDER_ERROR_TEXT[0],
message=INVALID_FOLDER_ERROR_TEXT[1])
2022-12-19 04:18:56 +01:00
return
root.export_path_var.set(path)
2023-09-26 00:11:08 +02:00
elif accept_mode in ['files', FILE_1, FILE_2, FILE_1_LB, FILE_2_LB]:
2022-12-19 04:18:56 +01:00
path = path.replace("{", "").replace("}", "")
2022-12-30 04:07:23 +01:00
for dnd_file in dnd_path_check:
path = path.replace(f" {dnd_file}", f";{dnd_file}")
2022-12-19 04:18:56 +01:00
path = path.split(';')
path[-1] = path[-1].replace(';', '')
2023-09-26 00:11:08 +02:00
if accept_mode == 'files':
root.inputPaths = tuple(path)
root.process_input_selections()
root.update_inputPaths()
elif accept_mode in [FILE_1, FILE_2]:
if len(path) == 2:
root.select_audiofile(path[0])
root.select_audiofile(path[1], is_primary=False)
root.DualBatch_inputPaths = []
root.check_dual_paths()
elif len(path) == 1:
if accept_mode == FILE_1:
root.select_audiofile(path[0])
else:
root.select_audiofile(path[0], is_primary=False)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
elif accept_mode in [FILE_1_LB, FILE_2_LB]:
return path
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
return
2022-12-19 04:18:56 +01:00
class ModelData():
def __init__(self, model_name: str,
selected_process_method=ENSEMBLE_MODE,
is_secondary_model=False,
primary_model_primary_stem=None,
is_primary_model_primary_stem_only=False,
is_primary_model_secondary_stem_only=False,
is_pre_proc_model=False,
2023-09-26 00:11:08 +02:00
is_dry_check=False,
is_change_def=False,
is_get_hash_dir_only=False,
is_vocal_split_model=False):
self.DENOISER_MODEL = DENOISER_MODEL_PATH
self.DEVERBER_MODEL = DEVERBER_MODEL_PATH
self.is_deverb_vocals = root.is_deverb_vocals_var.get() if os.path.isfile(DEVERBER_MODEL_PATH) else False
self.deverb_vocal_opt = DEVERB_MAPPER[root.deverb_vocal_opt_var.get()]
self.is_denoise_model = True if root.denoise_option_var.get() == DENOISE_M and os.path.isfile(DENOISER_MODEL_PATH) else False
2022-12-19 04:18:56 +01:00
self.is_gpu_conversion = 0 if root.is_gpu_conversion_var.get() else -1
self.is_normalization = root.is_normalization_var.get()
self.is_primary_stem_only = root.is_primary_stem_only_var.get()
self.is_secondary_stem_only = root.is_secondary_stem_only_var.get()
2023-09-26 00:11:08 +02:00
self.is_denoise = True if not root.denoise_option_var.get() == DENOISE_NONE else False
self.is_mdx_c_seg_def = root.is_mdx_c_seg_def_var.get()#
2023-03-31 12:15:39 +02:00
self.mdx_batch_size = 1 if root.mdx_batch_size_var.get() == DEF_OPT else int(root.mdx_batch_size_var.get())
2023-09-26 00:11:08 +02:00
self.mdxnet_stem_select = root.mdxnet_stems_var.get()
self.overlap = float(root.overlap_var.get()) if not root.overlap_var.get() == DEFAULT else 0.25
self.overlap_mdx = float(root.overlap_mdx_var.get()) if not root.overlap_mdx_var.get() == DEFAULT else root.overlap_mdx_var.get()
self.overlap_mdx23 = int(float(root.overlap_mdx23_var.get()))
self.semitone_shift = float(root.semitone_shift_var.get())
self.is_pitch_change = False if self.semitone_shift == 0 else True
self.is_match_frequency_pitch = root.is_match_frequency_pitch_var.get()
2023-03-31 12:15:39 +02:00
self.is_mdx_ckpt = False
2023-09-26 00:11:08 +02:00
self.is_mdx_c = False
self.is_mdx_combine_stems = root.is_mdx23_combine_stems_var.get()#
self.mdx_c_configs = None
self.mdx_model_stems = []
self.mdx_dim_f_set = None
self.mdx_dim_t_set = None
self.mdx_stem_count = 1
self.compensate = None
self.mdx_n_fft_scale_set = None
2023-10-16 02:27:38 +02:00
self.wav_type_set = root.wav_type_set#cuda_type
self.cuda_set = root.cuda_set_var.get()#cuda_type
2022-12-19 04:18:56 +01:00
self.mp3_bit_set = root.mp3_bit_set_var.get()
self.save_format = root.save_format_var.get()
2023-09-26 00:11:08 +02:00
self.is_invert_spec = root.is_invert_spec_var.get()#
self.is_mixer_mode = False#
2022-12-19 04:18:56 +01:00
self.demucs_stems = root.demucs_stems_var.get()
2023-09-26 00:11:08 +02:00
self.is_demucs_combine_stems = root.is_demucs_combine_stems_var.get()
2022-12-19 04:18:56 +01:00
self.demucs_source_list = []
self.demucs_stem_count = 0
2023-03-31 12:15:39 +02:00
self.mixer_path = MDX_MIXER_PATH
2022-12-19 04:18:56 +01:00
self.model_name = model_name
self.process_method = selected_process_method
self.model_status = False if self.model_name == CHOOSE_MODEL or self.model_name == NO_MODEL else True
self.primary_stem = None
self.secondary_stem = None
2023-09-26 00:11:08 +02:00
self.primary_stem_native = None
2022-12-19 04:18:56 +01:00
self.is_ensemble_mode = False
self.ensemble_primary_stem = None
self.ensemble_secondary_stem = None
self.primary_model_primary_stem = primary_model_primary_stem
2023-09-26 00:11:08 +02:00
self.is_secondary_model = True if is_vocal_split_model else is_secondary_model
2022-12-19 04:18:56 +01:00
self.secondary_model = None
self.secondary_model_scale = None
self.demucs_4_stem_added_count = 0
self.is_demucs_4_stem_secondaries = False
self.is_4_stem_ensemble = False
self.pre_proc_model = None
self.pre_proc_model_activated = False
self.is_pre_proc_model = is_pre_proc_model
self.is_dry_check = is_dry_check
self.model_samplerate = 44100
2023-03-31 12:15:39 +02:00
self.model_capacity = 32, 128
self.is_vr_51_model = False
2022-12-19 04:18:56 +01:00
self.is_demucs_pre_proc_model_inst_mix = False
2022-12-21 11:18:16 +01:00
self.manual_download_Button = None
2022-12-19 04:18:56 +01:00
self.secondary_model_4_stem = []
self.secondary_model_4_stem_scale = []
self.secondary_model_4_stem_names = []
self.secondary_model_4_stem_model_names_list = []
self.all_models = []
self.secondary_model_other = None
self.secondary_model_scale_other = None
self.secondary_model_bass = None
self.secondary_model_scale_bass = None
self.secondary_model_drums = None
self.secondary_model_scale_drums = None
2023-09-26 00:11:08 +02:00
self.is_multi_stem_ensemble = False
self.is_karaoke = False
self.is_bv_model = False
self.bv_model_rebalance = 0
self.is_sec_bv_rebalance = False
self.is_change_def = is_change_def
self.model_hash_dir = None
self.is_get_hash_dir_only = is_get_hash_dir_only
self.is_secondary_model_activated = False
self.vocal_split_model = None
self.is_vocal_split_model = is_vocal_split_model
self.is_vocal_split_model_activated = False
self.is_save_inst_vocal_splitter = root.is_save_inst_set_vocal_splitter_var.get()
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)
2022-12-19 04:18:56 +01:00
if selected_process_method == ENSEMBLE_MODE:
2023-09-26 00:11:08 +02:00
self.process_method, _, self.model_name = model_name.partition(ENSEMBLE_PARTITION)
2022-12-19 04:18:56 +01:00
self.model_and_process_tag = model_name
self.ensemble_primary_stem, self.ensemble_secondary_stem = root.return_ensemble_stems()
2023-09-26 00:11:08 +02:00
is_not_secondary_or_pre_proc = not is_secondary_model and not is_pre_proc_model
self.is_ensemble_mode = is_not_secondary_or_pre_proc
if root.ensemble_main_stem_var.get() == FOUR_STEM_ENSEMBLE:
self.is_4_stem_ensemble = self.is_ensemble_mode
elif root.ensemble_main_stem_var.get() == MULTI_STEM_ENSEMBLE and root.chosen_process_method_var.get() == ENSEMBLE_MODE:
self.is_multi_stem_ensemble = True
is_not_vocal_stem = self.ensemble_primary_stem != VOCAL_STEM
self.pre_proc_model_activated = root.is_demucs_pre_proc_model_activate_var.get() if is_not_vocal_stem else False
2022-12-19 04:18:56 +01:00
if self.process_method == VR_ARCH_TYPE:
2023-09-26 00:11:08 +02:00
self.is_secondary_model_activated = root.vr_is_secondary_model_activate_var.get() if not is_secondary_model else False
2022-12-19 04:18:56 +01:00
self.aggression_setting = float(int(root.aggression_setting_var.get())/100)
self.is_tta = root.is_tta_var.get()
self.is_post_process = root.is_post_process_var.get()
self.window_size = int(root.window_size_var.get())
2023-03-31 12:15:39 +02:00
self.batch_size = 1 if root.batch_size_var.get() == DEF_OPT else int(root.batch_size_var.get())
2022-12-19 04:18:56 +01:00
self.crop_size = int(root.crop_size_var.get())
self.is_high_end_process = 'mirroring' if root.is_high_end_process_var.get() else 'None'
2022-12-21 11:18:16 +01:00
self.post_process_threshold = float(root.post_process_threshold_var.get())
2023-03-31 12:15:39 +02:00
self.model_capacity = 32, 128
2022-12-19 04:18:56 +01:00
self.model_path = os.path.join(VR_MODELS_DIR, f"{self.model_name}.pth")
self.get_model_hash()
if self.model_hash:
2023-09-26 00:11:08 +02:00
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()
else:
self.model_data = self.get_model_data(VR_HASH_DIR, root.vr_hash_MAPPER) if not self.model_hash == WOOD_INST_MODEL_HASH else WOOD_INST_PARAMS
2022-12-19 04:18:56 +01:00
if self.model_data:
vr_model_param = os.path.join(VR_PARAM_DIR, "{}.json".format(self.model_data["vr_model_param"]))
self.primary_stem = self.model_data["primary_stem"]
2023-09-26 00:11:08 +02:00
self.secondary_stem = secondary_stem(self.primary_stem)
2022-12-19 04:18:56 +01:00
self.vr_model_param = ModelParameters(vr_model_param)
self.model_samplerate = self.vr_model_param.param['sr']
2023-09-26 00:11:08 +02:00
self.primary_stem_native = self.primary_stem
2023-03-31 12:15:39 +02:00
if "nout" in self.model_data.keys() and "nout_lstm" in self.model_data.keys():
self.model_capacity = self.model_data["nout"], self.model_data["nout_lstm"]
self.is_vr_51_model = True
2023-09-26 00:11:08 +02:00
self.check_if_karaokee_model()
2022-12-19 04:18:56 +01:00
else:
self.model_status = False
if self.process_method == MDX_ARCH_TYPE:
self.is_secondary_model_activated = root.mdx_is_secondary_model_activate_var.get() if not is_secondary_model else False
self.margin = int(root.margin_var.get())
2023-09-26 00:11:08 +02:00
self.chunks = 0
self.mdx_segment_size = int(root.mdx_segment_size_var.get())
2022-12-19 04:18:56 +01:00
self.get_mdx_model_path()
self.get_model_hash()
if self.model_hash:
2023-09-26 00:11:08 +02:00
self.model_hash_dir = os.path.join(MDX_HASH_DIR, f"{self.model_hash}.json")
if is_change_def:
self.model_data = self.change_model_data()
else:
self.model_data = self.get_model_data(MDX_HASH_DIR, root.mdx_hash_MAPPER)
2022-12-19 04:18:56 +01:00
if self.model_data:
2023-09-26 00:11:08 +02:00
if "config_yaml" in self.model_data:
self.is_mdx_c = True
config_path = os.path.join(MDX_C_CONFIG_PATH, self.model_data["config_yaml"])
if os.path.isfile(config_path):
with open(config_path) as f:
config = ConfigDict(yaml.load(f, Loader=yaml.FullLoader))
self.mdx_c_configs = config
if self.mdx_c_configs.training.target_instrument:
# 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]
self.primary_stem = target
else:
# If no specific target_instrument, use all instruments in the training config
self.mdx_model_stems = self.mdx_c_configs.training.instruments
self.mdx_stem_count = len(self.mdx_model_stems)
# Set primary stem based on stem count
if self.mdx_stem_count == 2:
self.primary_stem = self.mdx_model_stems[0]
else:
self.primary_stem = self.mdxnet_stem_select
# 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:
self.compensate = self.model_data["compensate"] if root.compensate_var.get() == AUTO_SELECT else float(root.compensate_var.get())
self.mdx_dim_f_set = self.model_data["mdx_dim_f_set"]
self.mdx_dim_t_set = self.model_data["mdx_dim_t_set"]
self.mdx_n_fft_scale_set = self.model_data["mdx_n_fft_scale_set"]
self.primary_stem = self.model_data["primary_stem"]
self.primary_stem_native = self.model_data["primary_stem"]
self.check_if_karaokee_model()
self.secondary_stem = secondary_stem(self.primary_stem)
2022-12-19 04:18:56 +01:00
else:
self.model_status = False
if self.process_method == DEMUCS_ARCH_TYPE:
self.is_secondary_model_activated = root.demucs_is_secondary_model_activate_var.get() if not is_secondary_model else False
if not self.is_ensemble_mode:
self.pre_proc_model_activated = root.is_demucs_pre_proc_model_activate_var.get() if not root.demucs_stems_var.get() in [VOCAL_STEM, INST_STEM] else False
self.margin_demucs = int(root.margin_demucs_var.get())
2023-09-26 00:11:08 +02:00
self.chunks_demucs = 0
2022-12-19 04:18:56 +01:00
self.shifts = int(root.shifts_var.get())
self.is_split_mode = root.is_split_mode_var.get()
self.segment = root.segment_var.get()
self.is_chunk_demucs = root.is_chunk_demucs_var.get()
self.is_primary_stem_only = root.is_primary_stem_only_var.get() if self.is_ensemble_mode else root.is_primary_stem_only_Demucs_var.get()
self.is_secondary_stem_only = root.is_secondary_stem_only_var.get() if self.is_ensemble_mode else root.is_secondary_stem_only_Demucs_var.get()
self.get_demucs_model_data()
2023-09-26 00:11:08 +02:00
self.get_demucs_model_path()
if self.model_status:
self.model_basename = os.path.splitext(os.path.basename(self.model_path))[0]
else:
self.model_basename = None
2022-12-19 04:18:56 +01:00
self.pre_proc_model_activated = self.pre_proc_model_activated if not self.is_secondary_model else False
self.is_primary_model_primary_stem_only = is_primary_model_primary_stem_only
self.is_primary_model_secondary_stem_only = is_primary_model_secondary_stem_only
2023-09-26 00:11:08 +02:00
is_secondary_activated_and_status = self.is_secondary_model_activated and self.model_status
is_demucs = self.process_method == DEMUCS_ARCH_TYPE
is_all_stems = root.demucs_stems_var.get() == ALL_STEMS
is_valid_ensemble = not self.is_ensemble_mode and is_all_stems and is_demucs
is_multi_stem_ensemble_demucs = self.is_multi_stem_ensemble and is_demucs
if is_secondary_activated_and_status:
if is_valid_ensemble or self.is_4_stem_ensemble or is_multi_stem_ensemble_demucs:
2022-12-19 04:18:56 +01:00
for key in DEMUCS_4_SOURCE_LIST:
self.secondary_model_data(key)
self.secondary_model_4_stem.append(self.secondary_model)
self.secondary_model_4_stem_scale.append(self.secondary_model_scale)
self.secondary_model_4_stem_names.append(key)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
self.demucs_4_stem_added_count = sum(i is not None for i in self.secondary_model_4_stem)
2023-09-26 00:11:08 +02:00
self.is_secondary_model_activated = any(i is not None for i in self.secondary_model_4_stem)
self.demucs_4_stem_added_count -= 1 if self.is_secondary_model_activated else 0
2022-12-19 04:18:56 +01:00
if self.is_secondary_model_activated:
2023-09-26 00:11:08 +02:00
self.secondary_model_4_stem_model_names_list = [i.model_basename if i is not None else None for i in self.secondary_model_4_stem]
self.is_demucs_4_stem_secondaries = True
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
primary_stem = self.ensemble_primary_stem if self.is_ensemble_mode and is_demucs else self.primary_stem
2022-12-19 04:18:56 +01:00
self.secondary_model_data(primary_stem)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if self.process_method == DEMUCS_ARCH_TYPE and not is_secondary_model:
if self.demucs_stem_count >= 3 and self.pre_proc_model_activated:
self.pre_proc_model = root.process_determine_demucs_pre_proc_model(self.primary_stem)
2023-09-26 00:11:08 +02:00
self.pre_proc_model_activated = True if self.pre_proc_model else False
2022-12-19 04:18:56 +01:00
self.is_demucs_pre_proc_model_inst_mix = root.is_demucs_pre_proc_model_inst_mix_var.get() if self.pre_proc_model else False
2023-09-26 00:11:08 +02:00
if self.is_vocal_split_model and self.model_status:
self.is_secondary_model_activated = False
if self.is_bv_model:
primary = BV_VOCAL_STEM if self.primary_stem_native == VOCAL_STEM else LEAD_VOCAL_STEM
else:
primary = LEAD_VOCAL_STEM if self.primary_stem_native == VOCAL_STEM else BV_VOCAL_STEM
self.primary_stem, self.secondary_stem = primary, secondary_stem(primary)
self.vocal_splitter_model_data()
def vocal_splitter_model_data(self):
if not self.is_secondary_model and self.model_status:
self.vocal_split_model = root.process_determine_vocal_split_model()
self.is_vocal_split_model_activated = True if self.vocal_split_model else False
if self.vocal_split_model:
if self.vocal_split_model.bv_model_rebalance:
self.is_sec_bv_rebalance = True
2022-12-19 04:18:56 +01:00
def secondary_model_data(self, primary_stem):
secondary_model_data = root.process_determine_secondary_model(self.process_method, primary_stem, self.is_primary_stem_only, self.is_secondary_stem_only)
self.secondary_model = secondary_model_data[0]
self.secondary_model_scale = secondary_model_data[1]
self.is_secondary_model_activated = False if not self.secondary_model else True
if self.secondary_model:
self.is_secondary_model_activated = False if self.secondary_model.model_basename == self.model_basename else True
2023-09-26 00:11:08 +02:00
#print("self.is_secondary_model_activated: ", self.is_secondary_model_activated)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def check_if_karaokee_model(self):
if IS_KARAOKEE in self.model_data.keys():
self.is_karaoke = self.model_data[IS_KARAOKEE]
if IS_BV_MODEL in self.model_data.keys():
self.is_bv_model = self.model_data[IS_BV_MODEL]#
if IS_BV_MODEL_REBAL in self.model_data.keys() and self.is_bv_model:
self.bv_model_rebalance = self.model_data[IS_BV_MODEL_REBAL]#
2022-12-19 04:18:56 +01:00
def get_mdx_model_path(self):
2023-03-31 12:15:39 +02:00
if self.model_name.endswith(CKPT):
self.is_mdx_ckpt = True
2023-09-26 00:11:08 +02:00
2023-03-31 12:15:39 +02:00
ext = '' if self.is_mdx_ckpt else ONNX
for file_name, chosen_mdx_model in root.mdx_name_select_MAPPER.items():
2022-12-19 04:18:56 +01:00
if self.model_name in chosen_mdx_model:
2023-09-26 00:11:08 +02:00
if file_name.endswith(CKPT):
ext = ''
2023-03-31 12:15:39 +02:00
self.model_path = os.path.join(MDX_MODELS_DIR, f"{file_name}{ext}")
2022-12-19 04:18:56 +01:00
break
else:
2023-03-31 12:15:39 +02:00
self.model_path = os.path.join(MDX_MODELS_DIR, f"{self.model_name}{ext}")
2022-12-19 04:18:56 +01:00
self.mixer_path = os.path.join(MDX_MODELS_DIR, f"mixer_val.ckpt")
def get_demucs_model_path(self):
2023-09-26 00:11:08 +02:00
demucs_newer = self.demucs_version in {DEMUCS_V3, DEMUCS_V4}
2022-12-19 04:18:56 +01:00
demucs_model_dir = DEMUCS_NEWER_REPO_DIR if demucs_newer else DEMUCS_MODELS_DIR
2023-03-31 12:15:39 +02:00
for file_name, chosen_model in root.demucs_name_select_MAPPER.items():
2023-09-26 00:11:08 +02:00
if self.model_name == chosen_model:
2022-12-19 04:18:56 +01:00
self.model_path = os.path.join(demucs_model_dir, file_name)
break
else:
self.model_path = os.path.join(DEMUCS_NEWER_REPO_DIR, f'{self.model_name}.yaml')
def get_demucs_model_data(self):
self.demucs_version = DEMUCS_V4
for key, value in DEMUCS_VERSION_MAPPER.items():
if value in self.model_name:
self.demucs_version = key
2023-09-26 00:11:08 +02:00
if DEMUCS_UVR_MODEL in self.model_name:
self.demucs_source_list, self.demucs_source_map, self.demucs_stem_count = DEMUCS_2_SOURCE, DEMUCS_2_SOURCE_MAPPER, 2
else:
self.demucs_source_list, self.demucs_source_map, self.demucs_stem_count = DEMUCS_4_SOURCE, DEMUCS_4_SOURCE_MAPPER, 4
2022-12-19 04:18:56 +01:00
if not self.is_ensemble_mode:
self.primary_stem = PRIMARY_STEM if self.demucs_stems == ALL_STEMS else self.demucs_stems
2023-09-26 00:11:08 +02:00
self.secondary_stem = secondary_stem(self.primary_stem)
def get_model_data(self, model_hash_dir, hash_mapper:dict):
model_settings_json = os.path.join(model_hash_dir, f"{self.model_hash}.json")
2022-12-19 04:18:56 +01:00
if os.path.isfile(model_settings_json):
2023-09-26 00:11:08 +02:00
with open(model_settings_json, 'r') as json_file:
return json.load(json_file)
2022-12-19 04:18:56 +01:00
else:
for hash, settings in hash_mapper.items():
if self.model_hash in hash:
return settings
2023-09-26 00:11:08 +02:00
return self.get_model_data_from_popup()
def change_model_data(self):
if self.is_get_hash_dir_only:
return None
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
return self.get_model_data_from_popup()
def get_model_data_from_popup(self):
if self.is_dry_check:
2022-12-19 04:18:56 +01:00
return None
2023-09-26 00:11:08 +02:00
if not self.is_change_def:
confirm = messagebox.askyesno(
title=UNRECOGNIZED_MODEL[0],
message=f'"{self.model_name}"{UNRECOGNIZED_MODEL[1]}',
parent=root
)
if not confirm:
return None
if self.process_method == VR_ARCH_TYPE:
root.pop_up_vr_param(self.model_hash)
return root.vr_model_params
elif self.process_method == MDX_ARCH_TYPE:
root.pop_up_mdx_model(self.model_hash, self.model_path)
return root.mdx_model_params
2022-12-19 04:18:56 +01:00
def get_model_hash(self):
self.model_hash = None
if not os.path.isfile(self.model_path):
self.model_status = False
self.model_hash is None
else:
if model_hash_table:
for (key, value) in model_hash_table.items():
if self.model_path == key:
self.model_hash = value
break
if not self.model_hash:
2023-03-31 12:15:39 +02:00
try:
with open(self.model_path, 'rb') as f:
f.seek(- 10000 * 1024, 2)
self.model_hash = hashlib.md5(f.read()).hexdigest()
except:
self.model_hash = hashlib.md5(open(self.model_path,'rb').read()).hexdigest()
2022-12-19 04:18:56 +01:00
table_entry = {self.model_path: self.model_hash}
model_hash_table.update(table_entry)
2023-09-26 00:11:08 +02:00
2023-09-26 01:14:03 +02:00
#print(self.model_name," - ", self.model_hash)
2022-12-19 04:18:56 +01:00
class Ensembler():
def __init__(self, is_manual_ensemble=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'
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.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 ''
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.primary_algorithm = ensemble_algorithm[0]
self.secondary_algorithm = ensemble_algorithm[2]
self.ensemble_primary_stem = ensemble_main_stem_pair[0]
self.ensemble_secondary_stem = ensemble_main_stem_pair[2]
self.is_normalization = root.is_normalization_var.get()
2023-09-26 00:11:08 +02:00
self.is_wav_ensemble = root.is_wav_ensemble_var.get()
2022-12-19 04:18:56 +01:00
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:
os.mkdir(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"""
if is_4_stem:
algorithm = root.ensemble_type_var.get()
stem_tag = stem
else:
if is_inst_mix:
algorithm = self.secondary_algorithm
stem_tag = f"{self.ensemble_secondary_stem} {INST_STEM}"
else:
algorithm = self.primary_algorithm if stem == PRIMARY_STEM else self.secondary_algorithm
stem_tag = self.ensemble_primary_stem if stem == PRIMARY_STEM else self.ensemble_secondary_stem
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))
2023-03-31 12:15:39 +02:00
2023-09-26 00:11:08 +02:00
#print("get_files_to_ensemble: ", stem_outputs)
if len(stem_outputs) > 1:
spec_utils.ensemble_inputs(stem_outputs, algorithm, self.is_normalization, self.wav_type_set, stem_save_path, is_wave=self.is_wav_ensemble)
2022-12-19 04:18:56 +01:00
save_format(stem_save_path, self.save_format, self.mp3_bit_set)
if self.is_save_all_outputs_ensemble:
for i in stem_outputs:
save_format(i, self.save_format, self.mp3_bit_set)
else:
for i in stem_outputs:
try:
os.remove(i)
except Exception as e:
print(e)
2023-03-31 12:15:39 +02:00
def ensemble_manual(self, audio_inputs, audio_file_base, is_bulk=False):
2022-12-19 04:18:56 +01:00
"""Processes the given outputs and ensembles them with the chosen algorithm"""
2023-03-31 12:15:39 +02:00
is_mv_sep = True
if is_bulk:
number_list = list(set([os.path.basename(i).split("_")[0] for i in audio_inputs]))
for n in number_list:
current_list = [i for i in audio_inputs if os.path.basename(i).startswith(n)]
audio_file_base = os.path.basename(current_list[0]).split('.wav')[0]
stem_testing = "instrum" if "Instrumental" in audio_file_base else "vocals"
if is_mv_sep:
audio_file_base = audio_file_base.split("_")
audio_file_base = f"{audio_file_base[1]}_{audio_file_base[2]}_{stem_testing}"
self.ensemble_manual_process(current_list, audio_file_base, is_bulk)
else:
self.ensemble_manual_process(audio_inputs, audio_file_base, is_bulk)
def ensemble_manual_process(self, audio_inputs, audio_file_base, is_bulk):
2022-12-19 04:18:56 +01:00
algorithm = root.choose_algorithm_var.get()
2023-03-31 12:15:39 +02:00
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))
2023-09-26 00:11:08 +02:00
spec_utils.ensemble_inputs(audio_inputs, algorithm, self.is_normalization, self.wav_type_set, stem_save_path, is_wave=self.is_wav_ensemble)
2022-12-19 04:18:56 +01:00
save_format(stem_save_path, self.save_format, self.mp3_bit_set)
def get_files_to_ensemble(self, folder="", prefix="", suffix=""):
2022-12-23 08:45:18 +01:00
"""Grab all the files to be ensembled"""
2022-12-19 04:18:56 +01:00
return [os.path.join(folder, i) for i in os.listdir(folder) if i.startswith(prefix) and i.endswith(suffix)]
2023-09-26 00:11:08 +02:00
def combine_audio(self, audio_inputs, audio_file_base):
save_format_ = lambda save_path:save_format(save_path, root.save_format_var.get(), root.mp3_bit_set_var.get())
spec_utils.combine_audio(audio_inputs,
os.path.join(self.main_export_path, f"{self.is_testing_audio}{audio_file_base}"),
self.wav_type_set,
save_format=save_format_)
2022-12-19 04:18:56 +01:00
class AudioTools():
def __init__(self, audio_tool):
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.save_format = lambda save_path:save_format(save_path, root.save_format_var.get(), root.mp3_bit_set_var.get())
2023-09-26 00:11:08 +02:00
self.align_window = TIME_WINDOW_MAPPER[root.time_window_var.get()]
self.align_intro_val = INTRO_MAPPER[root.intro_analysis_var.get()]
self.db_analysis_val = VOLUME_MAPPER[root.db_analysis_var.get()]
self.is_save_align = root.is_save_align_var.get()#
self.is_match_silence = root.is_match_silence_var.get()#
self.is_spec_match = root.is_spec_match_var.get()
self.phase_option = root.phase_option_var.get()#
self.phase_shifts = PHASE_SHIFTS_OPT[root.phase_shifts_var.get()]
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def align_inputs(self, audio_inputs, audio_file_base, audio_file_2_base, command_Text, set_progress_bar):
2022-12-19 04:18:56 +01:00
audio_file_base = f"{self.is_testing_audio}{audio_file_base}"
audio_file_2_base = f"{self.is_testing_audio}{audio_file_2_base}"
2023-09-26 00:11:08 +02:00
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))
spec_utils.align_audio(audio_inputs[0],
audio_inputs[1],
aligned_path,
inverted_path,
self.wav_type_set,
self.is_save_align,
command_Text,
self.save_format,
align_window=self.align_window,
align_intro_val=self.align_intro_val,
db_analysis=self.db_analysis_val,
set_progress_bar=set_progress_bar,
phase_option=self.phase_option,
phase_shifts=self.phase_shifts,
is_match_silence=self.is_match_silence,
is_spec_match=self.is_spec_match)
def match_inputs(self, audio_inputs, audio_file_base, command_Text):
target = audio_inputs[0]
reference = audio_inputs[1]
command_Text(f"Processing... ")
save_path = os.path.join('{}'.format(self.main_export_path),'{}_(Matched).wav'.format(f"{self.is_testing_audio}{audio_file_base}"))
match.process(
target=target,
reference=reference,
results=[match.save_audiofile(save_path, wav_set=self.wav_type_set),
],
)
self.save_format(save_path)
def combine_audio(self, audio_inputs, audio_file_base):
spec_utils.combine_audio(audio_inputs,
os.path.join(self.main_export_path, f"{self.is_testing_audio}{audio_file_base}"),
self.wav_type_set,
save_format=self.save_format)
2022-12-19 04:18:56 +01:00
def pitch_or_time_shift(self, audio_file, audio_file_base):
2023-09-26 00:11:08 +02:00
is_time_correction = True
2022-12-19 04:18:56 +01:00
rate = float(root.time_stretch_rate_var.get()) if self.audio_tool == TIME_STRETCH else float(root.pitch_rate_var.get())
is_pitch = False if self.audio_tool == TIME_STRETCH else True
2023-09-26 00:11:08 +02:00
if is_pitch:
is_time_correction = True if root.is_time_correction_var.get() else False
2022-12-19 04:18:56 +01:00
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")
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
class ToolTip(object):
def __init__(self, widget):
self.widget = widget
2023-09-26 00:11:08 +02:00
self.tooltip = None
def showtip(self, text, is_message_box=False, is_success_message=None):#
self.hidetip()
def create_label_config():
font_size = FONT_SIZE_3 if is_message_box else FONT_SIZE_2
"""Helper function to generate label configurations."""
common_config = {
"text": text,
"relief": tk.SOLID,
"borderwidth": 1,
"font": (MAIN_FONT_NAME, f"{font_size}", "normal")
}
if is_message_box:
background_color = "#03692d" if is_success_message else "#8B0000"
return {**common_config, "background": background_color, "foreground": "#ffffff"}
else:
return {**common_config, "background": "#1C1C1C", "foreground": "#ffffff",
"highlightcolor": "#898b8e", "justify": tk.LEFT}
if is_message_box:
temp_tooltip = tk.Toplevel(self.widget)
temp_tooltip.wm_overrideredirect(True)
temp_tooltip.withdraw()
label = tk.Label(temp_tooltip, **create_label_config())
label.pack()
temp_tooltip.update() if is_windows else temp_tooltip.update_idletasks()
x = self.widget.winfo_rootx() + (self.widget.winfo_width() // 2) - (temp_tooltip.winfo_reqwidth() // 2)
y = self.widget.winfo_rooty() + self.widget.winfo_height()
temp_tooltip.destroy()
else:
x, y, _, _ = self.widget.bbox("insert")
x += self.widget.winfo_rootx() + 25
y += self.widget.winfo_rooty() + 25
# Create the actual tooltip
self.tooltip = tk.Toplevel(self.widget)
self.tooltip.wm_overrideredirect(True)
self.tooltip.wm_geometry(f"+{x}+{y}")
label_config = create_label_config()
if not is_message_box:
label_config['padx'] = 10 # horizontal padding
label_config['pady'] = 10 # vertical padding
label_config["wraplength"] = 750
label = tk.Label(self.tooltip, **label_config)
label.pack()
if is_message_box:
self.tooltip.after(3000 if type(is_success_message) is bool else 2000, self.hidetip)
2022-12-19 04:18:56 +01:00
def hidetip(self):
2023-09-26 00:11:08 +02:00
if self.tooltip:
self.tooltip.destroy()
self.tooltip = None
class ListboxBatchFrame(tk.Frame):
def __init__(self, master=None, name="Listbox", command=None, image_sel=None, img_mapper=None):
super().__init__(master)
self.master = master
self.path_list = [] # A list to keep track of the paths
self.basename_to_path = {} # A dict to map basenames to paths
self.label = tk.Label(self, text=name, font=(MAIN_FONT_NAME, f"{FONT_SIZE_5}"), foreground=FG_COLOR)
self.label.pack(pady=(10, 8)) # add padding between label and listbox
self.input_button = ttk.Button(self, text=SELECT_INPUTS, command=self.select_input) # create button for selecting files
self.input_button.pack(pady=(0, 10)) # add padding between button and next widget
self.listbox = tk.Listbox(self, activestyle='dotbox', font=(MAIN_FONT_NAME, f"{FONT_SIZE_4}"), foreground='#cdd3ce', background='#101414', exportselection=0, width=70, height=15)
self.listbox.pack(fill="both", expand=True)
self.button_frame = tk.Frame(self)
self.button_frame.pack()
self.up_button = ttk.Button(self.button_frame, image=img_mapper["up"], command=self.move_up)
self.up_button.grid(row=0, column=0)
self.down_button = ttk.Button(self.button_frame, image=img_mapper["down"], command=self.move_down)
self.down_button.grid(row=0, column=1)
if command and image_sel:
self.move_button = ttk.Button(self.button_frame, image=image_sel, command=command)
self.move_button.grid(row=0, column=2)
self.duplicate_button = ttk.Button(self.button_frame, image=img_mapper["copy"], command=self.duplicate_selected)
self.duplicate_button.grid(row=0, column=3)
self.delete_button = ttk.Button(self.button_frame, image=img_mapper["clear"], command=self.delete_selected)
self.delete_button.grid(row=0, column=4)
def delete_selected(self):
selected = self.listbox.curselection()
if selected:
basename = self.listbox.get(selected[0]).split(": ", 1)[1] # We get the actual basename here, without the index
path_to_delete = self.basename_to_path[basename] # store the path to delete
del self.basename_to_path[basename] # delete from the dict
self.path_list.remove(path_to_delete) # delete from the list
self.listbox.delete(selected)
self.update_displayed_index()
def select_input(self, inputs=None):
2023-09-27 04:54:09 +02:00
files = inputs if inputs else root.show_file_dialog(dialoge_type=MULTIPLE_FILE)
2023-09-26 00:11:08 +02:00
for file in files:
if file not in self.path_list: # only add file if it's not already in the list
basename = os.path.basename(file)
self.listbox.insert(tk.END, basename) # insert basename to the listbox
self.path_list.append(file) # append the file path to the list
self.basename_to_path[basename] = file # add to the dict
self.update_displayed_index(is_acc_dupe=False)
def duplicate_selected(self):
selected = self.listbox.curselection()
if selected:
basename = self.listbox.get(selected[0]).split(": ", 1)[1] # We get the actual basename here, without the index
path_to_duplicate = self.basename_to_path[basename] # store the path to duplicate
self.path_list.append(path_to_duplicate) # add the duplicated path to the list
self.update_displayed_index() # redraw listbox with the duplicated item
def update_displayed_index(self, inputs=None, is_acc_dupe=True):
self.basename_to_path = {} # reset the dictionary
if inputs:
self.path_list = inputs
basename_count = Counter(self.path_list) # count occurrences of each path
for i in range(len(self.path_list)):
basename = os.path.basename(self.path_list[i])
# If the path is not unique or we are adding a duplicate
if basename_count[self.path_list[i]] > 1 and is_acc_dupe:
j = 1
new_basename = f"{basename} ({j})"
while new_basename in self.basename_to_path:
j += 1
new_basename = f"{basename} ({j})"
basename = new_basename
self.basename_to_path[basename] = self.path_list[i] # update the dict with the new order
self.listbox.delete(i)
self.listbox.insert(i, f"{i + 1}: {basename}")
def move_up(self):
selected = self.listbox.curselection()
if selected and selected[0] > 0:
# Swap items in path_list
self.path_list[selected[0] - 1], self.path_list[selected[0]] = self.path_list[selected[0]], self.path_list[selected[0] - 1]
# Redraw listbox
self.update_displayed_index()
# Reselect item
self.listbox.select_set(selected[0] - 1)
def move_down(self):
selected = self.listbox.curselection()
if selected and selected[0] < self.listbox.size() - 1:
# Swap items in path_list
self.path_list[selected[0] + 1], self.path_list[selected[0]] = self.path_list[selected[0]], self.path_list[selected[0] + 1]
# Redraw listbox
self.update_displayed_index()
# Reselect item
self.listbox.select_set(selected[0] + 1)
def get_selected_path(self):
"""Returns the path associated with the selected entry."""
selected = self.listbox.curselection()
if selected:
basename = self.listbox.get(selected[0]).split(": ", 1)[1] # We get the actual basename here, without the index
path = self.basename_to_path[basename] # get the path associated with the basename
return path
return None
class ComboBoxEditableMenu(ttk.Combobox):
def __init__(self, master=None, pattern=None, default=None, width=None, is_stay_disabled=False, **kw):
if 'values' in kw:
kw['values'] = tuple(kw['values']) + (OPT_SEPARATOR, USER_INPUT)
else:
kw['values'] = (USER_INPUT)
super().__init__(master, **kw)
self.textvariable = kw.get('textvariable', tk.StringVar())
self.pattern = pattern
self.test = 1
self.tooltip = ToolTip(self)
self.is_user_input_var = tk.BooleanVar(value=False)
self.is_stay_disabled = is_stay_disabled
if isinstance(default, (str, int)):
self.default = default
else:
self.default = default[0]
self.menu_combobox_configure()
self.var_validation(is_start_up=True)
if width:
self.configure(width=width)
def menu_combobox_configure(self):
self.bind('<<ComboboxSelected>>', self.check_input)
self.bind('<Button-1>', lambda e:self.focus())
self.bind('<FocusIn>', self.focusin)
self.bind('<FocusOut>', lambda e: self.var_validation(is_focus_only=True))
if is_macos:
self.bind('<Enter>', lambda e:self.button_released())
if not self.is_stay_disabled:
self.configure(state=READ_ONLY)
def check_input(self, event=None):
if self.textvariable.get() == USER_INPUT:
self.textvariable.set('')
self.configure(state=tk.NORMAL)
self.focus()
self.selection_range(0, 0)
else:
self.var_validation()
def var_validation(self, is_focus_only=False, is_start_up=False):
if is_focus_only and not self.is_stay_disabled:
self.configure(state=READ_ONLY)
if re.fullmatch(self.pattern, self.textvariable.get()) is None:
if not is_start_up and not self.textvariable.get() in (OPT_SEPARATOR, USER_INPUT):
self.tooltip.showtip(INVALID_INPUT_E, True)
self.textvariable.set(self.default)
def button_released(self, e=None):
self.event_generate('<Button-3>')
self.event_generate('<ButtonRelease-3>')
def focusin(self, e):
self.selection_clear()
if is_macos:
self.event_generate('<Leave>')
class ComboBoxMenu(ttk.Combobox):
def __init__(self, master=None, dropdown_name=None, offset=185, is_download_menu=False, command=None, width=None, **kw):
super().__init__(master, **kw)
# Configure the combobox using the menu_combobox_configure method
self.menu_combobox_configure(is_download_menu, width=width)
# Check if both dropdown_name and 'values' are provided to update dropdown size
if dropdown_name and 'values' in kw:
self.update_dropdown_size(kw['values'], dropdown_name, offset)
if command:
self.command(command)
def menu_combobox_configure(self, is_download_menu=False, command=None, width=None):
self.bind('<FocusIn>', self.focusin)
self.bind('<MouseWheel>', lambda e:"break")
if is_macos:
self.bind('<Enter>', lambda e:self.button_released())
if not is_download_menu:
self.configure(state=READ_ONLY)
if command:
self.command(command)
if width:
self.configure(width=width)
def button_released(self, e=None):
self.event_generate('<Button-3>')
self.event_generate('<ButtonRelease-3>')
def command(self, command):
if not self.bind('<<ComboboxSelected>>'):
self.bind('<<ComboboxSelected>>', command)
def focusin(self, e):
self.selection_clear()
if is_macos:
self.event_generate('<Leave>')
def update_dropdown_size(self, option_list, dropdown_name, offset=185, command=None):
dropdown_style = f"{dropdown_name}.TCombobox"
if option_list:
max_string = max(option_list, key=len)
font = Font(font=self.cget('font'))
width_in_pixels = font.measure(max_string) - offset
width_in_pixels = 0 if width_in_pixels < 0 else width_in_pixels
else:
width_in_pixels = 0
style = ttk.Style(self)
style.configure(dropdown_style, padding=(0, 0, 0, 0), postoffset=(0, 0, width_in_pixels, 0))
self.configure(style=dropdown_style)
if command:
self.command(command)
2022-12-19 04:18:56 +01:00
class ThreadSafeConsole(tk.Text):
"""
Text Widget which is thread safe for tkinter
"""
def __init__(self, master, **options):
tk.Text.__init__(self, master, **options)
self.queue = queue.Queue()
self.update_me()
def write(self, line):
self.queue.put(line)
def clear(self):
self.queue.put(None)
def update_me(self):
self.configure(state=tk.NORMAL)
try:
while 1:
line = self.queue.get_nowait()
if line is None:
self.delete(1.0, tk.END)
else:
self.insert(tk.END, str(line))
self.see(tk.END)
self.update_idletasks()
except queue.Empty:
pass
self.configure(state=tk.DISABLED)
self.after(100, self.update_me)
def copy_text(self):
hightlighted_text = self.selection_get()
self.clipboard_clear()
self.clipboard_append(hightlighted_text)
def select_all_text(self):
self.tag_add('sel', '1.0', 'end')
2022-12-29 00:48:28 +01:00
class MainWindow(TkinterDnD.Tk if is_dnd_compatible else tk.Tk):
2022-12-19 04:18:56 +01:00
# --Constants--
# Layout
2022-12-27 11:31:41 +01:00
2023-09-26 00:11:08 +02:00
IMAGE_HEIGHT = IMAGE_HEIGHT
FILEPATHS_HEIGHT = FILEPATHS_HEIGHT
OPTIONS_HEIGHT = OPTIONS_HEIGHT
CONVERSIONBUTTON_HEIGHT = CONVERSIONBUTTON_HEIGHT
COMMAND_HEIGHT = COMMAND_HEIGHT
PROGRESS_HEIGHT = PROGRESS_HEIGHT
PADDING = PADDING
WIDTH = WIDTH
2022-12-19 04:18:56 +01:00
COL1_ROWS = 11
COL2_ROWS = 11
def __init__(self):
#Run the __init__ method on the tk.Tk class
super().__init__()
2023-09-26 00:11:08 +02:00
self.set_app_font()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
style = ttk.Style(self)
style.map('TCombobox', selectbackground=[('focus', '#0c0c0c')], selectforeground=[('focus', 'white')])
style.configure('TCombobox', selectbackground='#0c0c0c')
#style.configure('TCheckbutton', indicatorsize=30)
2022-12-19 04:18:56 +01:00
# Calculate window height
height = self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT
height += self.CONVERSIONBUTTON_HEIGHT + self.COMMAND_HEIGHT + self.PROGRESS_HEIGHT
height += self.PADDING * 5 # Padding
2023-09-26 00:11:08 +02:00
width = self.WIDTH
2022-12-19 04:18:56 +01:00
self.main_window_width = width
self.main_window_height = height
# --Window Settings--
2023-09-26 00:11:08 +02:00
self.withdraw()
2022-12-19 04:18:56 +01:00
self.title('Ultimate Vocal Remover')
# Set Geometry and Center Window
self.geometry('{width}x{height}+{xpad}+{ypad}'.format(
width=self.main_window_width,
height=height,
xpad=int(self.winfo_screenwidth()/2 - width/2),
ypad=int(self.winfo_screenheight()/2 - height/2 - 30)))
2022-12-27 11:31:41 +01:00
self.iconbitmap(ICON_IMG_PATH) if is_windows else self.tk.call('wm', 'iconphoto', self._w, tk.PhotoImage(file=MAIN_ICON_IMG_PATH))
2022-12-19 04:18:56 +01:00
self.protocol("WM_DELETE_WINDOW", self.save_values)
self.resizable(False, False)
2023-09-26 00:11:08 +02:00
self.msg_queue = queue.Queue()
# Create a custom style that inherits from the original Combobox style.
if not is_windows:
self.update()
2022-12-19 04:18:56 +01:00
#Load Images
img = ImagePath(BASE_PATH)
2023-10-12 06:30:24 +02:00
self.logo_img = img.open_image(path=img.banner_path, size=(width, height))
2022-12-19 04:18:56 +01:00
self.efile_img = img.efile_img
self.stop_img = img.stop_img
self.help_img = img.help_img
self.download_img = img.download_img
self.donate_img = img.donate_img
self.key_img = img.key_img
self.credits_img = img.credits_img
2023-09-26 00:11:08 +02:00
self.right_img = img.right_img
self.left_img = img.left_img
self.img_mapper = {
"down":img.down_img,
"up":img.up_img,
"copy":img.copy_img,
"clear":img.clear_img
}
2022-12-19 04:18:56 +01:00
#Placeholders
self.error_log_var = tk.StringVar(value='')
self.vr_secondary_model_names = []
self.mdx_secondary_model_names = []
self.demucs_secondary_model_names = []
self.vr_primary_model_names = []
self.mdx_primary_model_names = []
self.demucs_primary_model_names = []
self.vr_cache_source_mapper = {}
self.mdx_cache_source_mapper = {}
self.demucs_cache_source_mapper = {}
# -Tkinter Value Holders-
try:
self.load_saved_vars(data)
except Exception as e:
self.error_log_var.set(error_text('Loading Saved Variables', e))
self.load_saved_vars(DEFAULT_DATA)
self.cached_sources_clear()
self.method_mapper = {
VR_ARCH_PM: self.vr_model_var,
MDX_ARCH_TYPE: self.mdx_net_model_var,
DEMUCS_ARCH_TYPE: self.demucs_model_var}
self.vr_secondary_model_vars = {'voc_inst_secondary_model': self.vr_voc_inst_secondary_model_var,
'other_secondary_model': self.vr_other_secondary_model_var,
'bass_secondary_model': self.vr_bass_secondary_model_var,
'drums_secondary_model': self.vr_drums_secondary_model_var,
'is_secondary_model_activate': self.vr_is_secondary_model_activate_var,
'voc_inst_secondary_model_scale': self.vr_voc_inst_secondary_model_scale_var,
2023-09-26 00:11:08 +02:00
'other_secondary_model_scale': self.vr_other_secondary_model_scale_var,
'bass_secondary_model_scale': self.vr_bass_secondary_model_scale_var,
'drums_secondary_model_scale': self.vr_drums_secondary_model_scale_var}
2022-12-19 04:18:56 +01:00
self.demucs_secondary_model_vars = {'voc_inst_secondary_model': self.demucs_voc_inst_secondary_model_var,
'other_secondary_model': self.demucs_other_secondary_model_var,
'bass_secondary_model': self.demucs_bass_secondary_model_var,
'drums_secondary_model': self.demucs_drums_secondary_model_var,
'is_secondary_model_activate': self.demucs_is_secondary_model_activate_var,
'voc_inst_secondary_model_scale': self.demucs_voc_inst_secondary_model_scale_var,
2023-09-26 00:11:08 +02:00
'other_secondary_model_scale': self.demucs_other_secondary_model_scale_var,
'bass_secondary_model_scale': self.demucs_bass_secondary_model_scale_var,
'drums_secondary_model_scale': self.demucs_drums_secondary_model_scale_var}
2022-12-19 04:18:56 +01:00
self.mdx_secondary_model_vars = {'voc_inst_secondary_model': self.mdx_voc_inst_secondary_model_var,
'other_secondary_model': self.mdx_other_secondary_model_var,
'bass_secondary_model': self.mdx_bass_secondary_model_var,
'drums_secondary_model': self.mdx_drums_secondary_model_var,
'is_secondary_model_activate': self.mdx_is_secondary_model_activate_var,
'voc_inst_secondary_model_scale': self.mdx_voc_inst_secondary_model_scale_var,
2023-09-26 00:11:08 +02:00
'other_secondary_model_scale': self.mdx_other_secondary_model_scale_var,
'bass_secondary_model_scale': self.mdx_bass_secondary_model_scale_var,
'drums_secondary_model_scale': self.mdx_drums_secondary_model_scale_var}
2022-12-19 04:18:56 +01:00
#Main Application Vars
self.progress_bar_main_var = tk.IntVar(value=0)
self.inputPathsEntry_var = tk.StringVar(value='')
self.conversion_Button_Text_var = tk.StringVar(value=START_PROCESSING)
self.chosen_ensemble_var = tk.StringVar(value=CHOOSE_ENSEMBLE_OPTION)
self.ensemble_main_stem_var = tk.StringVar(value=CHOOSE_STEM_PAIR)
self.ensemble_type_var = tk.StringVar(value=MAX_MIN)
self.save_current_settings_var = tk.StringVar(value=SELECT_SAVED_SET)
self.demucs_stems_var = tk.StringVar(value=ALL_STEMS)
2023-09-26 00:11:08 +02:00
self.mdxnet_stems_var = tk.StringVar(value=ALL_STEMS)
2022-12-19 04:18:56 +01:00
self.is_primary_stem_only_Text_var = tk.StringVar(value='')
self.is_secondary_stem_only_Text_var = tk.StringVar(value='')
self.is_primary_stem_only_Demucs_Text_var = tk.StringVar(value='')
self.is_secondary_stem_only_Demucs_Text_var = tk.StringVar(value='')
self.scaling_var = tk.DoubleVar(value=1.0)
self.active_processing_thread = None
self.verification_thread = None
self.is_menu_settings_open = False
2023-09-26 00:11:08 +02:00
self.is_root_defined_var = tk.BooleanVar(value=False)
self.is_check_splash = False
2022-12-19 04:18:56 +01:00
self.is_open_menu_advanced_vr_options = tk.BooleanVar(value=False)
self.is_open_menu_advanced_demucs_options = tk.BooleanVar(value=False)
self.is_open_menu_advanced_mdx_options = tk.BooleanVar(value=False)
self.is_open_menu_advanced_ensemble_options = tk.BooleanVar(value=False)
self.is_open_menu_view_inputs = tk.BooleanVar(value=False)
self.is_open_menu_help = tk.BooleanVar(value=False)
self.is_open_menu_error_log = tk.BooleanVar(value=False)
2023-09-26 00:11:08 +02:00
self.is_open_menu_advanced_align_options = tk.BooleanVar(value=False)
self.menu_advanced_vr_options_close_window = None
self.menu_advanced_demucs_options_close_window = None
self.menu_advanced_mdx_options_close_window = None
self.menu_advanced_ensemble_options_close_window = None
self.menu_help_close_window = None
self.menu_error_log_close_window = None
self.menu_view_inputs_close_window = None
self.menu_advanced_align_options_close_window = None
2022-12-19 04:18:56 +01:00
self.mdx_model_params = None
self.vr_model_params = None
self.current_text_box = None
self.wav_type_set = None
self.is_online_model_menu = None
self.progress_bar_var = tk.IntVar(value=0)
self.is_confirm_error_var = tk.BooleanVar(value=False)
self.clear_cache_torch = False
self.vr_hash_MAPPER = load_model_hash_data(VR_HASH_JSON)
self.mdx_hash_MAPPER = load_model_hash_data(MDX_HASH_JSON)
2023-03-31 12:15:39 +02:00
self.mdx_name_select_MAPPER = load_model_hash_data(MDX_MODEL_NAME_SELECT)
self.demucs_name_select_MAPPER = load_model_hash_data(DEMUCS_MODEL_NAME_SELECT)
2022-12-27 11:31:41 +01:00
self.is_gpu_available = torch.cuda.is_available() if not OPERATING_SYSTEM == 'Darwin' else torch.backends.mps.is_available()
2022-12-19 04:18:56 +01:00
self.is_process_stopped = False
self.inputs_from_dir = []
self.iteration = 0
2023-09-26 00:11:08 +02:00
self.true_model_count = 0
2022-12-19 04:18:56 +01:00
self.vr_primary_source = None
self.vr_secondary_source = None
self.mdx_primary_source = None
self.mdx_secondary_source = None
self.demucs_primary_source = None
self.demucs_secondary_source = None
2023-09-26 00:11:08 +02:00
self.toplevels = []
2022-12-19 04:18:56 +01:00
#Download Center Vars
self.online_data = {}
2023-09-26 00:11:08 +02:00
self.bulletin_data = INFO_UNAVAILABLE_TEXT
2022-12-19 04:18:56 +01:00
self.is_online = False
self.lastest_version = ''
self.model_download_demucs_var = tk.StringVar(value='')
self.model_download_mdx_var = tk.StringVar(value='')
self.model_download_vr_var = tk.StringVar(value='')
self.selected_download_var = tk.StringVar(value=NO_MODEL)
self.select_download_var = tk.StringVar(value='')
self.download_progress_info_var = tk.StringVar(value='')
self.download_progress_percent_var = tk.StringVar(value='')
self.download_progress_bar_var = tk.IntVar(value=0)
self.download_stop_var = tk.StringVar(value='')
2023-09-26 00:11:08 +02:00
self.app_update_status_Text_var = tk.StringVar(value=LOADING_VERSION_INFO_TEXT)
self.app_update_button_Text_var = tk.StringVar(value=CHECK_FOR_UPDATES_TEXT)
2022-12-19 04:18:56 +01:00
self.user_code_validation_var = tk.StringVar(value='')
self.download_link_path_var = tk.StringVar(value='')
self.download_save_path_var = tk.StringVar(value='')
self.download_update_link_var = tk.StringVar(value='')
self.download_update_path_var = tk.StringVar(value='')
self.download_demucs_models_list = []
self.download_demucs_newer_models = []
self.refresh_list_Button = None
self.stop_download_Button_DISABLE = None
self.enable_tabs = None
self.is_download_thread_active = False
self.is_process_thread_active = False
self.is_active_processing_thread = False
self.active_download_thread = None
2023-09-26 00:11:08 +02:00
self.pre_proc_model_toggle = None
self.change_state_lambda = None
self.file_one_sub_var = tk.StringVar(value=FILE_ONE_MAIN_LABEL)
self.file_two_sub_var = tk.StringVar(value=FILE_TWO_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
#Model Update
self.last_found_ensembles = ENSEMBLE_OPTIONS
self.last_found_settings = ENSEMBLE_OPTIONS
self.last_found_models = ()
self.model_data_table = ()
self.ensemble_model_list = ()
2023-09-26 00:11:08 +02:00
self.default_change_model_list = ()
2022-12-19 04:18:56 +01:00
# --Widgets--
self.fill_main_frame()
self.bind_widgets()
2022-12-30 04:07:23 +01:00
2022-12-19 04:18:56 +01:00
# --Update Widgets--
self.update_available_models()
self.update_main_widget_states()
self.update_loop()
self.update_button_states()
self.download_validate_code()
2023-09-26 00:11:08 +02:00
self.delete_temps(is_start_up=True)
2022-12-19 04:18:56 +01:00
self.ensemble_listbox_Option.configure(state=tk.DISABLED)
self.command_Text.write(f'Ultimate Vocal Remover {VERSION} [{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}]')
self.update_checkbox_text = lambda:self.selection_action_process_method(self.chosen_process_method_var.get())
2023-09-26 00:11:08 +02:00
self.check_dual_paths()
if not is_windows:
self.update_idletasks()
self.online_data_refresh(user_refresh=False, is_start_up=True)
2022-12-19 04:18:56 +01:00
# Menu Functions
2023-09-26 00:11:08 +02:00
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)
def main_window_LABEL_SUB_SET(self, master, text_var):return ttk.Label(master=master, textvariable=text_var, background=BG_COLOR, font=self.font_set, foreground=FG_COLOR, anchor=tk.CENTER)
def menu_title_LABEL_SET(self, frame, text, width=35):return ttk.Label(master=frame, text=text, font=(SEC_FONT_NAME, f"{FONT_SIZE_5}", "underline"), justify="center", foreground="#13849f", width=width, anchor=tk.CENTER)
def menu_sub_LABEL_SET(self, frame, text, font_size=FONT_SIZE_2):return ttk.Label(master=frame, text=text, font=(MAIN_FONT_NAME, f"{font_size}"), foreground=FG_COLOR, anchor=tk.CENTER)
def menu_FRAME_SET(self, frame, thickness=20):return tk.Frame(frame, highlightbackground=BG_COLOR, highlightcolor=BG_COLOR, highlightthicknes=thickness)
2022-12-19 04:18:56 +01:00
def check_is_menu_settings_open(self):self.menu_settings() if not self.is_menu_settings_open else None
2023-09-26 00:11:08 +02:00
def spacer_label(self, frame): return tk.Label(frame, text='', font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground='#868687', justify="left").grid()
2022-12-19 04:18:56 +01:00
#Ensemble Listbox Functions
def ensemble_listbox_get_all_selected_models(self):return [self.ensemble_listbox_Option.get(i) for i in self.ensemble_listbox_Option.curselection()]
def ensemble_listbox_select_from_indexs(self, indexes):return [self.ensemble_listbox_Option.selection_set(i) for i in indexes]
def ensemble_listbox_clear_and_insert_new(self, model_ensemble_updated):return (self.ensemble_listbox_Option.delete(0, 'end'), [self.ensemble_listbox_Option.insert(tk.END, models) for models in model_ensemble_updated])
def ensemble_listbox_get_indexes_for_files(self, updated, selected):return [updated.index(model) for model in selected if model in updated]
2023-09-26 00:11:08 +02:00
def set_app_font(self):
chosen_font_name, chosen_font_file = font_checker(OWN_FONT_PATH)
if chosen_font_name:
gui_data.sv_ttk.set_theme("dark", chosen_font_name, 10)
if chosen_font_file:
2023-09-27 06:41:47 +02:00
pyglet_font.add_file(chosen_font_file)
2023-09-26 00:11:08 +02:00
self.font_set = Font(family=chosen_font_name, size=FONT_SIZE_F2)
self.font_entry = Font(family=chosen_font_name, size=FONT_SIZE_F2)
else:
2023-09-27 06:41:47 +02:00
pyglet_font.add_file(FONT_MAPPER[MAIN_FONT_NAME])
pyglet_font.add_file(FONT_MAPPER[SEC_FONT_NAME])
2023-09-26 00:11:08 +02:00
gui_data.sv_ttk.set_theme("dark", MAIN_FONT_NAME, 10)
self.font_set = Font(family=SEC_FONT_NAME, size=FONT_SIZE_F2)
self.font_entry = Font(family=MAIN_FONT_NAME, size=FONT_SIZE_F2)
2022-12-19 04:18:56 +01:00
def process_iteration(self):
self.iteration = self.iteration + 1
2023-09-26 00:11:08 +02:00
def assemble_model_data(self, model=None, arch_type=ENSEMBLE_MODE, is_dry_check=False, is_change_def=False, is_get_hash_dir_only=False):
2022-12-19 04:18:56 +01:00
if arch_type == ENSEMBLE_STEM_CHECK:
model_data = self.model_data_table
missing_models = [model.model_status for model in model_data if not model.model_status]
if missing_models or not model_data:
model_data: List[ModelData] = [ModelData(model_name, is_dry_check=is_dry_check) for model_name in self.ensemble_model_list]
self.model_data_table = model_data
2023-09-26 00:11:08 +02:00
if arch_type == KARAOKEE_CHECK:
model_list = []
model_data: List[ModelData] = [ModelData(model_name, is_dry_check=is_dry_check) for model_name in self.default_change_model_list]
for model in model_data:
if model.model_status and model.is_karaoke or model.is_bv_model:
model_list.append(model.model_and_process_tag)
return model_list
2022-12-19 04:18:56 +01:00
if arch_type == ENSEMBLE_MODE:
model_data: List[ModelData] = [ModelData(model_name) for model_name in self.ensemble_listbox_get_all_selected_models()]
if arch_type == ENSEMBLE_CHECK:
2023-09-26 00:11:08 +02:00
model_data: List[ModelData] = [ModelData(model, is_change_def=is_change_def, is_get_hash_dir_only=is_get_hash_dir_only)]
2022-12-19 04:18:56 +01:00
if arch_type == VR_ARCH_TYPE or arch_type == VR_ARCH_PM:
model_data: List[ModelData] = [ModelData(model, VR_ARCH_TYPE)]
if arch_type == MDX_ARCH_TYPE:
model_data: List[ModelData] = [ModelData(model, MDX_ARCH_TYPE)]
if arch_type == DEMUCS_ARCH_TYPE:
2023-03-31 12:15:39 +02:00
model_data: List[ModelData] = [ModelData(model, DEMUCS_ARCH_TYPE)]#
2022-12-19 04:18:56 +01:00
return model_data
def clear_cache(self, network):
if network == VR_ARCH_TYPE:
dir = VR_HASH_DIR
if network == MDX_ARCH_TYPE:
dir = MDX_HASH_DIR
2023-09-26 00:11:08 +02:00
for filename in os.listdir(dir):
filepath = os.path.join(dir, filename)
if filename not in ['model_data.json', 'model_name_mapper.json', 'mdx_c_configs'] and not os.path.isdir(filepath):
os.remove(filepath)
2022-12-19 04:18:56 +01:00
self.vr_model_var.set(CHOOSE_MODEL)
self.mdx_net_model_var.set(CHOOSE_MODEL)
self.model_data_table.clear()
self.chosen_ensemble_var.set(CHOOSE_ENSEMBLE_OPTION)
self.ensemble_main_stem_var.set(CHOOSE_STEM_PAIR)
self.ensemble_listbox_Option.configure(state=tk.DISABLED)
self.update_checkbox_text()
def thread_check(self, thread_to_check):
'''Checks if thread is alive'''
is_running = False
if type(thread_to_check) is KThread:
if thread_to_check.is_alive():
is_running = True
return is_running
2022-12-27 11:31:41 +01:00
2022-12-19 04:18:56 +01:00
# -Widget Methods--
2022-12-27 11:31:41 +01:00
2022-12-19 04:18:56 +01:00
def fill_main_frame(self):
"""Creates root window widgets"""
self.title_Label = tk.Label(master=self, image=self.logo_img, compound=tk.TOP)
2022-12-30 04:07:23 +01:00
self.title_Label.place(x=-2, y=banner_placement)
2022-12-19 04:18:56 +01:00
self.fill_filePaths_Frame()
self.fill_options_Frame()
self.conversion_Button = ttk.Button(master=self, textvariable=self.conversion_Button_Text_var, command=self.process_initialize)
2023-09-26 00:11:08 +02:00
self.conversion_Button.place(x=X_CONVERSION_BUTTON_1080P, y=BUTTON_Y_1080P, width=WIDTH_CONVERSION_BUTTON_1080P, height=HEIGHT_GENERIC_BUTTON_1080P,
2022-12-19 04:18:56 +01:00
relx=0, rely=0, relwidth=1, relheight=0)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
self.conversion_Button_enable = lambda:(self.conversion_Button_Text_var.set(START_PROCESSING), self.conversion_Button.configure(state=tk.NORMAL))
self.conversion_Button_disable = lambda message:(self.conversion_Button_Text_var.set(message), self.conversion_Button.configure(state=tk.DISABLED))
self.stop_Button = ttk.Button(master=self, image=self.stop_img, command=self.confirm_stop_process)
2023-09-26 00:11:08 +02:00
self.stop_Button.place(x=X_STOP_BUTTON_1080P, y=BUTTON_Y_1080P, width=HEIGHT_GENERIC_BUTTON_1080P, height=HEIGHT_GENERIC_BUTTON_1080P,
relx=1, rely=0, relwidth=0, relheight=0)
2022-12-19 04:18:56 +01:00
self.help_hints(self.stop_Button, text=STOP_HELP)
self.settings_Button = ttk.Button(master=self, image=self.help_img, command=self.check_is_menu_settings_open)
2023-09-26 00:11:08 +02:00
self.settings_Button.place(x=X_SETTINGS_BUTTON_1080P, y=BUTTON_Y_1080P, width=HEIGHT_GENERIC_BUTTON_1080P, height=HEIGHT_GENERIC_BUTTON_1080P,
2022-12-19 04:18:56 +01:00
relx=1, rely=0, relwidth=0, relheight=0)
self.help_hints(self.settings_Button, text=SETTINGS_HELP)
2023-09-26 00:11:08 +02:00
self.progressbar = ttk.Progressbar(master=self, variable=self.progress_bar_main_var)
self.progressbar.place(x=X_PROGRESSBAR_1080P, y=Y_OFFSET_PROGRESS_BAR_1080P, width=WIDTH_PROGRESSBAR_1080P, height=HEIGHT_PROGRESSBAR_1080P,
relx=0, rely=0, relwidth=1, relheight=0)
# Select Music Files Option
self.console_Frame = tk.Frame(master=self, highlightbackground='#101012', highlightcolor='#101012', highlightthicknes=2)
2022-12-19 04:18:56 +01:00
self.console_Frame.place(x=15, y=self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT + self.CONVERSIONBUTTON_HEIGHT + self.PADDING + 5 *3, width=-30, height=self.COMMAND_HEIGHT+7,
relx=0, rely=0, relwidth=1, relheight=0)
2023-09-26 00:11:08 +02:00
self.command_Text = ThreadSafeConsole(master=self.console_Frame, background='#0c0c0d',fg='#898b8e', highlightcolor="#0c0c0d", font=(MAIN_FONT_NAME, FONT_SIZE_4), borderwidth=0)
self.command_Text.pack(fill=tk.BOTH, expand=1)
2022-12-21 11:18:16 +01:00
self.command_Text.bind(right_click_button, lambda e:self.right_click_console(e))
2022-12-19 04:18:56 +01:00
def fill_filePaths_Frame(self):
"""Fill Frame with neccessary widgets"""
2023-09-26 00:11:08 +02:00
# Select Music Files Option
2022-12-19 04:18:56 +01:00
self.filePaths_Frame = ttk.Frame(master=self)
2023-09-26 00:11:08 +02:00
self.filePaths_Frame.place(x=FILEPATHS_FRAME_X, y=FILEPATHS_FRAME_Y, width=FILEPATHS_FRAME_WIDTH, height=self.FILEPATHS_HEIGHT, relx=0, rely=0, relwidth=1, relheight=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.filePaths_musicFile_Button = ttk.Button(master=self.filePaths_Frame, text=SELECT_INPUT_TEXT, command=self.input_select_filedialog)
self.filePaths_musicFile_Button.place(x=MUSICFILE_BUTTON_X, y=MUSICFILE_BUTTON_Y, width=MUSICFILE_BUTTON_WIDTH, height=MUSICFILE_BUTTON_HEIGHT, relx=0, rely=0, relwidth=0.3, relheight=0.5)
self.filePaths_musicFile_Entry = ttk.Entry(master=self.filePaths_Frame, textvariable=self.inputPathsEntry_var, font=self.font_entry, state=tk.DISABLED)
self.filePaths_musicFile_Entry.place(x=MUSICFILE_ENTRY_X, y=MUSICFILE_BUTTON_Y, width=MUSICFILE_ENTRY_WIDTH, height=MUSICFILE_ENTRY_HEIGHT, relx=0.3, rely=0, relwidth=0.7, relheight=0.5)
2023-09-26 23:46:28 +02:00
self.filePaths_musicFile_Open = ttk.Button(master=self.filePaths_Frame, image=self.efile_img, command=lambda:OPEN_FILE_func(os.path.dirname(self.inputPaths[0])) if self.inputPaths and os.path.isdir(os.path.dirname(self.inputPaths[0])) else self.error_dialoge(INVALID_INPUT))
self.filePaths_musicFile_Open.place(x=OPEN_BUTTON_X, y=MUSICFILE_BUTTON_Y, width=OPEN_BUTTON_WIDTH, height=MUSICFILE_ENTRY_HEIGHT, relx=0.3, rely=0, relwidth=0.7, relheight=0.5)
2023-09-26 00:11:08 +02:00
# Add any additional configurations or method calls here
2022-12-19 04:18:56 +01:00
self.filePaths_musicFile_Entry.configure(cursor="hand2")
self.help_hints(self.filePaths_musicFile_Button, text=INPUT_FOLDER_ENTRY_HELP)
2022-12-23 08:45:18 +01:00
self.help_hints(self.filePaths_musicFile_Entry, text=INPUT_FOLDER_ENTRY_HELP_2)
2022-12-19 04:18:56 +01:00
self.help_hints(self.filePaths_musicFile_Open, text=INPUT_FOLDER_BUTTON_HELP)
# Save To Option
2023-09-26 00:11:08 +02:00
self.filePaths_saveTo_Button = ttk.Button(master=self.filePaths_Frame, text=SELECT_OUTPUT_TEXT, command=self.export_select_filedialog)
self.filePaths_saveTo_Button.place(x=SAVETO_BUTTON_X, y=SAVETO_BUTTON_Y, width=SAVETO_BUTTON_WIDTH, height=SAVETO_BUTTON_HEIGHT, relx=0, rely=0.5, relwidth=0.3, relheight=0.5)
self.filePaths_saveTo_Entry = ttk.Entry(master=self.filePaths_Frame, textvariable=self.export_path_var, font=self.font_entry, state=tk.DISABLED)
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)
2023-09-26 23:46:28 +02:00
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)
2022-12-19 04:18:56 +01:00
self.help_hints(self.filePaths_saveTo_Button, text=OUTPUT_FOLDER_ENTRY_HELP)
2023-09-26 00:11:08 +02:00
self.help_hints(self.filePaths_saveTo_Open, text=OUTPUT_FOLDER_BUTTON_HELP)
2022-12-19 04:18:56 +01:00
def fill_options_Frame(self):
"""Fill Frame with neccessary widgets"""
self.options_Frame = ttk.Frame(master=self)
2023-09-26 00:11:08 +02:00
self.options_Frame.place(x=OPTIONS_FRAME_X, y=OPTIONS_FRAME_Y, width=OPTIONS_FRAME_WIDTH, height=self.OPTIONS_HEIGHT, relx=0, rely=0, relwidth=1, relheight=0)
2022-12-19 04:18:56 +01:00
# -Create Widgets-
## Save Format
self.wav_button = ttk.Radiobutton(master=self.options_Frame, text=WAV, variable=self.save_format_var, value=WAV)
2023-09-26 00:11:08 +02:00
self.wav_button.place(x=RADIOBUTTON_X_WAV, y=RADIOBUTTON_Y, width=RADIOBUTTON_WIDTH, height=RADIOBUTTON_HEIGHT, relx=0, rely=0/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2022-12-19 04:18:56 +01:00
self.help_hints(self.wav_button, text=f'{FORMAT_SETTING_HELP}{WAV}')
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
self.flac_button = ttk.Radiobutton(master=self.options_Frame, text=FLAC, variable=self.save_format_var, value=FLAC)
2023-09-26 00:11:08 +02:00
self.flac_button.place(x=RADIOBUTTON_X_FLAC, y=RADIOBUTTON_Y, width=RADIOBUTTON_WIDTH, height=RADIOBUTTON_HEIGHT, relx=1/3, rely=0/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2022-12-19 04:18:56 +01:00
self.help_hints(self.flac_button, text=f'{FORMAT_SETTING_HELP}{FLAC}')
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
self.mp3_button = ttk.Radiobutton(master=self.options_Frame, text=MP3, variable=self.save_format_var, value=MP3)
2023-09-26 00:11:08 +02:00
self.mp3_button.place(x=RADIOBUTTON_X_MP3, y=RADIOBUTTON_Y, width=RADIOBUTTON_WIDTH, height=RADIOBUTTON_HEIGHT, relx=2/3, rely=0/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2022-12-19 04:18:56 +01:00
self.help_hints(self.mp3_button, text=f'{FORMAT_SETTING_HELP}{MP3}')
# Choose Conversion Method
2022-12-27 11:31:41 +01:00
self.chosen_process_method_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_PROC_METHOD_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.chosen_process_method_Label.place(x=0, y=MAIN_ROW_Y[0], width=LEFT_ROW_WIDTH, height=LABEL_HEIGHT, relx=0, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.chosen_process_method_Option = ComboBoxMenu(self.options_Frame, textvariable=self.chosen_process_method_var, values=PROCESS_METHODS, command=lambda e: self.selection_action_process_method(self.chosen_process_method_var.get(), from_widget=True, is_from_conv_menu=True))
2022-12-19 04:18:56 +01:00
self.chosen_process_method_Option.place(x=0, y=MAIN_ROW_Y[1], width=LEFT_ROW_WIDTH, height=OPTION_HEIGHT, relx=0, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
#self.chosen_process_method_var.trace_add('write', lambda *args: self.update_main_widget_states())
2022-12-19 04:18:56 +01:00
self.help_hints(self.chosen_process_method_Label, text=CHOSEN_PROCESS_METHOD_HELP)
# Choose Settings Option
2022-12-27 11:31:41 +01:00
self.save_current_settings_Label = self.main_window_LABEL_SET(self.options_Frame, SELECT_SAVED_SETTINGS_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.save_current_settings_Label_place = lambda:self.save_current_settings_Label.place(x=MAIN_ROW_2_X[0], y=LOW_MENU_Y[0], width=0, height=LABEL_HEIGHT, relx=2/3, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.save_current_settings_Option = ComboBoxMenu(self.options_Frame, textvariable=self.save_current_settings_var, command=lambda e:self.selection_action_saved_settings(self.save_current_settings_var.get()))
2022-12-19 04:18:56 +01:00
self.save_current_settings_Option_place = lambda:self.save_current_settings_Option.place(x=MAIN_ROW_2_X[1], y=LOW_MENU_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.save_current_settings_Label, text=SAVE_CURRENT_SETTINGS_HELP)
### MDX-NET ###
# Choose MDX-Net Model
2022-12-27 11:31:41 +01:00
self.mdx_net_model_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_MDX_MODEL_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.mdx_net_model_Label_place = lambda:self.mdx_net_model_Label.place(x=0, y=LOW_MENU_Y[0], width=LEFT_ROW_WIDTH, height=LABEL_HEIGHT, relx=0, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.mdx_net_model_Option = ComboBoxMenu(self.options_Frame, textvariable=self.mdx_net_model_var, command=lambda event: self.selection_action(event, self.mdx_net_model_var, is_mdx_net=True))
2022-12-19 04:18:56 +01:00
self.mdx_net_model_Option_place = lambda:self.mdx_net_model_Option.place(x=0, y=LOW_MENU_Y[1], width=LEFT_ROW_WIDTH, height=OPTION_HEIGHT, relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
#self.mdx_net_model_var.trace_add('write', lambda *args: self.update_main_widget_states_mdx())
2022-12-19 04:18:56 +01:00
self.help_hints(self.mdx_net_model_Label, text=CHOOSE_MODEL_HELP)
2023-09-26 00:11:08 +02:00
# MDX-Overlap
2023-09-26 07:44:03 +02:00
self.overlap_mdx_Label = self.main_window_LABEL_SET(self.options_Frame, 'OVERLAP')
2023-09-26 00:11:08 +02:00
self.overlap_mdx_Label_place = lambda:self.overlap_mdx_Label.place(x=MAIN_ROW_2_X[0], y=MAIN_ROW_2_Y[0], width=0, height=LABEL_HEIGHT, relx=2/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.overlap_mdx_Option = ComboBoxEditableMenu(self.options_Frame, values=MDX_OVERLAP, width=MENU_COMBOBOX_WIDTH, textvariable=self.overlap_mdx_var, pattern=REG_OVERLAP, default=MDX_OVERLAP)
self.overlap_mdx_Option_place = lambda:self.overlap_mdx_Option.place(x=MAIN_ROW_2_X[1], y=MAIN_ROW_2_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
# MDX23-Overlap
self.overlap_mdx23_Option = ComboBoxEditableMenu(self.options_Frame, values=MDX23_OVERLAP, width=MENU_COMBOBOX_WIDTH, textvariable=self.overlap_mdx23_var, pattern=REG_OVERLAP23, default="8")
self.overlap_mdx23_Option_place = lambda:self.overlap_mdx23_Option.place(x=MAIN_ROW_2_X[1], y=MAIN_ROW_2_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.overlap_mdx_Label, text=MDX_OVERLAP_HELP)
# Choose MDX-Net Stems
self.mdxnet_stems_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_STEMS_MAIN_LABEL)
self.mdxnet_stems_Label_place = lambda:self.mdxnet_stems_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.mdxnet_stems_Option = ComboBoxMenu(self.options_Frame, textvariable=self.mdxnet_stems_var)
self.mdxnet_stems_Option_place = lambda:self.mdxnet_stems_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.mdxnet_stems_Label, text=DEMUCS_STEMS_HELP)
# MDX-Segment Size
self.mdx_segment_size_Label = self.main_window_LABEL_SET(self.options_Frame, SEGMENT_MDX_MAIN_LABEL)
self.mdx_segment_size_Label_place = lambda:self.mdx_segment_size_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.mdx_segment_size_Option = ComboBoxEditableMenu(self.options_Frame, values=MDX_SEGMENTS, width=MENU_COMBOBOX_WIDTH, textvariable=self.mdx_segment_size_var, pattern=REG_MDX_SEG, default="256")#
self.mdx_segment_size_Option_place = lambda:self.mdx_segment_size_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.mdx_segment_size_Label, text=MDX_SEGMENT_SIZE_HELP)
2022-12-19 04:18:56 +01:00
### VR ARCH ###
# Choose VR Model
2022-12-27 11:31:41 +01:00
self.vr_model_Label = self.main_window_LABEL_SET(self.options_Frame, SELECT_VR_MODEL_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.vr_model_Label_place = lambda:self.vr_model_Label.place(x=0, y=LOW_MENU_Y[0], width=LEFT_ROW_WIDTH, height=LABEL_HEIGHT, relx=0, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.vr_model_Option = ComboBoxMenu(self.options_Frame, textvariable=self.vr_model_var, command=lambda event: self.selection_action(event, self.vr_model_var))
2022-12-19 04:18:56 +01:00
self.vr_model_Option_place = lambda:self.vr_model_Option.place(x=0, y=LOW_MENU_Y[1], width=LEFT_ROW_WIDTH, height=OPTION_HEIGHT, relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.vr_model_Label, text=CHOOSE_MODEL_HELP)
# Aggression Setting
2022-12-27 11:31:41 +01:00
self.aggression_setting_Label = self.main_window_LABEL_SET(self.options_Frame, AGGRESSION_SETTING_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.aggression_setting_Label_place = lambda:self.aggression_setting_Label.place(x=MAIN_ROW_2_X[0], y=MAIN_ROW_2_Y[0], width=0, height=LABEL_HEIGHT, relx=2/3, rely=2/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.aggression_setting_Option = ComboBoxEditableMenu(self.options_Frame, values=VR_AGGRESSION, textvariable=self.aggression_setting_var, pattern=REG_AGGRESSION, default=VR_AGGRESSION[5])#
2022-12-19 04:18:56 +01:00
self.aggression_setting_Option_place = lambda:self.aggression_setting_Option.place(x=MAIN_ROW_2_X[1], y=MAIN_ROW_2_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.aggression_setting_Label, text=AGGRESSION_SETTING_HELP)
# Window Size
2022-12-27 11:31:41 +01:00
self.window_size_Label = self.main_window_LABEL_SET(self.options_Frame, WINDOW_SIZE_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.window_size_Label_place = lambda:self.window_size_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.window_size_Option = ComboBoxEditableMenu(self.options_Frame, values=VR_WINDOW, textvariable=self.window_size_var, pattern=REG_WINDOW, default=VR_WINDOW[1])#
2022-12-19 04:18:56 +01:00
self.window_size_Option_place = lambda:self.window_size_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.window_size_Label, text=WINDOW_SIZE_HELP)
### DEMUCS ###
2023-09-26 00:11:08 +02:00
# Choose Demucs Models
2022-12-27 11:31:41 +01:00
self.demucs_model_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_DEMUCS_MODEL_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.demucs_model_Label_place = lambda:self.demucs_model_Label.place(x=0, y=LOW_MENU_Y[0], width=LEFT_ROW_WIDTH, height=LABEL_HEIGHT, relx=0, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.demucs_model_Option = ComboBoxMenu(self.options_Frame, textvariable=self.demucs_model_var, command=lambda event: self.selection_action(event, self.demucs_model_var))
2022-12-19 04:18:56 +01:00
self.demucs_model_Option_place = lambda:self.demucs_model_Option.place(x=0, y=LOW_MENU_Y[1], width=LEFT_ROW_WIDTH, height=OPTION_HEIGHT, relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.demucs_model_Label, text=CHOOSE_MODEL_HELP)
# Choose Demucs Stems
2023-09-26 00:11:08 +02:00
self.demucs_stems_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_STEMS_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.demucs_stems_Label_place = lambda:self.demucs_stems_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.demucs_stems_Option = ComboBoxMenu(self.options_Frame, textvariable=self.demucs_stems_var)
2022-12-19 04:18:56 +01:00
self.demucs_stems_Option_place = lambda:self.demucs_stems_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.demucs_stems_Label, text=DEMUCS_STEMS_HELP)
# Demucs-Segment
2022-12-27 11:31:41 +01:00
self.segment_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_SEGMENT_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.segment_Label_place = lambda:self.segment_Label.place(x=MAIN_ROW_2_X[0], y=MAIN_ROW_2_Y[0], width=0, height=LABEL_HEIGHT, relx=2/3, rely=2/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.segment_Option = ComboBoxEditableMenu(self.options_Frame, values=DEMUCS_SEGMENTS, textvariable=self.segment_var, pattern=REG_SEGMENTS, default=DEMUCS_SEGMENTS)#
2022-12-19 04:18:56 +01:00
self.segment_Option_place = lambda:self.segment_Option.place(x=MAIN_ROW_2_X[1], y=MAIN_ROW_2_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.segment_Label, text=SEGMENT_HELP)
# Stem A
self.is_primary_stem_only_Demucs_Option = ttk.Checkbutton(master=self.options_Frame, textvariable=self.is_primary_stem_only_Demucs_Text_var, variable=self.is_primary_stem_only_Demucs_var, command=lambda:self.is_primary_stem_only_Demucs_Option_toggle())
self.is_primary_stem_only_Demucs_Option_place = lambda:self.is_primary_stem_only_Demucs_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=6/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.is_primary_stem_only_Demucs_Option_toggle = lambda:self.is_secondary_stem_only_Demucs_var.set(False) if self.is_primary_stem_only_Demucs_var.get() else self.is_secondary_stem_only_Demucs_Option.configure(state=tk.NORMAL)
self.help_hints(self.is_primary_stem_only_Demucs_Option, text=SAVE_STEM_ONLY_HELP)
# Stem B
self.is_secondary_stem_only_Demucs_Option = ttk.Checkbutton(master=self.options_Frame, textvariable=self.is_secondary_stem_only_Demucs_Text_var, variable=self.is_secondary_stem_only_Demucs_var, command=lambda:self.is_secondary_stem_only_Demucs_Option_toggle())
self.is_secondary_stem_only_Demucs_Option_place = lambda:self.is_secondary_stem_only_Demucs_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=7/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.is_secondary_stem_only_Demucs_Option_toggle = lambda:self.is_primary_stem_only_Demucs_var.set(False) if self.is_secondary_stem_only_Demucs_var.get() else self.is_primary_stem_only_Demucs_Option.configure(state=tk.NORMAL)
self.is_stem_only_Demucs_Options_Enable = lambda:(self.is_primary_stem_only_Demucs_Option.configure(state=tk.NORMAL), self.is_secondary_stem_only_Demucs_Option.configure(state=tk.NORMAL))
self.help_hints(self.is_secondary_stem_only_Demucs_Option, text=SAVE_STEM_ONLY_HELP)
### ENSEMBLE MODE ###
# Ensemble Mode
2022-12-27 11:31:41 +01:00
self.chosen_ensemble_Label = self.main_window_LABEL_SET(self.options_Frame, ENSEMBLE_OPTIONS_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.chosen_ensemble_Label_place = lambda:self.chosen_ensemble_Label.place(x=0, y=LOW_MENU_Y[0], width=LEFT_ROW_WIDTH, height=LABEL_HEIGHT, relx=0, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.chosen_ensemble_Option = ComboBoxMenu(self.options_Frame, textvariable=self.chosen_ensemble_var, command=lambda e:self.selection_action_chosen_ensemble(self.chosen_ensemble_var.get()))
2022-12-19 04:18:56 +01:00
self.chosen_ensemble_Option_place = lambda:self.chosen_ensemble_Option.place(x=0, y=LOW_MENU_Y[1], width=LEFT_ROW_WIDTH, height=OPTION_HEIGHT, relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.chosen_ensemble_Label, text=CHOSEN_ENSEMBLE_HELP)
# Ensemble Main Stems
2022-12-27 11:31:41 +01:00
self.ensemble_main_stem_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_MAIN_PAIR_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.ensemble_main_stem_Label_place = lambda:self.ensemble_main_stem_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.ensemble_main_stem_Option = ComboBoxMenu(self.options_Frame, textvariable=self.ensemble_main_stem_var, values=ENSEMBLE_MAIN_STEM, command=lambda e: self.selection_action_ensemble_stems(self.ensemble_main_stem_var.get()))
2022-12-19 04:18:56 +01:00
self.ensemble_main_stem_Option_place = lambda:self.ensemble_main_stem_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.ensemble_main_stem_Label, text=ENSEMBLE_MAIN_STEM_HELP)
# Ensemble Algorithm
2022-12-27 11:31:41 +01:00
self.ensemble_type_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_ENSEMBLE_ALGORITHM_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.ensemble_type_Label_place = lambda:self.ensemble_type_Label.place(x=MAIN_ROW_2_X[0], y=MAIN_ROW_2_Y[0], width=0, height=LABEL_HEIGHT, relx=2/3, rely=2/11, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.ensemble_type_Option = ComboBoxMenu(self.options_Frame, textvariable=self.ensemble_type_var, values=ENSEMBLE_TYPE)
2022-12-19 04:18:56 +01:00
self.ensemble_type_Option_place = lambda:self.ensemble_type_Option.place(x=MAIN_ROW_2_X[1], y=MAIN_ROW_2_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT,relx=2/3, rely=3/11, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.ensemble_type_Label, text=ENSEMBLE_TYPE_HELP)
2023-09-26 00:11:08 +02:00
# Select Music Files Option
2022-12-19 04:18:56 +01:00
# Ensemble Save Ensemble Outputs
2022-12-27 11:31:41 +01:00
self.ensemble_listbox_Label = self.main_window_LABEL_SET(self.options_Frame, AVAILABLE_MODELS_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
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)
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
self.ensemble_listbox_Option.config(yscrollcommand=self.ensemble_listbox_scroll.set)
self.ensemble_listbox_scroll.configure(command=self.ensemble_listbox_Option.yview)
2023-09-26 00:11:08 +02:00
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_Option_pack = lambda:self.ensemble_listbox_Option.pack(fill=tk.BOTH, expand=1)
2022-12-19 04:18:56 +01:00
self.help_hints(self.ensemble_listbox_Label, text=ENSEMBLE_LISTBOX_HELP)
### AUDIO TOOLS ###
2023-09-26 00:11:08 +02:00
# Chosen Audio Tool
2022-12-27 11:31:41 +01:00
self.chosen_audio_tool_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_AUDIO_TOOLS_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.chosen_audio_tool_Label_place = lambda:self.chosen_audio_tool_Label.place(x=0, y=LOW_MENU_Y[0], width=LEFT_ROW_WIDTH, height=LABEL_HEIGHT, relx=0, rely=6/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
2023-09-26 00:11:08 +02:00
self.chosen_audio_tool_Option = ComboBoxMenu(self.options_Frame, textvariable=self.chosen_audio_tool_var, values=AUDIO_TOOL_OPTIONS, command=lambda e: self.update_main_widget_states())
2022-12-19 04:18:56 +01:00
self.chosen_audio_tool_Option_place = lambda:self.chosen_audio_tool_Option.place(x=0, y=LOW_MENU_Y[1], width=LEFT_ROW_WIDTH, height=OPTION_HEIGHT, relx=0, rely=7/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS)
self.help_hints(self.chosen_audio_tool_Label, text=AUDIO_TOOLS_HELP)
# Choose Agorithim
2022-12-27 11:31:41 +01:00
self.choose_algorithm_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_MANUAL_ALGORITHM_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.choose_algorithm_Label_place = lambda:self.choose_algorithm_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.choose_algorithm_Option = ComboBoxMenu(self.options_Frame, textvariable=self.choose_algorithm_var, values=MANUAL_ENSEMBLE_OPTIONS)
2022-12-19 04:18:56 +01:00
self.choose_algorithm_Option_place = lambda:self.choose_algorithm_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
#self.help_hints(self.mdx_segment_size_Label, text=MDX_SEGMENT_SIZE_HELP)
2022-12-19 04:18:56 +01:00
# Time Stretch
2022-12-27 11:31:41 +01:00
self.time_stretch_rate_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_RATE_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.time_stretch_rate_Label_place = lambda:self.time_stretch_rate_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.time_stretch_rate_Option = ComboBoxEditableMenu(self.options_Frame, values=TIME_PITCH, textvariable=self.time_stretch_rate_var, pattern=REG_TIME, default=TIME_PITCH)#
2022-12-19 04:18:56 +01:00
self.time_stretch_rate_Option_place = lambda:self.time_stretch_rate_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
#self.help_hints(self.mdx_segment_size_Label, text=MDX_SEGMENT_SIZE_HELP)
2022-12-19 04:18:56 +01:00
# Pitch Rate
2022-12-27 11:31:41 +01:00
self.pitch_rate_Label = self.main_window_LABEL_SET(self.options_Frame, CHOOSE_SEMITONES_MAIN_LABEL)
2022-12-19 04:18:56 +01:00
self.pitch_rate_Label_place = lambda:self.pitch_rate_Label.place(x=MAIN_ROW_X[0], y=MAIN_ROW_Y[0], width=0, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
self.pitch_rate_Option = ComboBoxEditableMenu(self.options_Frame, values=TIME_PITCH, textvariable=self.pitch_rate_var, pattern=REG_PITCH, default=TIME_PITCH)#
2022-12-19 04:18:56 +01:00
self.pitch_rate_Option_place = lambda:self.pitch_rate_Option.place(x=MAIN_ROW_X[1], y=MAIN_ROW_Y[1], width=MAIN_ROW_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2023-09-26 00:11:08 +02:00
# Is Time Correction
self.is_time_correction_Option = ttk.Checkbutton(master=self.options_Frame, text=TIME_CORRECTION_TEXT, variable=self.is_time_correction_var)
self.is_time_correction_Option_place = lambda:self.is_time_correction_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=5/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.is_time_correction_Option, text=IS_TIME_CORRECTION_HELP)
# Is Wav Ensemble
self.is_wav_ensemble_Option = ttk.Checkbutton(master=self.options_Frame, text=ENSEMBLE_WAVFORMS_TEXT, variable=self.is_wav_ensemble_var)
self.is_wav_ensemble_Option_place = lambda:self.is_wav_ensemble_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=5/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.is_wav_ensemble_Option, text=IS_WAV_ENSEMBLE_HELP)
## ALIGN TOOL ##
# Track 1
self.fileOne_Label = self.main_window_LABEL_SUB_SET(self.options_Frame, self.file_one_sub_var)
self.fileOne_Label_place = lambda: self.fileOne_Label.place(x=FILEONE_LABEL_X, y=LABEL_Y, width=FILEONE_LABEL_WIDTH, height=LABEL_HEIGHT, relx=1/3, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.fileOne_Entry = ttk.Entry(master=self.options_Frame, textvariable=self.fileOneEntry_var, font=self.font_entry, state=tk.DISABLED)
self.fileOne_Entry_place = lambda: self.fileOne_Entry.place(x=SUB_ENT_ROW_X, y=ENTRY_Y, width=ENTRY_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.fileOne_Entry, text=INPUT_SEC_FIELDS_HELP)
self.fileOne_Entry.configure(cursor="hand2")
self.fileOne_Open = ttk.Button(master=self.options_Frame, image=self.efile_img, command=lambda:OPEN_FILE_func(os.path.dirname(self.fileOneEntry_Full_var.get())))
self.fileOne_Open_place = lambda:self.fileOne_Open.place(x=ENTRY_OPEN_BUTT_X_OFF, y=ENTRY_Y, width=ENTRY_OPEN_BUTT_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)#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.help_hints(self.fileOne_Open, text=INPUT_FOLDER_BUTTON_HELP)
# Track 2
self.fileTwo_Label = self.main_window_LABEL_SUB_SET(self.options_Frame, self.file_two_sub_var)
self.fileTwo_Label_place = lambda: self.fileTwo_Label.place(x=FILETWO_LABEL_X, y=LABEL_Y, width=FILETWO_LABEL_WIDTH, height=LABEL_HEIGHT, relx=1/3, rely=4.5/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.fileTwo_Entry = ttk.Entry(master=self.options_Frame, textvariable=self.fileTwoEntry_var, font=self.font_entry, state=tk.DISABLED)
self.fileTwo_Entry_place = lambda:self.fileTwo_Entry.place(x=SUB_ENT_ROW_X, y=ENTRY_Y, width=ENTRY_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=5.5/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.fileTwo_Entry, text=INPUT_SEC_FIELDS_HELP)
self.fileTwo_Entry.configure(cursor="hand2")
self.fileTwo_Open = ttk.Button(master=self.options_Frame, image=self.efile_img, command=lambda:OPEN_FILE_func(os.path.dirname(self.fileTwoEntry_Full_var.get())))
self.fileTwo_Open_place = lambda:self.fileTwo_Open.place(x=ENTRY_OPEN_BUTT_X_OFF, y=ENTRY_Y, width=ENTRY_OPEN_BUTT_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=5.5/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.fileTwo_Open, text=INPUT_FOLDER_BUTTON_HELP)
# Time Window
self.time_window_Label = self.main_window_LABEL_SET(self.options_Frame, TIME_WINDOW_MAIN_LABEL)
self.time_window_Label_place = lambda: self.time_window_Label.place(x=TIME_WINDOW_LABEL_X, y=LABEL_Y, width=TIME_WINDOW_LABEL_WIDTH, height=LABEL_HEIGHT, relx=1/3, rely=7.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.time_window_Option = ComboBoxMenu(self.options_Frame, textvariable=self.time_window_var, values=tuple(TIME_WINDOW_MAPPER.keys()))
self.time_window_Option_place = lambda: self.time_window_Option.place(x=SUB_ENT_ROW_X, y=ENTRY_Y, width=OPTION_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=8.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.time_window_Label, text=TIME_WINDOW_ALIGN_HELP)
# Align Shifts
self.intro_analysis_Label = self.main_window_LABEL_SET(self.options_Frame, INTRO_ANALYSIS_MAIN_LABEL)
self.intro_analysis_Label_place = lambda: self.intro_analysis_Label.place(x=INTRO_ANALYSIS_LABEL_X, y=LABEL_Y, width=INTRO_ANALYSIS_LABEL_WIDTH, height=LABEL_HEIGHT, relx=2/3, rely=7.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.intro_analysis_Option = ComboBoxMenu(self.options_Frame, textvariable=self.intro_analysis_var, values=tuple(INTRO_MAPPER.keys()))
self.intro_analysis_Option_place = lambda: self.intro_analysis_Option.place(x=INTRO_ANALYSIS_OPTION_X, y=ENTRY_Y, width=OPTION_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=8.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.intro_analysis_Label, text=INTRO_ANALYSIS_ALIGN_HELP)
# Volume Adjustment
self.db_analysis_Label = self.main_window_LABEL_SET(self.options_Frame, VOLUME_ADJUSTMENT_MAIN_LABEL)
self.db_analysis_Label_place = lambda: self.db_analysis_Label.place(x=DB_ANALYSIS_LABEL_X, y=LABEL_Y, width=DB_ANALYSIS_LABEL_WIDTH, height=LABEL_HEIGHT, relx=2/3, rely=7.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.db_analysis_Option = ComboBoxMenu(self.options_Frame, textvariable=self.db_analysis_var, values=tuple(VOLUME_MAPPER.keys()))
self.db_analysis_Option_place = lambda: self.db_analysis_Option.place(x=DB_ANALYSIS_OPTION_X, y=ENTRY_Y, width=OPTION_WIDTH, height=OPTION_HEIGHT, relx=2/3, rely=8.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.db_analysis_Label, text=VOLUME_ANALYSIS_ALIGN_HELP)
# Wav-Type
self.wav_type_set_Label = self.main_window_LABEL_SET(self.options_Frame, WAVE_TYPE_TEXT)
self.wav_type_set_Label_place = lambda: self.wav_type_set_Label.place(x=WAV_TYPE_SET_LABEL_X, y=LABEL_Y, width=WAV_TYPE_SET_LABEL_WIDTH, height=LABEL_HEIGHT, relx=1/3, rely=7.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.wav_type_set_Option = ComboBoxMenu(self.options_Frame, textvariable=self.wav_type_set_var, values=WAV_TYPE)
self.wav_type_set_Option_place = lambda: self.wav_type_set_Option.place(x=SUB_ENT_ROW_X, y=ENTRY_Y, width=OPTION_WIDTH, height=OPTION_HEIGHT, relx=1/3, rely=8.37/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
2022-12-19 04:18:56 +01:00
### SHARED SETTINGS ###
# GPU Selection
2022-12-27 11:31:41 +01:00
self.is_gpu_conversion_Option = ttk.Checkbutton(master=self.options_Frame, text=GPU_CONVERSION_MAIN_LABEL, variable=self.is_gpu_conversion_var)
2022-12-19 04:18:56 +01:00
self.is_gpu_conversion_Option_place = lambda:self.is_gpu_conversion_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=5/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.is_gpu_conversion_Disable = lambda:(self.is_gpu_conversion_Option.configure(state=tk.DISABLED), self.is_gpu_conversion_var.set(False))
2022-12-27 11:31:41 +01:00
self.is_gpu_conversion_Enable = lambda:self.is_gpu_conversion_Option.configure(state=tk.NORMAL)
2022-12-19 04:18:56 +01:00
self.help_hints(self.is_gpu_conversion_Option, text=IS_GPU_CONVERSION_HELP)
# Vocal Only
self.is_primary_stem_only_Option = ttk.Checkbutton(master=self.options_Frame, textvariable=self.is_primary_stem_only_Text_var, variable=self.is_primary_stem_only_var, command=lambda:self.is_primary_stem_only_Option_toggle())
self.is_primary_stem_only_Option_place = lambda:self.is_primary_stem_only_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=6/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.is_primary_stem_only_Option_toggle = lambda:self.is_secondary_stem_only_var.set(False) if self.is_primary_stem_only_var.get() else self.is_secondary_stem_only_Option.configure(state=tk.NORMAL)
self.help_hints(self.is_primary_stem_only_Option, text=SAVE_STEM_ONLY_HELP)
# Instrumental Only
self.is_secondary_stem_only_Option = ttk.Checkbutton(master=self.options_Frame, textvariable=self.is_secondary_stem_only_Text_var, variable=self.is_secondary_stem_only_var, command=lambda:self.is_secondary_stem_only_Option_toggle())
self.is_secondary_stem_only_Option_place = lambda:self.is_secondary_stem_only_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=7/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.is_secondary_stem_only_Option_toggle = lambda:self.is_primary_stem_only_var.set(False) if self.is_secondary_stem_only_var.get() else self.is_primary_stem_only_Option.configure(state=tk.NORMAL)
self.is_stem_only_Options_Enable = lambda:(self.is_primary_stem_only_Option.configure(state=tk.NORMAL), self.is_secondary_stem_only_Option.configure(state=tk.NORMAL))
self.help_hints(self.is_secondary_stem_only_Option, text=SAVE_STEM_ONLY_HELP)
# Sample Mode
self.model_sample_mode_Option = ttk.Checkbutton(master=self.options_Frame, textvariable=self.model_sample_mode_duration_checkbox_var, variable=self.model_sample_mode_var)#f'Sample ({self.model_sample_mode_duration_var.get()} Seconds)'
self.model_sample_mode_Option_place = lambda rely=8:self.model_sample_mode_Option.place(x=CHECK_BOX_X, y=CHECK_BOX_Y, width=CHECK_BOX_WIDTH, height=CHECK_BOX_HEIGHT, relx=1/3, rely=rely/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS)
self.help_hints(self.model_sample_mode_Option, text=MODEL_SAMPLE_MODE_HELP)
self.GUI_LIST = (self.vr_model_Label,
self.vr_model_Option,
self.aggression_setting_Label,
self.aggression_setting_Option,
self.window_size_Label,
self.window_size_Option,
self.demucs_model_Label,
self.demucs_model_Option,
self.demucs_stems_Label,
self.demucs_stems_Option,
self.segment_Label,
self.segment_Option,
self.mdx_net_model_Label,
self.mdx_net_model_Option,
2023-09-26 00:11:08 +02:00
self.overlap_mdx_Label,
self.overlap_mdx_Option,
self.overlap_mdx23_Option,
self.mdxnet_stems_Label,
self.mdxnet_stems_Option,
self.mdx_segment_size_Label,
self.mdx_segment_size_Option,
2022-12-19 04:18:56 +01:00
self.chosen_ensemble_Label,
self.chosen_ensemble_Option,
self.save_current_settings_Label,
self.save_current_settings_Option,
self.ensemble_main_stem_Label,
self.ensemble_main_stem_Option,
self.ensemble_type_Label,
self.ensemble_type_Option,
self.ensemble_listbox_Label,
self.ensemble_listbox_Frame,
self.ensemble_listbox_Option,
self.ensemble_listbox_scroll,
self.chosen_audio_tool_Label,
self.chosen_audio_tool_Option,
self.choose_algorithm_Label,
self.choose_algorithm_Option,
self.time_stretch_rate_Label,
self.time_stretch_rate_Option,
2023-09-26 00:11:08 +02:00
self.wav_type_set_Label,
self.wav_type_set_Option,
2022-12-19 04:18:56 +01:00
self.pitch_rate_Label,
self.pitch_rate_Option,
2023-09-26 00:11:08 +02:00
self.fileOne_Label,
self.fileOne_Entry,
self.fileOne_Open,
self.fileTwo_Label,
self.fileTwo_Entry,
self.fileTwo_Open,
self.intro_analysis_Label,
self.intro_analysis_Option,
self.time_window_Label,
self.time_window_Option,
self.db_analysis_Label,
self.db_analysis_Option,
2022-12-19 04:18:56 +01:00
self.is_gpu_conversion_Option,
self.is_primary_stem_only_Option,
self.is_secondary_stem_only_Option,
self.is_primary_stem_only_Demucs_Option,
self.is_secondary_stem_only_Demucs_Option,
2023-09-26 00:11:08 +02:00
self.model_sample_mode_Option,
self.is_time_correction_Option,
self.is_wav_ensemble_Option)
2022-12-19 04:18:56 +01:00
REFRESH_VARS = (self.mdx_net_model_var,
self.vr_model_var,
self.demucs_model_var,
2023-09-26 00:11:08 +02:00
# self.demucs_stems_var,
# self.mdxnet_stems_var,
2022-12-19 04:18:56 +01:00
self.is_chunk_demucs_var,
2023-03-31 12:15:39 +02:00
self.is_chunk_mdxnet_var,
2023-09-26 00:11:08 +02:00
# self.is_primary_stem_only_Demucs_var,
# self.is_secondary_stem_only_Demucs_var,
# self.is_primary_stem_only_var,
# self.is_secondary_stem_only_var,
2022-12-19 04:18:56 +01:00
self.model_download_demucs_var,
self.model_download_mdx_var,
self.model_download_vr_var,
self.select_download_var,
2023-09-26 00:11:08 +02:00
# self.is_primary_stem_only_Demucs_Text_var,
# self.is_secondary_stem_only_Demucs_Text_var,
2022-12-19 04:18:56 +01:00
self.chosen_process_method_var,
self.ensemble_main_stem_var)
# Change States
for var in REFRESH_VARS:
var.trace_add('write', lambda *args: self.update_button_states())
2023-09-26 00:11:08 +02:00
def combo_box_selection_clear(self, frame:tk.Frame):
for option in frame.winfo_children():
if type(option) is ttk.Combobox or type(option) is ComboBoxEditableMenu:
2023-03-31 12:15:39 +02:00
option.selection_clear()
2023-09-26 00:11:08 +02:00
def focus_out_widgets(self, all_widgets, frame):
for option in all_widgets:
if not type(option) is ComboBoxEditableMenu:
option.bind('<Button-1>', lambda e:(option.focus(), self.combo_box_selection_clear(frame)))
2022-12-19 04:18:56 +01:00
def bind_widgets(self):
"""Bind widgets to the drag & drop mechanic"""
2023-03-31 12:15:39 +02:00
self.chosen_audio_tool_align = tk.BooleanVar(value=True)
other_items = [self.options_Frame, self.filePaths_Frame, self.title_Label, self.progressbar, self.conversion_Button, self.settings_Button, self.stop_Button, self.command_Text]
all_widgets = self.options_Frame.winfo_children() + self.filePaths_Frame.winfo_children() + other_items
2023-09-26 00:11:08 +02:00
self.focus_out_widgets(all_widgets, self.options_Frame)
2022-12-29 00:48:28 +01:00
if is_dnd_compatible:
2022-12-27 11:31:41 +01:00
self.filePaths_saveTo_Button.drop_target_register(DND_FILES)
self.filePaths_saveTo_Entry.drop_target_register(DND_FILES)
self.drop_target_register(DND_FILES)
self.dnd_bind('<<Drop>>', lambda e: drop(e, accept_mode='files'))
self.filePaths_saveTo_Button.dnd_bind('<<Drop>>', lambda e: drop(e, accept_mode='folder'))
self.filePaths_saveTo_Entry.dnd_bind('<<Drop>>', lambda e: drop(e, accept_mode='folder'))
2023-09-26 00:11:08 +02:00
self.fileOne_Entry.drop_target_register(DND_FILES)
self.fileTwo_Entry.drop_target_register(DND_FILES)
self.fileOne_Entry.dnd_bind('<<Drop>>', lambda e: drop(e, accept_mode=FILE_1))
self.fileTwo_Entry.dnd_bind('<<Drop>>', lambda e: drop(e, accept_mode=FILE_2))
2022-12-27 11:31:41 +01:00
self.ensemble_listbox_Option.bind('<<ListboxSelect>>', lambda e: self.chosen_ensemble_var.set(CHOOSE_ENSEMBLE_OPTION))
2023-03-31 12:15:39 +02:00
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()))
2023-09-26 00:11:08 +02:00
self.filePaths_musicFile_Entry.bind('<Button-1>', lambda e:(self.check_is_menu_open(INPUTS_MENU), self.filePaths_musicFile_Entry.focus()))
2023-03-31 12:15:39 +02:00
2023-09-26 00:11:08 +02:00
self.fileOne_Entry.bind('<Button-1>', lambda e:self.menu_batch_dual())
self.fileTwo_Entry.bind('<Button-1>', lambda e:self.menu_batch_dual())
self.fileOne_Entry.bind(right_click_button, lambda e:self.input_dual_right_click_menu(e, is_primary=True))
self.fileTwo_Entry.bind(right_click_button, lambda e:self.input_dual_right_click_menu(e, is_primary=False))
2023-09-27 04:54:09 +02:00
if not is_macos:
2023-09-26 00:11:08 +02:00
self.bind("<Configure>", self.adjust_toplevel_positions)
2023-10-12 06:30:24 +02:00
def auto_save(self):
try:
self.save_values(app_close=False, is_auto_save=True)
except Exception as e:
print(e)
2022-12-19 04:18:56 +01:00
#--Input/Export Methods--
2023-09-27 04:54:09 +02:00
def linux_filebox_fix(self, is_on=True):
fg_color_set = '#575757' if is_on else "#F6F6F7"
style = ttk.Style(self)
style.configure('TButton', foreground='#F6F6F7')
style.configure('TCheckbutton', foreground='#F6F6F7')
style.configure('TCombobox', foreground='#F6F6F7')
style.configure('TEntry', foreground='#F6F6F7')
style.configure('TLabel', foreground='#F6F6F7')
style.configure('TMenubutton', foreground='#F6F6F7')
style.configure('TRadiobutton', foreground='#F6F6F7')
gui_data.sv_ttk.set_theme("dark", MAIN_FONT_NAME, 10, fg_color_set=fg_color_set)
def show_file_dialog(self, text='Select Audio files', dialoge_type=None):
parent_win = root
is_linux = not is_windows and not is_macos
if is_linux:
self.linux_filebox_fix()
top = tk.Toplevel(root)
top.withdraw()
top.protocol("WM_DELETE_WINDOW", lambda: None)
parent_win = top
if dialoge_type == MULTIPLE_FILE:
filenames = filedialog.askopenfilenames(parent=parent_win,
title=text)
elif dialoge_type == MAIN_MULTIPLE_FILE:
filenames = filedialog.askopenfilenames(parent=parent_win,
title=text,
initialfile='',
initialdir=self.lastDir)
elif dialoge_type == SINGLE_FILE:
filenames = filedialog.askopenfilename(parent=parent_win,
title=text)
elif dialoge_type == CHOOSE_EXPORT_FIR:
filenames = filedialog.askdirectory(
parent=parent_win,
title=f'Select Folder',)
if is_linux:
print("Is Linux")
self.linux_filebox_fix(False)
top.destroy()
return filenames
2022-12-19 04:18:56 +01:00
def input_select_filedialog(self):
"""Make user select music files"""
if self.lastDir is not None:
if not os.path.isdir(self.lastDir):
self.lastDir = None
2023-09-27 04:54:09 +02:00
paths = self.show_file_dialog(dialoge_type=MAIN_MULTIPLE_FILE)
2022-12-19 04:18:56 +01:00
if paths: # Path selected
self.inputPaths = paths
self.process_input_selections()
self.update_inputPaths()
def export_select_filedialog(self):
"""Make user select a folder to export the converted files in"""
export_path = None
2023-09-27 04:54:09 +02:00
path = self.show_file_dialog(dialoge_type=CHOOSE_EXPORT_FIR)
2022-12-19 04:18:56 +01:00
if path: # Path selected
self.export_path_var.set(path)
export_path = self.export_path_var.get()
return export_path
def update_inputPaths(self):
"""Update the music file entry"""
if self.inputPaths:
if len(self.inputPaths) == 1:
text = self.inputPaths[0]
else:
count = len(self.inputPaths) - 1
file_text = 'file' if len(self.inputPaths) == 2 else 'files'
text = f"{self.inputPaths[0]}, +{count} {file_text}"
else:
# Empty Selection
text = ''
self.inputPathsEntry_var.set(text)
2023-09-26 00:11:08 +02:00
def select_audiofile(self, path=None, is_primary=True):
"""Make user select music files"""
vars = {
True: (self.fileOneEntry_Full_var, self.fileOneEntry_var, self.fileTwoEntry_Full_var, self.fileTwoEntry_var),
False: (self.fileTwoEntry_Full_var, self.fileTwoEntry_var, self.fileOneEntry_Full_var, self.fileOneEntry_var)
}
file_path_var, file_basename_var, file_path_2_var, file_basename_2_var = vars[is_primary]
if not path:
2023-09-27 04:54:09 +02:00
path = self.show_file_dialog(text='Select Audio file', dialoge_type=SINGLE_FILE)
2023-09-26 00:11:08 +02:00
if path: # Path selected
file_path_var.set(path)
file_basename_var.set(os.path.basename(path))
if BATCH_MODE_DUAL in file_path_2_var.get():
file_path_2_var.set("")
file_basename_2_var.set("")
self.DualBatch_inputPaths = []
self.check_dual_paths()
2022-12-19 04:18:56 +01:00
#--Utility Methods--
def restart(self):
"""Restart the application after asking for confirmation"""
2023-09-26 00:11:08 +02:00
confirm = messagebox.askyesno(parent=root,
title=CONFIRM_RESTART_TEXT[0],
message=CONFIRM_RESTART_TEXT[1])
2022-12-19 04:18:56 +01:00
if confirm:
2023-09-26 00:11:08 +02:00
self.save_values(app_close=True, is_restart=True)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def delete_temps(self, is_start_up=False):
2022-12-19 04:18:56 +01:00
"""Deletes temp files"""
DIRECTORIES = (BASE_PATH, VR_MODELS_DIR, MDX_MODELS_DIR, DEMUCS_MODELS_DIR, DEMUCS_NEWER_REPO_DIR)
EXTENSIONS = (('.aes', '.txt', '.tmp'))
try:
2022-12-30 04:07:23 +01:00
if os.path.isfile(f"{current_patch}{application_extension}"):
os.remove(f"{current_patch}{application_extension}")
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
if not is_start_up:
if os.path.isfile(SPLASH_DOC):
os.remove(SPLASH_DOC)
2022-12-19 04:18:56 +01:00
for dir in DIRECTORIES:
for temp_file in os.listdir(dir):
if temp_file.endswith(EXTENSIONS):
if os.path.isfile(os.path.join(dir, temp_file)):
os.remove(os.path.join(dir, temp_file))
except Exception as e:
2023-09-26 00:11:08 +02:00
self.error_log_var.set(error_text(TEMP_FILE_DELETION_TEXT, e))
2022-12-19 04:18:56 +01:00
2023-03-31 12:15:39 +02:00
def get_files_from_dir(self, directory, ext, is_mdxnet=False):
2022-12-19 04:18:56 +01:00
"""Gets files from specified directory that ends with specified extention"""
2023-09-26 00:11:08 +02:00
return tuple(
x if is_mdxnet and x.endswith(CKPT) else os.path.splitext(x)[0]
for x in os.listdir(directory)
if x.endswith(ext)
)
2022-12-19 04:18:56 +01:00
def return_ensemble_stems(self, is_primary=False):
"""Grabs and returns the chosen ensemble stems."""
ensemble_stem = self.ensemble_main_stem_var.get().partition("/")
if is_primary:
return ensemble_stem[0]
else:
return ensemble_stem[0], ensemble_stem[2]
def message_box(self, message):
"""Template for confirmation box"""
2023-09-26 00:11:08 +02:00
confirm = messagebox.askyesno(title=message[0],
2022-12-19 04:18:56 +01:00
message=message[1],
parent=root)
return confirm
def error_dialoge(self, message):
"""Template for messagebox that informs user of error"""
2023-09-26 00:11:08 +02:00
messagebox.showerror(master=self,
2022-12-19 04:18:56 +01:00
title=message[0],
message=message[1],
parent=root)
2023-09-26 00:11:08 +02:00
def model_list(self, primary_stem: str, secondary_stem: str, is_4_stem_check=False, is_multi_stem=False, is_dry_check=False, is_no_demucs=False, is_check_vocal_split=False):
2022-12-19 04:18:56 +01:00
stem_check = self.assemble_model_data(arch_type=ENSEMBLE_STEM_CHECK, is_dry_check=is_dry_check)
2023-09-26 00:11:08 +02:00
def matches_stem(model: ModelData):
primary_match = model.primary_stem in {primary_stem, secondary_stem}
mdx_stem_match = primary_stem in model.mdx_model_stems and model.mdx_stem_count <= 2
return primary_match or mdx_stem_match if is_no_demucs else primary_match or primary_stem in model.mdx_model_stems
result = []
for model in stem_check:
if is_multi_stem:
result.append(model.model_and_process_tag)
elif is_4_stem_check and (model.demucs_stem_count == 4 or model.mdx_stem_count == 4):
result.append(model.model_and_process_tag)
elif matches_stem(model) or (not is_no_demucs and primary_stem.lower() in model.demucs_source_list):
if is_check_vocal_split:
model_name = None if model.is_karaoke or not model.vocal_split_model else model.model_basename
else:
model_name = model.model_and_process_tag
result.append(model_name)
return result
2022-12-19 04:18:56 +01:00
def help_hints(self, widget, text):
toolTip = ToolTip(widget)
def enter(event):
if self.help_hints_var.get():
toolTip.showtip(text)
def leave(event):
toolTip.hidetip()
widget.bind('<Enter>', enter)
widget.bind('<Leave>', leave)
2022-12-21 11:18:16 +01:00
widget.bind(right_click_button, lambda e:copy_help_hint(e))
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def copy_help_hint(event):
if self.help_hints_var.get():
2023-09-26 00:11:08 +02:00
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
2022-12-19 04:18:56 +01:00
right_click_menu.add_command(label='Copy Help Hint Text', command=right_click_menu_copy_hint)
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
else:
2023-09-26 00:11:08 +02:00
if widget.winfo_toplevel() == root:
self.right_click_menu_popup(event, main_menu=True)
2022-12-19 04:18:56 +01:00
def right_click_menu_copy_hint():
pyperclip.copy(text)
2023-09-26 00:11:08 +02:00
def check_is_menu_open(self, menu):
try:
menu_mapping = {
VR_OPTION: (self.is_open_menu_advanced_vr_options, self.menu_advanced_vr_options, self.menu_advanced_vr_options_close_window),
DEMUCS_OPTION: (self.is_open_menu_advanced_demucs_options, self.menu_advanced_demucs_options, self.menu_advanced_demucs_options_close_window),
MDX_OPTION: (self.is_open_menu_advanced_mdx_options, self.menu_advanced_mdx_options, self.menu_advanced_mdx_options_close_window),
ENSEMBLE_OPTION: (self.is_open_menu_advanced_ensemble_options, self.menu_advanced_ensemble_options, self.menu_advanced_ensemble_options_close_window),
HELP_OPTION: (self.is_open_menu_help, self.menu_help, self.menu_help_close_window),
ERROR_OPTION: (self.is_open_menu_error_log, self.menu_error_log, self.menu_error_log_close_window),
INPUTS_MENU: (self.is_open_menu_view_inputs, self.menu_view_inputs, self.menu_view_inputs_close_window),
ALIGNMENT_TOOL: (self.is_open_menu_advanced_align_options, self.menu_advanced_align_options, self.menu_advanced_align_options_close_window)
}
is_open, open_method, close_method = menu_mapping.get(menu, (None, None, None))
if is_open and is_open.get():
close_method()
open_method()
except Exception as e:
self.error_log_var.set("{}".format(error_text(menu, e)))
2022-12-19 04:18:56 +01:00
def input_right_click_menu(self, event):
2023-09-26 00:11:08 +02:00
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
right_click_menu.add_command(label='See All Inputs', command=lambda:self.check_is_menu_open(INPUTS_MENU))
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 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)
right_click_menu.add_command(label=CHOOSE_INPUT_TEXT, command=lambda:self.select_audiofile(is_primary=is_primary))
if input_path and os.path.isdir(os.path.dirname(input_path)):
right_click_menu.add_command(label=OPEN_INPUT_DIR_TEXT, command=lambda:OPEN_FILE_func(os.path.dirname(input_path)))
right_click_menu.add_command(label=BATCH_PROCESS_MENU_TEXT, command=self.menu_batch_dual)
2022-12-19 04:18:56 +01:00
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
def cached_sources_clear(self):
self.vr_cache_source_mapper = {}
self.mdx_cache_source_mapper = {}
self.demucs_cache_source_mapper = {}
2023-09-27 04:54:09 +02:00
2022-12-19 04:18:56 +01:00
def cached_source_callback(self, process_method, model_name=None):
model, sources = None, None
if process_method == VR_ARCH_TYPE:
mapper = self.vr_cache_source_mapper
if process_method == MDX_ARCH_TYPE:
mapper = self.mdx_cache_source_mapper
if process_method == DEMUCS_ARCH_TYPE:
mapper = self.demucs_cache_source_mapper
for key, value in mapper.items():
if model_name in key:
model = key
sources = value
return model, sources
2023-09-27 04:54:09 +02:00
def cached_model_source_holder(self, process_method, sources, model_name=None):
if process_method == VR_ARCH_TYPE:
self.vr_cache_source_mapper = {**self.vr_cache_source_mapper, **{model_name: sources}}
if process_method == MDX_ARCH_TYPE:
self.mdx_cache_source_mapper = {**self.mdx_cache_source_mapper, **{model_name: sources}}
if process_method == DEMUCS_ARCH_TYPE:
self.demucs_cache_source_mapper = {**self.demucs_cache_source_mapper, **{model_name: sources}}
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def cached_source_model_list_check(self, model_list: List[ModelData]):
2022-12-19 04:18:56 +01:00
model: ModelData
primary_model_names = lambda process_method:[model.model_basename if model.process_method == process_method else None for model in model_list]
secondary_model_names = lambda process_method:[model.secondary_model.model_basename if model.is_secondary_model_activated and model.process_method == process_method else None for model in model_list]
self.vr_primary_model_names = primary_model_names(VR_ARCH_TYPE)
self.mdx_primary_model_names = primary_model_names(MDX_ARCH_TYPE)
self.demucs_primary_model_names = primary_model_names(DEMUCS_ARCH_TYPE)
self.vr_secondary_model_names = secondary_model_names(VR_ARCH_TYPE)
self.mdx_secondary_model_names = secondary_model_names(MDX_ARCH_TYPE)
self.demucs_secondary_model_names = [model.secondary_model.model_basename if model.is_secondary_model_activated and model.process_method == DEMUCS_ARCH_TYPE and not model.secondary_model is None else None for model in model_list]
self.demucs_pre_proc_model_name = [model.pre_proc_model.model_basename if model.pre_proc_model else None for model in model_list]#list(dict.fromkeys())
for model in model_list:
if model.process_method == DEMUCS_ARCH_TYPE and model.is_demucs_4_stem_secondaries:
if not model.is_4_stem_ensemble:
self.demucs_secondary_model_names = model.secondary_model_4_stem_model_names_list
break
else:
for i in model.secondary_model_4_stem_model_names_list:
self.demucs_secondary_model_names.append(i)
self.all_models = self.vr_primary_model_names + self.mdx_primary_model_names + self.demucs_primary_model_names + self.vr_secondary_model_names + self.mdx_secondary_model_names + self.demucs_secondary_model_names + self.demucs_pre_proc_model_name
def verify_audio(self, audio_file, is_process=True, sample_path=None):
is_good = False
error_data = ''
2023-09-26 00:11:08 +02:00
if not type(audio_file) is tuple:
audio_file = [audio_file]
for i in audio_file:
if os.path.isfile(i):
try:
librosa.load(i, duration=3, mono=False, sr=44100) if not type(sample_path) is str else self.create_sample(i, sample_path)
is_good = True
except Exception as e:
error_name = f'{type(e).__name__}'
traceback_text = ''.join(traceback.format_tb(e.__traceback__))
message = f'{error_name}: "{e}"\n{traceback_text}"'
if is_process:
audio_base_name = os.path.basename(i)
self.error_log_var.set(f'{ERROR_LOADING_FILE_TEXT[0]}:\n\n\"{audio_base_name}\"\n\n{ERROR_LOADING_FILE_TEXT[1]}:\n\n{message}')
else:
error_data = AUDIO_VERIFICATION_CHECK(i, message)
2022-12-19 04:18:56 +01:00
if is_process:
return is_good
else:
return is_good, error_data
def create_sample(self, audio_file, sample_path=SAMPLE_CLIP_PATH):
try:
with audioread.audio_open(audio_file) as f:
track_length = int(f.duration)
except Exception as e:
print('Audioread failed to get duration. Trying Librosa...')
y, sr = librosa.load(audio_file, mono=False, sr=44100)
track_length = int(librosa.get_duration(y=y, sr=sr))
clip_duration = int(self.model_sample_mode_duration_var.get())
if track_length >= clip_duration:
offset_cut = track_length//3
off_cut = offset_cut + track_length
if not off_cut >= clip_duration:
offset_cut = 0
name_apped = f'{clip_duration}_second_'
else:
offset_cut, clip_duration = 0, track_length
name_apped = ''
sample = librosa.load(audio_file, offset=offset_cut, duration=clip_duration, mono=False, sr=44100)[0].T
audio_sample = os.path.join(sample_path, f'{os.path.splitext(os.path.basename(audio_file))[0]}_{name_apped}sample.wav')
sf.write(audio_sample, sample, 44100)
return audio_sample
#--Right Click Menu Pop-Ups--
def right_click_select_settings_sub(self, parent_menu, process_method):
2023-09-26 00:11:08 +02:00
saved_settings_sub_menu = tk.Menu(parent_menu, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=False)
settings_options = self.last_found_settings + tuple(SAVE_SET_OPTIONS)
2022-12-19 04:18:56 +01:00
for settings_options in settings_options:
settings_options = settings_options.replace("_", " ")
saved_settings_sub_menu.add_command(label=settings_options, command=lambda o=settings_options:self.selection_action_saved_settings(o, process_method=process_method))
saved_settings_sub_menu.insert_separator(len(self.last_found_settings))
return saved_settings_sub_menu
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def right_click_menu_popup(self, event, text_box=False, main_menu=False):
2023-09-26 00:11:08 +02:00
def add_text_edit_options(menu):
"""Add options related to text editing."""
menu.add_command(label='Copy', command=self.right_click_menu_copy)
menu.add_command(label='Paste', command=lambda: self.right_click_menu_paste(text_box=text_box))
menu.add_command(label='Delete', command=lambda: self.right_click_menu_delete(text_box=text_box))
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def add_advanced_settings_options(menu, settings_mapper, var_mapper):
"""Add advanced settings options to the menu."""
current_method = self.chosen_process_method_var.get()
if current_method in settings_mapper and (var_mapper[current_method] or (current_method == DEMUCS_ARCH_TYPE and self.is_demucs_pre_proc_model_activate_var.get())):
menu.add_cascade(label='Select Saved Settings', menu=saved_settings_sub_load_for_menu)
menu.add_separator()
for method, option in settings_mapper.items():
if method != ENSEMBLE_MODE or current_method == ENSEMBLE_MODE:
menu.add_command(label=f'Advanced {method} Settings', command=option)
elif current_method in settings_mapper:
menu.add_command(label=f'Advanced {current_method} Settings', command=settings_mapper[current_method])
# Create the right-click menu
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
# Mappings
settings_mapper = {
ENSEMBLE_MODE: lambda: self.check_is_menu_open(ENSEMBLE_OPTION),
VR_ARCH_PM: lambda: self.check_is_menu_open(VR_OPTION),
MDX_ARCH_TYPE: lambda: self.check_is_menu_open(MDX_OPTION),
DEMUCS_ARCH_TYPE: lambda: self.check_is_menu_open(DEMUCS_OPTION)
}
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
var_mapper = {
ENSEMBLE_MODE: True,
VR_ARCH_PM: self.vr_is_secondary_model_activate_var.get(),
MDX_ARCH_TYPE: self.mdx_is_secondary_model_activate_var.get(),
DEMUCS_ARCH_TYPE: self.demucs_is_secondary_model_activate_var.get()
}
# Submenu for saved settings
saved_settings_sub_load_for_menu = tk.Menu(right_click_menu, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=False)
for label, arch_type in [(VR_ARCH_SETTING_LOAD, VR_ARCH_PM), (MDX_SETTING_LOAD, MDX_ARCH_TYPE), (DEMUCS_SETTING_LOAD, DEMUCS_ARCH_TYPE), (ALL_ARCH_SETTING_LOAD, None)]:
submenu = self.right_click_select_settings_sub(saved_settings_sub_load_for_menu, arch_type)
saved_settings_sub_load_for_menu.add_cascade(label=label, menu=submenu)
2022-12-19 04:18:56 +01:00
if not main_menu:
2023-09-26 00:11:08 +02:00
add_text_edit_options(right_click_menu)
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
if self.chosen_process_method_var.get() == AUDIO_TOOLS and self.chosen_audio_tool_var.get() == ALIGN_INPUTS:
right_click_menu.add_command(label='Advanced Align Tool Settings', command=lambda: self.check_is_menu_open(ALIGNMENT_TOOL))
else:
add_advanced_settings_options(right_click_menu, settings_mapper, var_mapper)
# Additional Settings and Help Hints
2022-12-19 04:18:56 +01:00
if not self.is_menu_settings_open:
2023-09-26 00:11:08 +02:00
right_click_menu.add_command(label='Additional Settings', command=lambda: self.menu_settings(select_tab_2=True))
help_hints_label = 'Enable' if not self.help_hints_var.get() else 'Disable'
right_click_menu.add_command(label=f'{help_hints_label} Help Hints', command=lambda: self.help_hints_var.set(not self.help_hints_var.get()))
2022-12-19 04:18:56 +01:00
if self.error_log_var.get():
2023-09-26 00:11:08 +02:00
right_click_menu.add_command(label='Error Log', command=lambda: self.check_is_menu_open(ERROR_OPTION))
2022-12-19 04:18:56 +01:00
try:
2023-09-26 00:11:08 +02:00
right_click_menu.tk_popup(event.x_root, event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
def right_click_menu_copy(self):
hightlighted_text = self.current_text_box.selection_get()
self.clipboard_clear()
self.clipboard_append(hightlighted_text)
def right_click_menu_paste(self, text_box=False):
clipboard = self.clipboard_get()
self.right_click_menu_delete(text_box=True) if text_box else self.right_click_menu_delete()
self.current_text_box.insert(self.current_text_box.index(tk.INSERT), clipboard)
def right_click_menu_delete(self, text_box=False):
if text_box:
try:
s0 = self.current_text_box.index("sel.first")
s1 = self.current_text_box.index("sel.last")
self.current_text_box.tag_configure('highlight')
self.current_text_box.tag_add("highlight", s0, s1)
start_indexes = self.current_text_box.tag_ranges("highlight")[0::2]
end_indexes = self.current_text_box.tag_ranges("highlight")[1::2]
for start, end in zip(start_indexes, end_indexes):
self.current_text_box.tag_remove("highlight", start, end)
for start, end in zip(start_indexes, end_indexes):
self.current_text_box.delete(start, end)
except Exception as e:
print('RIGHT-CLICK-DELETE ERROR: \n', e)
else:
2023-09-26 00:11:08 +02:00
self.current_text_box.delete(0, tk.END)
2022-12-19 04:18:56 +01:00
def right_click_console(self, event):
2023-09-26 00:11:08 +02:00
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
2022-12-19 04:18:56 +01:00
right_click_menu.add_command(label='Copy', command=self.command_Text.copy_text)
right_click_menu.add_command(label='Select All', command=self.command_Text.select_all_text)
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
#--Secondary Window Methods--
2023-09-26 00:11:08 +02:00
def vocal_splitter_Button_opt(self, top_window, frame, pady, width=15):
vocal_splitter_Button = ttk.Button(frame, text=VOCAL_SPLITTER_OPTIONS_TEXT, command=lambda:self.pop_up_set_vocal_splitter(top_window), width=width)#
vocal_splitter_Button.grid(pady=pady)
def adjust_toplevel_positions(self, event):
# Copy the list to avoid modifying while iterating
for toplevel in self.toplevels.copy():
# Check if the toplevel window is still alive
if not toplevel.winfo_exists():
self.toplevels.remove(toplevel)
else:
menu_offset_x = (root.winfo_width() - toplevel.winfo_width()) // 2
menu_offset_y = (root.winfo_height() - toplevel.winfo_height()) // 2
toplevel.geometry("+%d+%d" % (root.winfo_x() + menu_offset_x, root.winfo_y() + menu_offset_y))
def menu_placement(self, window: tk.Toplevel, title, pop_up=False, is_help_hints=False, close_function=None, frame_list=None, top_window=None):
2022-12-19 04:18:56 +01:00
"""Prepares and centers each secondary window relative to the main window"""
2023-09-26 00:11:08 +02:00
top_window = top_window if top_window else root
window.withdraw()
2022-12-19 04:18:56 +01:00
window.resizable(False, False)
2023-09-26 00:11:08 +02:00
window.wm_transient(top_window)
2022-12-19 04:18:56 +01:00
window.title(title)
2023-09-29 09:08:14 +02:00
window.iconbitmap(ICON_IMG_PATH) if is_windows else self.tk.call('wm', 'iconphoto', window._w, tk.PhotoImage(file=MAIN_ICON_IMG_PATH))
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
root_location_x = root.winfo_x()
root_location_y = root.winfo_y()
root_x = root.winfo_width()
root_y = root.winfo_height()
2023-09-26 00:11:08 +02:00
window.update() if is_windows else window.update_idletasks()
sub_menu_x = window.winfo_reqwidth()
sub_menu_y = window.winfo_reqheight()
2022-12-19 04:18:56 +01:00
menu_offset_x = (root_x - sub_menu_x) // 2
menu_offset_y = (root_y - sub_menu_y) // 2
window.geometry("+%d+%d" %(root_location_x+menu_offset_x, root_location_y+menu_offset_y))
2023-09-26 00:11:08 +02:00
window.deiconify()
window.configure(bg=BG_COLOR)
2023-09-27 04:54:09 +02:00
if not is_macos:
2023-09-26 00:11:08 +02:00
self.toplevels.append(window)
2022-12-19 04:18:56 +01:00
def right_click_menu(event):
help_hints_label = 'Enable' if self.help_hints_var.get() == False else 'Disable'
help_hints_bool = True if self.help_hints_var.get() == False else False
2023-09-26 00:11:08 +02:00
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
2022-12-19 04:18:56 +01:00
if is_help_hints:
right_click_menu.add_command(label=f'{help_hints_label} Help Hints', command=lambda:self.help_hints_var.set(help_hints_bool))
right_click_menu.add_command(label='Exit Window', command=close_function)
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu, window)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
if close_function:
2022-12-21 11:18:16 +01:00
window.bind(right_click_button, lambda e:right_click_menu(e))
2023-09-26 00:11:08 +02:00
if frame_list:
for frame in frame_list:
#self.adjust_widget_widths(frame)
self.focus_out_widgets(frame.winfo_children() + [frame], frame)
2022-12-19 04:18:56 +01:00
if pop_up:
2022-12-30 11:52:37 +01:00
window.attributes('-topmost', 'true') if OPERATING_SYSTEM == "Linux" else None
2022-12-19 04:18:56 +01:00
window.grab_set()
root.wait_window(window)
2023-09-26 00:11:08 +02:00
def adjust_widget_widths(self, frame):
def resize_widget(widgets):
max_width = max(wid.winfo_width() for wid in widgets)
for wid in widgets:
if isinstance(wid, (tk.Button, ttk.Combobox)):
# For widgets where width represents characters, not pixels
wid.configure(width=int(max_width / wid.winfo_pixels('1c')))
else:
# For widgets where width represents pixels
wid.configure(width=max_width)
resize_widget([widget for widget in frame.winfo_children() if isinstance(widget, tk.Button)])
resize_widget([widget for widget in frame.winfo_children() if isinstance(widget, ttk.Combobox)])
def menu_move_tab(notebook: ttk.Notebook, tab_text, new_position):
# Get the tab ID
tab_id = None
for tab in notebook.tabs():
if notebook.tab(tab, "text") == tab_text:
tab_id = tab
break
if tab_id is None:
print(f"No tab named '{tab_text}'")
return
# remove the tab
notebook.forget(tab_id)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
# add it back in new position
notebook.insert(new_position, tab_id)
def menu_tab_control(self, toplevel, ai_network_vars, is_demucs=False, is_mdxnet=False):
2022-12-19 04:18:56 +01:00
"""Prepares the tabs setup for some windows"""
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
tabControl = ttk.Notebook(toplevel)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
2023-09-26 00:11:08 +02:00
tabControl.add(tab1, text=SETTINGS_GUIDE_TEXT)
tabControl.add(tab2, text=SECONDARY_MODEL_TEXT)
2022-12-19 04:18:56 +01:00
tab1.grid_rowconfigure(0, weight=1)
tab1.grid_columnconfigure(0, weight=1)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
tab2.grid_rowconfigure(0, weight=1)
tab2.grid_columnconfigure(0, weight=1)
2023-09-26 00:11:08 +02:00
if is_demucs or is_mdxnet:
2022-12-19 04:18:56 +01:00
tab3 = ttk.Frame(tabControl)
2023-09-26 00:11:08 +02:00
tabControl.add(tab3, text=PREPROCESS_MODEL_CHOOSE_TEXT if is_demucs else MDX23C_ONLY_OPTIONS_TEXT)
2022-12-19 04:18:56 +01:00
tab3.grid_rowconfigure(0, weight=1)
tab3.grid_columnconfigure(0, weight=1)
2023-09-26 00:11:08 +02:00
tabControl.pack(expand=1, fill=tk.BOTH)
self.tab2_loaded = False
self.tab3_loaded = False
def on_tab_selected(event):
# Check if it's tab2 (by tab id or tab title) and if it hasn't been loaded before
load_screen = False
if event.widget.tab('current', option='text') == 'Secondary Model' and not self.tab2_loaded:
tab = tab2
self.tab2_loaded = True
tab_load = lambda:self.menu_secondary_model(tab, ai_network_vars)
load_screen = True
elif event.widget.tab('current', option='text') == PREPROCESS_MODEL_CHOOSE_TEXT and not self.tab3_loaded:
tab = tab3
self.tab3_loaded = True
tab_load = lambda:self.menu_preproc_model(tab)
load_screen = True
if load_screen:
# Step 1: Add "Loading..." label
loading_label = ttk.Label(tab, text="Updating model lists...", font=Font(family=MAIN_FONT_NAME, size=14))
loading_label.place(relx=0.5, rely=0.5, anchor=tk.CENTER) # Assuming you want to center it
# Step 2: Update the UI to show the label
tab.update_idletasks()
# Load the content
tab_load()
# Step 3: Remove or update the "Loading..." label
loading_label.destroy() # Remove the label. Or you can update its text if desired.
#self.on_tab_changed(tabControl)
tabControl.bind("<<NotebookTabChanged>>", on_tab_selected)
if is_demucs or is_mdxnet:
2022-12-19 04:18:56 +01:00
return tab1, tab3
else:
return tab1
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def menu_view_inputs(self):
2023-09-26 00:11:08 +02:00
menu_view_inputs_top = tk.Toplevel(root)
2022-12-19 04:18:56 +01:00
self.is_open_menu_view_inputs.set(True)
self.menu_view_inputs_close_window = lambda:close_window()
menu_view_inputs_top.protocol("WM_DELETE_WINDOW", self.menu_view_inputs_close_window)
input_length_var = tk.StringVar(value='')
input_info_text_var = tk.StringVar(value='')
is_widen_box_var = tk.BooleanVar(value=False)
is_play_file_var = tk.BooleanVar(value=False)
2023-09-26 00:11:08 +02:00
varification_text_var = tk.StringVar(value=VERIFY_INPUTS_TEXT)
2022-12-19 04:18:56 +01:00
reset_list = lambda:(input_files_listbox_Option.delete(0, 'end'), [input_files_listbox_Option.insert(tk.END, inputs) for inputs in self.inputPaths])
2023-09-26 00:11:08 +02:00
audio_input_total = lambda:input_length_var.set(f'{AUDIO_INPUT_TOTAL_TEXT}: {len(self.inputPaths)}')
2022-12-19 04:18:56 +01:00
audio_input_total()
def list_diff(list1, list2): return list(set(list1).symmetric_difference(set(list2)))
def list_to_string(list1): return '\n'.join(''.join(sub) for sub in list1)
def close_window():
self.verification_thread.kill() if self.thread_check(self.verification_thread) else None
self.is_open_menu_view_inputs.set(False)
menu_view_inputs_top.destroy()
def drag_n_drop(e):
input_info_text_var.set('')
drop(e, accept_mode='files')
reset_list()
audio_input_total()
def selected_files(is_remove=False):
if not self.thread_check(self.active_processing_thread):
items_list = [input_files_listbox_Option.get(i) for i in input_files_listbox_Option.curselection()]
inputPaths = list(self.inputPaths)# if is_remove else items_list
if is_remove:
[inputPaths.remove(i) for i in items_list if items_list]
else:
[inputPaths.remove(i) for i in self.inputPaths if i not in items_list]
removed_files = list_diff(self.inputPaths, inputPaths)
[input_files_listbox_Option.delete(input_files_listbox_Option.get(0, tk.END).index(i)) for i in removed_files]
starting_len = len(self.inputPaths)
self.inputPaths = tuple(inputPaths)
self.update_inputPaths()
audio_input_total()
input_info_text_var.set(f'{starting_len - len(self.inputPaths)} input(s) removed.')
else:
input_info_text_var.set('You cannot remove inputs during an active process.')
def box_size():
input_info_text_var.set('')
input_files_listbox_Option.config(width=230, height=25) if is_widen_box_var.get() else input_files_listbox_Option.config(width=110, height=17)
self.menu_placement(menu_view_inputs_top, 'Selected Inputs', pop_up=True)
def input_options(is_select_inputs=True):
input_info_text_var.set('')
if is_select_inputs:
self.input_select_filedialog()
else:
self.inputPaths = ()
reset_list()
self.update_inputPaths()
audio_input_total()
def pop_open_file_path(is_play_file=False):
if self.inputPaths:
track_selected = self.inputPaths[input_files_listbox_Option.index(tk.ACTIVE)]
if os.path.isfile(track_selected):
2022-12-27 11:31:41 +01:00
OPEN_FILE_func(track_selected if is_play_file else os.path.dirname(track_selected))
2022-12-19 04:18:56 +01:00
def get_export_dir():
if os.path.isdir(self.export_path_var.get()):
export_dir = self.export_path_var.get()
else:
export_dir = self.export_select_filedialog()
return export_dir
def verify_audio(is_create_samples=False):
inputPaths = list(self.inputPaths)
iterated_list = self.inputPaths if not is_create_samples else [input_files_listbox_Option.get(i) for i in input_files_listbox_Option.curselection()]
removed_files = []
export_dir = None
total_audio_count, current_file = len(iterated_list), 0
if iterated_list:
for i in iterated_list:
current_file += 1
input_info_text_var.set(f'{SAMPLE_BEGIN if is_create_samples else VERIFY_BEGIN}{current_file}/{total_audio_count}')
if is_create_samples:
export_dir = get_export_dir()
if not export_dir:
input_info_text_var.set(f'No export directory selected.')
return
is_good, error_data = self.verify_audio(i, is_process=False, sample_path=export_dir)
if not is_good:
inputPaths.remove(i)
removed_files.append(error_data)#sample = self.create_sample(i)
2023-09-26 00:11:08 +02:00
varification_text_var.set(VERIFY_INPUTS_TEXT)
2022-12-19 04:18:56 +01:00
input_files_listbox_Option.configure(state=tk.NORMAL)
if removed_files:
2023-09-26 00:11:08 +02:00
input_info_text_var.set(f'{len(removed_files)} {BROKEN_OR_INCOM_TEXT}')
2022-12-19 04:18:56 +01:00
error_text = ''
for i in removed_files:
error_text += i
removed_files = list_diff(self.inputPaths, inputPaths)
[input_files_listbox_Option.delete(input_files_listbox_Option.get(0, tk.END).index(i)) for i in removed_files]
self.error_log_var.set(REMOVED_FILES(list_to_string(removed_files), error_text))
self.inputPaths = tuple(inputPaths)
self.update_inputPaths()
else:
input_info_text_var.set(f'No errors found!')
audio_input_total()
else:
2023-09-26 00:11:08 +02:00
input_info_text_var.set(f'{NO_FILES_TEXT} {SELECTED_VER if is_create_samples else DETECTED_VER}')
varification_text_var.set(VERIFY_INPUTS_TEXT)
2022-12-19 04:18:56 +01:00
input_files_listbox_Option.configure(state=tk.NORMAL)
return
audio_input_total()
def verify_audio_start_thread(is_create_samples=False):
if not self.thread_check(self.active_processing_thread):
if not self.thread_check(self.verification_thread):
varification_text_var.set('Stop Progress')
input_files_listbox_Option.configure(state=tk.DISABLED)
self.verification_thread = KThread(target=lambda:verify_audio(is_create_samples=is_create_samples))
self.verification_thread.start()
else:
input_files_listbox_Option.configure(state=tk.NORMAL)
2023-09-26 00:11:08 +02:00
varification_text_var.set(VERIFY_INPUTS_TEXT)
2022-12-19 04:18:56 +01:00
input_info_text_var.set('Process Stopped')
self.verification_thread.kill()
else:
input_info_text_var.set('You cannot verify inputs during an active process.')
def right_click_menu(event):
2023-09-26 00:11:08 +02:00
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
2022-12-19 04:18:56 +01:00
right_click_menu.add_command(label='Remove Selected Items Only', command=lambda:selected_files(is_remove=True))
right_click_menu.add_command(label='Keep Selected Items Only', command=lambda:selected_files(is_remove=False))
right_click_menu.add_command(label='Clear All Input(s)', command=lambda:input_options(is_select_inputs=False))
right_click_menu.add_separator()
2023-09-26 00:11:08 +02:00
right_click_menu_sub = tk.Menu(right_click_menu, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=False)
2022-12-19 04:18:56 +01:00
right_click_menu.add_command(label='Verify and Create Samples of Selected Inputs', command=lambda:verify_audio_start_thread(is_create_samples=True))
right_click_menu.add_cascade(label='Preferred Double Click Action', menu=right_click_menu_sub)
if is_play_file_var.get():
right_click_menu_sub.add_command(label='Enable: Open Audio File Directory', command=lambda:(input_files_listbox_Option.bind('<Double-Button>', lambda e:pop_open_file_path()), is_play_file_var.set(False)))
else:
right_click_menu_sub.add_command(label='Enable: Open Audio File', command=lambda:(input_files_listbox_Option.bind('<Double-Button>', lambda e:pop_open_file_path(is_play_file=True)), is_play_file_var.set(True)))
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu, menu_view_inputs_top)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
menu_view_inputs_Frame = self.menu_FRAME_SET(menu_view_inputs_top)
2023-09-26 00:11:08 +02:00
menu_view_inputs_Frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.main_window_LABEL_SET(menu_view_inputs_Frame, SELECTED_INPUTS).grid(row=0,column=0,padx=0,pady=MENU_PADDING_1)
tk.Label(menu_view_inputs_Frame, textvariable=input_length_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground=FG_COLOR).grid(row=1, column=0, padx=0, pady=MENU_PADDING_1)
2022-12-30 12:49:26 +01:00
if not OPERATING_SYSTEM == "Linux":
2023-09-26 00:11:08 +02:00
ttk.Button(menu_view_inputs_Frame, text=SELECT_INPUTS, command=lambda:input_options()).grid(row=2,column=0,padx=0,pady=MENU_PADDING_2)
input_files_listbox_Option = tk.Listbox(menu_view_inputs_Frame, selectmode=tk.EXTENDED, activestyle='dotbox', font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), background='#101414', exportselection=0, width=110, height=17, relief=tk.SOLID, borderwidth=0)
input_files_listbox_vertical_scroll = ttk.Scrollbar(menu_view_inputs_Frame, orient=tk.VERTICAL)
2022-12-19 04:18:56 +01:00
input_files_listbox_Option.config(yscrollcommand=input_files_listbox_vertical_scroll.set)
input_files_listbox_vertical_scroll.configure(command=input_files_listbox_Option.yview)
2023-09-26 00:11:08 +02:00
input_files_listbox_Option.grid(row=4, sticky=tk.W)
input_files_listbox_vertical_scroll.grid(row=4, column=1, sticky=tk.NS)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
tk.Label(menu_view_inputs_Frame, textvariable=input_info_text_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground=FG_COLOR).grid(row=5, column=0, padx=0, pady=0)
ttk.Checkbutton(menu_view_inputs_Frame, text=WIDEN_BOX, variable=is_widen_box_var, command=lambda:box_size()).grid(row=6,column=0,padx=0,pady=0)
2022-12-19 04:18:56 +01:00
verify_audio_Button = ttk.Button(menu_view_inputs_Frame, textvariable=varification_text_var, command=lambda:verify_audio_start_thread())
2023-09-26 00:11:08 +02:00
verify_audio_Button.grid(row=7,column=0,padx=0,pady=MENU_PADDING_1)
ttk.Button(menu_view_inputs_Frame, text=CLOSE_WINDOW, command=lambda:menu_view_inputs_top.destroy()).grid(row=8,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2022-12-29 00:48:28 +01:00
if is_dnd_compatible:
2022-12-27 11:31:41 +01:00
menu_view_inputs_top.drop_target_register(DND_FILES)
menu_view_inputs_top.dnd_bind('<<Drop>>', lambda e: drag_n_drop(e))
2022-12-21 11:18:16 +01:00
input_files_listbox_Option.bind(right_click_button, lambda e:right_click_menu(e))
2022-12-19 04:18:56 +01:00
input_files_listbox_Option.bind('<Double-Button>', lambda e:pop_open_file_path())
input_files_listbox_Option.bind('<Delete>', lambda e:selected_files(is_remove=True))
input_files_listbox_Option.bind('<BackSpace>', lambda e:selected_files(is_remove=False))
reset_list()
2022-12-30 12:49:26 +01:00
2022-12-19 04:18:56 +01:00
self.menu_placement(menu_view_inputs_top, 'Selected Inputs', pop_up=True)
2023-09-26 00:11:08 +02:00
def menu_batch_dual(self):
menu_batch_dual_top = tk.Toplevel(root)
def drag_n_drop(event, accept_mode):
listbox = left_frame if accept_mode == FILE_1_LB else right_frame
paths = drop(event, accept_mode)
for item in paths:
if item not in listbox.path_list: # only add file if it's not already in the list
basename = os.path.basename(item)
listbox.listbox.insert(tk.END, basename) # insert basename to the listbox
listbox.path_list.append(item) # append the file path to the list
listbox.update_displayed_index()
def move_entry(is_primary=True):
if is_primary:
selected_frame, other_frame = left_frame, right_frame
else:
selected_frame, other_frame = right_frame, left_frame
selected = selected_frame.listbox.curselection()
if selected:
basename = selected_frame.listbox.get(selected[0]).split(': ', 1)[1] # remove displayed index
if basename in other_frame.basename_to_path:
return
path = selected_frame.basename_to_path[basename] # Get the actual path
selected_frame.listbox.delete(selected)
other_frame.listbox.insert(tk.END, basename)
selected_frame.path_list.remove(path)
del selected_frame.basename_to_path[basename]
other_frame.path_list.append(path)
other_frame.basename_to_path[basename] = path
selected_frame.update_displayed_index()
other_frame.update_displayed_index()
def open_selected_path(lb, is_play_file=False):
selected_frame = left_frame if lb == FILE_1_LB else right_frame
selected_path = selected_frame.get_selected_path()
if selected_path:
if os.path.isfile(selected_path):
OPEN_FILE_func(selected_path if is_play_file else os.path.dirname(selected_path))
def clear_all_data(lb):
selected_frame = left_frame if lb == FILE_1_LB else right_frame
selected_frame.listbox.delete(0, "end")
selected_frame.path_list.clear()
selected_frame.basename_to_path.clear()
def clear_all(event, lb):
selected_frame = left_frame if lb == FILE_1_LB else right_frame
selected = selected_frame.listbox.curselection()
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
if selected:
right_click_menu.add_command(label='Open Location', command=lambda:open_selected_path(lb))
right_click_menu.add_command(label='Open File', command=lambda:open_selected_path(lb, is_play_file=True))
right_click_menu.add_command(label='Clear All', command=lambda:clear_all_data(lb))
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2023-09-27 04:54:09 +02:00
right_click_release_linux(right_click_menu, menu_batch_dual_top)
2023-09-26 00:11:08 +02:00
finally:
right_click_menu.grab_release()
def gather_input_list():
left_paths = list(left_frame.basename_to_path.values())
right_paths = list(right_frame.basename_to_path.values())
clear_all_data(FILE_1_LB)
clear_all_data(FILE_2_LB)
if left_paths and right_paths:
left_frame.select_input(left_paths)
right_frame.select_input(right_paths)
self.DualBatch_inputPaths = list(zip(left_paths, right_paths))
self.check_dual_paths()
menu_batch_dual_top.destroy()
menu_view_inputs_Frame = self.menu_FRAME_SET(menu_batch_dual_top)
menu_view_inputs_Frame.grid(row=0)
left_frame = ListboxBatchFrame(menu_view_inputs_Frame, self.file_one_sub_var.get().title(), move_entry, self.right_img, self.img_mapper)
left_frame.grid(row=0, column=0, sticky="nsew", padx=(0, 5))
right_frame = ListboxBatchFrame(menu_view_inputs_Frame, self.file_two_sub_var.get().title(), lambda:move_entry(False), self.left_img, self.img_mapper)
right_frame.grid(row=0, column=1, sticky="nsew", padx=(5, 0))
left_frame.listbox.drop_target_register(DND_FILES)
right_frame.listbox.drop_target_register(DND_FILES)
left_frame.listbox.dnd_bind('<<Drop>>', lambda e: drag_n_drop(e, FILE_1_LB))
right_frame.listbox.dnd_bind('<<Drop>>', lambda e: drag_n_drop(e, FILE_2_LB))
left_frame.listbox.dnd_bind(right_click_button, lambda e: clear_all(e, FILE_1_LB))
right_frame.listbox.dnd_bind(right_click_button, lambda e: clear_all(e, FILE_2_LB))
menu_view_inputs_bottom_Frame = self.menu_FRAME_SET(menu_batch_dual_top)
menu_view_inputs_bottom_Frame.grid(row=1)
confirm_btn = ttk.Button(menu_view_inputs_bottom_Frame, text=CONFIRM_ENTRIES, command=gather_input_list)
confirm_btn.grid(pady=MENU_PADDING_1)
close_btn = ttk.Button(menu_view_inputs_bottom_Frame, text=CLOSE_WINDOW, command=lambda:menu_batch_dual_top.destroy())
close_btn.grid(pady=MENU_PADDING_1)
if self.check_dual_paths():
left_frame_pane = [i[0] for i in self.DualBatch_inputPaths]
right_frame_pane = [i[1] for i in self.DualBatch_inputPaths]
left_frame.update_displayed_index(left_frame_pane)
right_frame.update_displayed_index(right_frame_pane)
self.check_dual_paths()
self.menu_placement(menu_batch_dual_top, DUAL_AUDIO_PROCESSING, pop_up=True)
def check_dual_paths(self, is_fill_menu=False):
if self.DualBatch_inputPaths:
first_paths = tuple(self.DualBatch_inputPaths)
first_paths_len = len(first_paths)
first_paths = first_paths[0]
if first_paths_len == 1:
file1_base_text = os.path.basename(first_paths[0])
file2_base_text = os.path.basename(first_paths[1])
else:
first_paths_len = first_paths_len - 1
file1_base_text = f"{os.path.basename(first_paths[0])}, +{first_paths_len} file(s){BATCH_MODE_DUAL}"
file2_base_text = f"{os.path.basename(first_paths[1])}, +{first_paths_len} file(s){BATCH_MODE_DUAL}"
self.fileOneEntry_var.set(file1_base_text)
self.fileOneEntry_Full_var.set(f"{first_paths[0]}")
self.fileTwoEntry_var.set(file2_base_text)
self.fileTwoEntry_Full_var.set(f"{first_paths[1]}")
else:
if is_fill_menu:
file_one = self.fileOneEntry_Full_var.get()
file_two = self.fileTwoEntry_Full_var.get()
if file_one and file_two and BATCH_MODE_DUAL not in file_one and BATCH_MODE_DUAL not in file_two:
self.DualBatch_inputPaths = [(file_one, file_two)]
else:
if BATCH_MODE_DUAL in self.fileOneEntry_var.get():
self.fileOneEntry_var.set("")
self.fileOneEntry_Full_var.set("")
if BATCH_MODE_DUAL in self.fileTwoEntry_var.get():
self.fileTwoEntry_var.set("")
self.fileTwoEntry_Full_var.set("")
return self.DualBatch_inputPaths
def menu_settings(self, select_tab_2=False, select_tab_3=False):#**
2022-12-19 04:18:56 +01:00
"""Open Settings and Download Center"""
2023-09-26 00:11:08 +02:00
settings_menu = tk.Toplevel()
2022-12-19 04:18:56 +01:00
option_var = tk.StringVar(value=SELECT_SAVED_SETTING)
self.is_menu_settings_open = True
tabControl = ttk.Notebook(settings_menu)
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tab3 = ttk.Frame(tabControl)
2023-09-26 00:11:08 +02:00
tabControl.add(tab1, text = SETTINGS_GUIDE_TEXT)
tabControl.add(tab2, text = ADDITIONAL_SETTINGS_TEXT)
tabControl.add(tab3, text = DOWNLOAD_CENTER_TEXT)
2022-12-19 04:18:56 +01:00
tabControl.pack(expand = 1, fill ="both")
tab1.grid_rowconfigure(0, weight=1)
tab1.grid_columnconfigure(0, weight=1)
tab2.grid_rowconfigure(0, weight=1)
tab2.grid_columnconfigure(0, weight=1)
tab3.grid_rowconfigure(0, weight=1)
tab3.grid_columnconfigure(0, weight=1)
self.disable_tabs = lambda:(tabControl.tab(0, state="disabled"), tabControl.tab(1, state="disabled"))
self.enable_tabs = lambda:(tabControl.tab(0, state="normal"), tabControl.tab(1, state="normal"))
2023-09-26 00:11:08 +02:00
self.main_menu_var = tk.StringVar(value=CHOOSE_ADVANCED_MENU_TEXT)
2022-12-21 11:18:16 +01:00
2022-12-19 04:18:56 +01:00
self.download_progress_bar_var.set(0)
self.download_progress_info_var.set('')
self.download_progress_percent_var.set('')
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def set_vars_for_sample_mode(event):
value = int(float(event))
value = round(value / 5) * 5
self.model_sample_mode_duration_var.set(value)
self.model_sample_mode_duration_checkbox_var.set(SAMPLE_MODE_CHECKBOX(value))
2023-09-26 00:11:08 +02:00
self.model_sample_mode_duration_label_var.set(f'{value} {SECONDS_TEXT}')
2022-12-19 04:18:56 +01:00
#Settings Tab 1
settings_menu_main_Frame = self.menu_FRAME_SET(tab1)
2023-09-26 00:11:08 +02:00
settings_menu_main_Frame.grid(row=0)
settings_title_Label = self.menu_title_LABEL_SET(settings_menu_main_Frame, GENERAL_MENU_TEXT)
settings_title_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
select_Label = self.menu_sub_LABEL_SET(settings_menu_main_Frame, ADDITIONAL_MENUS_INFORMATION_TEXT)
select_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
select_Option = ComboBoxMenu(settings_menu_main_Frame, textvariable=self.main_menu_var, values=OPTION_LIST, width=GEN_SETTINGS_WIDTH+(3 if is_windows else 3))
select_Option.update_dropdown_size(OPTION_LIST, 'menuchoose', command=lambda e:(self.check_is_menu_open(self.main_menu_var.get()), close_window()))
select_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
help_hints_Option = ttk.Checkbutton(settings_menu_main_Frame, text=ENABLE_HELP_HINTS_TEXT, variable=self.help_hints_var, width=HELP_HINT_CHECKBOX_WIDTH)
help_hints_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
open_app_dir_Button = ttk.Button(settings_menu_main_Frame, text=OPEN_APPLICATION_DIRECTORY_TEXT, command=lambda:OPEN_FILE_func(BASE_PATH), width=SETTINGS_BUT_WIDTH)
open_app_dir_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
reset_all_app_settings_Button = ttk.Button(settings_menu_main_Frame, text=RESET_ALL_SETTINGS_TO_DEFAULT_TEXT, command=lambda:self.load_to_default_confirm(), width=SETTINGS_BUT_WIDTH)#pop_up_change_model_defaults
reset_all_app_settings_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2022-12-27 11:31:41 +01:00
if is_windows:
2023-09-26 00:11:08 +02:00
restart_app_Button = ttk.Button(settings_menu_main_Frame, text=RESTART_APPLICATION_TEXT, command=lambda:self.restart())
restart_app_Button.grid(pady=MENU_PADDING_1)
delete_your_settings_Label = self.menu_title_LABEL_SET(settings_menu_main_Frame, DELETE_USER_SAVED_SETTING_TEXT)
delete_your_settings_Label.grid(pady=MENU_PADDING_2)
self.help_hints(delete_your_settings_Label, text=DELETE_YOUR_SETTINGS_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
delete_your_settings_Option = ComboBoxMenu(settings_menu_main_Frame, textvariable=option_var, width=GEN_SETTINGS_WIDTH+(3 if is_windows else 3))
delete_your_settings_Option.grid(padx=20,pady=MENU_PADDING_1)
self.deletion_list_fill(delete_your_settings_Option, option_var, SETTINGS_CACHE_DIR, SELECT_SAVED_SETTING, menu_name='deletesetting')
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
app_update_Label = self.menu_title_LABEL_SET(settings_menu_main_Frame, APPLICATION_UPDATES_TEXT)
app_update_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.app_update_button = ttk.Button(settings_menu_main_Frame, textvariable=self.app_update_button_Text_var, width=SETTINGS_BUT_WIDTH-2, command=lambda:self.pop_up_update_confirmation())
self.app_update_button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-10-07 02:05:25 +02:00
self.app_update_status_Label = tk.Label(settings_menu_main_Frame, textvariable=self.app_update_status_Text_var, padx=3, pady=3, font=(MAIN_FONT_NAME, f"{FONT_SIZE_4}"), width=UPDATE_LABEL_WIDTH, justify="center", relief="ridge", fg="#13849f")
2023-09-26 00:11:08 +02:00
self.app_update_status_Label.grid(pady=20)
2022-12-19 04:18:56 +01:00
donate_Button = ttk.Button(settings_menu_main_Frame, image=self.donate_img, command=lambda:webbrowser.open_new_tab(DONATE_LINK_BMAC))
2023-09-26 00:11:08 +02:00
donate_Button.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
self.help_hints(donate_Button, text=DONATE_HELP)
2023-09-26 00:11:08 +02:00
close_settings_win_Button = ttk.Button(settings_menu_main_Frame, text=CLOSE_WINDOW, command=lambda:close_window())
close_settings_win_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
#Settings Tab 2
settings_menu_format_Frame = self.menu_FRAME_SET(tab2)
2023-09-26 00:11:08 +02:00
settings_menu_format_Frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
audio_format_title_Label = self.menu_title_LABEL_SET(settings_menu_format_Frame, AUDIO_FORMAT_SETTINGS_TEXT, width=20)
audio_format_title_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
wav_type_set_Label = self.menu_sub_LABEL_SET(settings_menu_format_Frame, WAV_TYPE_TEXT)
wav_type_set_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
wav_type_set_Option = ComboBoxMenu(settings_menu_format_Frame, textvariable=self.wav_type_set_var, values=WAV_TYPE, width=HELP_HINT_CHECKBOX_WIDTH)
wav_type_set_Option.grid(padx=20,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
mp3_bit_set_Label = self.menu_sub_LABEL_SET(settings_menu_format_Frame, MP3_BITRATE_TEXT)
mp3_bit_set_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
mp3_bit_set_Option = ComboBoxMenu(settings_menu_format_Frame, textvariable=self.mp3_bit_set_var, values=MP3_BIT_RATES, width=HELP_HINT_CHECKBOX_WIDTH)
mp3_bit_set_Option.grid(padx=20,pady=MENU_PADDING_1)
2023-10-16 02:27:38 +02:00
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_add_model_name_Option = ttk.Checkbutton(settings_menu_format_Frame, text=MODEL_TEST_MODE_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_add_model_name_var)
is_add_model_name_Option.grid()
self.help_hints(is_add_model_name_Option, text=IS_MODEL_TESTING_AUDIO_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_create_model_folder_Option = ttk.Checkbutton(settings_menu_format_Frame, text=GENERATE_MODEL_FOLDER_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_create_model_folder_var)
is_create_model_folder_Option.grid()
self.help_hints(is_create_model_folder_Option, text=IS_CREATE_MODEL_FOLDER_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_accept_any_input_Option = ttk.Checkbutton(settings_menu_format_Frame, text=ACCEPT_ANY_INPUT_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_accept_any_input_var)
is_accept_any_input_Option.grid()
self.help_hints(is_accept_any_input_Option, text=IS_ACCEPT_ANY_INPUT_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_task_complete_Option = ttk.Checkbutton(settings_menu_format_Frame, text=NOTIFICATION_CHIMES_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_task_complete_var)
is_task_complete_Option.grid()
self.help_hints(is_task_complete_Option, text=IS_TASK_COMPLETE_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_normalization_Option = ttk.Checkbutton(settings_menu_format_Frame, text=NORMALIZE_OUTPUT_TEXT, width=GEN_SETTINGS_WIDTH, variable=self.is_normalization_var)
is_normalization_Option.grid()
2022-12-19 04:18:56 +01:00
self.help_hints(is_normalization_Option, text=IS_NORMALIZATION_HELP)
2023-09-26 00:11:08 +02:00
change_model_default_Button = ttk.Button(settings_menu_format_Frame, text=CHANGE_MODEL_DEFAULTS_TEXT, command=lambda:self.pop_up_change_model_defaults(settings_menu), width=SETTINGS_BUT_WIDTH-2)#
change_model_default_Button.grid(pady=MENU_PADDING_4)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.vocal_splitter_Button_opt(settings_menu, settings_menu_format_Frame, width=SETTINGS_BUT_WIDTH-2, pady=MENU_PADDING_4)
2022-12-19 04:18:56 +01:00
2023-10-16 02:27:38 +02:00
if not is_macos and self.is_gpu_available:
cuda_set_Label = self.menu_title_LABEL_SET(settings_menu_format_Frame, CUDA_NUM_TEXT)
cuda_set_Label.grid(pady=MENU_PADDING_2)
cuda_set_Option = ComboBoxMenu(settings_menu_format_Frame, textvariable=self.cuda_set_var, values=CUDA_TYPE, width=HELP_HINT_CHECKBOX_WIDTH)
cuda_set_Option.grid(padx=20,pady=MENU_PADDING_1)
self.help_hints(cuda_set_Label, text=IS_CUDA_SELECT_HELP)
2023-09-26 00:11:08 +02:00
model_sample_mode_Label = self.menu_title_LABEL_SET(settings_menu_format_Frame, MODEL_SAMPLE_MODE_SETTINGS_TEXT)
model_sample_mode_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
model_sample_mode_duration_Label = self.menu_sub_LABEL_SET(settings_menu_format_Frame, SAMPLE_CLIP_DURATION_TEXT)
model_sample_mode_duration_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
tk.Label(settings_menu_format_Frame, textvariable=self.model_sample_mode_duration_label_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground=FG_COLOR).grid(pady=2)
model_sample_mode_duration_Option = ttk.Scale(settings_menu_format_Frame, variable=self.model_sample_mode_duration_var, from_=5, to=120, command=set_vars_for_sample_mode, orient='horizontal')
model_sample_mode_duration_Option.grid(pady=2)
2022-12-19 04:18:56 +01:00
#Settings Tab 3
settings_menu_download_center_Frame = self.menu_FRAME_SET(tab3)
2023-09-26 00:11:08 +02:00
settings_menu_download_center_Frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
download_center_title_Label = self.menu_title_LABEL_SET(settings_menu_download_center_Frame, APPLICATION_DOWNLOAD_CENTER_TEXT)
download_center_title_Label.grid(padx=20,pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
select_download_Label = self.menu_sub_LABEL_SET(settings_menu_download_center_Frame, SELECT_DOWNLOAD_TEXT)
select_download_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
self.model_download_vr_Button = ttk.Radiobutton(settings_menu_download_center_Frame, text='VR Arch', width=8, variable=self.select_download_var, value='VR Arc', command=lambda:self.download_list_state())
2023-09-26 00:11:08 +02:00
self.model_download_vr_Button.grid(pady=MENU_PADDING_1)
self.model_download_vr_Option = ComboBoxMenu(settings_menu_download_center_Frame, textvariable=self.model_download_vr_var, width=READ_ONLY_COMBO_WIDTH)
self.model_download_vr_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.model_download_mdx_Button = ttk.Radiobutton(settings_menu_download_center_Frame, text='MDX-Net', width=8, variable=self.select_download_var, value='MDX-Net', command=lambda:self.download_list_state())
2023-09-26 00:11:08 +02:00
self.model_download_mdx_Button.grid(pady=MENU_PADDING_1)
self.model_download_mdx_Option = ComboBoxMenu(settings_menu_download_center_Frame, textvariable=self.model_download_mdx_var, width=READ_ONLY_COMBO_WIDTH)
self.model_download_mdx_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.model_download_demucs_Button = ttk.Radiobutton(settings_menu_download_center_Frame, text='Demucs', width=8, variable=self.select_download_var, value='Demucs', command=lambda:self.download_list_state())
2023-09-26 00:11:08 +02:00
self.model_download_demucs_Button.grid(pady=MENU_PADDING_1)
self.model_download_demucs_Option = ComboBoxMenu(settings_menu_download_center_Frame, textvariable=self.model_download_demucs_var, width=READ_ONLY_COMBO_WIDTH)
self.model_download_demucs_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.download_Button = ttk.Button(settings_menu_download_center_Frame, image=self.download_img, command=lambda:self.download_item())#, command=download_model)
2023-09-26 00:11:08 +02:00
self.download_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.download_progress_info_Label = tk.Label(settings_menu_download_center_Frame, textvariable=self.download_progress_info_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_2}"), foreground=FG_COLOR, borderwidth=0)
self.download_progress_info_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.download_progress_percent_Label = tk.Label(settings_menu_download_center_Frame, textvariable=self.download_progress_percent_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_2}"), wraplength=350, foreground=FG_COLOR)
self.download_progress_percent_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.download_progress_bar_Progressbar = ttk.Progressbar(settings_menu_download_center_Frame, variable=self.download_progress_bar_var)
2023-09-26 00:11:08 +02:00
self.download_progress_bar_Progressbar.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.stop_download_Button = ttk.Button(settings_menu_download_center_Frame, textvariable=self.download_stop_var, width=15, command=lambda:self.download_post_action(DOWNLOAD_STOPPED))
2023-09-26 00:11:08 +02:00
self.stop_download_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.stop_download_Button_DISABLE = lambda:(self.download_stop_var.set(""), self.stop_download_Button.configure(state=tk.DISABLED))
2023-09-26 00:11:08 +02:00
self.stop_download_Button_ENABLE = lambda:(self.download_stop_var.set(STOP_DOWNLOAD_TEXT), self.stop_download_Button.configure(state=tk.NORMAL))
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.refresh_list_Button = ttk.Button(settings_menu_download_center_Frame, text=REFRESH_LIST_TEXT, command=lambda:self.online_data_refresh(refresh_list_Button=True))#, command=refresh_list)
self.refresh_list_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.download_key_Button = ttk.Button(settings_menu_download_center_Frame, image=self.key_img, command=lambda:self.pop_up_user_code_input())
2023-09-26 00:11:08 +02:00
self.download_key_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.manual_download_Button = ttk.Button(settings_menu_download_center_Frame, text=TRY_MANUAL_DOWNLOAD_TEXT, command=self.menu_manual_downloads)
self.manual_download_Button.grid(pady=MENU_PADDING_1)
2022-12-30 04:07:23 +01:00
2022-12-19 04:18:56 +01:00
self.download_center_Buttons = (self.model_download_vr_Button,
self.model_download_mdx_Button,
self.model_download_demucs_Button,
self.download_Button,
self.download_key_Button)
self.download_lists = (self.model_download_vr_Option,
self.model_download_mdx_Option,
self.model_download_demucs_Option)
self.download_list_vars = (self.model_download_vr_var,
2023-09-26 00:11:08 +02:00
self.model_download_mdx_var,
self.model_download_demucs_var)
2022-12-19 04:18:56 +01:00
self.online_data_refresh()
2022-12-27 11:31:41 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(settings_menu, SETTINGS_GUIDE_TEXT, is_help_hints=True, close_function=lambda:close_window())
2022-12-19 04:18:56 +01:00
if select_tab_2:
tabControl.select(tab2)
2023-09-26 00:11:08 +02:00
settings_menu.update_idletasks()
2022-12-19 04:18:56 +01:00
if select_tab_3:
tabControl.select(tab3)
2023-09-26 00:11:08 +02:00
settings_menu.update_idletasks()
2022-12-19 04:18:56 +01:00
def close_window():
self.active_download_thread.terminate() if self.thread_check(self.active_download_thread) else None
self.is_menu_settings_open = False
2023-09-26 00:11:08 +02:00
self.select_download_var.set('')
2022-12-19 04:18:56 +01:00
settings_menu.destroy()
2023-09-26 00:11:08 +02:00
#self.update_checkbox_text()
2022-12-19 04:18:56 +01:00
settings_menu.protocol("WM_DELETE_WINDOW", close_window)
2023-09-26 00:11:08 +02:00
def menu_advanced_vr_options(self):#**
2022-12-19 04:18:56 +01:00
"""Open Advanced VR Options"""
2023-09-26 00:11:08 +02:00
vr_opt = tk.Toplevel()
2022-12-19 04:18:56 +01:00
tab1 = self.menu_tab_control(vr_opt, self.vr_secondary_model_vars)
self.is_open_menu_advanced_vr_options.set(True)
self.menu_advanced_vr_options_close_window = lambda:(self.is_open_menu_advanced_vr_options.set(False), vr_opt.destroy())
vr_opt.protocol("WM_DELETE_WINDOW", self.menu_advanced_vr_options_close_window)
2023-09-26 00:11:08 +02:00
toggle_post_process = lambda:self.post_process_threshold_Option.configure(state=READ_ONLY) if self.is_post_process_var.get() else self.post_process_threshold_Option.configure(state=tk.DISABLED)
2022-12-21 11:18:16 +01:00
2022-12-19 04:18:56 +01:00
vr_opt_frame = self.menu_FRAME_SET(tab1)
2023-09-26 00:11:08 +02:00
vr_opt_frame.grid(pady=0 if not self.chosen_process_method_var.get() == VR_ARCH_PM else 70)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
vr_title = self.menu_title_LABEL_SET(vr_opt_frame, ADVANCED_VR_OPTIONS_TEXT)
vr_title.grid(padx=25, pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
if not self.chosen_process_method_var.get() == VR_ARCH_PM:
2023-09-26 00:11:08 +02:00
window_size_Label = self.menu_sub_LABEL_SET(vr_opt_frame, WINDOW_SIZE_TEXT)
window_size_Label.grid(pady=MENU_PADDING_1)
window_size_Option = ComboBoxEditableMenu(vr_opt_frame, values=VR_WINDOW, width=MENU_COMBOBOX_WIDTH, textvariable=self.window_size_var, pattern=REG_WINDOW, default=VR_WINDOW[1])#
window_size_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(window_size_Label, text=WINDOW_SIZE_HELP)
2023-09-26 00:11:08 +02:00
aggression_setting_Label = self.menu_sub_LABEL_SET(vr_opt_frame, AGGRESSION_SETTING_TEXT)
aggression_setting_Label.grid(pady=MENU_PADDING_1)
aggression_setting_Option = ComboBoxEditableMenu(vr_opt_frame, values=VR_AGGRESSION, width=MENU_COMBOBOX_WIDTH, textvariable=self.aggression_setting_var, pattern=REG_AGGRESSION, default=VR_AGGRESSION[5])#
aggression_setting_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(aggression_setting_Label, text=AGGRESSION_SETTING_HELP)
2023-09-26 00:11:08 +02:00
self.batch_size_Label = self.menu_sub_LABEL_SET(vr_opt_frame, BATCH_SIZE_TEXT)
self.batch_size_Label.grid(pady=MENU_PADDING_1)
self.batch_size_Option = ComboBoxEditableMenu(vr_opt_frame, values=BATCH_SIZE, width=MENU_COMBOBOX_WIDTH, textvariable=self.batch_size_var, pattern=REG_BATCHES, default=BATCH_SIZE)#
self.batch_size_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(self.batch_size_Label, text=BATCH_SIZE_HELP)
2023-09-26 00:11:08 +02:00
self.post_process_threshold_Label = self.menu_sub_LABEL_SET(vr_opt_frame, POST_PROCESS_THRESHOLD_TEXT)
self.post_process_threshold_Label.grid(pady=MENU_PADDING_1)
self.post_process_threshold_Option = ComboBoxEditableMenu(vr_opt_frame, values=POST_PROCESSES_THREASHOLD_VALUES, width=MENU_COMBOBOX_WIDTH, textvariable=self.post_process_threshold_var, pattern=REG_THES_POSTPORCESS, default=POST_PROCESSES_THREASHOLD_VALUES[1])#
self.post_process_threshold_Option.grid(pady=MENU_PADDING_1)
2022-12-21 11:18:16 +01:00
self.help_hints(self.post_process_threshold_Label, text=POST_PROCESS_THREASHOLD_HELP)
2023-09-26 00:11:08 +02:00
self.is_tta_Option = ttk.Checkbutton(vr_opt_frame, text=ENABLE_TTA_TEXT, width=VR_CHECKBOXS_WIDTH, variable=self.is_tta_var)
self.is_tta_Option.grid(pady=0)
2022-12-19 04:18:56 +01:00
self.help_hints(self.is_tta_Option, text=IS_TTA_HELP)
2023-09-26 00:11:08 +02:00
self.is_post_process_Option = ttk.Checkbutton(vr_opt_frame, text=POST_PROCESS_TEXT, width=VR_CHECKBOXS_WIDTH, variable=self.is_post_process_var, command=toggle_post_process)
self.is_post_process_Option.grid(pady=0)
2022-12-19 04:18:56 +01:00
self.help_hints(self.is_post_process_Option, text=IS_POST_PROCESS_HELP)
2023-09-26 00:11:08 +02:00
self.is_high_end_process_Option = ttk.Checkbutton(vr_opt_frame, text=HIGHEND_PROCESS_TEXT, width=VR_CHECKBOXS_WIDTH, variable=self.is_high_end_process_var)
self.is_high_end_process_Option.grid(pady=0)
2022-12-19 04:18:56 +01:00
self.help_hints(self.is_high_end_process_Option, text=IS_HIGH_END_PROCESS_HELP)
2023-09-26 00:11:08 +02:00
self.vocal_splitter_Button_opt(vr_opt, vr_opt_frame, pady=MENU_PADDING_1, width=VR_BUT_WIDTH)
self.vr_clear_cache_Button = ttk.Button(vr_opt_frame, text=CLEAR_AUTOSET_CACHE_TEXT, command=lambda:self.clear_cache(VR_ARCH_TYPE), width=VR_BUT_WIDTH)
self.vr_clear_cache_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(self.vr_clear_cache_Button, text=CLEAR_CACHE_HELP)
2023-09-26 00:11:08 +02:00
self.open_vr_model_dir_Button = ttk.Button(vr_opt_frame, text=OPEN_MODELS_FOLDER_TEXT, command=lambda:OPEN_FILE_func(VR_MODELS_DIR), width=VR_BUT_WIDTH)
self.open_vr_model_dir_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.vr_return_Button=ttk.Button(vr_opt_frame, text=BACK_TO_MAIN_MENU, command=lambda:(self.menu_advanced_vr_options_close_window(), self.check_is_menu_settings_open()))
2023-09-26 00:11:08 +02:00
self.vr_return_Button.grid(pady=MENU_PADDING_1)
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
self.vr_close_Button = ttk.Button(vr_opt_frame, text=CLOSE_WINDOW, command=lambda:self.menu_advanced_vr_options_close_window())
self.vr_close_Button.grid(pady=MENU_PADDING_1)
2022-12-21 11:18:16 +01:00
toggle_post_process()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
frame_list = [vr_opt_frame]
self.menu_placement(vr_opt, ADVANCED_VR_OPTIONS_TEXT, is_help_hints=True, close_function=self.menu_advanced_vr_options_close_window, frame_list=frame_list)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def menu_advanced_demucs_options(self):#**
2022-12-19 04:18:56 +01:00
"""Open Advanced Demucs Options"""
2023-09-26 00:11:08 +02:00
demuc_opt = tk.Toplevel()
2022-12-19 04:18:56 +01:00
self.is_open_menu_advanced_demucs_options.set(True)
self.menu_advanced_demucs_options_close_window = lambda:(self.is_open_menu_advanced_demucs_options.set(False), demuc_opt.destroy())
demuc_opt.protocol("WM_DELETE_WINDOW", self.menu_advanced_demucs_options_close_window)
tab1, tab3 = self.menu_tab_control(demuc_opt, self.demucs_secondary_model_vars, is_demucs=True)
demucs_frame = self.menu_FRAME_SET(tab1)
2023-09-26 00:11:08 +02:00
demucs_frame.grid(pady=0 if not self.chosen_process_method_var.get() == DEMUCS_ARCH_TYPE else 55)
2022-12-19 04:18:56 +01:00
demucs_pre_model_frame = self.menu_FRAME_SET(tab3)
2023-09-26 00:11:08 +02:00
demucs_pre_model_frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
demucs_title_Label = self.menu_title_LABEL_SET(demucs_frame, ADVANCED_DEMUCS_OPTIONS_TEXT)
demucs_title_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
if not self.chosen_process_method_var.get() == DEMUCS_ARCH_TYPE:
2023-09-26 00:11:08 +02:00
segment_Label = self.menu_sub_LABEL_SET(demucs_frame, SEGMENTS_TEXT)
segment_Label.grid(pady=MENU_PADDING_2)
segment_Option = ComboBoxEditableMenu(demucs_frame, values=DEMUCS_SEGMENTS, width=MENU_COMBOBOX_WIDTH, textvariable=self.segment_var, pattern=REG_SEGMENTS, default=DEMUCS_SEGMENTS)#
segment_Option.grid()
2022-12-19 04:18:56 +01:00
self.help_hints(segment_Label, text=SEGMENT_HELP)
2023-09-26 00:11:08 +02:00
self.shifts_Label = self.menu_sub_LABEL_SET(demucs_frame, SHIFTS_TEXT)
self.shifts_Label.grid(pady=MENU_PADDING_1)
self.shifts_Option = ComboBoxEditableMenu(demucs_frame, values=DEMUCS_SHIFTS, width=MENU_COMBOBOX_WIDTH, textvariable=self.shifts_var, pattern=REG_SHIFTS, default=DEMUCS_SHIFTS[2])#
self.shifts_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(self.shifts_Label, text=SHIFTS_HELP)
2023-09-26 00:11:08 +02:00
self.overlap_Label = self.menu_sub_LABEL_SET(demucs_frame, OVERLAP_TEXT)
self.overlap_Label.grid(pady=MENU_PADDING_1)
self.overlap_Option = ComboBoxEditableMenu(demucs_frame, values=DEMUCS_OVERLAP, width=MENU_COMBOBOX_WIDTH, textvariable=self.overlap_var, pattern=REG_OVERLAP, default=DEMUCS_OVERLAP)#
self.overlap_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(self.overlap_Label, text=OVERLAP_HELP)
2023-09-26 00:11:08 +02:00
pitch_shift_Label = self.menu_sub_LABEL_SET(demucs_frame, SHIFT_CONVERSION_PITCH_TEXT)
pitch_shift_Label.grid(pady=MENU_PADDING_1)
pitch_shift_Option = ComboBoxEditableMenu(demucs_frame, values=SEMITONE_SEL, width=MENU_COMBOBOX_WIDTH, textvariable=self.semitone_shift_var, pattern=REG_SEMITONES, default=SEMI_DEF)#
pitch_shift_Option.grid(pady=MENU_PADDING_1)
self.help_hints(pitch_shift_Label, text=PITCH_SHIFT_HELP)
self.is_split_mode_Option = ttk.Checkbutton(demucs_frame, text=SPLIT_MODE_TEXT, width=DEMUCS_CHECKBOXS_WIDTH, variable=self.is_split_mode_var)
self.is_split_mode_Option.grid()
2022-12-19 04:18:56 +01:00
self.help_hints(self.is_split_mode_Option, text=IS_SPLIT_MODE_HELP)
2023-09-26 00:11:08 +02:00
self.is_demucs_combine_stems_Option = ttk.Checkbutton(demucs_frame, text=COMBINE_STEMS_TEXT, width=DEMUCS_CHECKBOXS_WIDTH, variable=self.is_demucs_combine_stems_var)
self.is_demucs_combine_stems_Option.grid()
2022-12-19 04:18:56 +01:00
self.help_hints(self.is_demucs_combine_stems_Option, text=IS_DEMUCS_COMBINE_STEMS_HELP)
2023-09-26 00:11:08 +02:00
is_invert_spec_Option = ttk.Checkbutton(demucs_frame, text=SPECTRAL_INVERSION_TEXT, width=DEMUCS_CHECKBOXS_WIDTH, variable=self.is_invert_spec_var)
is_invert_spec_Option.grid()
2022-12-19 04:18:56 +01:00
self.help_hints(is_invert_spec_Option, text=IS_INVERT_SPEC_HELP)
2023-09-26 00:11:08 +02:00
self.vocal_splitter_Button_opt(demuc_opt, demucs_frame, width=VR_BUT_WIDTH, pady=MENU_PADDING_1)
2023-03-31 12:15:39 +02:00
2023-09-26 00:11:08 +02:00
self.open_demucs_model_dir_Button = ttk.Button(demucs_frame, text=OPEN_MODELS_FOLDER_TEXT, command=lambda:OPEN_FILE_func(DEMUCS_MODELS_DIR), width=VR_BUT_WIDTH)
self.open_demucs_model_dir_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.demucs_return_Button = ttk.Button(demucs_frame, text=BACK_TO_MAIN_MENU, command=lambda:(self.menu_advanced_demucs_options_close_window(), self.check_is_menu_settings_open()))
2023-09-26 00:11:08 +02:00
self.demucs_return_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.demucs_close_Button = ttk.Button(demucs_frame, text=CLOSE_WINDOW, command=lambda:self.menu_advanced_demucs_options_close_window())
self.demucs_close_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
frame_list = [demucs_pre_model_frame, demucs_frame]
self.menu_placement(demuc_opt, ADVANCED_DEMUCS_OPTIONS_TEXT, is_help_hints=True, close_function=self.menu_advanced_demucs_options_close_window, frame_list=frame_list)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def menu_advanced_mdx_options(self):#**
2022-12-19 04:18:56 +01:00
"""Open Advanced MDX Options"""
2023-09-26 00:11:08 +02:00
mdx_net_opt = tk.Toplevel()
2022-12-19 04:18:56 +01:00
self.is_open_menu_advanced_mdx_options.set(True)
self.menu_advanced_mdx_options_close_window = lambda:(self.is_open_menu_advanced_mdx_options.set(False), mdx_net_opt.destroy())
mdx_net_opt.protocol("WM_DELETE_WINDOW", self.menu_advanced_mdx_options_close_window)
2023-09-26 00:11:08 +02:00
tab1, tab3 = self.menu_tab_control(mdx_net_opt, self.mdx_secondary_model_vars, is_mdxnet=True)
2023-03-31 12:15:39 +02:00
2022-12-19 04:18:56 +01:00
mdx_net_frame = self.menu_FRAME_SET(tab1)
2023-09-26 00:11:08 +02:00
mdx_net_frame.grid(pady=0)
mdx_net23_frame = self.menu_FRAME_SET(tab3)
mdx_net23_frame.grid(pady=0)
mdx_opt_title = self.menu_title_LABEL_SET(mdx_net_frame, ADVANCED_MDXNET_OPTIONS_TEXT)
mdx_opt_title.grid(pady=MENU_PADDING_1)
compensate_Label = self.menu_sub_LABEL_SET(mdx_net_frame, VOLUME_COMPENSATION_TEXT)
compensate_Label.grid(pady=MENU_PADDING_4)
compensate_Option = ComboBoxEditableMenu(mdx_net_frame, values=VOL_COMPENSATION, width=MENU_COMBOBOX_WIDTH, textvariable=self.compensate_var, pattern=REG_COMPENSATION, default=VOL_COMPENSATION)#
compensate_Option.grid(pady=MENU_PADDING_4)
self.help_hints(compensate_Label, text=COMPENSATE_HELP)
mdx_segment_size_Label = self.menu_sub_LABEL_SET(mdx_net_frame, SEGMENT_SIZE_TEXT)
mdx_segment_size_Label.grid(pady=MENU_PADDING_4)
mdx_segment_size_Option = ComboBoxEditableMenu(mdx_net_frame, values=MDX_SEGMENTS, width=MENU_COMBOBOX_WIDTH, textvariable=self.mdx_segment_size_var, pattern=REG_MDX_SEG, default="256")#
mdx_segment_size_Option.grid(pady=MENU_PADDING_4)
self.help_hints(mdx_segment_size_Label, text=MDX_SEGMENT_SIZE_HELP)
overlap_mdx_Label = self.menu_sub_LABEL_SET(mdx_net_frame, OVERLAP_TEXT)
overlap_mdx_Label.grid(pady=MENU_PADDING_4)
overlap_mdx_Option = ComboBoxEditableMenu(mdx_net_frame, values=MDX_OVERLAP, width=MENU_COMBOBOX_WIDTH, textvariable=self.overlap_mdx_var, pattern=REG_OVERLAP, default=MDX_OVERLAP)#
overlap_mdx_Option.grid(pady=MENU_PADDING_4)
self.help_hints(overlap_mdx_Label, text=OVERLAP_HELP)
pitch_shift_Label = self.menu_sub_LABEL_SET(mdx_net_frame, SHIFT_CONVERSION_PITCH_TEXT)
pitch_shift_Label.grid(pady=MENU_PADDING_4)
pitch_shift_Option = ComboBoxEditableMenu(mdx_net_frame, values=SEMITONE_SEL, width=MENU_COMBOBOX_WIDTH, textvariable=self.semitone_shift_var, pattern=REG_SEMITONES, default=SEMI_DEF)#
pitch_shift_Option.grid(pady=MENU_PADDING_4)
self.help_hints(pitch_shift_Label, text=PITCH_SHIFT_HELP)
if not os.path.isfile(DENOISER_MODEL_PATH):
denoise_options_var_text = self.denoise_option_var.get()
denoise_options = [option for option in MDX_DENOISE_OPTION if option != DENOISE_M]
self.denoise_option_var.set(DENOISE_S if denoise_options_var_text == DENOISE_M else denoise_options_var_text)
else:
denoise_options = MDX_DENOISE_OPTION
denoise_option_Label = self.menu_sub_LABEL_SET(mdx_net_frame, DENOISE_OUTPUT_TEXT)
denoise_option_Label.grid(pady=MENU_PADDING_4)
denoise_option_Option = ComboBoxMenu(mdx_net_frame, textvariable=self.denoise_option_var, values=denoise_options, width=MENU_COMBOBOX_WIDTH)
denoise_option_Option.grid(pady=MENU_PADDING_4)
self.help_hints(denoise_option_Label, text=IS_DENOISE_HELP)
is_match_frequency_pitch_Option = ttk.Checkbutton(mdx_net_frame, text=MATCH_FREQ_CUTOFF_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_match_frequency_pitch_var)
is_match_frequency_pitch_Option.grid(pady=0)
self.help_hints(is_match_frequency_pitch_Option, text=IS_FREQUENCY_MATCH_HELP)
is_invert_spec_Option = ttk.Checkbutton(mdx_net_frame, text=SPECTRAL_INVERSION_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_invert_spec_var)
is_invert_spec_Option.grid(pady=0)
2022-12-19 04:18:56 +01:00
self.help_hints(is_invert_spec_Option, text=IS_INVERT_SPEC_HELP)
2023-09-26 00:11:08 +02:00
self.vocal_splitter_Button_opt(mdx_net_opt, mdx_net_frame, pady=MENU_PADDING_1, width=VR_BUT_WIDTH)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
clear_mdx_cache_Button = ttk.Button(mdx_net_frame, text=CLEAR_AUTOSET_CACHE_TEXT, command=lambda:self.clear_cache(MDX_ARCH_TYPE), width=VR_BUT_WIDTH)
clear_mdx_cache_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(clear_mdx_cache_Button, text=CLEAR_CACHE_HELP)
2023-09-26 00:11:08 +02:00
open_mdx_model_dir_Button = ttk.Button(mdx_net_frame, text=OPEN_MODELS_FOLDER_TEXT, command=lambda:OPEN_FILE_func(MDX_MODELS_DIR), width=VR_BUT_WIDTH)
open_mdx_model_dir_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
mdx_return_Button = ttk.Button(mdx_net_frame, text=BACK_TO_MAIN_MENU, command=lambda:(self.menu_advanced_mdx_options_close_window(), self.check_is_menu_settings_open()))
2023-09-26 00:11:08 +02:00
mdx_return_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
mdx_close_Button = ttk.Button(mdx_net_frame, text=CLOSE_WINDOW, command=lambda:self.menu_advanced_mdx_options_close_window())
mdx_close_Button.grid(pady=MENU_PADDING_1)
mdx23_opt_title = self.menu_title_LABEL_SET(mdx_net23_frame, ADVANCED_MDXNET23_OPTIONS_TEXT)
mdx23_opt_title.grid(pady=MENU_PADDING_2)
mdx_batch_size_Label = self.menu_sub_LABEL_SET(mdx_net23_frame, BATCH_SIZE_TEXT)
mdx_batch_size_Label.grid(pady=MENU_PADDING_1)
mdx_batch_size_Option = ComboBoxEditableMenu(mdx_net23_frame, values=BATCH_SIZE, width=MENU_COMBOBOX_WIDTH, textvariable=self.mdx_batch_size_var, pattern=REG_BATCHES, default=BATCH_SIZE)#
mdx_batch_size_Option.grid(pady=MENU_PADDING_1)
self.help_hints(mdx_batch_size_Label, text=BATCH_SIZE_HELP)
overlap_mdx23_Label = self.menu_sub_LABEL_SET(mdx_net23_frame, OVERLAP_TEXT)
overlap_mdx23_Label.grid(pady=MENU_PADDING_1)
overlap_mdx23_Option = ComboBoxEditableMenu(mdx_net23_frame, values=MDX23_OVERLAP, width=MENU_COMBOBOX_WIDTH, textvariable=self.overlap_mdx23_var, pattern=REG_OVERLAP23, default="8")#
overlap_mdx23_Option.grid(pady=MENU_PADDING_1)
self.help_hints(overlap_mdx23_Label, text=OVERLAP_23_HELP)
2023-03-31 12:15:39 +02:00
2023-09-26 00:11:08 +02:00
is_mdx_c_seg_def_Option = ttk.Checkbutton(mdx_net23_frame, text=SEGMENT_DEFAULT_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_mdx_c_seg_def_var)
is_mdx_c_seg_def_Option.grid(pady=0)
self.help_hints(is_mdx_c_seg_def_Option, text=IS_SEGMENT_DEFAULT_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_mdx_combine_stems_Option = ttk.Checkbutton(mdx_net23_frame, text=COMBINE_STEMS_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_mdx23_combine_stems_var)
is_mdx_combine_stems_Option.grid()
self.help_hints(is_mdx_combine_stems_Option, text=IS_DEMUCS_COMBINE_STEMS_HELP)
mdx23_close_Button = ttk.Button(mdx_net23_frame, text=CLOSE_WINDOW, command=lambda:self.menu_advanced_mdx_options_close_window())
mdx23_close_Button.grid(pady=MENU_PADDING_2)
frame_list = [mdx_net_frame, mdx_net23_frame]
self.menu_placement(mdx_net_opt, ADVANCED_MDXNET_OPTIONS_TEXT, is_help_hints=True, close_function=self.menu_advanced_mdx_options_close_window, frame_list=frame_list)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def menu_advanced_ensemble_options(self):#**
2022-12-19 04:18:56 +01:00
"""Open Ensemble Custom"""
2023-09-26 00:11:08 +02:00
custom_ens_opt = tk.Toplevel()
2022-12-19 04:18:56 +01:00
self.is_open_menu_advanced_ensemble_options.set(True)
self.menu_advanced_ensemble_options_close_window = lambda:(self.is_open_menu_advanced_ensemble_options.set(False), custom_ens_opt.destroy())
custom_ens_opt.protocol("WM_DELETE_WINDOW", self.menu_advanced_ensemble_options_close_window)
option_var = tk.StringVar(value=SELECT_SAVED_ENSEMBLE)
custom_ens_opt_frame = self.menu_FRAME_SET(custom_ens_opt)
2023-09-26 00:11:08 +02:00
custom_ens_opt_frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
settings_title_Label = self.menu_title_LABEL_SET(custom_ens_opt_frame, ADVANCED_OPTION_MENU_TEXT)
settings_title_Label.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
delete_entry_Label = self.menu_sub_LABEL_SET(custom_ens_opt_frame, REMOVE_SAVED_ENSEMBLE_TEXT)
delete_entry_Label.grid(pady=MENU_PADDING_1)
delete_entry_Option = ComboBoxMenu(custom_ens_opt_frame, textvariable=option_var, width=ENSEMBLE_CHECKBOXS_WIDTH+2)
delete_entry_Option.grid(padx=20,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_save_all_outputs_ensemble_Option = ttk.Checkbutton(custom_ens_opt_frame, text=SAVE_ALL_OUTPUTS_TEXT, width=ENSEMBLE_CHECKBOXS_WIDTH, variable=self.is_save_all_outputs_ensemble_var)
is_save_all_outputs_ensemble_Option.grid(pady=0)
2022-12-19 04:18:56 +01:00
self.help_hints(is_save_all_outputs_ensemble_Option, text=IS_SAVE_ALL_OUTPUTS_ENSEMBLE_HELP)
2023-09-26 00:11:08 +02:00
is_append_ensemble_name_Option = ttk.Checkbutton(custom_ens_opt_frame, text=APPEND_ENSEMBLE_NAME_TEXT, width=ENSEMBLE_CHECKBOXS_WIDTH, variable=self.is_append_ensemble_name_var)
is_append_ensemble_name_Option.grid(pady=0)
2022-12-19 04:18:56 +01:00
self.help_hints(is_append_ensemble_name_Option, text=IS_APPEND_ENSEMBLE_NAME_HELP)
2023-09-26 00:11:08 +02:00
is_wav_ensemble_Option = ttk.Checkbutton(custom_ens_opt_frame, text=ENSEMBLE_WAVFORMS_TEXT, width=ENSEMBLE_CHECKBOXS_WIDTH, variable=self.is_wav_ensemble_var)
is_wav_ensemble_Option.grid(pady=0)
self.help_hints(is_wav_ensemble_Option, text=IS_WAV_ENSEMBLE_HELP)
ensemble_return_Button = ttk.Button(custom_ens_opt_frame, text=BACK_TO_MAIN_MENU, command=lambda:(self.menu_advanced_ensemble_options_close_window(), self.check_is_menu_settings_open()))
ensemble_return_Button.grid(pady=MENU_PADDING_1)
ensemble_close_Button = ttk.Button(custom_ens_opt_frame, text=CLOSE_WINDOW, command=lambda:self.menu_advanced_ensemble_options_close_window())
ensemble_close_Button.grid(pady=MENU_PADDING_1)
self.deletion_list_fill(delete_entry_Option, option_var, ENSEMBLE_CACHE_DIR, SELECT_SAVED_ENSEMBLE, menu_name='deleteensemble')
self.menu_placement(custom_ens_opt, ADVANCED_ENSEMBLE_OPTIONS_TEXT, is_help_hints=True, close_function=self.menu_advanced_ensemble_options_close_window)
def menu_advanced_align_options(self):#**
"""Open Ensemble Custom"""
advanced_align_opt = tk.Toplevel()
self.is_open_menu_advanced_align_options.set(True)
self.menu_advanced_align_options_close_window = lambda:(self.is_open_menu_advanced_align_options.set(False), advanced_align_opt.destroy())
advanced_align_opt.protocol("WM_DELETE_WINDOW", self.menu_advanced_align_options_close_window)
advanced_align_opt_frame = self.menu_FRAME_SET(advanced_align_opt)
advanced_align_opt_frame.grid(row=0)
settings_title_Label = self.menu_title_LABEL_SET(advanced_align_opt_frame, ADVANCED_ALIGN_TOOL_OPTIONS_TEXT)
settings_title_Label.grid(pady=MENU_PADDING_2)
phase_option_Label = self.menu_sub_LABEL_SET(advanced_align_opt_frame, SECONDARY_PHASE_TEXT)
phase_option_Label.grid(pady=4)
phase_option_Option = ComboBoxMenu(advanced_align_opt_frame, textvariable=self.phase_option_var, values=ALIGN_PHASE_OPTIONS, width=MENU_COMBOBOX_WIDTH)
phase_option_Option.grid(pady=4)
self.help_hints(phase_option_Label, text=IS_PHASE_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
phase_shifts_Label = self.menu_sub_LABEL_SET(advanced_align_opt_frame, PHASE_SHIFTS_TEXT)
phase_shifts_Label.grid(pady=4)#
phase_shifts_Option = ComboBoxMenu(advanced_align_opt_frame, textvariable=self.phase_shifts_var, values=list(PHASE_SHIFTS_OPT.keys()), width=MENU_COMBOBOX_WIDTH)
phase_shifts_Option.grid(pady=4)
self.help_hints(phase_shifts_Label, text=PHASE_SHIFTS_ALIGN_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_save_align_Option = ttk.Checkbutton(advanced_align_opt_frame, text=SAVE_ALIGNED_TRACK_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_save_align_var)
is_save_align_Option.grid(pady=0)
self.help_hints(is_save_align_Option, text=IS_ALIGN_TRACK_HELP)
is_match_silence_Option = ttk.Checkbutton(advanced_align_opt_frame, text=SILENCE_MATCHING_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_match_silence_var)
is_match_silence_Option.grid(pady=0)
self.help_hints(is_match_silence_Option, text=IS_MATCH_SILENCE_HELP)
is_spec_match_Option = ttk.Checkbutton(advanced_align_opt_frame, text=SPECTRAL_MATCHING_TEXT, width=MDX_CHECKBOXS_WIDTH, variable=self.is_spec_match_var)
is_spec_match_Option.grid(pady=0)
self.help_hints(is_spec_match_Option, text=IS_MATCH_SPEC_HELP)
ensemble_return_Button = ttk.Button(advanced_align_opt_frame, text=BACK_TO_MAIN_MENU, command=lambda:(self.menu_advanced_align_options_close_window(), self.check_is_menu_settings_open()))
ensemble_return_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
ensemble_close_Button = ttk.Button(advanced_align_opt_frame, text=CLOSE_WINDOW, command=lambda:self.menu_advanced_align_options_close_window())
ensemble_close_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(advanced_align_opt, ADVANCED_ALIGN_TOOL_OPTIONS_TEXT, is_help_hints=True, close_function=self.menu_advanced_align_options_close_window)
def menu_help(self):#**
2022-12-19 04:18:56 +01:00
"""Open Help Guide"""
2023-09-26 00:11:08 +02:00
help_guide_opt = tk.Toplevel()
2022-12-19 04:18:56 +01:00
self.is_open_menu_help.set(True)
self.menu_help_close_window = lambda:(self.is_open_menu_help.set(False), help_guide_opt.destroy())
help_guide_opt.protocol("WM_DELETE_WINDOW", self.menu_help_close_window)
tabControl = ttk.Notebook(help_guide_opt)
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tab3 = ttk.Frame(tabControl)
tab4 = ttk.Frame(tabControl)
tabControl.add(tab1, text ='Credits')
tabControl.add(tab2, text ='Resources')
tabControl.add(tab3, text ='Application License & Version Information')
2023-09-26 01:50:23 +02:00
tabControl.add(tab4, text ='Additional Information')
2022-12-19 04:18:56 +01:00
tabControl.pack(expand = 1, fill ="both")
tab1.grid_rowconfigure(0, weight=1)
tab1.grid_columnconfigure(0, weight=1)
tab2.grid_rowconfigure(0, weight=1)
tab2.grid_columnconfigure(0, weight=1)
tab3.grid_rowconfigure(0, weight=1)
tab3.grid_columnconfigure(0, weight=1)
tab4.grid_rowconfigure(0, weight=1)
tab4.grid_columnconfigure(0, weight=1)
2023-09-26 00:11:08 +02:00
section_title_Label = lambda place, frame, text, font_size=FONT_SIZE_4: tk.Label(master=frame, text=text,font=(MAIN_FONT_NAME, f"{font_size}", "bold"), justify="center", fg="#F4F4F4").grid(row=place,column=0,padx=0,pady=MENU_PADDING_4)
description_Label = lambda place, frame, text, font=FONT_SIZE_2: tk.Label(master=frame, text=text, font=(MAIN_FONT_NAME, f"{font}"), justify="center", fg="#F6F6F7").grid(row=place,column=0,padx=0,pady=MENU_PADDING_4)
2022-12-19 04:18:56 +01:00
def credit_label(place, frame, text, link=None, message=None, is_link=False, is_top=False):
if is_top:
2022-12-29 00:48:28 +01:00
thank = tk.Label(master=frame, text=text, font=(MAIN_FONT_NAME, f"{FONT_SIZE_3}", "bold"), justify="center", fg="#13849f")
2022-12-19 04:18:56 +01:00
else:
2022-12-29 00:48:28 +01:00
thank = tk.Label(master=frame, text=text, font=(MAIN_FONT_NAME, f"{FONT_SIZE_3}", "underline" if is_link else "normal"), justify="center", fg="#13849f")
2022-12-19 04:18:56 +01:00
thank.configure(cursor="hand2") if is_link else None
thank.grid(row=place,column=0,padx=0,pady=1)
if link:
thank.bind("<Button-1>", lambda e:webbrowser.open_new_tab(link))
if message:
description_Label(place+1, frame, message)
2022-12-21 11:18:16 +01:00
def Link(place, frame, text, link, description, font=FONT_SIZE_2):
2023-09-26 00:11:08 +02:00
link_label = tk.Label(master=frame, text=text, font=(MAIN_FONT_NAME, f"{FONT_SIZE_4}", "underline"), foreground=FG_COLOR, justify="center", cursor="hand2")
link_label.grid(row=place,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
link_label.bind("<Button-1>", lambda e:webbrowser.open_new_tab(link))
description_Label(place+1, frame, description, font=font)
def right_click_menu(event):
2023-09-26 00:11:08 +02:00
right_click_menu = tk.Menu(self, font=(MAIN_FONT_NAME, FONT_SIZE_1), tearoff=0)
2022-12-19 04:18:56 +01:00
right_click_menu.add_command(label='Return to Settings Menu', command=lambda:(self.menu_help_close_window(), self.check_is_menu_settings_open()))
right_click_menu.add_command(label='Exit Window', command=lambda:self.menu_help_close_window())
try:
right_click_menu.tk_popup(event.x_root,event.y_root)
2022-12-30 12:49:26 +01:00
right_click_release_linux(right_click_menu, help_guide_opt)
2022-12-19 04:18:56 +01:00
finally:
right_click_menu.grab_release()
2022-12-21 11:18:16 +01:00
help_guide_opt.bind(right_click_button, lambda e:right_click_menu(e))
2023-09-26 00:11:08 +02:00
credits_Frame = tk.Frame(tab1, highlightthicknes=50)
2022-12-19 04:18:56 +01:00
credits_Frame.grid(row=0, column=0, padx=0, pady=0)
2023-09-26 00:11:08 +02:00
tk.Label(credits_Frame, image=self.credits_img).grid(row=1,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
section_title_Label(place=0,
frame=credits_Frame,
text="Core UVR Developers")
credit_label(place=2,
frame=credits_Frame,
text="Anjok07\nAufr33",
is_top=True)
section_title_Label(place=3,
frame=credits_Frame,
text="Special Thanks")
credit_label(place=6,
frame=credits_Frame,
text="Tsurumeso",
message="Developed the original VR Architecture AI code.",
link="https://github.com/tsurumeso/vocal-remover",
is_link=True)
credit_label(place=8,
frame=credits_Frame,
text="Kuielab & Woosung Choi",
message="Developed the original MDX-Net AI code.",
link="https://github.com/kuielab",
is_link=True)
credit_label(place=10,
frame=credits_Frame,
text="Adefossez & Demucs",
message="Core developer of Facebook's Demucs Music Source Separation.",
link="https://github.com/facebookresearch/demucs",
is_link=True)
credit_label(place=12,
frame=credits_Frame,
text="Bas Curtiz",
message="Designed the official UVR logo, icon, banner, splash screen.")
credit_label(place=14,
frame=credits_Frame,
text="DilanBoskan",
message="Your contributions at the start of this project were essential to the success of UVR. Thank you!")
credit_label(place=16,
frame=credits_Frame,
2023-04-16 22:55:23 +02:00
text="Audio Separation and CC Karaoke & Friends Discord Communities",
2022-12-19 04:18:56 +01:00
message="Thank you for the support!")
2023-09-26 00:11:08 +02:00
more_info_tab_Frame = tk.Frame(tab2, highlightthicknes=30)
2022-12-19 04:18:56 +01:00
more_info_tab_Frame.grid(row=0,column=0,padx=0,pady=0)
section_title_Label(place=3,
frame=more_info_tab_Frame,
text="Resources")
Link(place=4,
frame=more_info_tab_Frame,
text="Ultimate Vocal Remover (Official GitHub)",
link="https://github.com/Anjok07/ultimatevocalremovergui",
description="You can find updates, report issues, and give us a shout via our official GitHub.",
2023-09-26 00:11:08 +02:00
font=FONT_SIZE_1)
2022-12-19 04:18:56 +01:00
Link(place=8,
frame=more_info_tab_Frame,
text="X-Minus AI",
link="https://x-minus.pro/ai",
description="Many of the models provided are also on X-Minus.\n" + \
"X-Minus benefits users without the computing resources to run the GUI or models locally.",
2023-09-26 00:11:08 +02:00
font=FONT_SIZE_1)
2022-12-19 04:18:56 +01:00
Link(place=12,
2022-12-27 11:31:41 +01:00
frame=more_info_tab_Frame,
text="MVSep",
link="https://mvsep.com/quality_checker/leaderboard.php",
description="Some of our models are also on MVSep.\n" + \
2023-09-26 00:11:08 +02:00
"Click the link above for a list of some of the best settings \nand model combinations recorded by fellow UVR users.\nSpecial thanks to ZFTurbo for all his work on MVSep!",
font=FONT_SIZE_1)
2022-12-27 11:31:41 +01:00
Link(place=18,
2022-12-19 04:18:56 +01:00
frame=more_info_tab_Frame,
text="FFmpeg",
link="https://www.wikihow.com/Install-FFmpeg-on-Windows",
description="UVR relies on FFmpeg for processing non-wav audio files.\n" + \
"If you are missing FFmpeg, please see the installation guide via the link provided.",
2023-09-26 00:11:08 +02:00
font=FONT_SIZE_1)
2022-12-19 04:18:56 +01:00
2022-12-27 11:31:41 +01:00
Link(place=22,
2022-12-19 04:18:56 +01:00
frame=more_info_tab_Frame,
text="Rubber Band Library",
link="https://breakfastquay.com/rubberband/",
description="UVR uses the Rubber Band library for the sound stretch and pitch shift tool.\n" + \
"You can get more information on it via the link provided.",
2023-09-26 00:11:08 +02:00
font=FONT_SIZE_1)
2022-12-19 04:18:56 +01:00
2022-12-27 11:31:41 +01:00
Link(place=26,
2022-12-19 04:18:56 +01:00
frame=more_info_tab_Frame,
2023-09-26 00:11:08 +02:00
text="Matchering",
link="https://github.com/sergree/matchering",
description="UVR uses the Matchering library for the \"Matchering\" Audio Tool.\n" + \
"You can get more information on it via the link provided.",
font=FONT_SIZE_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
Link(place=30,
frame=more_info_tab_Frame,
text="Official UVR BMAC",
link=DONATE_LINK_BMAC,
description="If you wish to support and donate to this project, click the link above!",
font=FONT_SIZE_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
appplication_license_tab_Frame = tk.Frame(tab3)
2022-12-19 04:18:56 +01:00
appplication_license_tab_Frame.grid(row=0,column=0,padx=0,pady=0)
2022-12-29 00:48:28 +01:00
appplication_license_Label = tk.Label(appplication_license_tab_Frame, text='UVR License Information', font=(MAIN_FONT_NAME, f"{FONT_SIZE_6}", "bold"), justify="center", fg="#f4f4f4")
2022-12-19 04:18:56 +01:00
appplication_license_Label.grid(row=0,column=0,padx=0,pady=25)
2023-09-26 00:11:08 +02:00
appplication_license_Text = tk.Text(appplication_license_tab_Frame, font=(MAIN_FONT_NAME, f"{FONT_SIZE_4}"), fg="white", bg="black", width=72, wrap=tk.WORD, borderwidth=0)
2022-12-19 04:18:56 +01:00
appplication_license_Text.grid(row=1,column=0,padx=0,pady=0)
2023-09-26 00:11:08 +02:00
appplication_license_Text_scroll = ttk.Scrollbar(appplication_license_tab_Frame, orient=tk.VERTICAL)
2022-12-19 04:18:56 +01:00
appplication_license_Text.config(yscrollcommand=appplication_license_Text_scroll.set)
appplication_license_Text_scroll.configure(command=appplication_license_Text.yview)
2023-09-26 00:11:08 +02:00
appplication_license_Text.grid(row=4,sticky=tk.W)
appplication_license_Text_scroll.grid(row=4, column=1, sticky=tk.NS)
2022-12-30 04:07:23 +01:00
appplication_license_Text.insert("insert", LICENSE_TEXT(VERSION, current_patch))
2022-12-19 04:18:56 +01:00
appplication_license_Text.configure(state=tk.DISABLED)
2023-09-26 00:11:08 +02:00
application_change_log_tab_Frame = tk.Frame(tab4)
2022-12-19 04:18:56 +01:00
application_change_log_tab_Frame.grid(row=0,column=0,padx=0,pady=0)
2022-12-30 04:07:23 +01:00
2023-09-26 01:50:23 +02:00
application_change_log_Label = tk.Label(application_change_log_tab_Frame, text='Additional Information', font=(MAIN_FONT_NAME, f"{FONT_SIZE_6}", "bold"), justify="center", fg="#f4f4f4")
2022-12-19 04:18:56 +01:00
application_change_log_Label.grid(row=0,column=0,padx=0,pady=25)
2023-09-27 04:54:09 +02:00
application_change_log_Text = tk.Text(application_change_log_tab_Frame, font=(MAIN_FONT_NAME, f"{FONT_SIZE_4}"), fg="white", bg="black", width=72, wrap=tk.WORD, borderwidth=0)
2023-09-26 00:11:08 +02:00
application_change_log_Text.grid(row=1,column=0,padx=40 if is_macos else 30,pady=0)
application_change_log_Text_scroll = ttk.Scrollbar(application_change_log_tab_Frame, orient=tk.VERTICAL)
2022-12-19 04:18:56 +01:00
application_change_log_Text.config(yscrollcommand=application_change_log_Text_scroll.set)
application_change_log_Text_scroll.configure(command=application_change_log_Text.yview)
2023-09-26 00:11:08 +02:00
application_change_log_Text.grid(row=4,sticky=tk.W)
application_change_log_Text_scroll.grid(row=4, column=1, sticky=tk.NS)
application_change_log_Text.insert("insert", self.bulletin_data)
auto_hyperlink(application_change_log_Text)
2022-12-19 04:18:56 +01:00
application_change_log_Text.configure(state=tk.DISABLED)
self.menu_placement(help_guide_opt, "Information Guide")
2023-09-26 00:11:08 +02:00
def menu_error_log(self):#
2022-12-19 04:18:56 +01:00
"""Open Error Log"""
self.is_confirm_error_var.set(False)
2022-12-21 11:18:16 +01:00
copied_var = tk.StringVar(value='')
2023-09-26 00:11:08 +02:00
error_log_screen = tk.Toplevel()
2022-12-19 04:18:56 +01:00
self.is_open_menu_error_log.set(True)
self.menu_error_log_close_window = lambda:(self.is_open_menu_error_log.set(False), error_log_screen.destroy())
error_log_screen.protocol("WM_DELETE_WINDOW", self.menu_error_log_close_window)
error_log_frame = self.menu_FRAME_SET(error_log_screen)
2023-09-26 00:11:08 +02:00
error_log_frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
error_consol_title_Label = self.menu_title_LABEL_SET(error_log_frame, ERROR_CONSOLE_TEXT)
error_consol_title_Label.grid(row=1,column=0,padx=20,pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
error_details_Text = tk.Text(error_log_frame, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), fg="#D37B7B", bg="black", width=110, wrap=tk.WORD, borderwidth=0)
error_details_Text.grid(row=2,column=0,padx=0,pady=0)
2022-12-19 04:18:56 +01:00
error_details_Text.insert("insert", self.error_log_var.get())
2022-12-21 11:18:16 +01:00
error_details_Text.bind(right_click_button, lambda e:self.right_click_menu_popup(e, text_box=True))
2022-12-19 04:18:56 +01:00
self.current_text_box = error_details_Text
2023-09-26 00:11:08 +02:00
error_details_Text_scroll = ttk.Scrollbar(error_log_frame, orient=tk.VERTICAL)
2022-12-19 04:18:56 +01:00
error_details_Text.config(yscrollcommand=error_details_Text_scroll.set)
error_details_Text_scroll.configure(command=error_details_Text.yview)
2023-09-26 00:11:08 +02:00
error_details_Text.grid(row=2,sticky=tk.W)
error_details_Text_scroll.grid(row=2, column=1, sticky=tk.NS)
2022-12-19 04:18:56 +01:00
2022-12-29 00:48:28 +01:00
copy_text_Label = tk.Label(error_log_frame, textvariable=copied_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_0}"), justify="center", fg="#f4f4f4")
2023-09-26 00:11:08 +02:00
copy_text_Label.grid(padx=20,pady=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
copy_text_Button = ttk.Button(error_log_frame, text=COPY_ALL_TEXT_TEXT, width=14, command=lambda:(pyperclip.copy(error_details_Text.get(1.0, tk.END+"-1c")), copied_var.set('Copied!')))
copy_text_Button.grid(padx=20,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
report_issue_Button = ttk.Button(error_log_frame, text=REPORT_ISSUE_TEXT, width=14, command=lambda:webbrowser.open_new_tab(ISSUE_LINK))
report_issue_Button.grid(padx=20,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
error_log_return_Button = ttk.Button(error_log_frame, text=BACK_TO_MAIN_MENU, command=lambda:(self.menu_error_log_close_window(), self.menu_settings()))
error_log_return_Button.grid(padx=20,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
error_log_close_Button = ttk.Button(error_log_frame, text=CLOSE_WINDOW, command=lambda:self.menu_error_log_close_window())
error_log_close_Button.grid(padx=20,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(error_log_screen, UVR_ERROR_LOG_TEXT)
2022-12-19 04:18:56 +01:00
def menu_secondary_model(self, tab, ai_network_vars: dict):
#Settings Tab 1
secondary_model_Frame = self.menu_FRAME_SET(tab)
2023-09-26 00:11:08 +02:00
secondary_model_Frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
settings_title_Label = self.menu_title_LABEL_SET(secondary_model_Frame, SECONDARY_MODEL_TEXT)
settings_title_Label.grid(row=0,column=0,padx=0,pady=MENU_PADDING_3)
2022-12-19 04:18:56 +01:00
voc_inst_list = self.model_list(VOCAL_STEM, INST_STEM, is_dry_check=True)
other_list = self.model_list(OTHER_STEM, NO_OTHER_STEM, is_dry_check=True)
bass_list = self.model_list(BASS_STEM, NO_BASS_STEM, is_dry_check=True)
drum_list = self.model_list(DRUM_STEM, NO_DRUM_STEM, is_dry_check=True)
voc_inst_secondary_model_var = ai_network_vars["voc_inst_secondary_model"]
other_secondary_model_var = ai_network_vars["other_secondary_model"]
bass_secondary_model_var = ai_network_vars["bass_secondary_model"]
drums_secondary_model_var = ai_network_vars["drums_secondary_model"]
voc_inst_secondary_model_scale_var = ai_network_vars['voc_inst_secondary_model_scale']
other_secondary_model_scale_var = ai_network_vars['other_secondary_model_scale']
bass_secondary_model_scale_var = ai_network_vars['bass_secondary_model_scale']
drums_secondary_model_scale_var = ai_network_vars['drums_secondary_model_scale']
is_secondary_model_activate_var = ai_network_vars["is_secondary_model_activate"]
2023-09-26 00:11:08 +02:00
change_state_lambda = lambda:change_state(tk.NORMAL if is_secondary_model_activate_var.get() else tk.DISABLED)
2022-12-19 04:18:56 +01:00
init_convert_to_percentage = lambda raw_value:f"{int(float(raw_value)*100)}%"
voc_inst_secondary_model_scale_LABEL_var = tk.StringVar(value=init_convert_to_percentage(voc_inst_secondary_model_scale_var.get()))
other_secondary_model_scale_LABEL_var = tk.StringVar(value=init_convert_to_percentage(other_secondary_model_scale_var.get()))
bass_secondary_model_scale_LABEL_var = tk.StringVar(value=init_convert_to_percentage(bass_secondary_model_scale_var.get()))
drums_secondary_model_scale_LABEL_var = tk.StringVar(value=init_convert_to_percentage(drums_secondary_model_scale_var.get()))
def change_state(change_state):
for child_widget in secondary_model_Frame.winfo_children():
2023-09-26 00:11:08 +02:00
if type(child_widget) is ComboBoxMenu:
change_state = READ_ONLY if change_state == tk.NORMAL else change_state
2022-12-19 04:18:56 +01:00
child_widget.configure(state=change_state)
2023-09-26 00:11:08 +02:00
elif type(child_widget) is ttk.Scale:
child_widget.configure(state=change_state)
2022-12-19 04:18:56 +01:00
def convert_to_percentage(raw_value, scale_var: tk.StringVar, label_var: tk.StringVar):
raw_value = '%0.2f' % float(raw_value)
scale_var.set(raw_value)
label_var.set(f"{int(float(raw_value)*100)}%")
2023-09-26 00:11:08 +02:00
def build_widgets(stem_pair: str, model_list: list, option_var: tk.StringVar, label_var: tk.StringVar, scale_var: tk.DoubleVar):
model_list.insert(0, NO_MODEL)
2022-12-21 11:18:16 +01:00
secondary_model_Label = self.menu_sub_LABEL_SET(secondary_model_Frame, f'{stem_pair}', font_size=FONT_SIZE_3)
2023-09-26 00:11:08 +02:00
secondary_model_Label.grid(pady=MENU_PADDING_1)
secondary_model_Option = ComboBoxMenu(secondary_model_Frame, textvariable=option_var, values=model_list, dropdown_name=stem_pair, offset=310, width=READ_ONLY_COMBO_WIDTH)
secondary_model_Option.grid(pady=MENU_PADDING_1)
secondary_scale_info_Label = tk.Label(secondary_model_Frame, textvariable=label_var, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground=FG_COLOR)
secondary_scale_info_Label.grid(pady=0)
2022-12-19 04:18:56 +01:00
secondary_model_scale_Option = ttk.Scale(secondary_model_Frame, variable=scale_var, from_=0.01, to=0.99, command=lambda s:convert_to_percentage(s, scale_var, label_var), orient='horizontal')
2023-09-26 00:11:08 +02:00
secondary_model_scale_Option.grid(pady=2)
2022-12-19 04:18:56 +01:00
self.help_hints(secondary_model_Label, text=SECONDARY_MODEL_HELP)
self.help_hints(secondary_scale_info_Label, text=SECONDARY_MODEL_SCALE_HELP)
build_widgets(stem_pair=VOCAL_PAIR,
model_list=voc_inst_list,
option_var=voc_inst_secondary_model_var,
label_var=voc_inst_secondary_model_scale_LABEL_var,
2023-09-26 00:11:08 +02:00
scale_var=voc_inst_secondary_model_scale_var)
2022-12-19 04:18:56 +01:00
build_widgets(stem_pair=OTHER_PAIR,
model_list=other_list,
option_var=other_secondary_model_var,
label_var=other_secondary_model_scale_LABEL_var,
2023-09-26 00:11:08 +02:00
scale_var=other_secondary_model_scale_var)
2022-12-19 04:18:56 +01:00
build_widgets(stem_pair=BASS_PAIR,
model_list=bass_list,
option_var=bass_secondary_model_var,
label_var=bass_secondary_model_scale_LABEL_var,
2023-09-26 00:11:08 +02:00
scale_var=bass_secondary_model_scale_var)
2022-12-19 04:18:56 +01:00
build_widgets(stem_pair=DRUM_PAIR,
model_list=drum_list,
option_var=drums_secondary_model_var,
label_var=drums_secondary_model_scale_LABEL_var,
2023-09-26 00:11:08 +02:00
scale_var=drums_secondary_model_scale_var)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
is_secondary_model_activate_Option = ttk.Checkbutton(secondary_model_Frame, text=ACTIVATE_SECONDARY_MODEL_TEXT, variable=is_secondary_model_activate_var, command=change_state_lambda)
is_secondary_model_activate_Option.grid(row=21,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(is_secondary_model_activate_Option, text=SECONDARY_MODEL_ACTIVATE_HELP)
change_state_lambda()
2023-09-26 00:11:08 +02:00
self.change_state_lambda = change_state_lambda
def menu_preproc_model(self, tab):
preproc_model_Frame = self.menu_FRAME_SET(tab)
preproc_model_Frame.grid(row=0)
demucs_pre_proc_model_title_Label = self.menu_title_LABEL_SET(preproc_model_Frame, PREPROCESS_MODEL_CHOOSE_TEXT)
demucs_pre_proc_model_title_Label.grid(pady=MENU_PADDING_3)
pre_proc_list = self.model_list(VOCAL_STEM, INST_STEM, is_dry_check=True, is_no_demucs=True)
pre_proc_list.insert(0, NO_MODEL)
enable_pre_proc_model = lambda:(is_demucs_pre_proc_model_inst_mix_Option.configure(state=tk.NORMAL), demucs_pre_proc_model_Option.configure(state=READ_ONLY))
disable_pre_proc_model = lambda:(is_demucs_pre_proc_model_inst_mix_Option.configure(state=tk.DISABLED), demucs_pre_proc_model_Option.configure(state=tk.DISABLED), self.is_demucs_pre_proc_model_inst_mix_var.set(False))
pre_proc_model_toggle = lambda:enable_pre_proc_model() if self.is_demucs_pre_proc_model_activate_var.get() else disable_pre_proc_model()
demucs_pre_proc_model_Label = self.menu_sub_LABEL_SET(preproc_model_Frame, SELECT_MODEL_TEXT, font_size=FONT_SIZE_3)
demucs_pre_proc_model_Label.grid()
demucs_pre_proc_model_Option = ComboBoxMenu(preproc_model_Frame, textvariable=self.demucs_pre_proc_model_var, values=pre_proc_list, dropdown_name='demucspre', offset=310, width=READ_ONLY_COMBO_WIDTH)
demucs_pre_proc_model_Option.grid(pady=MENU_PADDING_2)
is_demucs_pre_proc_model_inst_mix_Option = ttk.Checkbutton(preproc_model_Frame, text='Save Instrumental Mixture', width=DEMUCS_PRE_CHECKBOXS_WIDTH, variable=self.is_demucs_pre_proc_model_inst_mix_var)
is_demucs_pre_proc_model_inst_mix_Option.grid()
self.help_hints(is_demucs_pre_proc_model_inst_mix_Option, text=PRE_PROC_MODEL_INST_MIX_HELP)
is_demucs_pre_proc_model_activate_Option = ttk.Checkbutton(preproc_model_Frame, text=ACTIVATE_PRE_PROCESS_MODEL_TEXT, width=DEMUCS_PRE_CHECKBOXS_WIDTH, variable=self.is_demucs_pre_proc_model_activate_var, command=pre_proc_model_toggle)
is_demucs_pre_proc_model_activate_Option.grid()
self.help_hints(is_demucs_pre_proc_model_activate_Option, text=PRE_PROC_MODEL_ACTIVATE_HELP)
pre_proc_model_toggle()
2022-12-21 11:18:16 +01:00
def menu_manual_downloads(self):
2023-09-26 00:11:08 +02:00
manual_downloads_menu = tk.Toplevel()
model_selection_var = tk.StringVar(value=SELECT_MODEL_TEXT)
#info_text_var = tk.StringVar(value='')
if self.is_online:
model_data = self.online_data
# Save the data as a JSON file
with open(DOWNLOAD_MODEL_CACHE, 'w') as json_file:
json.dump(model_data, json_file)
else:
if os.path.isfile(DOWNLOAD_MODEL_CACHE):
with open(DOWNLOAD_MODEL_CACHE, 'r') as json_file:
model_data = json.load(json_file)
vr_download_list = model_data["vr_download_list"]
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"])
2022-12-21 11:18:16 +01:00
def create_link(link):
final_link = lambda:webbrowser.open_new_tab(link)
return final_link
def get_links():
for widgets in manual_downloads_link_Frame.winfo_children():
widgets.destroy()
main_selection = model_selection_var.get()
MAIN_ROW = 0
2023-09-26 00:11:08 +02:00
self.menu_sub_LABEL_SET(manual_downloads_link_Frame, 'Download Link(s)').grid(row=0,column=0,padx=0,pady=MENU_PADDING_4)
2022-12-21 11:18:16 +01:00
if VR_ARCH_TYPE in main_selection:
2023-09-26 00:11:08 +02:00
main_selection = vr_download_list[main_selection]
2022-12-31 11:31:10 +01:00
model_dir = VR_MODELS_DIR
2023-09-26 00:11:08 +02:00
elif MDX_ARCH_TYPE in main_selection or MDX_23_NAME in main_selection:
if isinstance(mdx_download_list[main_selection], dict):
main_selection = mdx_download_list[main_selection]
main_selection = list(main_selection.keys())[0]
else:
main_selection = mdx_download_list[main_selection]
2022-12-31 11:31:10 +01:00
model_dir = MDX_MODELS_DIR
2023-09-26 00:11:08 +02:00
2022-12-21 11:18:16 +01:00
elif DEMUCS_ARCH_TYPE in main_selection:
2022-12-31 11:31:10 +01:00
model_dir = DEMUCS_NEWER_REPO_DIR if 'v3' in main_selection or 'v4' in main_selection else DEMUCS_MODELS_DIR
2023-09-26 00:11:08 +02:00
main_selection = demucs_download_list[main_selection]
2022-12-31 11:31:10 +01:00
2022-12-21 11:18:16 +01:00
if type(main_selection) is dict:
for links in main_selection.values():
MAIN_ROW += 1
button_text = f" - Item {MAIN_ROW}" if len(main_selection.keys()) >= 2 else ''
link = create_link(links)
2023-09-26 00:11:08 +02:00
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)
2022-12-21 11:18:16 +01:00
else:
link = f"{NORMAL_REPO}{main_selection}"
2023-09-26 00:11:08 +02:00
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)
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
self.menu_sub_LABEL_SET(manual_downloads_link_Frame, SELECTED_MODEL_PLACE_PATH_TEXT).grid(row=MAIN_ROW+2,column=0,padx=0,pady=MENU_PADDING_4)
ttk.Button(manual_downloads_link_Frame, text=OPEN_MODEL_DIRECTORY_TEXT, command=lambda:OPEN_FILE_func(model_dir)).grid(row=MAIN_ROW+3,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-21 11:18:16 +01:00
manual_downloads_menu_Frame = self.menu_FRAME_SET(manual_downloads_menu)
2023-09-26 00:11:08 +02:00
manual_downloads_menu_Frame.grid(row=0)
2022-12-21 11:18:16 +01:00
manual_downloads_link_Frame = self.menu_FRAME_SET(manual_downloads_menu, thickness=5)
2023-09-26 00:11:08 +02:00
manual_downloads_link_Frame.grid(row=1)
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
manual_downloads_menu_title_Label = self.menu_title_LABEL_SET(manual_downloads_menu_Frame, MANUAL_DOWNLOADS_TEXT, width=45)
manual_downloads_menu_title_Label.grid(row=0,column=0,padx=0,pady=MENU_PADDING_3)
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
manual_downloads_menu_select_Label = self.menu_sub_LABEL_SET(manual_downloads_menu_Frame, SELECT_MODEL_TEXT)
manual_downloads_menu_select_Label.grid(row=1,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-21 11:18:16 +01:00
manual_downloads_menu_select_Option = ttk.OptionMenu(manual_downloads_menu_Frame, model_selection_var)
manual_downloads_menu_select_VR_Option = tk.Menu(manual_downloads_menu_select_Option['menu'])
manual_downloads_menu_select_MDX_Option = tk.Menu(manual_downloads_menu_select_Option['menu'])
manual_downloads_menu_select_DEMUCS_Option = tk.Menu(manual_downloads_menu_select_Option['menu'])
manual_downloads_menu_select_Option['menu'].add_cascade(label='VR Models', menu= manual_downloads_menu_select_VR_Option)
manual_downloads_menu_select_Option['menu'].add_cascade(label='MDX-Net Models', menu= manual_downloads_menu_select_MDX_Option)
manual_downloads_menu_select_Option['menu'].add_cascade(label='Demucs Models', menu= manual_downloads_menu_select_DEMUCS_Option)
2023-09-26 00:11:08 +02:00
for model_selection_vr in vr_download_list.keys():
if not os.path.isfile(os.path.join(VR_MODELS_DIR, vr_download_list[model_selection_vr])):
manual_downloads_menu_select_VR_Option.add_radiobutton(label=model_selection_vr, variable=model_selection_var, command=get_links)
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
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}"
config_local = os.path.join(MDX_C_CONFIG_PATH, config)
if not os.path.isfile(config_local):
try:
with urllib.request.urlopen(config_link) as response:
with open(config_local, 'wb') as out_file:
out_file.write(response.read())
except Exception as e:
model_name = None
#print(model_name)
if model_name:
if not os.path.isfile(os.path.join(MDX_MODELS_DIR, model_name)):
manual_downloads_menu_select_MDX_Option.add_radiobutton(label=model_selection_mdx, variable=model_selection_var, command=get_links)
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
for model_selection_demucs in demucs_download_list.keys():
2022-12-21 11:18:16 +01:00
manual_downloads_menu_select_DEMUCS_Option.add_radiobutton(label=model_selection_demucs, variable=model_selection_var, command=get_links)
2023-09-26 00:11:08 +02:00
manual_downloads_menu_select_Option.grid(row=2,column=0,padx=0,pady=MENU_PADDING_1)
self.menu_placement(manual_downloads_menu, MANUAL_DOWNLOADS_TEXT, pop_up=True, close_function=lambda:manual_downloads_menu.destroy())
def invalid_tooltip(self, widget, pattern=None):
tooltip = ToolTip(widget)
invalid_message = lambda:tooltip.showtip(INVALID_INPUT_E, True)
def invalid_message_():
tooltip.showtip(INVALID_INPUT_E, True)
def validation(value):
if re.fullmatch(modified_pattern, value) is None:
return False
else:
return True
if not pattern:
pattern = r'^[a-zA-Z0-9 -]{0,25}$'
modified_pattern = f"({pattern}|)"
widget.configure(
validate='key',
validatecommand=(self.register(validation), '%P'),
invalidcommand=(self.register(invalid_message))
)
return invalid_message_
2022-12-21 11:18:16 +01:00
2022-12-19 04:18:56 +01:00
def pop_up_save_current_settings(self):
"""Save current application settings as..."""
2023-09-26 00:11:08 +02:00
settings_save = tk.Toplevel(root)
2022-12-19 04:18:56 +01:00
2022-12-21 11:18:16 +01:00
settings_save_var = tk.StringVar(value='')
2022-12-19 04:18:56 +01:00
settings_save_Frame = self.menu_FRAME_SET(settings_save)
2023-09-26 00:11:08 +02:00
settings_save_Frame.grid(row=1)
2022-12-19 04:18:56 +01:00
save_func = lambda:(self.pop_up_save_current_settings_sub_json_dump(settings_save_var.get()), settings_save.destroy())
2023-09-26 00:11:08 +02:00
validation = lambda value:False if re.fullmatch(REG_SAVE_INPUT, value) is None else True
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
settings_save_title = self.menu_title_LABEL_SET(settings_save_Frame, SAVE_CURRENT_SETTINGS_TEXT)
settings_save_title.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
settings_save_name_Label = self.menu_sub_LABEL_SET(settings_save_Frame, NAME_SETTINGS_TEXT)
settings_save_name_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
settings_save_name_Entry = ttk.Entry(settings_save_Frame, textvariable=settings_save_var, justify='center', width=25)
2023-09-26 00:11:08 +02:00
settings_save_name_Entry.grid(pady=MENU_PADDING_1)
invalid_message = self.invalid_tooltip(settings_save_name_Entry)
2022-12-21 11:18:16 +01:00
settings_save_name_Entry.bind(right_click_button, self.right_click_menu_popup)
2022-12-19 04:18:56 +01:00
self.current_text_box = settings_save_name_Entry
2023-09-26 00:11:08 +02:00
settings_save_name_Entry.focus_set()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.spacer_label(settings_save_Frame)
2022-12-19 04:18:56 +01:00
2022-12-29 00:48:28 +01:00
entry_rules_Label = tk.Label(settings_save_Frame, text=ENSEMBLE_INPUT_RULE, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground='#868687', justify="left")
2023-09-26 00:11:08 +02:00
entry_rules_Label.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
settings_save_Button = ttk.Button(settings_save_Frame, text=SAVE_TEXT, command=lambda:save_func() if validation(settings_save_var.get()) else invalid_message())
settings_save_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
stop_process_Button = ttk.Button(settings_save_Frame, text=CANCEL_TEXT, command=lambda:settings_save.destroy())
stop_process_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(settings_save, SAVE_CURRENT_SETTINGS_TEXT, pop_up=True)
2022-12-19 04:18:56 +01:00
def pop_up_save_current_settings_sub_json_dump(self, settings_save_name: str):
"""Dumps current application settings to a json named after user input"""
if settings_save_name:
self.save_current_settings_var.set(settings_save_name)
settings_save_name = settings_save_name.replace(" ", "_")
current_settings = self.save_values(app_close=False)
saved_data_dump = json.dumps(current_settings, indent=4)
with open(os.path.join(SETTINGS_CACHE_DIR, f'{settings_save_name}.json'), "w") as outfile:
outfile.write(saved_data_dump)
def pop_up_update_confirmation(self):
"""Ask user is they want to update"""
is_new_update = self.online_data_refresh(confirmation_box=True)
2022-12-27 11:31:41 +01:00
is_download_in_app_var = tk.BooleanVar(value=False)
2022-12-19 04:18:56 +01:00
2022-12-27 11:31:41 +01:00
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())
update_confirmation_win.destroy()
2022-12-19 04:18:56 +01:00
if is_new_update:
2023-09-26 00:11:08 +02:00
update_confirmation_win = tk.Toplevel()
2022-12-27 11:31:41 +01:00
2022-12-19 04:18:56 +01:00
update_confirmation_Frame = self.menu_FRAME_SET(update_confirmation_win)
2023-09-26 00:11:08 +02:00
update_confirmation_Frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
update_found_label = self.menu_title_LABEL_SET(update_confirmation_Frame, UPDATE_FOUND_TEXT, width=15)
update_found_label.grid(row=0,column=0,padx=0,pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
confirm_update_label = self.menu_sub_LABEL_SET(update_confirmation_Frame, UPDATE_CONFIRMATION_TEXT, font_size=FONT_SIZE_3)
confirm_update_label.grid(row=1,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
yes_button = ttk.Button(update_confirmation_Frame, text=YES_TEXT, command=update_type)
yes_button.grid(row=2,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
2022-12-29 00:53:15 +01:00
if is_windows:
download_outside_application_button = ttk.Checkbutton(update_confirmation_Frame, variable=is_download_in_app_var, text='Download Update in Application')
2023-09-26 00:11:08 +02:00
download_outside_application_button.grid(row=4,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-29 00:53:15 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(update_confirmation_win, CONFIRM_UPDATE_TEXT, pop_up=True)
2022-12-19 04:18:56 +01:00
def pop_up_user_code_input(self):
"""Input VIP Code"""
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
self.user_code_validation_var.set('')
2023-09-26 00:11:08 +02:00
self.user_code = tk.Toplevel()
2022-12-19 04:18:56 +01:00
user_code_Frame = self.menu_FRAME_SET(self.user_code)
2023-09-26 00:11:08 +02:00
user_code_Frame.grid(row=0)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
user_code_title_Label = self.menu_title_LABEL_SET(user_code_Frame, USER_DOWNLOAD_CODES_TEXT, width=20)
user_code_title_Label.grid(row=0,column=0,padx=0,pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
user_code_Label = self.menu_sub_LABEL_SET(user_code_Frame, DOWNLOAD_CODE_TEXT)
user_code_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.user_code_Entry = ttk.Entry(user_code_Frame, textvariable=self.user_code_var, justify='center')
2023-09-26 00:11:08 +02:00
self.user_code_Entry.grid(pady=MENU_PADDING_1)
2022-12-21 11:18:16 +01:00
self.user_code_Entry.bind(right_click_button, self.right_click_menu_popup)
2022-12-19 04:18:56 +01:00
self.current_text_box = self.user_code_Entry
2023-09-26 00:11:08 +02:00
tooltip = ToolTip(self.user_code_Entry)
def invalid_message_(text, is_success_message):
tooltip.hidetip()
tooltip.showtip(text, True, is_success_message)
self.spacer_label(user_code_Frame)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
user_code_confrim_Button = ttk.Button(user_code_Frame, text=CONFIRM_TEXT, command=lambda:self.download_validate_code(confirm=True, code_message=invalid_message_))
user_code_confrim_Button.grid(pady=MENU_PADDING_1)
user_code_cancel_Button = ttk.Button(user_code_Frame, text=CANCEL_TEXT, command=lambda:self.user_code.destroy())
user_code_cancel_Button.grid(pady=MENU_PADDING_1)
support_title_Label = self.menu_title_LABEL_SET(user_code_Frame, text=SUPPORT_UVR_TEXT, width=20)
support_title_Label.grid(pady=MENU_PADDING_1)
support_sub_Label = tk.Label(user_code_Frame, text=GET_DL_VIP_CODE_TEXT, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground=FG_COLOR)
support_sub_Label.grid(pady=MENU_PADDING_1)
uvr_patreon_Button = ttk.Button(user_code_Frame, text=UVR_PATREON_LINK_TEXT, command=lambda:webbrowser.open_new_tab(DONATE_LINK_PATREON))
uvr_patreon_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
bmac_patreon_Button=ttk.Button(user_code_Frame, text=BMAC_UVR_TEXT, command=lambda:webbrowser.open_new_tab(DONATE_LINK_BMAC))
bmac_patreon_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(self.user_code, INPUT_CODE_TEXT, pop_up=True)
def pop_up_change_model_defaults(self, top_window):
"""
Change model defaults...
"""
def message_box_(text, is_success_message):
tooltip.hidetip()
tooltip.showtip(text, True, is_success_message)
def delete_entry():
model_data = self.assemble_model_data(model=change_model_defaults_var.get(), arch_type=ENSEMBLE_CHECK, is_change_def=True, is_get_hash_dir_only=True)[0]
hash_file = model_data.model_hash_dir
if hash_file:
if os.path.isfile(hash_file):
os.remove(hash_file)
message_box_("Defined Parameters Deleted", True)
else:
message_box_("No Defined Parameters Found", False)
self.update_checkbox_text()
def change_default():
model_data = self.assemble_model_data(model=change_model_defaults_var.get(), arch_type=ENSEMBLE_CHECK, is_change_def=True)[0]
if model_data.model_status:
message_box_("Model Parameters Changed", True)
self.update_checkbox_text()
change_model_defaults = tk.Toplevel(root)
change_model_defaults_var = tk.StringVar(value=NO_MODEL)
default_change_model_list = list(self.default_change_model_list)
default_change_model_list.insert(0, NO_MODEL)
change_model_defaults_Frame = self.menu_FRAME_SET(change_model_defaults)
change_model_defaults_Frame.grid(row=1)
change_model_defaults_title = self.menu_title_LABEL_SET(change_model_defaults_Frame, CHANGE_MODEL_DEFAULT_TEXT)
change_model_defaults_title.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
model_param_Label = self.menu_sub_LABEL_SET(change_model_defaults_Frame, SELECT_MODEL_TEXT)
model_param_Label.grid(pady=MENU_PADDING_1)
model_param_Option = ComboBoxMenu(change_model_defaults_Frame, dropdown_name='changemodeldefault', textvariable=change_model_defaults_var, values=default_change_model_list, offset=310, width=READ_ONLY_COMBO_WIDTH)
model_param_Option.grid(pady=MENU_PADDING_1)
tooltip = ToolTip(model_param_Option)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.spacer_label(change_model_defaults_Frame)
change_params_Button = ttk.Button(change_model_defaults_Frame, text=CHANGE_PARAMETERS_TEXT, command=change_default, width=20)
change_params_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
delete_params_Button = ttk.Button(change_model_defaults_Frame, text=DELETE_PARAMETERS_TEXT, command=delete_entry, width=20)
delete_params_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
cancel_Button = ttk.Button(change_model_defaults_Frame, text=CANCEL_TEXT, command=lambda:change_model_defaults.destroy())
cancel_Button.grid(pady=MENU_PADDING_1)
self.menu_placement(change_model_defaults, CHANGE_MODEL_DEFAULT_TEXT, top_window=top_window)
def pop_up_set_vocal_splitter(self, top_window):
"""
Set vocal splitter
"""
try:
set_vocal_splitter = tk.Toplevel(root)
model_list = self.assemble_model_data(arch_type=KARAOKEE_CHECK, is_dry_check=True)
if not model_list:
self.set_vocal_splitter_var.set(NO_MODEL)
model_list.insert(0, NO_MODEL)
enable_voc_split_model = lambda:(model_select_Option.configure(state=READ_ONLY), save_inst_Button.configure(state=tk.NORMAL))
disable_voc_split_model = lambda:(model_select_Option.configure(state=tk.DISABLED), save_inst_Button.configure(state=tk.DISABLED), self.is_save_inst_set_vocal_splitter_var.set(False))
voc_split_model_toggle = lambda:enable_voc_split_model() if self.is_set_vocal_splitter_var.get() else disable_voc_split_model()
enable_deverb_opt = lambda:(deverb_vocals_Option.configure(state=READ_ONLY))
disable_deverb_opt= lambda:(deverb_vocals_Option.configure(state=tk.DISABLED))
deverb_opt_toggle = lambda:enable_deverb_opt() if self.is_deverb_vocals_var.get() else disable_deverb_opt()
set_vocal_splitter_Frame = self.menu_FRAME_SET(set_vocal_splitter)
set_vocal_splitter_Frame.grid(row=1)
set_vocal_splitter_title = self.menu_title_LABEL_SET(set_vocal_splitter_Frame, VOCAL_SPLIT_MODE_OPTIONS_TEXT)
set_vocal_splitter_title.grid(pady=MENU_PADDING_2)
model_select_Label = self.menu_sub_LABEL_SET(set_vocal_splitter_Frame, SELECT_MODEL_TEXT)
model_select_Label.grid(pady=MENU_PADDING_1)
model_select_Option = ComboBoxMenu(set_vocal_splitter_Frame, dropdown_name='setvocalsplit', textvariable=self.set_vocal_splitter_var, values=model_list, offset=310, width=READ_ONLY_COMBO_WIDTH)
model_select_Option.grid(pady=7)
self.help_hints(model_select_Option, text=VOC_SPLIT_MODEL_SELECT_HELP)#
save_inst_Button = ttk.Checkbutton(set_vocal_splitter_Frame, text=SAVE_SPLIT_VOCAL_INSTRUMENTALS_TEXT, variable=self.is_save_inst_set_vocal_splitter_var, width=SET_VOC_SPLIT_CHECK_WIDTH, command=voc_split_model_toggle)
save_inst_Button.grid()#
self.help_hints(save_inst_Button, text=IS_VOC_SPLIT_INST_SAVE_SELECT_HELP)#
change_params_Button = ttk.Checkbutton(set_vocal_splitter_Frame, text=ENABLE_VOCAL_SPLIT_MODE_TEXT, variable=self.is_set_vocal_splitter_var, width=SET_VOC_SPLIT_CHECK_WIDTH, command=voc_split_model_toggle)
change_params_Button.grid()#
self.help_hints(change_params_Button, text=IS_VOC_SPLIT_MODEL_SELECT_HELP)#
set_vocal_splitter_title = self.menu_title_LABEL_SET(set_vocal_splitter_Frame, VOCAL_DEVERB_OPTIONS_TEXT)
set_vocal_splitter_title.grid(pady=MENU_PADDING_2)
deverb_vocals_Label = self.menu_sub_LABEL_SET(set_vocal_splitter_Frame, 'Select Vocal Type to Deverb')
deverb_vocals_Label.grid(pady=MENU_PADDING_1)
deverb_vocals_Option = ComboBoxMenu(set_vocal_splitter_Frame, dropdown_name='setvocaldeverb', textvariable=self.deverb_vocal_opt_var, values=list(DEVERB_MAPPER.keys()), width=23)
deverb_vocals_Option.grid(pady=7)
self.help_hints(deverb_vocals_Option, text=IS_DEVERB_OPT_HELP)#
is_deverb_vocals_Option = ttk.Checkbutton(set_vocal_splitter_Frame, text=DEVERB_VOCALS_TEXT, width=15 if is_windows else 11, variable=self.is_deverb_vocals_var, command=deverb_opt_toggle)
is_deverb_vocals_Option.grid(pady=0)
self.help_hints(is_deverb_vocals_Option, text=IS_DEVERB_VOC_HELP)#
if not os.path.isfile(DEVERBER_MODEL_PATH):
self.is_deverb_vocals_var.set(False)
is_deverb_vocals_Option.configure(state=tk.DISABLED)
disable_deverb_opt()
cancel_Button = ttk.Button(set_vocal_splitter_Frame, text=CLOSE_WINDOW, command=lambda:set_vocal_splitter.destroy(), width=16)
cancel_Button.grid(pady=MENU_PADDING_3)
voc_split_model_toggle()
deverb_opt_toggle()
self.menu_placement(set_vocal_splitter, VOCAL_SPLIT_OPTIONS_TEXT, top_window=top_window, pop_up=True)
except Exception as e:
error_name = f'{type(e).__name__}'
traceback_text = ''.join(traceback.format_tb(e.__traceback__))
message = f'{error_name}: "{e}"\n{traceback_text}"'
self.error_log_var.set(message)
2022-12-19 04:18:56 +01:00
def pop_up_mdx_model(self, mdx_model_hash, model_path):
"""Opens MDX-Net model settings"""
2023-09-26 00:11:08 +02:00
2023-03-31 12:15:39 +02:00
is_compatible_model = True
is_ckpt = False
primary_stem = VOCAL_STEM
2022-12-19 04:18:56 +01:00
2022-12-27 11:31:41 +01:00
try:
2023-03-31 12:15:39 +02:00
if model_path.endswith(ONNX):
model = onnx.load(model_path)
model_shapes = [[d.dim_value for d in _input.type.tensor_type.shape.dim] for _input in model.graph.input][0]
dim_f = model_shapes[2]
dim_t = int(math.log(model_shapes[3], 2))
n_fft = '6144'
2023-09-26 00:11:08 +02:00
2023-03-31 12:15:39 +02:00
if model_path.endswith(CKPT):
is_ckpt = True
2023-09-26 00:11:08 +02:00
model_params = torch.load(model_path, map_location=lambda storage, loc: storage)
model_params = model_params['hyper_parameters']
2023-03-31 12:15:39 +02:00
dim_f = model_params['dim_f']
dim_t = int(math.log(model_params['dim_t'], 2))
n_fft = model_params['n_fft']
for stem in STEM_SET_MENU:
if model_params['target_name'] == stem.lower():
primary_stem = INST_STEM if model_params['target_name'] == OTHER_STEM.lower() else stem
2022-12-27 11:31:41 +01:00
except Exception as e:
2023-09-26 00:11:08 +02:00
error_name = f'{type(e).__name__}'
traceback_text = ''.join(traceback.format_tb(e.__traceback__))
message = f'{error_name}: "{e}"\n{traceback_text}"'
#self.error_log_var.set(message)
2023-03-31 12:15:39 +02:00
is_compatible_model = False
2023-09-26 00:11:08 +02:00
if is_ckpt:
self.pop_up_mdx_c_param(mdx_model_hash)
else:
dim_f = 0
dim_t = 0
self.error_dialoge(INVALID_ONNX_MODEL_ERROR)
self.error_log_var.set("{}".format(error_text('MDX-Net Model Settings', e)))
self.mdx_model_params = None
2023-03-31 12:15:39 +02:00
if is_compatible_model:
2023-09-26 00:11:08 +02:00
mdx_model_set = tk.Toplevel(root)
2023-03-31 12:15:39 +02:00
mdx_n_fft_scale_set_var = tk.StringVar(value=n_fft)
2022-12-27 11:31:41 +01:00
mdx_dim_f_set_var = tk.StringVar(value=dim_f)
mdx_dim_t_set_var = tk.StringVar(value=dim_t)
2023-03-31 12:15:39 +02:00
primary_stem_var = tk.StringVar(value=primary_stem)
2022-12-27 11:31:41 +01:00
mdx_compensate_var = tk.StringVar(value=1.035)
2023-09-26 00:11:08 +02:00
balance_value_var = tk.StringVar(value=0)
is_kara_model_var = tk.BooleanVar(value=False)
is_bv_model_var = tk.BooleanVar(value=False)
def toggle_kara():
if is_kara_model_var.get():
is_bv_model_var.set(False)
balance_value_Option.configure(state=tk.DISABLED)
def toggle_bv():
if is_bv_model_var.get():
is_kara_model_var.set(False)
balance_value_Option.configure(state=READ_ONLY)
else:
balance_value_Option.configure(state=tk.DISABLED)
def opt_menu_selection(selection):
if not selection in [VOCAL_STEM, INST_STEM]:
balance_value_Option.configure(state=tk.DISABLED)
is_kara_model_Option.configure(state=tk.DISABLED)
is_bv_model_Option.configure(state=tk.DISABLED)
is_kara_model_var.set(False)
is_bv_model_var.set(False)
balance_value_var.set(0)
else:
is_kara_model_Option.configure(state=tk.NORMAL)
is_bv_model_Option.configure(state=tk.NORMAL)
2022-12-19 04:18:56 +01:00
2022-12-27 11:31:41 +01:00
mdx_model_set_Frame = self.menu_FRAME_SET(mdx_model_set)
2023-09-26 00:11:08 +02:00
mdx_model_set_Frame.grid(row=2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
mdx_model_set_title = self.menu_title_LABEL_SET(mdx_model_set_Frame, SPECIFY_MDX_NET_MODEL_PARAMETERS_TEXT)
mdx_model_set_title.grid(pady=MENU_PADDING_3)
2022-12-27 11:31:41 +01:00
2023-09-26 00:11:08 +02:00
set_stem_name_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, PRIMARY_STEM_TEXT)
set_stem_name_Label.grid(pady=MENU_PADDING_1)
set_stem_name_Option = ttk.OptionMenu(mdx_model_set_Frame, primary_stem_var, None, *STEM_SET_MENU, command=opt_menu_selection)
set_stem_name_Option.configure(width=15)
set_stem_name_Option.grid(pady=MENU_PADDING_1)
set_stem_name_Option['menu'].insert_separator(len(STEM_SET_MENU))
set_stem_name_Option['menu'].add_radiobutton(label=INPUT_STEM_NAME, command=tk._setit(primary_stem_var, INPUT_STEM_NAME, lambda e:self.pop_up_input_stem_name(primary_stem_var, mdx_model_set)))
2022-12-27 11:31:41 +01:00
self.help_hints(set_stem_name_Label, text=SET_STEM_NAME_HELP)
2023-09-26 00:11:08 +02:00
is_kara_model_Option = ttk.Checkbutton(mdx_model_set_Frame, text=KARAOKE_MODEL_TEXT, width=SET_MENUS_CHECK_WIDTH, variable=is_kara_model_var, command=toggle_kara)
is_kara_model_Option.grid(pady=0)
is_bv_model_Option = ttk.Checkbutton(mdx_model_set_Frame, text=BV_MODEL_TEXT, width=SET_MENUS_CHECK_WIDTH, variable=is_bv_model_var, command=toggle_bv)
is_bv_model_Option.grid(pady=0)
balance_value_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, BALANCE_VALUE_TEXT)
balance_value_Label.grid(pady=MENU_PADDING_1)
balance_value_Option = ComboBoxMenu(mdx_model_set_Frame, textvariable=balance_value_var, values=BALANCE_VALUES, width=COMBO_WIDTH)
balance_value_Option.configure(state=tk.DISABLED)
balance_value_Option.grid(pady=MENU_PADDING_1)
#self.help_hints(balance_value_Label, text=balance_value_HELP)
2022-12-27 11:31:41 +01:00
mdx_dim_t_set_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, 'Dim_t')
2023-09-26 00:11:08 +02:00
mdx_dim_t_set_Label.grid(pady=MENU_PADDING_1)
mdx_dim_f_set_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, MDX_MENU_WAR_TEXT)
mdx_dim_f_set_Label.grid(pady=MENU_PADDING_1)
mdx_dim_t_set_Option = ComboBoxEditableMenu(mdx_model_set_Frame, values=('7', '8'), textvariable=mdx_dim_t_set_var, pattern=REG_SHIFTS, default=mdx_dim_t_set_var.get(), width=COMBO_WIDTH, is_stay_disabled=is_ckpt)
mdx_dim_t_set_Option.grid(pady=MENU_PADDING_1)
2022-12-27 11:31:41 +01:00
self.help_hints(mdx_dim_t_set_Label, text=MDX_DIM_T_SET_HELP)
mdx_dim_f_set_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, 'Dim_f')
2023-09-26 00:11:08 +02:00
mdx_dim_f_set_Label.grid(pady=MENU_PADDING_1)
mdx_dim_f_set_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, MDX_MENU_WAR_TEXT)
mdx_dim_f_set_Label.grid(pady=MENU_PADDING_1)
mdx_dim_f_set_Option = ComboBoxEditableMenu(mdx_model_set_Frame, values=(MDX_POP_DIMF), textvariable=mdx_dim_f_set_var, pattern=REG_SHIFTS, default=mdx_dim_f_set_var.get(), width=COMBO_WIDTH, is_stay_disabled=is_ckpt)
mdx_dim_f_set_Option.grid(pady=MENU_PADDING_1)
2022-12-27 11:31:41 +01:00
self.help_hints(mdx_dim_f_set_Label, text=MDX_DIM_F_SET_HELP)
mdx_n_fft_scale_set_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, 'N_FFT Scale')
2023-09-26 00:11:08 +02:00
mdx_n_fft_scale_set_Label.grid(pady=MENU_PADDING_1)
mdx_n_fft_scale_set_Option = ComboBoxEditableMenu(mdx_model_set_Frame, values=(MDX_POP_NFFT), textvariable=mdx_n_fft_scale_set_var, pattern=REG_SHIFTS, default=mdx_n_fft_scale_set_var.get(), width=COMBO_WIDTH, is_stay_disabled=is_ckpt)
mdx_n_fft_scale_set_Option.grid(pady=MENU_PADDING_1)
2022-12-27 11:31:41 +01:00
self.help_hints(mdx_n_fft_scale_set_Label, text=MDX_N_FFT_SCALE_SET_HELP)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
mdx_compensate_Label = self.menu_sub_LABEL_SET(mdx_model_set_Frame, VOLUME_COMPENSATION_TEXT)
mdx_compensate_Label.grid(pady=MENU_PADDING_1)
mdx_compensate_Entry = ComboBoxEditableMenu(mdx_model_set_Frame, values=('1.035', '1.08'), textvariable=mdx_compensate_var, pattern=REG_VOL_COMP, default=mdx_compensate_var.get(), width=COMBO_WIDTH)
mdx_compensate_Entry.grid(pady=MENU_PADDING_1)
2022-12-27 11:31:41 +01:00
self.help_hints(mdx_compensate_Label, text=POPUP_COMPENSATE_HELP)
2023-09-26 00:11:08 +02:00
mdx_param_set_Button = ttk.Button(mdx_model_set_Frame, text=CONFIRM_TEXT, command=lambda:pull_data())
mdx_param_set_Button.grid(pady=MENU_PADDING_2)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
stop_process_Button = ttk.Button(mdx_model_set_Frame, text=CANCEL_TEXT, command=lambda:cancel())
stop_process_Button.grid(pady=0)
2022-12-27 11:31:41 +01:00
2023-03-31 12:15:39 +02:00
if is_ckpt:
2023-09-26 00:11:08 +02:00
mdx_dim_t_set_Option.configure(state=tk.DISABLED)
mdx_dim_f_set_Option.configure(state=tk.DISABLED)
mdx_n_fft_scale_set_Option.configure(state=tk.DISABLED)
2023-03-31 12:15:39 +02:00
2022-12-27 11:31:41 +01:00
def pull_data():
mdx_model_params = {
'compensate': float(mdx_compensate_var.get()),
'mdx_dim_f_set': int(mdx_dim_f_set_var.get()),
'mdx_dim_t_set': int(mdx_dim_t_set_var.get()),
'mdx_n_fft_scale_set': int(mdx_n_fft_scale_set_var.get()),
2023-09-26 00:11:08 +02:00
'primary_stem': primary_stem_var.get(),
IS_KARAOKEE: bool(is_kara_model_var.get()),
IS_BV_MODEL: bool(is_bv_model_var.get()),
IS_BV_MODEL_REBAL: float(balance_value_var.get())
2022-12-27 11:31:41 +01:00
}
self.pop_up_mdx_model_sub_json_dump(mdx_model_params, mdx_model_hash)
mdx_model_set.destroy()
def cancel():
mdx_model_set.destroy()
mdx_model_set.protocol("WM_DELETE_WINDOW", cancel)
2023-09-26 00:11:08 +02:00
frame_list = [mdx_model_set_Frame]
opt_menu_selection(primary_stem_var.get())
self.menu_placement(mdx_model_set, SPECIFY_PARAMETERS_TEXT, pop_up=False if is_macos else True, frame_list=frame_list)
2022-12-19 04:18:56 +01:00
def pop_up_mdx_model_sub_json_dump(self, mdx_model_params, mdx_model_hash):
"""Dumps current selected MDX-Net model settings to a json named after model hash"""
self.mdx_model_params = mdx_model_params
mdx_model_params_dump = json.dumps(mdx_model_params, indent=4)
with open(os.path.join(MDX_HASH_DIR, f'{mdx_model_hash}.json'), "w") as outfile:
outfile.write(mdx_model_params_dump)
2023-09-26 00:11:08 +02:00
def pop_up_mdx_c_param(self, mdx_model_hash):
"""Opens MDX-C param settings"""
mdx_c_param_menu = tk.Toplevel()
get_mdx_c_params = lambda dir, ext:tuple(os.path.splitext(x)[0] for x in os.listdir(dir) if x.endswith(ext))
new_mdx_c_params = get_mdx_c_params(MDX_C_CONFIG_PATH, YAML)
mdx_c_model_param_var = tk.StringVar(value=NONE_SELECTED)
def pull_data():
mdx_c_model_params = {
'config_yaml': f"{mdx_c_model_param_var.get()}{YAML}"}
if not mdx_c_model_param_var.get() == NONE_SELECTED:
self.pop_up_mdx_model_sub_json_dump(mdx_c_model_params, mdx_model_hash)
mdx_c_param_menu.destroy()
else:
self.mdx_model_params = None
def cancel():
self.mdx_model_params = None
mdx_c_param_menu.destroy()
mdx_c_param_Frame = self.menu_FRAME_SET(mdx_c_param_menu)
mdx_c_param_Frame.grid(row=0)
mdx_c_param_title_title = self.menu_title_LABEL_SET(mdx_c_param_Frame, MDXNET_C_MODEL_PARAMETERS_TEXT, width=28)
mdx_c_param_title_title.grid(row=0,column=0,padx=0,pady=0)
mdx_c_model_param_Label = self.menu_sub_LABEL_SET(mdx_c_param_Frame, SELECT_MODEL_PARAM_TEXT)
mdx_c_model_param_Label.grid(pady=MENU_PADDING_1)
mdx_c_model_param_Option = ComboBoxMenu(mdx_c_param_Frame, textvariable=mdx_c_model_param_var, values=new_mdx_c_params, width=30)
mdx_c_model_param_Option.grid(padx=20,pady=MENU_PADDING_1)
self.help_hints(mdx_c_model_param_Label, text=VR_MODEL_PARAM_HELP)
mdx_c_param_confrim_Button = ttk.Button(mdx_c_param_Frame, text=CONFIRM_TEXT, command=lambda:pull_data())
mdx_c_param_confrim_Button.grid(pady=MENU_PADDING_1)
mdx_c_param_cancel_Button = ttk.Button(mdx_c_param_Frame, text=CANCEL_TEXT, command=cancel)
mdx_c_param_cancel_Button.grid(pady=MENU_PADDING_1)
mdx_c_param_menu.protocol("WM_DELETE_WINDOW", cancel)
self.menu_placement(mdx_c_param_menu, CHOOSE_MODEL_PARAM_TEXT, pop_up=True)
2022-12-19 04:18:56 +01:00
def pop_up_vr_param(self, vr_model_hash):
"""Opens VR param settings"""
2023-09-26 00:11:08 +02:00
vr_param_menu = tk.Toplevel()
2022-12-19 04:18:56 +01:00
get_vr_params = lambda dir, ext:tuple(os.path.splitext(x)[0] for x in os.listdir(dir) if x.endswith(ext))
2023-03-31 12:15:39 +02:00
new_vr_params = get_vr_params(VR_PARAM_DIR, JSON)
2023-09-26 00:11:08 +02:00
vr_model_param_var = tk.StringVar(value=NONE_SELECTED)
2022-12-19 04:18:56 +01:00
vr_model_stem_var = tk.StringVar(value='Vocals')
2023-09-26 00:11:08 +02:00
vr_model_nout_var = tk.StringVar(value=32)
vr_model_nout_lstm_var = tk.StringVar(value=128)
is_new_vr_model_var = tk.BooleanVar(value=False)
balance_value_var = tk.StringVar(value=0)
is_kara_model_var = tk.BooleanVar(value=False)
is_bv_model_var = tk.BooleanVar(value=False)
enable_new_vr_op = lambda:(vr_model_nout_Option.configure(state=READ_ONLY), vr_model_nout_lstm_Option.configure(state=READ_ONLY))
disable_new_vr_op = lambda:(vr_model_nout_Option.configure(state=tk.DISABLED), vr_model_nout_lstm_Option.configure(state=tk.DISABLED))
vr_new_toggle = lambda:enable_new_vr_op() if is_new_vr_model_var.get() else disable_new_vr_op()
2022-12-19 04:18:56 +01:00
def pull_data():
2023-09-26 00:11:08 +02:00
if is_new_vr_model_var.get():
vr_model_params = {
'vr_model_param': vr_model_param_var.get(),
'primary_stem': vr_model_stem_var.get(),
'nout': int(vr_model_nout_var.get()),
'nout_lstm': int(vr_model_nout_lstm_var.get()),
IS_KARAOKEE: bool(is_kara_model_var.get()),
IS_BV_MODEL: bool(is_bv_model_var.get()),
IS_BV_MODEL_REBAL: float(balance_value_var.get())
}
else:
vr_model_params = {
'vr_model_param': vr_model_param_var.get(),
'primary_stem': vr_model_stem_var.get(),
IS_KARAOKEE: bool(is_kara_model_var.get()),
IS_BV_MODEL: bool(is_bv_model_var.get()),
IS_BV_MODEL_REBAL: float(balance_value_var.get())}
if not vr_model_param_var.get() == NONE_SELECTED:
2022-12-19 04:18:56 +01:00
self.pop_up_vr_param_sub_json_dump(vr_model_params, vr_model_hash)
vr_param_menu.destroy()
else:
self.vr_model_params = None
2023-09-26 00:11:08 +02:00
self.error_dialoge(INVALID_PARAM_MODEL_ERROR)
2022-12-19 04:18:56 +01:00
def cancel():
self.vr_model_params = None
vr_param_menu.destroy()
2023-09-26 00:11:08 +02:00
def toggle_kara():
if is_kara_model_var.get():
is_bv_model_var.set(False)
balance_value_Option.configure(state=tk.DISABLED)
def toggle_bv():
if is_bv_model_var.get():
is_kara_model_var.set(False)
balance_value_Option.configure(state=READ_ONLY)
else:
balance_value_Option.configure(state=tk.DISABLED)
def opt_menu_selection(selection):
if not selection in [VOCAL_STEM, INST_STEM]:
balance_value_Option.configure(state=tk.DISABLED)
is_kara_model_Option.configure(state=tk.DISABLED)
is_bv_model_Option.configure(state=tk.DISABLED)
is_kara_model_var.set(False)
is_bv_model_var.set(False)
balance_value_var.set(0)
else:
is_kara_model_Option.configure(state=tk.NORMAL)
is_bv_model_Option.configure(state=tk.NORMAL)
2022-12-19 04:18:56 +01:00
vr_param_Frame = self.menu_FRAME_SET(vr_param_menu)
2023-09-26 00:11:08 +02:00
vr_param_Frame.grid(row=0, padx=20)
2022-12-19 04:18:56 +01:00
2023-09-27 04:54:09 +02:00
vr_param_title_title = self.menu_title_LABEL_SET(vr_param_Frame, SPECIFY_VR_MODEL_PARAMETERS_TEXT)
vr_param_title_title.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
vr_model_stem_Label = self.menu_sub_LABEL_SET(vr_param_Frame, PRIMARY_STEM_TEXT)
vr_model_stem_Label.grid(pady=MENU_PADDING_1)
vr_model_stem_Option = ttk.OptionMenu(vr_param_Frame, vr_model_stem_var, None, *STEM_SET_MENU, command=opt_menu_selection)
vr_model_stem_Option.configure(width=15)
vr_model_stem_Option.grid(pady=MENU_PADDING_1)
vr_model_stem_Option['menu'].insert_separator(len(STEM_SET_MENU))
vr_model_stem_Option['menu'].add_radiobutton(label=INPUT_STEM_NAME, command=tk._setit(vr_model_stem_var, INPUT_STEM_NAME, lambda e:self.pop_up_input_stem_name(vr_model_stem_var, vr_param_menu)))
2022-12-19 04:18:56 +01:00
self.help_hints(vr_model_stem_Label, text=SET_STEM_NAME_HELP)
2023-09-26 00:11:08 +02:00
is_kara_model_Option = ttk.Checkbutton(vr_param_Frame, text=KARAOKE_MODEL_TEXT, width=SET_MENUS_CHECK_WIDTH, variable=is_kara_model_var, command=toggle_kara)
is_kara_model_Option.grid(pady=0)
is_bv_model_Option = ttk.Checkbutton(vr_param_Frame, text=BV_MODEL_TEXT, width=SET_MENUS_CHECK_WIDTH, variable=is_bv_model_var, command=toggle_bv)
is_bv_model_Option.grid(pady=0)
balance_value_Label = self.menu_sub_LABEL_SET(vr_param_Frame, BALANCE_VALUE_TEXT)
balance_value_Label.grid(pady=MENU_PADDING_1)
balance_value_Option = ComboBoxMenu(vr_param_Frame, textvariable=balance_value_var, values=BALANCE_VALUES, width=COMBO_WIDTH)
balance_value_Option.configure(state=tk.DISABLED)
balance_value_Option.grid(pady=MENU_PADDING_1)
is_new_vr_model_Option = ttk.Checkbutton(vr_param_Frame, text=VR_51_MODEL_TEXT, width=SET_MENUS_CHECK_WIDTH, variable=is_new_vr_model_var, command=vr_new_toggle)
is_new_vr_model_Option.grid(pady=MENU_PADDING_1)
vr_model_nout_Label = self.menu_sub_LABEL_SET(vr_param_Frame, 'Out Channels')
vr_model_nout_Label.grid(pady=MENU_PADDING_1)
vr_model_nout_Option = ComboBoxEditableMenu(vr_param_Frame, values=NOUT_SEL, textvariable=vr_model_nout_var, pattern=REG_SHIFTS, default='32', width=COMBO_WIDTH)
vr_model_nout_Option.grid(pady=MENU_PADDING_1)
#self.help_hints(vr_model_nout_Label, text=VR_MODEL_NOUT_HELP)
vr_model_nout_lstm_Label = self.menu_sub_LABEL_SET(vr_param_Frame, 'Out Channels (LSTM layer)')
vr_model_nout_lstm_Label.grid(pady=MENU_PADDING_1)
vr_model_nout_lstm_Option = ComboBoxEditableMenu(vr_param_Frame, values=NOUT_LSTM_SEL, textvariable=vr_model_nout_lstm_var, pattern=REG_SHIFTS, default='128', width=COMBO_WIDTH)#
vr_model_nout_lstm_Option.grid(pady=MENU_PADDING_1)
#self.help_hints(vr_model_param_Label, text=VR_MODEL_NOUT_LSTM_HELP)
vr_model_param_Label = self.menu_sub_LABEL_SET(vr_param_Frame, SELECT_MODEL_PARAM_TEXT)
vr_model_param_Label.grid(pady=MENU_PADDING_1)
vr_model_param_Option = ComboBoxMenu(vr_param_Frame, textvariable=vr_model_param_var, values=new_vr_params, width=30)
vr_model_param_Option.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
self.help_hints(vr_model_param_Label, text=VR_MODEL_PARAM_HELP)
2023-09-26 00:11:08 +02:00
vr_param_confrim_Button = ttk.Button(vr_param_Frame, text=CONFIRM_TEXT, command=lambda:pull_data())
vr_param_confrim_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
vr_param_cancel_Button = ttk.Button(vr_param_Frame, text=CANCEL_TEXT, command=cancel)
vr_param_cancel_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
vr_new_toggle()
opt_menu_selection(vr_model_stem_var.get())
2022-12-19 04:18:56 +01:00
vr_param_menu.protocol("WM_DELETE_WINDOW", cancel)
2023-09-26 00:11:08 +02:00
frame_list = [vr_param_Frame]
self.menu_placement(vr_param_menu, CHOOSE_MODEL_PARAM_TEXT, pop_up=False if is_macos else True, frame_list=frame_list)
2022-12-19 04:18:56 +01:00
def pop_up_vr_param_sub_json_dump(self, vr_model_params, vr_model_hash):
"""Dumps current selected VR model settings to a json named after model hash"""
self.vr_model_params = vr_model_params
vr_model_params_dump = json.dumps(vr_model_params, indent=4)
with open(os.path.join(VR_HASH_DIR, f'{vr_model_hash}.json'), "w") as outfile:
outfile.write(vr_model_params_dump)
2023-09-26 00:11:08 +02:00
def pop_up_input_stem_name(self, stem_var:tk.StringVar, parent_window:tk.Toplevel):
"""
Input Stem Name
"""
stem_input_save = tk.Toplevel(root)
def close_window(is_cancel=True):
if is_cancel or not stem_input_save_var.get():
stem_var.set(VOCAL_STEM)
else:
stem_input_save_text = stem_input_save_var.get().capitalize()
if stem_input_save_text == VOCAL_STEM:
stem_text = INST_STEM if is_inverse_stem_var.get() else stem_input_save_text
elif stem_input_save_text == INST_STEM:
stem_text = VOCAL_STEM if is_inverse_stem_var.get() else stem_input_save_text
else:
stem_text = f"{NO_STEM}{stem_input_save_text}" if is_inverse_stem_var.get() else stem_input_save_text
stem_var.set(stem_text)
stem_input_save.destroy()
parent_window.attributes('-topmost', 'true') if OPERATING_SYSTEM == "Linux" else None
parent_window.grab_set()
root.wait_window(parent_window)
stem_input_save_var = tk.StringVar(value='')
is_inverse_stem_var = tk.BooleanVar(value=False)
validation = lambda value:False if re.fullmatch(REG_INPUT_STEM_NAME, value) is None else True
stem_input_save_Frame = self.menu_FRAME_SET(stem_input_save)
stem_input_save_Frame.grid(row=1)
stem_input_save_title = self.menu_title_LABEL_SET(stem_input_save_Frame, INPUT_STEM_NAME_TEXT)
stem_input_save_title.grid(pady=0)
stem_input_name_Label = self.menu_sub_LABEL_SET(stem_input_save_Frame, STEM_NAME_TEXT)
stem_input_name_Label.grid(pady=MENU_PADDING_1)
stem_input_name_Entry = ttk.Combobox(stem_input_save_Frame, textvariable=stem_input_save_var, values=STEM_SET_MENU_2, justify='center', width=25)
invalid_message = self.invalid_tooltip(stem_input_name_Entry, REG_INPUT_STEM_NAME)
stem_input_name_Entry.grid(pady=MENU_PADDING_1)
stem_input_name_Entry.focus_set()
self.spacer_label(stem_input_save_Frame)
is_inverse_stem_Button = ttk.Checkbutton(stem_input_save_Frame, text=IS_INVERSE_STEM_TEXT, variable=is_inverse_stem_var)
is_inverse_stem_Button.grid(pady=0)
entry_rules_Label = tk.Label(stem_input_save_Frame, text=STEM_INPUT_RULE, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground='#868687', justify="left")
entry_rules_Label.grid(pady=MENU_PADDING_1)
mdx_param_set_Button = ttk.Button(stem_input_save_Frame, text=DONE_MENU_TEXT, command=lambda:close_window(is_cancel=False) if validation(stem_input_save_var.get()) else invalid_message())
mdx_param_set_Button.grid(pady=MENU_PADDING_1)
stop_process_Button = ttk.Button(stem_input_save_Frame, text=CANCEL_TEXT, command=close_window)
stop_process_Button.grid(pady=MENU_PADDING_1)
stem_input_save.protocol("WM_DELETE_WINDOW", close_window)
frame_list = [stem_input_save_Frame]
self.menu_placement(stem_input_save, INPUT_UNIQUE_STEM_NAME_TEXT, pop_up=True, frame_list=frame_list)
2022-12-19 04:18:56 +01:00
def pop_up_save_ensemble(self):
"""
Save Ensemble as...
"""
2023-09-26 00:11:08 +02:00
ensemble_save = tk.Toplevel(root)
2022-12-19 04:18:56 +01:00
2022-12-21 11:18:16 +01:00
ensemble_save_var = tk.StringVar(value='')
2022-12-19 04:18:56 +01:00
ensemble_save_Frame = self.menu_FRAME_SET(ensemble_save)
2023-09-26 00:11:08 +02:00
ensemble_save_Frame.grid(row=1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
validation = lambda value:False if re.fullmatch(REG_SAVE_INPUT, value) is None else True
2022-12-19 04:18:56 +01:00
save_func = lambda:(self.pop_up_save_ensemble_sub_json_dump(self.ensemble_listbox_get_all_selected_models(), ensemble_save_var.get()), ensemble_save.destroy())
if len(self.ensemble_listbox_get_all_selected_models()) <= 1:
2023-09-26 00:11:08 +02:00
ensemble_save_title = self.menu_title_LABEL_SET(ensemble_save_Frame, ENSEMBLE_WARNING_NOT_ENOUGH_SHORT_TEXT, width=20)
ensemble_save_title.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
ensemble_save_title = self.menu_sub_LABEL_SET(ensemble_save_Frame, ENSEMBLE_WARNING_NOT_ENOUGH_TEXT)
ensemble_save_title.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
stop_process_Button = ttk.Button(ensemble_save_Frame, text=OK_TEXT, command=lambda:ensemble_save.destroy())
stop_process_Button.grid()
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
ensemble_save_title = self.menu_title_LABEL_SET(ensemble_save_Frame, SAVE_CURRENT_ENSEMBLE_TEXT)
ensemble_save_title.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
ensemble_name_Label = self.menu_sub_LABEL_SET(ensemble_save_Frame, ENSEMBLE_NAME_TEXT)
ensemble_name_Label.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
ensemble_name_Entry = ttk.Entry(ensemble_save_Frame, textvariable=ensemble_save_var, justify='center', width=25)
2023-09-26 00:11:08 +02:00
ensemble_name_Entry.grid(pady=MENU_PADDING_1)
invalid_message = self.invalid_tooltip(ensemble_name_Entry)
ensemble_name_Entry.focus_set()
self.spacer_label(ensemble_save_Frame)
2022-12-19 04:18:56 +01:00
2022-12-29 00:48:28 +01:00
entry_rules_Label = tk.Label(ensemble_save_Frame, text=ENSEMBLE_INPUT_RULE, font=(MAIN_FONT_NAME, f"{FONT_SIZE_1}"), foreground='#868687', justify="left")
2023-09-26 00:11:08 +02:00
entry_rules_Label.grid()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
mdx_param_set_Button = ttk.Button(ensemble_save_Frame, text=SAVE_TEXT, command=lambda:save_func() if validation(ensemble_save_var.get()) else invalid_message())
mdx_param_set_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
stop_process_Button = ttk.Button(ensemble_save_Frame, text=CANCEL_TEXT, command=lambda:ensemble_save.destroy())
stop_process_Button.grid(pady=MENU_PADDING_1)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.menu_placement(ensemble_save, SAVE_CURRENT_ENSEMBLE_TEXT, pop_up=True)
2022-12-19 04:18:56 +01:00
def pop_up_save_ensemble_sub_json_dump(self, selected_ensemble_model, ensemble_save_name: str):
"""Dumps current ensemble settings to a json named after user input"""
if ensemble_save_name:
self.chosen_ensemble_var.set(ensemble_save_name)
ensemble_save_name = ensemble_save_name.replace(" ", "_")
saved_data = {
'ensemble_main_stem': self.ensemble_main_stem_var.get(),
'ensemble_type': self.ensemble_type_var.get(),
'selected_models': selected_ensemble_model,
}
saved_data_dump = json.dumps(saved_data, indent=4)
with open(os.path.join(ENSEMBLE_CACHE_DIR, f'{ensemble_save_name}.json'), "w") as outfile:
outfile.write(saved_data_dump)
2023-09-26 00:11:08 +02:00
def deletion_list_fill(self, option_menu: ComboBoxMenu, selection_var: tk.StringVar, selection_dir, var_set, menu_name=None):
2022-12-19 04:18:56 +01:00
"""Fills the saved settings menu located in tab 2 of the main settings window"""
2023-09-26 00:11:08 +02:00
def command_callback(event=None):
self.deletion_entry(selection_var.get(), selection_dir, refresh_menu)
selection_var.set(var_set)
def refresh_menu(remove=None):
selection_list = self.last_found_ensembles if menu_name == 'deleteensemble' else self.last_found_settings
main_var = self.chosen_ensemble_var if menu_name == 'deleteensemble' else self.save_current_settings_var
if remove and remove in selection_list:
selection_list = list(selection_list)
selection_list.remove(remove)
main_var.set(CHOOSE_ENSEMBLE_OPTION)
self.update_menus(option_widget=option_menu,
style_name=menu_name,
command=command_callback,
new_items=selection_list)
refresh_menu()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def deletion_entry(self, selection: str, path, callback):
2022-12-19 04:18:56 +01:00
"""Deletes selected user saved application settings"""
if selection not in [SELECT_SAVED_SET, SELECT_SAVED_ENSEMBLE]:
saved_path = os.path.join(path, f'{selection.replace(" ", "_")}.json')
confirm = self.message_box(DELETE_ENS_ENTRY)
if confirm:
if os.path.isfile(saved_path):
os.remove(saved_path)
2023-09-26 00:11:08 +02:00
callback(selection)
2022-12-19 04:18:56 +01:00
#--Download Center Methods--
2023-09-26 00:11:08 +02:00
def online_data_refresh(self, user_refresh=True, confirmation_box=False, refresh_list_Button=False, is_start_up=False, is_download_complete=False):
2022-12-19 04:18:56 +01:00
"""Checks for application updates"""
def online_check():
2023-09-26 00:11:08 +02:00
if not is_start_up:
self.app_update_status_Text_var.set(LOADING_VERSION_INFO_TEXT)
self.app_update_button_Text_var.set(CHECK_FOR_UPDATES_TEXT)
2022-12-27 11:31:41 +01:00
2022-12-19 04:18:56 +01:00
is_new_update = False
try:
self.online_data = json.load(urllib.request.urlopen(DOWNLOAD_CHECKS))
self.is_online = True
2022-12-30 04:07:23 +01:00
2023-09-26 00:11:08 +02:00
try:
with urllib.request.urlopen(BULLETIN_CHECK) as response:
self.bulletin_data = response.read().decode('utf-8')
if not is_windows:
self.bulletin_data = read_bulliten_text_mac(CR_TEXT, self.bulletin_data)
else:
self.bulletin_data = self.bulletin_data.replace("~", "")
except Exception as e:
self.bulletin_data = INFO_UNAVAILABLE_TEXT
print(e)
2022-12-30 04:07:23 +01:00
if user_refresh:
self.download_list_state()
2023-09-26 00:11:08 +02:00
for widget in self.download_center_Buttons:
widget.configure(state=tk.NORMAL)
2022-12-30 04:07:23 +01:00
if refresh_list_Button:
self.download_progress_info_var.set('Download List Refreshed!')
if OPERATING_SYSTEM=="Darwin":
self.lastest_version = self.online_data["current_version_mac"]
elif OPERATING_SYSTEM=="Linux":
self.lastest_version = self.online_data["current_version_linux"]
else:
self.lastest_version = self.online_data["current_version"]
2023-09-26 00:11:08 +02:00
if self.lastest_version == current_patch and not is_start_up:
2022-12-19 04:18:56 +01:00
self.app_update_status_Text_var.set('UVR Version Current')
else:
is_new_update = True
2023-03-31 12:15:39 +02:00
is_beta_version = True if self.lastest_version == PREVIOUS_PATCH_WIN and BETA_VERSION in current_patch else False
2023-09-26 00:11:08 +02:00
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_button_Text_var.set(ROLL_BACK_TEXT)
else:
self.app_update_status_Text_var.set(f"Update Found: {self.lastest_version}")
self.app_update_button_Text_var.set('Click Here to Update')
2023-03-31 12:15:39 +02:00
2023-09-26 00:11:08 +02:00
if OPERATING_SYSTEM == "Windows":
self.download_update_link_var.set('{}{}{}'.format(UPDATE_REPO, self.lastest_version, application_extension))
self.download_update_path_var.set(os.path.join(BASE_PATH, f'{self.lastest_version}{application_extension}'))
elif OPERATING_SYSTEM == "Darwin":
self.download_update_link_var.set(UPDATE_MAC_ARM_REPO if SYSTEM_PROC == ARM or ARM in SYSTEM_ARCH else UPDATE_MAC_X86_64_REPO)
elif OPERATING_SYSTEM == "Linux":
self.download_update_link_var.set(UPDATE_LINUX_REPO)
2022-12-19 04:18:56 +01:00
if not user_refresh:
2023-09-26 04:47:04 +02:00
if not is_beta_version and not self.lastest_version == PATCH:
2023-09-26 00:11:08 +02:00
self.command_Text.write(NEW_UPDATE_FOUND_TEXT(self.lastest_version))
2022-12-19 04:18:56 +01:00
2023-09-26 04:47:04 +02:00
2023-09-26 00:11:08 +02:00
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:
self.download_model_settings()
2023-09-26 23:46:28 +02:00
# if is_download_complete:
# self.download_model_settings()
2022-12-30 04:07:23 +01:00
2022-12-19 04:18:56 +01:00
except Exception as e:
2023-09-26 00:11:08 +02:00
self.offline_state_set(is_start_up)
2022-12-19 04:18:56 +01:00
is_new_update = False
if user_refresh:
self.download_list_state(disable_only=True)
2023-09-26 00:11:08 +02:00
for widget in self.download_center_Buttons:
widget.configure(state=tk.DISABLED)
try:
self.error_log_var.set(error_text('Online Data Refresh', e))
except Exception as e:
print(e)
2022-12-19 04:18:56 +01:00
return is_new_update
if confirmation_box:
return online_check()
else:
self.current_thread = KThread(target=online_check)
2022-12-27 11:31:41 +01:00
self.current_thread.setDaemon(True) if not is_windows else None
2022-12-19 04:18:56 +01:00
self.current_thread.start()
2023-09-27 04:54:09 +02:00
2023-09-26 00:11:08 +02:00
def offline_state_set(self, is_start_up=False):
2023-09-27 06:41:47 +02:00
"""Changes relevant settings and "Download Center" buttons if no internet connection is available"""
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
if not is_start_up and self.is_menu_settings_open:
self.app_update_status_Text_var.set(f'Version Status: {NO_CONNECTION}')
self.download_progress_info_var.set(NO_CONNECTION)
self.app_update_button_Text_var.set('Refresh')
self.refresh_list_Button.configure(state=tk.NORMAL)
self.stop_download_Button_DISABLE()
self.enable_tabs()
2022-12-19 04:18:56 +01:00
self.is_online = False
2023-09-26 00:11:08 +02:00
def download_validate_code(self, confirm=False, code_message=None):
2022-12-19 04:18:56 +01:00
"""Verifies the VIP download code"""
self.decoded_vip_link = vip_downloads(self.user_code_var.get())
if confirm:
if not self.decoded_vip_link == NO_CODE:
2023-09-26 00:11:08 +02:00
info_text = 'VIP Models Added!'
is_success_message = True
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
info_text = 'Incorrect Code'
is_success_message = False
self.download_progress_info_var.set(info_text)
self.user_code_validation_var.set(info_text)
if code_message:
code_message(info_text, is_success_message)
2022-12-19 04:18:56 +01:00
self.download_list_fill()
2023-09-26 00:11:08 +02:00
def download_list_fill(self, model_type=ALL_TYPES):
2022-12-19 04:18:56 +01:00
"""Fills the download lists with the data retrieved from the update check."""
self.download_demucs_models_list.clear()
2023-09-26 00:11:08 +02:00
model_download_mdx_list, model_download_mdx_name = [], "mdxdownload"
model_download_vr_list, model_download_vr_name = [], "vrdownload"
model_download_demucs_list, model_download_demucs_name = [], "demucsmdxdownload"
2022-12-19 04:18:56 +01:00
self.vr_download_list = self.online_data["vr_download_list"]
self.mdx_download_list = self.online_data["mdx_download_list"]
self.demucs_download_list = self.online_data["demucs_download_list"]
2023-09-26 00:11:08 +02:00
self.mdx_download_list.update(self.online_data["mdx23c_download_list"])
2022-12-19 04:18:56 +01:00
if not self.decoded_vip_link is NO_CODE:
self.vr_download_list.update(self.online_data["vr_download_vip_list"])
self.mdx_download_list.update(self.online_data["mdx_download_vip_list"])
2023-09-26 00:11:08 +02:00
self.mdx_download_list.update(self.online_data["mdx23c_download_vip_list"])
def configure_combobox(combobox:ComboBoxMenu, values:list, variable:tk.StringVar, arch_type, name):
values = [NO_NEW_MODELS] if not values else values
combobox['values'] = values
combobox.update_dropdown_size(values, name, offset=310,
command=lambda s: self.download_model_select(variable.get(), arch_type, variable))
if model_type in [VR_ARCH_TYPE, ALL_TYPES]:
for (selectable, model) in self.vr_download_list.items():
if not os.path.isfile(os.path.join(VR_MODELS_DIR, model)):
model_download_vr_list.append(selectable)
configure_combobox(self.model_download_vr_Option, model_download_vr_list, self.model_download_vr_var, VR_ARCH_TYPE, model_download_vr_name)
if model_type in [MDX_ARCH_TYPE, ALL_TYPES]:
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}"
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:
with open(config_local, 'wb') as out_file:
out_file.write(response.read())
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
model_name = str(model)
if not os.path.isfile(os.path.join(MDX_MODELS_DIR, model_name)):
model_download_mdx_list.append(selectable)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
configure_combobox(self.model_download_mdx_Option, model_download_mdx_list, self.model_download_mdx_var, MDX_ARCH_TYPE, model_download_mdx_name)
if model_type in [DEMUCS_ARCH_TYPE, ALL_TYPES]:
for (selectable, model) in self.demucs_download_list.items():
for name in model.items():
if [True for x in DEMUCS_NEWER_ARCH_TYPES if x in selectable]:
if not os.path.isfile(os.path.join(DEMUCS_NEWER_REPO_DIR, name[0])):
self.download_demucs_models_list.append(selectable)
else:
if not os.path.isfile(os.path.join(DEMUCS_MODELS_DIR, name[0])):
self.download_demucs_models_list.append(selectable)
self.download_demucs_models_list = list(dict.fromkeys(self.download_demucs_models_list))
for option_name in self.download_demucs_models_list:
model_download_demucs_list.append(option_name)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
configure_combobox(self.model_download_demucs_Option, model_download_demucs_list, self.model_download_demucs_var, DEMUCS_ARCH_TYPE, model_download_demucs_name)
2022-12-19 04:18:56 +01:00
def download_model_settings(self):
'''Update the newest model settings'''
try:
2023-09-26 00:11:08 +02:00
self.vr_hash_MAPPER = json.load(urllib.request.urlopen(VR_MODEL_DATA_LINK))
self.mdx_hash_MAPPER = json.load(urllib.request.urlopen(MDX_MODEL_DATA_LINK))
self.mdx_name_select_MAPPER = json.load(urllib.request.urlopen(MDX_MODEL_NAME_DATA_LINK))
self.demucs_name_select_MAPPER = json.load(urllib.request.urlopen(DEMUCS_MODEL_NAME_DATA_LINK))
2022-12-19 04:18:56 +01:00
vr_hash_MAPPER_dump = json.dumps(self.vr_hash_MAPPER, indent=4)
with open(VR_HASH_JSON, "w") as outfile:
outfile.write(vr_hash_MAPPER_dump)
mdx_hash_MAPPER_dump = json.dumps(self.mdx_hash_MAPPER, indent=4)
with open(MDX_HASH_JSON, "w") as outfile:
outfile.write(mdx_hash_MAPPER_dump)
2023-03-31 12:15:39 +02:00
mdx_name_select_MAPPER_dump = json.dumps(self.mdx_name_select_MAPPER, indent=4)
with open(MDX_MODEL_NAME_SELECT, "w") as outfile:
outfile.write(mdx_name_select_MAPPER_dump)
demucs_name_select_MAPPER_dump = json.dumps(self.demucs_name_select_MAPPER, indent=4)
with open(DEMUCS_MODEL_NAME_SELECT, "w") as outfile:
outfile.write(demucs_name_select_MAPPER_dump)
2022-12-19 04:18:56 +01:00
except Exception as e:
2023-09-26 00:11:08 +02:00
self.vr_hash_MAPPER = load_model_hash_data(VR_HASH_JSON)
self.mdx_hash_MAPPER = load_model_hash_data(MDX_HASH_JSON)
self.mdx_name_select_MAPPER = load_model_hash_data(MDX_MODEL_NAME_SELECT)
self.demucs_name_select_MAPPER = load_model_hash_data(DEMUCS_MODEL_NAME_SELECT)
2022-12-19 04:18:56 +01:00
self.error_log_var.set(e)
print(e)
def download_list_state(self, reset=True, disable_only=False):
"""Makes sure only the models from the chosen AI network are selectable."""
2023-09-26 00:11:08 +02:00
for widget in self.download_lists:
widget.configure(state=tk.DISABLED)
2022-12-19 04:18:56 +01:00
if reset:
for download_list_var in self.download_list_vars:
if self.is_online:
download_list_var.set(NO_MODEL)
self.download_Button.configure(state=tk.NORMAL)
else:
download_list_var.set(NO_CONNECTION)
self.download_Button.configure(state=tk.DISABLED)
2023-09-26 00:11:08 +02:00
disable_only = True
2022-12-19 04:18:56 +01:00
if not disable_only:
self.download_Button.configure(state=tk.NORMAL)
if self.select_download_var.get() == VR_ARCH_TYPE:
2023-09-26 00:11:08 +02:00
self.model_download_vr_Option.configure(state=READ_ONLY)
2022-12-19 04:18:56 +01:00
self.selected_download_var = self.model_download_vr_var
2023-09-26 00:11:08 +02:00
self.download_list_fill(model_type=VR_ARCH_TYPE)
2022-12-19 04:18:56 +01:00
if self.select_download_var.get() == MDX_ARCH_TYPE:
2023-09-26 00:11:08 +02:00
self.model_download_mdx_Option.configure(state=READ_ONLY)
2022-12-19 04:18:56 +01:00
self.selected_download_var = self.model_download_mdx_var
2023-09-26 00:11:08 +02:00
self.download_list_fill(model_type=MDX_ARCH_TYPE)
2022-12-19 04:18:56 +01:00
if self.select_download_var.get() == DEMUCS_ARCH_TYPE:
2023-09-26 00:11:08 +02:00
self.model_download_demucs_Option.configure(state=READ_ONLY)
2022-12-19 04:18:56 +01:00
self.selected_download_var = self.model_download_demucs_var
2023-09-26 00:11:08 +02:00
self.download_list_fill(model_type=DEMUCS_ARCH_TYPE)
2022-12-19 04:18:56 +01:00
self.stop_download_Button_DISABLE()
2023-09-26 00:11:08 +02:00
def download_model_select(self, selection, type, var:tk.StringVar):
2022-12-19 04:18:56 +01:00
"""Prepares the data needed to download selected model."""
self.download_demucs_newer_models.clear()
2023-09-26 00:11:08 +02:00
if selection == NO_NEW_MODELS:
selection = NO_MODEL
var.set(NO_MODEL)
2022-12-19 04:18:56 +01:00
model_repo = self.decoded_vip_link if VIP_SELECTION in selection else NORMAL_REPO
is_demucs_newer = [True for x in DEMUCS_NEWER_ARCH_TYPES if x in selection]
if type == VR_ARCH_TYPE:
for selected_model in self.vr_download_list.items():
if selection in selected_model:
self.download_link_path_var.set("{}{}".format(model_repo, selected_model[1]))
self.download_save_path_var.set(os.path.join(VR_MODELS_DIR, selected_model[1]))
break
if type == MDX_ARCH_TYPE:
for selected_model in self.mdx_download_list.items():
if selection in selected_model:
2023-09-26 00:11:08 +02:00
if isinstance(selected_model[1], dict):
model_name = list(selected_model[1].keys())[0]
else:
model_name = str(selected_model[1])
self.download_link_path_var.set("{}{}".format(model_repo, model_name))
self.download_save_path_var.set(os.path.join(MDX_MODELS_DIR, model_name))
2022-12-19 04:18:56 +01:00
break
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if type == DEMUCS_ARCH_TYPE:
for selected_model, model_data in self.demucs_download_list.items():
if selection == selected_model:
for key, value in model_data.items():
if is_demucs_newer:
self.download_demucs_newer_models.append([os.path.join(DEMUCS_NEWER_REPO_DIR, key), value])
else:
self.download_save_path_var.set(os.path.join(DEMUCS_MODELS_DIR, key))
self.download_link_path_var.set(value)
def download_item(self, is_update_app=False):
"""Downloads the model selected."""
if not is_update_app:
if self.selected_download_var.get() == NO_MODEL:
self.download_progress_info_var.set(NO_MODEL)
return
2023-09-26 00:11:08 +02:00
for widget in self.download_center_Buttons:
widget.configure(state=tk.DISABLED)
2022-12-19 04:18:56 +01:00
self.refresh_list_Button.configure(state=tk.DISABLED)
2022-12-30 04:07:23 +01:00
self.manual_download_Button.configure(state=tk.DISABLED)
2022-12-19 04:18:56 +01:00
is_demucs_newer = [True for x in DEMUCS_NEWER_ARCH_TYPES if x in self.selected_download_var.get()]
self.download_list_state(reset=False, disable_only=True)
self.stop_download_Button_ENABLE()
self.disable_tabs()
def download_progress_bar(current, total, model=80):
progress = ('%s' % (100 * current // total))
self.download_progress_bar_var.set(int(progress))
self.download_progress_percent_var.set(progress + ' %')
def push_download():
self.is_download_thread_active = True
try:
if is_update_app:
self.download_progress_info_var.set(DOWNLOADING_UPDATE)
if os.path.isfile(self.download_update_path_var.get()):
self.download_progress_info_var.set(FILE_EXISTS)
else:
wget.download(self.download_update_link_var.get(), self.download_update_path_var.get(), bar=download_progress_bar)
self.download_post_action(DOWNLOAD_UPDATE_COMPLETE)
else:
if self.select_download_var.get() == DEMUCS_ARCH_TYPE and is_demucs_newer:
for model_num, model_data in enumerate(self.download_demucs_newer_models, start=1):
self.download_progress_info_var.set('{} {}/{}...'.format(DOWNLOADING_ITEM, model_num, len(self.download_demucs_newer_models)))
if os.path.isfile(model_data[0]):
continue
else:
wget.download(model_data[1], model_data[0], bar=download_progress_bar)
else:
self.download_progress_info_var.set(SINGLE_DOWNLOAD)
if os.path.isfile(self.download_save_path_var.get()):
self.download_progress_info_var.set(FILE_EXISTS)
else:
wget.download(self.download_link_path_var.get(), self.download_save_path_var.get(), bar=download_progress_bar)
self.download_post_action(DOWNLOAD_COMPLETE)
except Exception as e:
self.error_log_var.set(error_text(DOWNLOADING_ITEM, e))
self.download_progress_info_var.set(DOWNLOAD_FAILED)
if type(e).__name__ == 'URLError':
self.offline_state_set()
else:
self.download_progress_percent_var.set(f"{type(e).__name__}")
self.download_post_action(DOWNLOAD_FAILED)
self.active_download_thread = KThread(target=push_download)
self.active_download_thread.start()
def download_post_action(self, action):
"""Resets the widget variables in the "Download Center" based on the state of the download."""
2023-09-26 00:11:08 +02:00
for widget in self.download_center_Buttons:
widget.configure(state=tk.NORMAL)
2022-12-19 04:18:56 +01:00
self.refresh_list_Button.configure(state=tk.NORMAL)
2022-12-30 04:07:23 +01:00
self.manual_download_Button.configure(state=tk.NORMAL)
2022-12-19 04:18:56 +01:00
self.enable_tabs()
self.stop_download_Button_DISABLE()
if action == DOWNLOAD_FAILED:
try:
self.active_download_thread.terminate()
finally:
self.download_progress_info_var.set(DOWNLOAD_FAILED)
self.download_list_state(reset=False)
if action == DOWNLOAD_STOPPED:
try:
self.active_download_thread.terminate()
finally:
self.download_progress_info_var.set(DOWNLOAD_STOPPED)
self.download_list_state(reset=False)
if action == DOWNLOAD_COMPLETE:
2023-09-26 00:11:08 +02:00
self.online_data_refresh(is_download_complete=True)
2022-12-19 04:18:56 +01:00
self.download_progress_info_var.set(DOWNLOAD_COMPLETE)
self.download_list_state()
if action == DOWNLOAD_UPDATE_COMPLETE:
self.download_progress_info_var.set(DOWNLOAD_UPDATE_COMPLETE)
if os.path.isfile(self.download_update_path_var.get()):
subprocess.Popen(self.download_update_path_var.get())
self.download_list_state()
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
self.is_download_thread_active = False
self.delete_temps()
#--Refresh/Loop Methods--
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def update_loop(self):
"""Update the model dropdown menus"""
if self.clear_cache_torch:
2023-10-12 06:30:24 +02:00
clear_gpu_cache()
2022-12-19 04:18:56 +01:00
self.clear_cache_torch = False
2023-10-12 06:30:24 +02:00
2022-12-19 04:18:56 +01:00
if self.is_process_stopped:
if self.thread_check(self.active_processing_thread):
self.conversion_Button_Text_var.set(STOP_PROCESSING)
self.conversion_Button.configure(state=tk.DISABLED)
self.stop_Button.configure(state=tk.DISABLED)
else:
self.stop_Button.configure(state=tk.NORMAL)
self.conversion_Button_Text_var.set(START_PROCESSING)
self.conversion_Button.configure(state=tk.NORMAL)
self.progress_bar_main_var.set(0)
2023-10-12 06:30:24 +02:00
clear_gpu_cache()
2022-12-19 04:18:56 +01:00
self.is_process_stopped = False
2023-10-12 06:30:24 +02:00
2022-12-19 04:18:56 +01:00
if self.is_confirm_error_var.get():
2023-09-26 00:11:08 +02:00
self.check_is_menu_open(ERROR_OPTION)
2022-12-19 04:18:56 +01:00
self.is_confirm_error_var.set(False)
2023-09-26 00:11:08 +02:00
if self.is_check_splash and is_windows:
while not self.msg_queue.empty():
message = self.msg_queue.get_nowait()
print(message)
close_process(self.msg_queue)
self.is_check_splash = False
2023-10-12 06:30:24 +02:00
#self.auto_save()
2022-12-19 04:18:56 +01:00
self.update_available_models()
self.after(600, self.update_loop)
2023-09-26 00:11:08 +02:00
def update_menus(self, option_widget:ComboBoxMenu, style_name, command, new_items, last_items=None, base_options=None):
if new_items != last_items:
formatted_items = [item.replace("_", " ") for item in new_items]
if not formatted_items and base_options:
base_options = [option for option in base_options if option != OPT_SEPARATOR_SAVE]
final_options = formatted_items + base_options if base_options else formatted_items
option_widget['values'] = final_options
option_widget.update_dropdown_size(formatted_items, style_name, command=command)
return new_items
return last_items
2022-12-19 04:18:56 +01:00
def update_available_models(self):
"""
Loops through all models in each model directory and adds them to the appropriate model menu.
Also updates ensemble listbox and user saved settings list.
"""
2023-09-26 00:11:08 +02:00
def fix_name(name, mapper:dict): return next((new_name for old_name, new_name in mapper.items() if name in old_name), name)
2022-12-19 04:18:56 +01:00
2023-03-31 12:15:39 +02:00
new_vr_models = self.get_files_from_dir(VR_MODELS_DIR, PTH)
new_mdx_models = self.get_files_from_dir(MDX_MODELS_DIR, (ONNX, CKPT), is_mdxnet=True)
new_demucs_models = self.get_files_from_dir(DEMUCS_MODELS_DIR, (CKPT, '.gz', '.th')) + self.get_files_from_dir(DEMUCS_NEWER_REPO_DIR, YAML)
new_ensembles_found = self.get_files_from_dir(ENSEMBLE_CACHE_DIR, JSON)
new_settings_found = self.get_files_from_dir(SETTINGS_CACHE_DIR, JSON)
2022-12-19 04:18:56 +01:00
new_models_found = new_vr_models + new_mdx_models + new_demucs_models
is_online = self.is_online_model_menu
2023-09-26 00:11:08 +02:00
def loop_directories(option_menu:ComboBoxMenu, option_var, model_list, model_type, name_mapper=None):
current_selection = option_menu.get()
option_list = [fix_name(file_name, name_mapper) for file_name in model_list] if name_mapper else model_list
sorted_options = natsort.natsorted(option_list)
option_list_option_menu = sorted_options + [OPT_SEPARATOR, DOWNLOAD_MORE] if self.is_online else sorted_options
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
if not option_list and self.is_online:
option_list_option_menu = [option for option in option_list_option_menu if option != OPT_SEPARATOR]
option_menu['values'] = option_list_option_menu
option_menu.set(current_selection)
2023-10-12 06:30:24 +02:00
option_menu.update_dropdown_size(option_list, model_type)
2023-09-26 00:11:08 +02:00
if self.is_root_defined_var.get() and model_type == MDX_ARCH_TYPE and self.chosen_process_method_var.get() == MDX_ARCH_TYPE:
self.selection_action_models_sub(current_selection, model_type, option_var)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
return tuple(f"{model_type}{ENSEMBLE_PARTITION}{model_name}" for model_name in sorted_options)
2022-12-19 04:18:56 +01:00
if new_models_found != self.last_found_models or is_online != self.is_online:
self.model_data_table = []
vr_model_list = loop_directories(self.vr_model_Option, self.vr_model_var, new_vr_models, VR_ARCH_TYPE, name_mapper=None)
2023-03-31 12:15:39 +02:00
mdx_model_list = loop_directories(self.mdx_net_model_Option, self.mdx_net_model_var, new_mdx_models, MDX_ARCH_TYPE, name_mapper=self.mdx_name_select_MAPPER)
demucs_model_list = loop_directories(self.demucs_model_Option, self.demucs_model_var, new_demucs_models, DEMUCS_ARCH_TYPE, name_mapper=self.demucs_name_select_MAPPER)
2022-12-19 04:18:56 +01:00
self.ensemble_model_list = vr_model_list + mdx_model_list + demucs_model_list
2023-09-26 00:11:08 +02:00
self.default_change_model_list = vr_model_list + mdx_model_list
2022-12-19 04:18:56 +01:00
self.last_found_models = new_models_found
self.is_online_model_menu = self.is_online
if not self.chosen_ensemble_var.get() == CHOOSE_ENSEMBLE_OPTION:
self.selection_action_chosen_ensemble(self.chosen_ensemble_var.get())
else:
if not self.ensemble_main_stem_var.get() == CHOOSE_STEM_PAIR:
self.selection_action_ensemble_stems(self.ensemble_main_stem_var.get(), auto_update=self.ensemble_listbox_get_all_selected_models())
else:
self.ensemble_listbox_clear_and_insert_new(self.ensemble_model_list)
2023-09-26 00:11:08 +02:00
self.last_found_ensembles = self.update_menus(option_widget=self.chosen_ensemble_Option,
style_name='savedensembles',
command=None,
new_items=new_ensembles_found,
last_items=self.last_found_ensembles,
base_options=ENSEMBLE_OPTIONS
)
self.last_found_settings = self.update_menus(option_widget=self.save_current_settings_Option,
style_name='savedsettings',
command=None,
new_items=new_settings_found,
last_items=self.last_found_settings,
base_options=SAVE_SET_OPTIONS
)
def update_main_widget_states_mdx(self):
if not self.mdx_net_model_var.get() == DOWNLOAD_MORE:
self.update_main_widget_states()
def move_widget_offscreen(self, widget, step=10):
current_x = widget.winfo_x()
current_y = widget.winfo_y()
if current_x > -1000: # assuming -1000 is your off-screen target
widget.place(x=current_x - step, y=current_y)
widget.after(10, lambda: self.move_widget_offscreen(widget, step))
2022-12-19 04:18:56 +01:00
def update_main_widget_states(self):
"""Updates main widget states based on chosen process method"""
2023-09-26 00:11:08 +02:00
def place_widgets(*widgets):
for widget in widgets:
widget()
def general_shared_buttons():
place_widgets(self.is_gpu_conversion_Option_place,
self.model_sample_mode_Option_place)
def stem_save_options():
place_widgets(self.is_primary_stem_only_Option_place,
self.is_secondary_stem_only_Option_place)
def stem_save_demucs_options():
place_widgets(self.is_primary_stem_only_Demucs_Option_place,
self.is_secondary_stem_only_Demucs_Option_place)
def no_ensemble_shared():
place_widgets(self.save_current_settings_Label_place,
self.save_current_settings_Option_place)
process_method = self.chosen_process_method_var.get()
audio_tool = self.chosen_audio_tool_var.get()
2022-12-19 04:18:56 +01:00
for widget in self.GUI_LIST:
2023-09-26 00:11:08 +02:00
widget.place(x=-1000, y=-1000)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
if process_method == MDX_ARCH_TYPE:
place_widgets(self.mdx_net_model_Label_place,
self.mdx_net_model_Option_place,
general_shared_buttons,
stem_save_options,
no_ensemble_shared)
elif process_method == VR_ARCH_PM:
place_widgets(self.vr_model_Label_place, self.vr_model_Option_place,
self.aggression_setting_Label_place,
self.aggression_setting_Option_place,
self.window_size_Label_place,
self.window_size_Option_place,
general_shared_buttons,
stem_save_options,
no_ensemble_shared)
elif process_method == DEMUCS_ARCH_TYPE:
place_widgets(self.demucs_model_Label_place,
self.demucs_model_Option_place,
self.demucs_stems_Label_place,
self.demucs_stems_Option_place,
self.segment_Label_place,
self.segment_Option_place,
general_shared_buttons,
stem_save_demucs_options,
no_ensemble_shared)
elif process_method == AUDIO_TOOLS:
place_widgets(self.chosen_audio_tool_Label_place,
self.chosen_audio_tool_Option_place)
if audio_tool == ALIGN_INPUTS:
self.file_one_sub_var.set(FILE_ONE_MAIN_LABEL)
self.file_two_sub_var.set(FILE_TWO_MAIN_LABEL)
elif audio_tool == MATCH_INPUTS:
self.file_one_sub_var.set(FILE_ONE_MATCH_MAIN_LABEL)
self.file_two_sub_var.set(FILE_TWO_MATCH_MAIN_LABEL)
audio_tool_options = {
MANUAL_ENSEMBLE: [self.choose_algorithm_Label_place,
self.choose_algorithm_Option_place,
self.is_wav_ensemble_Option_place],
TIME_STRETCH: [lambda: self.model_sample_mode_Option_place(rely=5),
self.time_stretch_rate_Label_place,
self.time_stretch_rate_Option_place],
CHANGE_PITCH: [self.is_time_correction_Option_place,
lambda: self.model_sample_mode_Option_place(rely=6),
self.pitch_rate_Label_place,
self.pitch_rate_Option_place],
ALIGN_INPUTS: [self.fileOne_Label_place,
self.fileOne_Entry_place,
self.fileTwo_Label_place,
self.fileTwo_Entry_place,
self.fileOne_Open_place,
self.fileTwo_Open_place,
self.intro_analysis_Label_place,
self.intro_analysis_Option_place,
self.db_analysis_Label_place,
self.db_analysis_Option_place,
self.time_window_Label_place,
self.time_window_Option_place],
MATCH_INPUTS: [self.fileOne_Label_place,
self.fileOne_Entry_place,
self.fileTwo_Label_place,
self.fileTwo_Entry_place,
self.fileOne_Open_place,
self.fileTwo_Open_place,
self.wav_type_set_Label_place,
self.wav_type_set_Option_place],
}
place_widgets(*audio_tool_options.get(audio_tool, []))
elif process_method == ENSEMBLE_MODE:
place_widgets(self.chosen_ensemble_Label_place,
self.chosen_ensemble_Option_place,
self.ensemble_main_stem_Label_place,
self.ensemble_main_stem_Option_place,
self.ensemble_type_Label_place,
self.ensemble_type_Option_place,
self.ensemble_listbox_Label_place,
self.ensemble_listbox_Option_place,
self.ensemble_listbox_Option_pack,
general_shared_buttons,
stem_save_options)
if not self.is_gpu_available:
self.is_gpu_conversion_Disable()
2022-12-19 04:18:56 +01:00
self.update_inputPaths()
def update_button_states(self):
"""Updates the available stems for selected Demucs model"""
2023-09-26 00:11:08 +02:00
if self.chosen_process_method_var.get() == DEMUCS_ARCH_TYPE:
if self.demucs_stems_var.get() == ALL_STEMS:
self.update_stem_checkbox_labels(PRIMARY_STEM, demucs=True)
elif self.demucs_stems_var.get() == VOCAL_STEM:
self.update_stem_checkbox_labels(VOCAL_STEM, demucs=True, is_disable_demucs_boxes=False)
self.is_stem_only_Demucs_Options_Enable()
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
self.is_stem_only_Demucs_Options_Enable()
#self.demucs_stems_Option['menu'].delete(0,'end')
if not self.demucs_model_var.get() == CHOOSE_MODEL:
if DEMUCS_UVR_MODEL in self.demucs_model_var.get():
stems = DEMUCS_2_STEM_OPTIONS
elif DEMUCS_6_STEM_MODEL in self.demucs_model_var.get():
stems = DEMUCS_6_STEM_OPTIONS
else:
stems = DEMUCS_4_STEM_OPTIONS
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.demucs_stems_Option['values'] = stems
self.demucs_stems_Option.command(lambda e:self.update_stem_checkbox_labels(self.demucs_stems_var.get(), demucs=True))
def update_button_states_mdx(self, model_stems):
"""Updates the available stems for selected Demucs model"""
model_stems = [stem for stem in model_stems]
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])
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.is_stem_only_Options_Enable()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
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()))
2022-12-19 04:18:56 +01:00
def update_stem_checkbox_labels(self, selection, demucs=False, disable_boxes=False, is_disable_demucs_boxes=True):
"""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
2023-09-26 00:11:08 +02:00
if selection == ALL_STEMS:
selection = PRIMARY_STEM
else:
self.is_stem_only_Options_Enable()
if disable_boxes or selection == PRIMARY_STEM:
2022-12-19 04:18:56 +01:00
self.is_primary_stem_only_Option.configure(state=tk.DISABLED)
self.is_secondary_stem_only_Option.configure(state=tk.DISABLED)
self.is_primary_stem_only_var.set(False)
self.is_secondary_stem_only_var.set(False)
2023-09-26 00:11:08 +02:00
else:
self.is_primary_stem_only_Option.configure(state=tk.NORMAL)
self.is_secondary_stem_only_Option.configure(state=tk.NORMAL)
2022-12-19 04:18:56 +01:00
if demucs:
stem_text = self.is_primary_stem_only_Demucs_Text_var, self.is_secondary_stem_only_Demucs_Text_var
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if is_disable_demucs_boxes:
self.is_primary_stem_only_Demucs_Option.configure(state=tk.DISABLED)
self.is_secondary_stem_only_Demucs_Option.configure(state=tk.DISABLED)
self.is_primary_stem_only_Demucs_var.set(False)
self.is_secondary_stem_only_Demucs_var.set(False)
2023-09-26 00:11:08 +02:00
if not selection == PRIMARY_STEM:
self.is_primary_stem_only_Demucs_Option.configure(state=tk.NORMAL)
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")
2022-12-19 04:18:56 +01:00
def update_ensemble_algorithm_menu(self, is_4_stem=False):
options = ENSEMBLE_TYPE_4_STEM if is_4_stem else ENSEMBLE_TYPE
if not "/" in self.ensemble_type_var.get() or is_4_stem:
self.ensemble_type_var.set(options[0])
2023-09-26 00:11:08 +02:00
self.ensemble_type_Option["values"] = options
def selection_action(self, event, option_var, is_mdx_net=False):
selected_value = event.widget.get()
selected_value = CHOOSE_MODEL if selected_value == OPT_SEPARATOR else selected_value
option_var.set(selected_value)
if is_mdx_net:
self.update_main_widget_states_mdx()
self.selection_action_models(selected_value)
2022-12-19 04:18:56 +01:00
def selection_action_models(self, selection):
2023-09-26 00:11:08 +02:00
"""Accepts model names and verifies their state."""
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
# Handle different selections.
if selection in CHOOSE_MODEL:
2022-12-19 04:18:56 +01:00
self.update_stem_checkbox_labels(PRIMARY_STEM, disable_boxes=True)
else:
self.is_stem_only_Options_Enable()
2023-09-26 00:11:08 +02:00
# Process method matching current selection.
self._handle_model_by_chosen_method(selection)
# Handle Ensemble mode case.
2022-12-19 04:18:56 +01:00
if self.chosen_process_method_var.get() == ENSEMBLE_MODE:
2023-09-26 00:11:08 +02:00
return self._handle_ensemble_mode_selection(selection)
if not self.is_menu_settings_open and selection == DOWNLOAD_MORE:
self.update_checkbox_text()
self.menu_settings(select_tab_3=True)
def _handle_model_by_chosen_method(self, selection):
"""Handles model selection based on the currently chosen method."""
current_method = self.chosen_process_method_var.get()
model_var = self.method_mapper.get(current_method)
if model_var:
self.selection_action_models_sub(selection, current_method, model_var)
def _handle_ensemble_mode_selection(self, selection):
"""Handles the case where the current method is 'ENSEMBLE_MODE'."""
model_data = self.assemble_model_data(selection, ENSEMBLE_CHECK)[0]
if not model_data.model_status:
return self.model_stems_list.index(selection)
return False
2022-12-19 04:18:56 +01:00
def selection_action_models_sub(self, selection, ai_type, var: tk.StringVar):
"""Takes input directly from the selection_action_models parent function"""
2023-09-26 00:11:08 +02:00
if selection == DOWNLOAD_MORE:
is_model_status = False
else:
model_data = self.assemble_model_data(selection, ai_type)[0]
is_model_status = model_data.model_status
if not is_model_status:
2022-12-19 04:18:56 +01:00
var.set(CHOOSE_MODEL)
2023-09-26 00:11:08 +02:00
if ai_type == MDX_ARCH_TYPE:
self.mdx_segment_size_Label_place()
self.mdx_segment_size_Option_place()
self.overlap_mdx_Label_place()
self.overlap_mdx_Option_place()
self.update_stem_checkbox_labels(PRIMARY_STEM, disable_boxes=True)
2022-12-19 04:18:56 +01:00
else:
if ai_type == DEMUCS_ARCH_TYPE:
if not self.demucs_stems_var.get().lower() in model_data.demucs_source_list:
self.demucs_stems_var.set(ALL_STEMS if model_data.demucs_stem_count == 4 else VOCAL_STEM)
2023-09-26 00:11:08 +02:00
self.update_button_states()
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
if model_data.is_mdx_c and len(model_data.mdx_model_stems) >= 2:
if len(model_data.mdx_model_stems) >= 3:
self.mdxnet_stems_Label_place()
self.mdxnet_stems_Option_place()
else:
self.mdx_segment_size_Label_place()
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)
else:
if ai_type == MDX_ARCH_TYPE:
self.mdx_segment_size_Label_place()
self.mdx_segment_size_Option_place()
self.overlap_mdx_Label_place()
self.overlap_mdx_Option_place()
stem = model_data.primary_stem
self.update_stem_checkbox_labels(stem)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def selection_action_process_method(self, selection, from_widget=False, is_from_conv_menu=False):
2022-12-19 04:18:56 +01:00
"""Checks model and variable status when toggling between process methods"""
2023-09-26 00:11:08 +02:00
if is_from_conv_menu:
self.update_main_widget_states()
2022-12-19 04:18:56 +01:00
if from_widget:
self.save_current_settings_var.set(CHOOSE_ENSEMBLE_OPTION)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if selection == ENSEMBLE_MODE:
2023-09-26 00:11:08 +02:00
ensemble_choice = self.ensemble_main_stem_var.get()
if ensemble_choice in [CHOOSE_STEM_PAIR, FOUR_STEM_ENSEMBLE, MULTI_STEM_ENSEMBLE]:
2022-12-19 04:18:56 +01:00
self.update_stem_checkbox_labels(PRIMARY_STEM, disable_boxes=True)
else:
self.update_stem_checkbox_labels(self.return_ensemble_stems(is_primary=True))
self.is_stem_only_Options_Enable()
2023-09-26 00:11:08 +02:00
return
for method_type, model_var in self.method_mapper.items():
if method_type in selection:
self.selection_action_models(model_var.get())
break
2022-12-19 04:18:56 +01:00
def selection_action_chosen_ensemble(self, selection):
"""Activates specific actions depending on selected ensemble option"""
if selection not in ENSEMBLE_OPTIONS:
self.selection_action_chosen_ensemble_load_saved(selection)
2023-09-26 00:11:08 +02:00
elif selection == SAVE_ENSEMBLE:
2022-12-19 04:18:56 +01:00
self.chosen_ensemble_var.set(CHOOSE_ENSEMBLE_OPTION)
self.pop_up_save_ensemble()
2023-09-26 00:11:08 +02:00
elif selection == OPT_SEPARATOR_SAVE:
2022-12-19 04:18:56 +01:00
self.chosen_ensemble_var.set(CHOOSE_ENSEMBLE_OPTION)
2023-09-26 00:11:08 +02:00
elif selection == CLEAR_ENSEMBLE:
2022-12-19 04:18:56 +01:00
self.ensemble_listbox_Option.selection_clear(0, 'end')
self.chosen_ensemble_var.set(CHOOSE_ENSEMBLE_OPTION)
def selection_action_chosen_ensemble_load_saved(self, saved_ensemble):
"""Loads the data from selected saved ensemble"""
saved_data = None
saved_ensemble = saved_ensemble.replace(" ", "_")
saved_ensemble_path = os.path.join(ENSEMBLE_CACHE_DIR, f'{saved_ensemble}.json')
if os.path.isfile(saved_ensemble_path):
saved_data = json.load(open(saved_ensemble_path))
if saved_data:
self.selection_action_ensemble_stems(saved_data['ensemble_main_stem'], from_menu=False)
self.ensemble_main_stem_var.set(saved_data['ensemble_main_stem'])
self.ensemble_type_var.set(saved_data['ensemble_type'])
self.saved_model_list = saved_data['selected_models']
for saved_model in self.saved_model_list:
status = self.assemble_model_data(saved_model, ENSEMBLE_CHECK)[0].model_status
if not status:
self.saved_model_list.remove(saved_model)
indexes = self.ensemble_listbox_get_indexes_for_files(self.model_stems_list, self.saved_model_list)
for i in indexes:
self.ensemble_listbox_Option.selection_set(i)
2023-09-26 00:11:08 +02:00
self.update_checkbox_text()
2022-12-19 04:18:56 +01:00
def selection_action_ensemble_stems(self, selection: str, from_menu=True, auto_update=None):
"""Filters out all models from ensemble listbox that are incompatible with selected ensemble stem"""
2023-09-26 00:11:08 +02:00
is_multi_stem = False
2022-12-19 04:18:56 +01:00
if not selection == CHOOSE_STEM_PAIR:
2023-09-26 00:11:08 +02:00
if selection in [FOUR_STEM_ENSEMBLE, MULTI_STEM_ENSEMBLE]:
2022-12-19 04:18:56 +01:00
self.update_stem_checkbox_labels(PRIMARY_STEM, disable_boxes=True)
self.update_ensemble_algorithm_menu(is_4_stem=True)
self.ensemble_primary_stem = PRIMARY_STEM
self.ensemble_secondary_stem = SECONDARY_STEM
is_4_stem_check = True
2023-09-26 00:11:08 +02:00
if selection == MULTI_STEM_ENSEMBLE:
is_multi_stem = True
2022-12-19 04:18:56 +01:00
else:
self.update_ensemble_algorithm_menu()
self.is_stem_only_Options_Enable()
stems = selection.partition("/")
self.update_stem_checkbox_labels(stems[0])
self.ensemble_primary_stem = stems[0]
self.ensemble_secondary_stem = stems[2]
is_4_stem_check = False
2023-09-26 00:11:08 +02:00
self.model_stems_list = self.model_list(self.ensemble_primary_stem, self.ensemble_secondary_stem, is_4_stem_check=is_4_stem_check, is_multi_stem=is_multi_stem)
2022-12-19 04:18:56 +01:00
self.ensemble_listbox_Option.configure(state=tk.NORMAL)
self.ensemble_listbox_clear_and_insert_new(self.model_stems_list)
if auto_update:
indexes = self.ensemble_listbox_get_indexes_for_files(self.model_stems_list, auto_update)
self.ensemble_listbox_select_from_indexs(indexes)
else:
self.ensemble_listbox_Option.configure(state=tk.DISABLED)
self.update_stem_checkbox_labels(PRIMARY_STEM, disable_boxes=True)
self.model_stems_list = ()
if from_menu:
self.chosen_ensemble_var.set(CHOOSE_ENSEMBLE_OPTION)
def selection_action_saved_settings(self, selection, process_method=None):
"""Activates specific action based on the selected settings from the saved settings selections"""
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if self.thread_check(self.active_processing_thread):
self.error_dialoge(SET_TO_ANY_PROCESS_ERROR)
2023-09-26 00:11:08 +02:00
return
chosen_process_method = self.chosen_process_method_var.get()
if process_method:
chosen_process_method = process_method
if selection in SAVE_SET_OPTIONS:
self.handle_special_options(selection, chosen_process_method)
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
self.handle_saved_settings(selection, chosen_process_method)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
self.update_checkbox_text()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def handle_special_options(self, selection, process_method):
"""Handles actions for special options."""
if selection == SAVE_SETTINGS:
self.save_current_settings_var.set(SELECT_SAVED_SET)
self.pop_up_save_current_settings()
elif selection == RESET_TO_DEFAULT:
self.save_current_settings_var.set(SELECT_SAVED_SET)
self.load_saved_settings(DEFAULT_DATA, process_method)
elif selection == OPT_SEPARATOR_SAVE:
self.save_current_settings_var.set(SELECT_SAVED_SET)
def handle_saved_settings(self, selection, process_method):
"""Handles actions for saved settings."""
selection = selection.replace(" ", "_")
saved_ensemble_path = os.path.join(SETTINGS_CACHE_DIR, f'{selection}.json')
if os.path.isfile(saved_ensemble_path):
with open(saved_ensemble_path, 'r') as file:
saved_data = json.load(file)
if saved_data:
self.load_saved_settings(saved_data, process_method)
2022-12-19 04:18:56 +01:00
#--Processing Methods--
def process_input_selections(self):
"""Grabbing all audio files from selected directories."""
input_list = []
ext = FFMPEG_EXT if not self.is_accept_any_input_var.get() else ANY_EXT
for i in self.inputPaths:
if os.path.isfile(i):
if i.endswith(ext):
input_list.append(i)
for root, dirs, files in os.walk(i):
for file in files:
if file.endswith(ext):
file = os.path.join(root, file)
if os.path.isfile(file):
input_list.append(file)
self.inputPaths = tuple(input_list)
2023-09-26 00:11:08 +02:00
def process_check_wav_type(self):
2022-12-19 04:18:56 +01:00
if self.wav_type_set_var.get() == '32-bit Float':
self.wav_type_set = 'FLOAT'
2023-09-26 00:11:08 +02:00
elif self.wav_type_set_var.get() == '64-bit Float':#
2022-12-19 04:18:56 +01:00
self.wav_type_set = 'FLOAT' if not self.save_format_var.get() == WAV else 'DOUBLE'
else:
self.wav_type_set = self.wav_type_set_var.get()
2023-09-26 00:11:08 +02:00
def process_preliminary_checks(self):
"""Verifies a valid model is chosen"""
self.process_check_wav_type()
2022-12-19 04:18:56 +01:00
if self.chosen_process_method_var.get() == ENSEMBLE_MODE:
continue_process = lambda:False if len(self.ensemble_listbox_get_all_selected_models()) <= 1 else True
if self.chosen_process_method_var.get() == VR_ARCH_PM:
continue_process = lambda:False if self.vr_model_var.get() == CHOOSE_MODEL else True
if self.chosen_process_method_var.get() == MDX_ARCH_TYPE:
continue_process = lambda:False if self.mdx_net_model_var.get() == CHOOSE_MODEL else True
if self.chosen_process_method_var.get() == DEMUCS_ARCH_TYPE:
continue_process = lambda:False if self.demucs_model_var.get() == CHOOSE_MODEL else True
return continue_process()
def process_storage_check(self):
"""Verifies storage requirments"""
total, used, free = shutil.disk_usage("/")
space_details = f'Detected Total Space: {int(total/1.074e+9)} GB\'s\n' +\
f'Detected Used Space: {int(used/1.074e+9)} GB\'s\n' +\
f'Detected Free Space: {int(free/1.074e+9)} GB\'s\n'
appropriate_storage = True
if int(free/1.074e+9) <= int(2):
self.error_dialoge([STORAGE_ERROR[0], f'{STORAGE_ERROR[1]}{space_details}'])
appropriate_storage = False
if int(free/1.074e+9) in [3, 4, 5, 6, 7, 8]:
appropriate_storage = self.message_box([STORAGE_WARNING[0], f'{STORAGE_WARNING[1]}{space_details}{CONFIRM_WARNING}'])
return appropriate_storage
def process_initialize(self):
"""Verifies the input/output directories are valid and prepares to thread the main process."""
2023-09-26 00:11:08 +02:00
if not (
self.chosen_process_method_var.get() == AUDIO_TOOLS
and self.chosen_audio_tool_var.get() in [ALIGN_INPUTS, MATCH_INPUTS]
and self.fileOneEntry_var.get()
and self.fileTwoEntry_var.get()
) and not (
self.inputPaths and os.path.isfile(self.inputPaths[0])
):
2022-12-19 04:18:56 +01:00
self.error_dialoge(INVALID_INPUT)
return
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if not os.path.isdir(self.export_path_var.get()):
self.error_dialoge(INVALID_EXPORT)
return
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
if not self.process_storage_check():
return
2023-09-26 00:11:08 +02:00
if self.chosen_process_method_var.get() != AUDIO_TOOLS:
2022-12-19 04:18:56 +01:00
if not self.process_preliminary_checks():
2023-09-26 00:11:08 +02:00
error_msg = INVALID_ENSEMBLE if self.chosen_process_method_var.get() == ENSEMBLE_MODE else INVALID_MODEL
self.error_dialoge(error_msg)
2022-12-19 04:18:56 +01:00
return
2023-09-26 00:11:08 +02:00
target_function = self.process_start
2022-12-19 04:18:56 +01:00
else:
2023-09-26 00:11:08 +02:00
target_function = self.process_tool_start
self.active_processing_thread = KThread(target=target_function)
self.active_processing_thread.start()
2022-12-19 04:18:56 +01:00
def process_button_init(self):
2023-10-12 06:30:24 +02:00
self.auto_save()
2022-12-19 04:18:56 +01:00
self.conversion_Button_Text_var.set(WAIT_PROCESSING)
self.conversion_Button.configure(state=tk.DISABLED)
2023-03-31 12:15:39 +02:00
self.command_Text.clear()
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def process_get_baseText(self, total_files, file_num, is_dual=False):
2022-12-19 04:18:56 +01:00
"""Create the base text for the command widget"""
2023-09-26 00:11:08 +02:00
init_text = 'Files' if is_dual else 'File'
text = '{init_text} {file_num}/{total_files} '.format(init_text=init_text,
file_num=file_num,
total_files=total_files)
2022-12-19 04:18:56 +01:00
return text
2023-09-26 00:11:08 +02:00
def process_update_progress(self, total_files, step: float = 1):
2022-12-19 04:18:56 +01:00
"""Calculate the progress for the progress widget in the GUI"""
2023-09-26 00:11:08 +02:00
total_count = self.true_model_count * total_files
2022-12-19 04:18:56 +01:00
base = (100 / total_count)
progress = base * self.iteration - base
progress += base * step
self.progress_bar_main_var.set(progress)
self.conversion_Button_Text_var.set(f'Process Progress: {int(progress)}%')
def confirm_stop_process(self):
"""Asks for confirmation before halting active process"""
2023-10-12 06:30:24 +02:00
self.auto_save()
2022-12-19 04:18:56 +01:00
if self.thread_check(self.active_processing_thread):
2023-09-26 00:11:08 +02:00
confirm = messagebox.askyesno(parent=root, title=STOP_PROCESS_CONFIRM[0], message=STOP_PROCESS_CONFIRM[1])
2022-12-19 04:18:56 +01:00
if confirm:
try:
self.active_processing_thread.terminate()
finally:
self.is_process_stopped = True
2023-09-26 00:11:08 +02:00
self.command_Text.write(PROCESS_STOPPED_BY_USER)
2022-12-19 04:18:56 +01:00
else:
self.clear_cache_torch = True
def process_end(self, error=None):
"""End of process actions"""
2023-10-12 06:30:24 +02:00
self.auto_save()
2022-12-19 04:18:56 +01:00
self.cached_sources_clear()
self.clear_cache_torch = True
self.conversion_Button_Text_var.set(START_PROCESSING)
self.conversion_Button.configure(state=tk.NORMAL)
self.progress_bar_main_var.set(0)
2023-03-31 12:15:39 +02:00
2022-12-19 04:18:56 +01:00
if error:
error_message_box_text = f'{error_dialouge(error)}{ERROR_OCCURED[1]}'
2023-09-26 00:11:08 +02:00
confirm = messagebox.askyesno(parent=root,
2022-12-19 04:18:56 +01:00
title=ERROR_OCCURED[0],
message=error_message_box_text)
if confirm:
self.is_confirm_error_var.set(True)
self.clear_cache_torch = True
self.clear_cache_torch = True
if MODEL_MISSING_CHECK in error_message_box_text:
self.update_checkbox_text()
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def process_tool_start(self):
"""Start the conversion for all the given mp3 and wav files"""
2023-09-26 00:11:08 +02:00
def time_elapsed():
return f'Time Elapsed: {time.strftime("%H:%M:%S", time.gmtime(int(time.perf_counter() - stime)))}'
def get_audio_file_base(audio_file):
if audio_tool.audio_tool == MANUAL_ENSEMBLE:
return f'{os.path.splitext(os.path.basename(inputPaths[0]))[0]}'
elif audio_tool.audio_tool in [ALIGN_INPUTS, MATCH_INPUTS]:
return f'{os.path.splitext(os.path.basename(audio_file[0]))[0]}'
else:
return f'{os.path.splitext(os.path.basename(audio_file))[0]}'
def handle_ensemble(inputPaths, audio_file_base):
self.progress_bar_main_var.set(50)
if self.choose_algorithm_var.get() == COMBINE_INPUTS:
audio_tool.combine_audio(inputPaths, audio_file_base)
else:
audio_tool.ensemble_manual(inputPaths, audio_file_base)
self.progress_bar_main_var.set(100)
self.command_Text.write(DONE)
def handle_alignment_match(audio_file, audio_file_base, command_Text, set_progress_bar):
audio_file_2_base = f'{os.path.splitext(os.path.basename(audio_file[1]))[0]}'
if audio_tool.audio_tool == MATCH_INPUTS:
audio_tool.match_inputs(audio_file, audio_file_base, command_Text)
else:
2023-09-29 08:46:41 +02:00
command_Text(f"{PROCESS_STARTING_TEXT}\n")
2023-09-26 00:11:08 +02:00
audio_tool.align_inputs(audio_file, audio_file_base, audio_file_2_base, command_Text, set_progress_bar)
self.progress_bar_main_var.set(base * file_num)
self.command_Text.write(f"{DONE}\n")
def handle_pitch_time_shift(audio_file, audio_file_base):
audio_tool.pitch_or_time_shift(audio_file, audio_file_base)
self.progress_bar_main_var.set(base * file_num)
self.command_Text.write(DONE)
2022-12-19 04:18:56 +01:00
multiple_files = False
stime = time.perf_counter()
self.process_button_init()
inputPaths = self.inputPaths
is_verified_audio = True
2023-09-26 00:11:08 +02:00
is_dual = False
2022-12-19 04:18:56 +01:00
is_model_sample_mode = self.model_sample_mode_var.get()
2023-09-26 00:11:08 +02:00
self.iteration = 0
self.true_model_count = 1
self.process_check_wav_type()
process_complete_text = PROCESS_COMPLETE
if self.chosen_audio_tool_var.get() in [ALIGN_INPUTS, MATCH_INPUTS]:
if self.DualBatch_inputPaths:
inputPaths = tuple(self.DualBatch_inputPaths)
else:
if not self.fileOneEntry_Full_var.get() or not self.fileTwoEntry_Full_var.get():
self.command_Text.write(NOT_ENOUGH_ERROR_TEXT)
self.process_end()
return
else:
inputPaths = [(self.fileOneEntry_Full_var.get(), self.fileTwoEntry_Full_var.get())]
2022-12-19 04:18:56 +01:00
try:
total_files = len(inputPaths)
if self.chosen_audio_tool_var.get() == TIME_STRETCH:
audio_tool = AudioTools(TIME_STRETCH)
self.progress_bar_main_var.set(2)
2023-09-26 00:11:08 +02:00
elif self.chosen_audio_tool_var.get() == CHANGE_PITCH:
2022-12-19 04:18:56 +01:00
audio_tool = AudioTools(CHANGE_PITCH)
self.progress_bar_main_var.set(2)
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
multiple_files = True
if total_files <= 1:
2023-09-26 00:11:08 +02:00
self.command_Text.write(NOT_ENOUGH_ERROR_TEXT)
2022-12-19 04:18:56 +01:00
self.process_end()
return
2023-09-26 00:11:08 +02:00
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
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
for file_num, audio_file in enumerate(inputPaths, start=1):
self.iteration += 1
base = (100 / total_files)
audio_file_base = get_audio_file_base(audio_file)
self.base_text = self.process_get_baseText(total_files=total_files, file_num=total_files if multiple_files else file_num, is_dual=is_dual)
command_Text = lambda text: self.command_Text.write(self.base_text + text)
set_progress_bar = lambda step, inference_iterations=0:self.process_update_progress(total_files=total_files, step=(step + (inference_iterations)))
if not self.verify_audio(audio_file):
error_text_console = f'{self.base_text}"{os.path.basename(audio_file)}\" {MISSING_MESS_TEXT}\n'
if total_files >= 2:
self.command_Text.write(f'\n{error_text_console}')
2022-12-19 04:18:56 +01:00
is_verified_audio = False
continue
2023-09-26 00:11:08 +02:00
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}')
elif audio_tool_action in [ALIGN_INPUTS, MATCH_INPUTS]:
text_write = ("File 1", "File 2") if audio_tool_action == ALIGN_INPUTS else ("Target", "Reference")
if audio_file[0] != audio_file[1]:
self.command_Text.write(f'{self.base_text}{text_write[0]}: "{os.path.basename(audio_file[0])}"{NEW_LINE}')
self.command_Text.write(f'{self.base_text}{text_write[1]}: "{os.path.basename(audio_file[1])}"{NEW_LINES}')
else:
self.command_Text.write(f'{self.base_text}{text_write[0]} & {text_write[1]} {SIMILAR_TEXT}{NEW_LINES}')
continue
elif audio_tool_action == MANUAL_ENSEMBLE:
for n, i in enumerate(inputPaths):
self.command_Text.write(f'File {n+1} "{os.path.basename(i)}"{NEW_LINE}')
self.command_Text.write(NEW_LINE)
is_verified_audio = True
if not audio_tool_action in [ALIGN_INPUTS, MATCH_INPUTS]:
command_Text(PROCESS_STARTING_TEXT)
if audio_tool_action == MANUAL_ENSEMBLE:
handle_ensemble(inputPaths, audio_file_base)
2022-12-19 04:18:56 +01:00
break
2023-09-26 00:11:08 +02:00
if audio_tool_action in [ALIGN_INPUTS, MATCH_INPUTS]:
process_complete_text = PROCESS_COMPLETE_2
handle_alignment_match(audio_file, audio_file_base, command_Text, set_progress_bar)
if audio_tool_action in [TIME_STRETCH, CHANGE_PITCH]:
handle_pitch_time_shift(audio_file, audio_file_base)
2022-12-19 04:18:56 +01:00
if total_files == 1 and not is_verified_audio:
self.command_Text.write(f'{error_text_console}\n{PROCESS_FAILED}')
self.command_Text.write(time_elapsed())
playsound(FAIL_CHIME) if self.is_task_complete_var.get() else None
else:
2023-09-26 00:11:08 +02:00
self.command_Text.write('{}{}'.format(process_complete_text, time_elapsed()))
2022-12-19 04:18:56 +01:00
playsound(COMPLETE_CHIME) if self.is_task_complete_var.get() else None
self.process_end()
except Exception as e:
self.error_log_var.set(error_text(self.chosen_audio_tool_var.get(), e))
self.command_Text.write(f'\n\n{PROCESS_FAILED}')
self.command_Text.write(time_elapsed())
playsound(FAIL_CHIME) if self.is_task_complete_var.get() else None
self.process_end(error=e)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
def process_determine_secondary_model(self, process_method, main_model_primary_stem, is_primary_stem_only=False, is_secondary_stem_only=False):
"""Obtains the correct secondary model data for conversion."""
secondary_model_scale = None
2023-09-26 00:11:08 +02:00
secondary_model = tk.StringVar(value=NO_MODEL)
2022-12-19 04:18:56 +01:00
if process_method == VR_ARCH_TYPE:
secondary_model_vars = self.vr_secondary_model_vars
if process_method == MDX_ARCH_TYPE:
secondary_model_vars = self.mdx_secondary_model_vars
if process_method == DEMUCS_ARCH_TYPE:
secondary_model_vars = self.demucs_secondary_model_vars
if main_model_primary_stem in [VOCAL_STEM, INST_STEM]:
secondary_model = secondary_model_vars["voc_inst_secondary_model"]
secondary_model_scale = secondary_model_vars["voc_inst_secondary_model_scale"].get()
if main_model_primary_stem in [OTHER_STEM, NO_OTHER_STEM]:
secondary_model = secondary_model_vars["other_secondary_model"]
secondary_model_scale = secondary_model_vars["other_secondary_model_scale"].get()
if main_model_primary_stem in [DRUM_STEM, NO_DRUM_STEM]:
secondary_model = secondary_model_vars["drums_secondary_model"]
secondary_model_scale = secondary_model_vars["drums_secondary_model_scale"].get()
if main_model_primary_stem in [BASS_STEM, NO_BASS_STEM]:
secondary_model = secondary_model_vars["bass_secondary_model"]
secondary_model_scale = secondary_model_vars["bass_secondary_model_scale"].get()
if secondary_model_scale:
secondary_model_scale = float(secondary_model_scale)
if not secondary_model.get() == NO_MODEL:
secondary_model = ModelData(secondary_model.get(),
is_secondary_model=True,
primary_model_primary_stem=main_model_primary_stem,
is_primary_model_primary_stem_only=is_primary_stem_only,
is_primary_model_secondary_stem_only=is_secondary_stem_only)
if not secondary_model.model_status:
secondary_model = None
else:
secondary_model = None
return secondary_model, secondary_model_scale
def process_determine_demucs_pre_proc_model(self, primary_stem=None):
2023-09-26 00:11:08 +02:00
"""Obtains the correct pre-process secondary model data for conversion."""
# Check if a pre-process model is set and it's not the 'NO_MODEL' value
if self.demucs_pre_proc_model_var.get() != NO_MODEL and self.is_demucs_pre_proc_model_activate_var.get():
2022-12-19 04:18:56 +01:00
pre_proc_model = ModelData(self.demucs_pre_proc_model_var.get(),
primary_model_primary_stem=primary_stem,
is_pre_proc_model=True)
2023-09-26 00:11:08 +02:00
# Return the model if it's valid
if pre_proc_model.model_status:
return pre_proc_model
return None
def process_determine_vocal_split_model(self):
"""Obtains the correct vocal splitter secondary model data for conversion."""
# Check if a vocal splitter model is set and if it's not the 'NO_MODEL' value
if self.set_vocal_splitter_var.get() != NO_MODEL and self.is_set_vocal_splitter_var.get():
vocal_splitter_model = ModelData(self.set_vocal_splitter_var.get(), is_vocal_split_model=True)
# Return the model if it's valid
if vocal_splitter_model.model_status:
return vocal_splitter_model
return None
def check_only_selection_stem(self, checktype):
chosen_method = self.chosen_process_method_var.get()
is_demucs = chosen_method == DEMUCS_ARCH_TYPE#
stem_primary_label = self.is_primary_stem_only_Demucs_Text_var.get() if is_demucs else self.is_primary_stem_only_Text_var.get()
stem_primary_bool = self.is_primary_stem_only_Demucs_var.get() if is_demucs else self.is_primary_stem_only_var.get()
stem_secondary_label = self.is_secondary_stem_only_Demucs_Text_var.get() if is_demucs else self.is_secondary_stem_only_Text_var.get()
stem_secondary_bool = self.is_secondary_stem_only_Demucs_var.get() if is_demucs else self.is_secondary_stem_only_var.get()
if checktype == VOCAL_STEM_ONLY:
return not (
(not VOCAL_STEM_ONLY == stem_primary_label and stem_primary_bool) or
(not VOCAL_STEM_ONLY in stem_secondary_label and stem_secondary_bool)
)
elif checktype == INST_STEM_ONLY:
return (
(INST_STEM_ONLY == stem_primary_label and stem_primary_bool and self.is_save_inst_set_vocal_splitter_var.get() and self.set_vocal_splitter_var.get() != NO_MODEL) or
(INST_STEM_ONLY == stem_secondary_label and stem_secondary_bool and self.is_save_inst_set_vocal_splitter_var.get() and self.set_vocal_splitter_var.get() != NO_MODEL)
)
elif checktype == IS_SAVE_VOC_ONLY:
return (
(VOCAL_STEM_ONLY == stem_primary_label and stem_primary_bool) or
(VOCAL_STEM_ONLY == stem_secondary_label and stem_secondary_bool)
)
elif checktype == IS_SAVE_INST_ONLY:
return (
(INST_STEM_ONLY == stem_primary_label and stem_primary_bool) or
(INST_STEM_ONLY == stem_secondary_label and stem_secondary_bool)
)
def determine_voc_split(self, models):
is_vocal_active = self.check_only_selection_stem(VOCAL_STEM_ONLY) or self.check_only_selection_stem(INST_STEM_ONLY)
if self.set_vocal_splitter_var.get() != NO_MODEL and self.is_set_vocal_splitter_var.get() and is_vocal_active:
model_stems_list = self.model_list(VOCAL_STEM, INST_STEM, is_dry_check=True, is_check_vocal_split=True)
if any(model.model_basename in model_stems_list for model in models):
return 1
return 0
2022-12-19 04:18:56 +01:00
def process_start(self):
"""Start the conversion for all the given mp3 and wav files"""
stime = time.perf_counter()
time_elapsed = lambda:f'Time Elapsed: {time.strftime("%H:%M:%S", time.gmtime(int(time.perf_counter() - stime)))}'
export_path = self.export_path_var.get()
is_ensemble = False
2023-09-26 00:11:08 +02:00
self.true_model_count = 0
2022-12-19 04:18:56 +01:00
self.iteration = 0
is_verified_audio = True
self.process_button_init()
inputPaths = self.inputPaths
inputPath_total_len = len(inputPaths)
is_model_sample_mode = self.model_sample_mode_var.get()
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
try:
if self.chosen_process_method_var.get() == ENSEMBLE_MODE:
model, ensemble = self.assemble_model_data(), Ensembler()
export_path, is_ensemble = ensemble.ensemble_folder_name, True
if self.chosen_process_method_var.get() == VR_ARCH_PM:
model = self.assemble_model_data(self.vr_model_var.get(), VR_ARCH_TYPE)
if self.chosen_process_method_var.get() == MDX_ARCH_TYPE:
model = self.assemble_model_data(self.mdx_net_model_var.get(), MDX_ARCH_TYPE)
if self.chosen_process_method_var.get() == DEMUCS_ARCH_TYPE:
model = self.assemble_model_data(self.demucs_model_var.get(), DEMUCS_ARCH_TYPE)
self.cached_source_model_list_check(model)
true_model_4_stem_count = sum(m.demucs_4_stem_added_count if m.process_method == DEMUCS_ARCH_TYPE else 0 for m in model)
true_model_pre_proc_model_count = sum(2 if m.pre_proc_model_activated else 0 for m in model)
2023-09-26 00:11:08 +02:00
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)
2022-12-19 04:18:56 +01:00
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)
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}')
is_verified_audio = True
else:
2023-09-26 00:11:08 +02:00
error_text_console = f'{base_text}"{os.path.basename(audio_file)}\" {MISSING_MESS_TEXT}\n'
2022-12-19 04:18:56 +01:00
self.command_Text.write(f'\n{error_text_console}') if inputPath_total_len >= 2 else None
2023-09-26 00:11:08 +02:00
self.iteration += self.true_model_count
2022-12-19 04:18:56 +01:00
is_verified_audio = False
continue
for current_model_num, current_model in enumerate(model, start=1):
self.iteration += 1
2022-12-30 04:07:23 +01:00
2022-12-19 04:18:56 +01:00
if is_ensemble:
self.command_Text.write(f'Ensemble Mode - {current_model.model_basename} - Model {current_model_num}/{len(model)}{NEW_LINES}')
model_name_text = f'({current_model.model_basename})' if not is_ensemble else ''
2023-09-26 00:11:08 +02:00
self.command_Text.write(base_text + f'{LOADING_MODEL_TEXT} {model_name_text}...')
2022-12-30 04:07:23 +01:00
2023-09-26 00:11:08 +02:00
set_progress_bar = lambda step, inference_iterations=0:self.process_update_progress(total_files=inputPath_total_len, step=(step + (inference_iterations)))
2022-12-19 04:18:56 +01:00
write_to_console = lambda progress_text, base_text=base_text:self.command_Text.write(base_text + progress_text)
2022-12-30 04:07:23 +01:00
2022-12-19 04:18:56 +01:00
audio_file_base = f"{file_num}_{os.path.splitext(os.path.basename(audio_file))[0]}"
audio_file_base = audio_file_base if not self.is_testing_audio_var.get() or is_ensemble else f"{round(time.time())}_{audio_file_base}"
audio_file_base = audio_file_base if not is_ensemble else f"{audio_file_base}_{current_model.model_basename}"
2023-03-31 12:15:39 +02:00
if not is_ensemble:
audio_file_base = audio_file_base if not self.is_add_model_name_var.get() else f"{audio_file_base}_{current_model.model_basename}"
2022-12-19 04:18:56 +01:00
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)
process_data = {
'model_data': current_model,
'export_path': export_path,
'audio_file_base': audio_file_base,
'audio_file': audio_file,
'set_progress_bar': set_progress_bar,
'write_to_console': write_to_console,
'process_iteration': self.process_iteration,
'cached_source_callback': self.cached_source_callback,
'cached_model_source_holder': self.cached_model_source_holder,
'list_all_models': self.all_models,
'is_ensemble_master': is_ensemble,
2023-09-26 00:11:08 +02:00
'is_4_stem_ensemble': True if self.ensemble_main_stem_var.get() in [FOUR_STEM_ENSEMBLE, MULTI_STEM_ENSEMBLE] and is_ensemble else False}
2023-03-31 12:15:39 +02:00
2022-12-19 04:18:56 +01:00
if current_model.process_method == VR_ARCH_TYPE:
seperator = SeperateVR(current_model, process_data)
if current_model.process_method == MDX_ARCH_TYPE:
2023-09-26 00:11:08 +02:00
seperator = SeperateMDXC(current_model, process_data) if current_model.is_mdx_c else SeperateMDX(current_model, process_data)
2022-12-19 04:18:56 +01:00
if current_model.process_method == DEMUCS_ARCH_TYPE:
seperator = SeperateDemucs(current_model, process_data)
2023-03-31 12:15:39 +02:00
2022-12-19 04:18:56 +01:00
seperator.seperate()
if is_ensemble:
self.command_Text.write('\n')
if is_ensemble:
audio_file_base = audio_file_base.replace(f"_{current_model.model_basename}","")
self.command_Text.write(base_text + ENSEMBLING_OUTPUTS)
2023-09-26 00:11:08 +02:00
if self.ensemble_main_stem_var.get() in [FOUR_STEM_ENSEMBLE, MULTI_STEM_ENSEMBLE]:
stem_list = extract_stems(audio_file_base, export_path)
for output_stem in stem_list:
2022-12-19 04:18:56 +01:00
ensemble.ensemble_outputs(audio_file_base, export_path, output_stem, is_4_stem=True)
else:
if not self.is_secondary_stem_only_var.get():
ensemble.ensemble_outputs(audio_file_base, export_path, PRIMARY_STEM)
if not self.is_primary_stem_only_var.get():
ensemble.ensemble_outputs(audio_file_base, export_path, SECONDARY_STEM)
ensemble.ensemble_outputs(audio_file_base, export_path, SECONDARY_STEM, is_inst_mix=True)
self.command_Text.write(DONE)
if is_model_sample_mode:
if os.path.isfile(audio_file):
os.remove(audio_file)
2023-10-12 06:30:24 +02:00
clear_gpu_cache()
2022-12-19 04:18:56 +01:00
shutil.rmtree(export_path) if is_ensemble and len(os.listdir(export_path)) == 0 else None
if inputPath_total_len == 1 and not is_verified_audio:
self.command_Text.write(f'{error_text_console}\n{PROCESS_FAILED}')
self.command_Text.write(time_elapsed())
playsound(FAIL_CHIME) if self.is_task_complete_var.get() else None
else:
set_progress_bar(1.0)
2023-09-26 00:11:08 +02:00
self.command_Text.write(PROCESS_COMPLETE)
2022-12-19 04:18:56 +01:00
self.command_Text.write(time_elapsed())
playsound(COMPLETE_CHIME) if self.is_task_complete_var.get() else None
self.process_end()
2023-03-31 12:15:39 +02:00
2022-12-19 04:18:56 +01:00
except Exception as e:
2022-12-19 23:26:47 +01:00
self.error_log_var.set("{}{}".format(error_text(self.chosen_process_method_var.get(), e), self.get_settings_list()))
2022-12-19 04:18:56 +01:00
self.command_Text.write(f'\n\n{PROCESS_FAILED}')
self.command_Text.write(time_elapsed())
playsound(FAIL_CHIME) if self.is_task_complete_var.get() else None
self.process_end(error=e)
#--Varible Methods--
def load_to_default_confirm(self):
"""Reset settings confirmation after asking for confirmation"""
if self.thread_check(self.active_processing_thread):
2023-09-26 00:11:08 +02:00
self.error_dialogue(SET_TO_DEFAULT_PROCESS_ERROR)
return
confirm = messagebox.askyesno(
parent=root,
title=RESET_ALL_TO_DEFAULT_WARNING[0],
message=RESET_ALL_TO_DEFAULT_WARNING[1]
)
if not confirm:
return
self.load_saved_settings(DEFAULT_DATA, is_default_reset=True)
self.update_checkbox_text()
if self.pre_proc_model_toggle is not None and self.is_open_menu_advanced_demucs_options.get():
self.pre_proc_model_toggle()
if (self.change_state_lambda is not None and (
self.is_open_menu_advanced_vr_options.get() or
self.is_open_menu_advanced_mdx_options.get() or
self.is_open_menu_advanced_demucs_options.get()
)):
self.change_state_lambda()
2022-12-19 04:18:56 +01:00
def load_saved_vars(self, data):
"""Initializes primary Tkinter vars"""
2022-12-21 11:18:16 +01:00
for key, value in DEFAULT_DATA.items():
if not key in data.keys():
data = {**data, **{key:value}}
2023-03-31 12:15:39 +02:00
data['batch_size'] = DEF_OPT
2022-12-19 04:18:56 +01:00
## ADD_BUTTON
self.chosen_process_method_var = tk.StringVar(value=data['chosen_process_method'])
#VR Architecture Vars
self.vr_model_var = tk.StringVar(value=data['vr_model'])
self.aggression_setting_var = tk.StringVar(value=data['aggression_setting'])
self.window_size_var = tk.StringVar(value=data['window_size'])
2023-09-26 00:11:08 +02:00
self.mdx_segment_size_var = tk.StringVar(value=data['mdx_segment_size'])
2022-12-19 04:18:56 +01:00
self.batch_size_var = tk.StringVar(value=data['batch_size'])
self.crop_size_var = tk.StringVar(value=data['crop_size'])
self.is_tta_var = tk.BooleanVar(value=data['is_tta'])
self.is_output_image_var = tk.BooleanVar(value=data['is_output_image'])
self.is_post_process_var = tk.BooleanVar(value=data['is_post_process'])
self.is_high_end_process_var = tk.BooleanVar(value=data['is_high_end_process'])
2022-12-21 11:18:16 +01:00
self.post_process_threshold_var = tk.StringVar(value=data['post_process_threshold'])
2022-12-19 04:18:56 +01:00
self.vr_voc_inst_secondary_model_var = tk.StringVar(value=data['vr_voc_inst_secondary_model'])
self.vr_other_secondary_model_var = tk.StringVar(value=data['vr_other_secondary_model'])
self.vr_bass_secondary_model_var = tk.StringVar(value=data['vr_bass_secondary_model'])
self.vr_drums_secondary_model_var = tk.StringVar(value=data['vr_drums_secondary_model'])
self.vr_is_secondary_model_activate_var = tk.BooleanVar(value=data['vr_is_secondary_model_activate'])
self.vr_voc_inst_secondary_model_scale_var = tk.StringVar(value=data['vr_voc_inst_secondary_model_scale'])
self.vr_other_secondary_model_scale_var = tk.StringVar(value=data['vr_other_secondary_model_scale'])
self.vr_bass_secondary_model_scale_var = tk.StringVar(value=data['vr_bass_secondary_model_scale'])
self.vr_drums_secondary_model_scale_var = tk.StringVar(value=data['vr_drums_secondary_model_scale'])
#Demucs Vars
self.demucs_model_var = tk.StringVar(value=data['demucs_model'])
self.segment_var = tk.StringVar(value=data['segment'])
self.overlap_var = tk.StringVar(value=data['overlap'])
2023-09-26 00:11:08 +02:00
self.overlap_mdx_var = tk.StringVar(value=data['overlap_mdx'])
self.overlap_mdx23_var = tk.StringVar(value=data['overlap_mdx23'])
2022-12-19 04:18:56 +01:00
self.shifts_var = tk.StringVar(value=data['shifts'])
self.chunks_demucs_var = tk.StringVar(value=data['chunks_demucs'])
self.margin_demucs_var = tk.StringVar(value=data['margin_demucs'])
self.is_chunk_demucs_var = tk.BooleanVar(value=data['is_chunk_demucs'])
2023-09-26 00:11:08 +02:00
self.is_chunk_mdxnet_var = tk.BooleanVar(value=False)
2022-12-19 04:18:56 +01:00
self.is_primary_stem_only_Demucs_var = tk.BooleanVar(value=data['is_primary_stem_only_Demucs'])
self.is_secondary_stem_only_Demucs_var = tk.BooleanVar(value=data['is_secondary_stem_only_Demucs'])
self.is_split_mode_var = tk.BooleanVar(value=data['is_split_mode'])
2023-09-26 00:11:08 +02:00
self.is_demucs_combine_stems_var = tk.BooleanVar(value=data['is_demucs_combine_stems'])#is_mdx23_combine_stems
self.is_mdx23_combine_stems_var = tk.BooleanVar(value=data['is_mdx23_combine_stems'])
2022-12-19 04:18:56 +01:00
self.demucs_voc_inst_secondary_model_var = tk.StringVar(value=data['demucs_voc_inst_secondary_model'])
self.demucs_other_secondary_model_var = tk.StringVar(value=data['demucs_other_secondary_model'])
self.demucs_bass_secondary_model_var = tk.StringVar(value=data['demucs_bass_secondary_model'])
self.demucs_drums_secondary_model_var = tk.StringVar(value=data['demucs_drums_secondary_model'])
self.demucs_is_secondary_model_activate_var = tk.BooleanVar(value=data['demucs_is_secondary_model_activate'])
self.demucs_voc_inst_secondary_model_scale_var = tk.StringVar(value=data['demucs_voc_inst_secondary_model_scale'])
self.demucs_other_secondary_model_scale_var = tk.StringVar(value=data['demucs_other_secondary_model_scale'])
self.demucs_bass_secondary_model_scale_var = tk.StringVar(value=data['demucs_bass_secondary_model_scale'])
self.demucs_drums_secondary_model_scale_var = tk.StringVar(value=data['demucs_drums_secondary_model_scale'])
self.demucs_pre_proc_model_var = tk.StringVar(value=data['demucs_pre_proc_model'])
self.is_demucs_pre_proc_model_activate_var = tk.BooleanVar(value=data['is_demucs_pre_proc_model_activate'])
self.is_demucs_pre_proc_model_inst_mix_var = tk.BooleanVar(value=data['is_demucs_pre_proc_model_inst_mix'])
#MDX-Net Vars
self.mdx_net_model_var = tk.StringVar(value=data['mdx_net_model'])
self.chunks_var = tk.StringVar(value=data['chunks'])
self.margin_var = tk.StringVar(value=data['margin'])
self.compensate_var = tk.StringVar(value=data['compensate'])
2023-09-26 00:11:08 +02:00
self.denoise_option_var = tk.StringVar(value=data['denoise_option'])#
self.phase_option_var = tk.StringVar(value=data['phase_option'])#
self.phase_shifts_var = tk.StringVar(value=data['phase_shifts'])#
self.is_save_align_var = tk.BooleanVar(value=data['is_save_align'])#,
self.is_match_silence_var = tk.BooleanVar(value=data['is_match_silence'])#
self.is_spec_match_var = tk.BooleanVar(value=data['is_spec_match'])#
self.is_match_frequency_pitch_var = tk.BooleanVar(value=data['is_match_frequency_pitch'])#
self.is_mdx_c_seg_def_var = tk.BooleanVar(value=data['is_mdx_c_seg_def'])#
self.is_invert_spec_var = tk.BooleanVar(value=data['is_invert_spec'])#
self.is_deverb_vocals_var = tk.BooleanVar(value=data['is_deverb_vocals'])#
self.deverb_vocal_opt_var = tk.StringVar(value=data['deverb_vocal_opt'])#
self.voc_split_save_opt_var = tk.StringVar(value=data['voc_split_save_opt'])#
2023-03-31 12:15:39 +02:00
self.is_mixer_mode_var = tk.BooleanVar(value=data['is_mixer_mode'])
self.mdx_batch_size_var = tk.StringVar(value=data['mdx_batch_size'])
2022-12-19 04:18:56 +01:00
self.mdx_voc_inst_secondary_model_var = tk.StringVar(value=data['mdx_voc_inst_secondary_model'])
self.mdx_other_secondary_model_var = tk.StringVar(value=data['mdx_other_secondary_model'])
self.mdx_bass_secondary_model_var = tk.StringVar(value=data['mdx_bass_secondary_model'])
self.mdx_drums_secondary_model_var = tk.StringVar(value=data['mdx_drums_secondary_model'])
self.mdx_is_secondary_model_activate_var = tk.BooleanVar(value=data['mdx_is_secondary_model_activate'])
self.mdx_voc_inst_secondary_model_scale_var = tk.StringVar(value=data['mdx_voc_inst_secondary_model_scale'])
self.mdx_other_secondary_model_scale_var = tk.StringVar(value=data['mdx_other_secondary_model_scale'])
self.mdx_bass_secondary_model_scale_var = tk.StringVar(value=data['mdx_bass_secondary_model_scale'])
self.mdx_drums_secondary_model_scale_var = tk.StringVar(value=data['mdx_drums_secondary_model_scale'])
2023-09-26 00:11:08 +02:00
self.is_mdxnet_c_model_var = tk.BooleanVar(value=False)
2022-12-19 04:18:56 +01:00
#Ensemble Vars
self.is_save_all_outputs_ensemble_var = tk.BooleanVar(value=data['is_save_all_outputs_ensemble'])
self.is_append_ensemble_name_var = tk.BooleanVar(value=data['is_append_ensemble_name'])
#Audio Tool Vars
self.chosen_audio_tool_var = tk.StringVar(value=data['chosen_audio_tool'])
self.choose_algorithm_var = tk.StringVar(value=data['choose_algorithm'])
self.time_stretch_rate_var = tk.StringVar(value=data['time_stretch_rate'])
self.pitch_rate_var = tk.StringVar(value=data['pitch_rate'])
2023-09-26 00:11:08 +02:00
self.is_time_correction_var = tk.BooleanVar(value=data['is_time_correction'])
2022-12-19 04:18:56 +01:00
#Shared Vars
2023-09-26 00:11:08 +02:00
self.semitone_shift_var = tk.StringVar(value=data['semitone_shift'])
2022-12-19 04:18:56 +01:00
self.mp3_bit_set_var = tk.StringVar(value=data['mp3_bit_set'])
self.save_format_var = tk.StringVar(value=data['save_format'])
2023-10-16 02:27:38 +02:00
self.wav_type_set_var = tk.StringVar(value=data['wav_type_set'])#
self.cuda_set_var = tk.StringVar(value=data['cuda_set'])#
2022-12-19 04:18:56 +01:00
self.user_code_var = tk.StringVar(value=data['user_code'])
self.is_gpu_conversion_var = tk.BooleanVar(value=data['is_gpu_conversion'])
self.is_primary_stem_only_var = tk.BooleanVar(value=data['is_primary_stem_only'])
self.is_secondary_stem_only_var = tk.BooleanVar(value=data['is_secondary_stem_only'])
2023-09-26 00:11:08 +02:00
self.is_testing_audio_var = tk.BooleanVar(value=data['is_testing_audio'])#
self.is_auto_update_model_params_var = tk.BooleanVar(value=True)#
self.is_auto_update_model_params = data['is_auto_update_model_params']
2022-12-19 04:18:56 +01:00
self.is_add_model_name_var = tk.BooleanVar(value=data['is_add_model_name'])
self.is_accept_any_input_var = tk.BooleanVar(value=data['is_accept_any_input'])
self.is_task_complete_var = tk.BooleanVar(value=data['is_task_complete'])
2023-09-26 00:11:08 +02:00
self.is_normalization_var = tk.BooleanVar(value=data['is_normalization'])#
self.is_wav_ensemble_var = tk.BooleanVar(value=data['is_wav_ensemble'])#
2022-12-19 04:18:56 +01:00
self.is_create_model_folder_var = tk.BooleanVar(value=data['is_create_model_folder'])
self.help_hints_var = tk.BooleanVar(value=data['help_hints_var'])
self.model_sample_mode_var = tk.BooleanVar(value=data['model_sample_mode'])
self.model_sample_mode_duration_var = tk.StringVar(value=data['model_sample_mode_duration'])
self.model_sample_mode_duration_checkbox_var = tk.StringVar(value=SAMPLE_MODE_CHECKBOX(self.model_sample_mode_duration_var.get()))
2023-09-26 00:11:08 +02:00
self.model_sample_mode_duration_label_var = tk.StringVar(value=f'{self.model_sample_mode_duration_var.get()} Seconds')
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'])#
2022-12-19 04:18:56 +01:00
#Path Vars
self.export_path_var = tk.StringVar(value=data['export_path'])
self.inputPaths = data['input_paths']
self.lastDir = data['lastDir']
2023-09-26 00:11:08 +02:00
#DualPaths-Align
self.time_window_var = tk.StringVar(value=data['time_window'])#
self.intro_analysis_var = tk.StringVar(value=data['intro_analysis'])
self.db_analysis_var = tk.StringVar(value=data['db_analysis'])
self.fileOneEntry_var = tk.StringVar(value=data['fileOneEntry'])
self.fileOneEntry_Full_var = tk.StringVar(value=data['fileOneEntry_Full'])
self.fileTwoEntry_var = tk.StringVar(value=data['fileTwoEntry'])
self.fileTwoEntry_Full_var = tk.StringVar(value=data['fileTwoEntry_Full'])
self.DualBatch_inputPaths = data['DualBatch_inputPaths']
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
def load_saved_settings(self, loaded_setting: dict, process_method=None, is_default_reset=False):
2022-12-19 04:18:56 +01:00
"""Loads user saved application settings or resets to default"""
2022-12-21 11:18:16 +01:00
for key, value in DEFAULT_DATA.items():
if not key in loaded_setting.keys():
loaded_setting = {**loaded_setting, **{key:value}}
2023-03-31 12:15:39 +02:00
loaded_setting['batch_size'] = DEF_OPT
2023-09-26 00:11:08 +02:00
is_default_reset = True if process_method == ENSEMBLE_MODE or is_default_reset else False
2022-12-21 11:18:16 +01:00
2023-09-26 00:11:08 +02:00
if process_method == VR_ARCH_PM or is_default_reset:
2022-12-19 04:18:56 +01:00
self.vr_model_var.set(loaded_setting['vr_model'])
self.aggression_setting_var.set(loaded_setting['aggression_setting'])
self.window_size_var.set(loaded_setting['window_size'])
2023-09-26 00:11:08 +02:00
self.mdx_segment_size_var.set(loaded_setting['mdx_segment_size'])
2022-12-19 04:18:56 +01:00
self.batch_size_var.set(loaded_setting['batch_size'])
self.crop_size_var.set(loaded_setting['crop_size'])
self.is_tta_var.set(loaded_setting['is_tta'])
self.is_output_image_var.set(loaded_setting['is_output_image'])
self.is_post_process_var.set(loaded_setting['is_post_process'])
self.is_high_end_process_var.set(loaded_setting['is_high_end_process'])
2022-12-21 11:18:16 +01:00
self.post_process_threshold_var.set(loaded_setting['post_process_threshold'])
2022-12-19 04:18:56 +01:00
self.vr_voc_inst_secondary_model_var.set(loaded_setting['vr_voc_inst_secondary_model'])
self.vr_other_secondary_model_var.set(loaded_setting['vr_other_secondary_model'])
self.vr_bass_secondary_model_var.set(loaded_setting['vr_bass_secondary_model'])
self.vr_drums_secondary_model_var.set(loaded_setting['vr_drums_secondary_model'])
self.vr_is_secondary_model_activate_var.set(loaded_setting['vr_is_secondary_model_activate'])
self.vr_voc_inst_secondary_model_scale_var.set(loaded_setting['vr_voc_inst_secondary_model_scale'])
self.vr_other_secondary_model_scale_var.set(loaded_setting['vr_other_secondary_model_scale'])
self.vr_bass_secondary_model_scale_var.set(loaded_setting['vr_bass_secondary_model_scale'])
self.vr_drums_secondary_model_scale_var.set(loaded_setting['vr_drums_secondary_model_scale'])
2023-09-26 00:11:08 +02:00
if process_method == DEMUCS_ARCH_TYPE or is_default_reset:
2022-12-19 04:18:56 +01:00
self.demucs_model_var.set(loaded_setting['demucs_model'])
self.segment_var.set(loaded_setting['segment'])
self.overlap_var.set(loaded_setting['overlap'])
self.shifts_var.set(loaded_setting['shifts'])
self.chunks_demucs_var.set(loaded_setting['chunks_demucs'])
self.margin_demucs_var.set(loaded_setting['margin_demucs'])
self.is_chunk_demucs_var.set(loaded_setting['is_chunk_demucs'])
2023-03-31 12:15:39 +02:00
self.is_chunk_mdxnet_var.set(loaded_setting['is_chunk_mdxnet'])
2022-12-19 04:18:56 +01:00
self.is_primary_stem_only_Demucs_var.set(loaded_setting['is_primary_stem_only_Demucs'])
self.is_secondary_stem_only_Demucs_var.set(loaded_setting['is_secondary_stem_only_Demucs'])
self.is_split_mode_var.set(loaded_setting['is_split_mode'])
2023-09-26 00:11:08 +02:00
self.is_demucs_combine_stems_var.set(loaded_setting['is_demucs_combine_stems'])#
self.is_mdx23_combine_stems_var.set(loaded_setting['is_mdx23_combine_stems'])#
2022-12-19 04:18:56 +01:00
self.demucs_voc_inst_secondary_model_var.set(loaded_setting['demucs_voc_inst_secondary_model'])
self.demucs_other_secondary_model_var.set(loaded_setting['demucs_other_secondary_model'])
self.demucs_bass_secondary_model_var.set(loaded_setting['demucs_bass_secondary_model'])
self.demucs_drums_secondary_model_var.set(loaded_setting['demucs_drums_secondary_model'])
self.demucs_is_secondary_model_activate_var.set(loaded_setting['demucs_is_secondary_model_activate'])
self.demucs_voc_inst_secondary_model_scale_var.set(loaded_setting['demucs_voc_inst_secondary_model_scale'])
self.demucs_other_secondary_model_scale_var.set(loaded_setting['demucs_other_secondary_model_scale'])
self.demucs_bass_secondary_model_scale_var.set(loaded_setting['demucs_bass_secondary_model_scale'])
self.demucs_drums_secondary_model_scale_var.set(loaded_setting['demucs_drums_secondary_model_scale'])
self.demucs_stems_var.set(loaded_setting['demucs_stems'])
2023-09-26 00:11:08 +02:00
self.mdxnet_stems_var.set(loaded_setting['mdx_stems'])
2022-12-19 04:18:56 +01:00
self.update_stem_checkbox_labels(self.demucs_stems_var.get(), demucs=True)
2023-09-26 00:11:08 +02:00
self.demucs_pre_proc_model_var.set(loaded_setting['demucs_pre_proc_model'])
self.is_demucs_pre_proc_model_activate_var.set(loaded_setting['is_demucs_pre_proc_model_activate'])
self.is_demucs_pre_proc_model_inst_mix_var.set(loaded_setting['is_demucs_pre_proc_model_inst_mix'])
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
if process_method == MDX_ARCH_TYPE or is_default_reset:
2022-12-19 04:18:56 +01:00
self.mdx_net_model_var.set(loaded_setting['mdx_net_model'])
self.chunks_var.set(loaded_setting['chunks'])
self.margin_var.set(loaded_setting['margin'])
self.compensate_var.set(loaded_setting['compensate'])
2023-09-26 00:11:08 +02:00
self.denoise_option_var.set(loaded_setting['denoise_option'])
self.is_match_frequency_pitch_var.set(loaded_setting['is_match_frequency_pitch'])#
self.overlap_mdx_var.set(loaded_setting['overlap_mdx'])
self.overlap_mdx23_var.set(loaded_setting['overlap_mdx23'])
self.is_mdx_c_seg_def_var.set(loaded_setting['is_mdx_c_seg_def'])#
self.is_invert_spec_var.set(loaded_setting['is_invert_spec'])#
2023-03-31 12:15:39 +02:00
self.is_mixer_mode_var.set(loaded_setting['is_mixer_mode'])
self.mdx_batch_size_var.set(loaded_setting['mdx_batch_size'])
2022-12-19 04:18:56 +01:00
self.mdx_voc_inst_secondary_model_var.set(loaded_setting['mdx_voc_inst_secondary_model'])
self.mdx_other_secondary_model_var.set(loaded_setting['mdx_other_secondary_model'])
self.mdx_bass_secondary_model_var.set(loaded_setting['mdx_bass_secondary_model'])
self.mdx_drums_secondary_model_var.set(loaded_setting['mdx_drums_secondary_model'])
self.mdx_is_secondary_model_activate_var.set(loaded_setting['mdx_is_secondary_model_activate'])
self.mdx_voc_inst_secondary_model_scale_var.set(loaded_setting['mdx_voc_inst_secondary_model_scale'])
self.mdx_other_secondary_model_scale_var.set(loaded_setting['mdx_other_secondary_model_scale'])
self.mdx_bass_secondary_model_scale_var.set(loaded_setting['mdx_bass_secondary_model_scale'])
self.mdx_drums_secondary_model_scale_var.set(loaded_setting['mdx_drums_secondary_model_scale'])
2023-09-26 00:11:08 +02:00
if is_default_reset:
2022-12-19 04:18:56 +01:00
self.is_save_all_outputs_ensemble_var.set(loaded_setting['is_save_all_outputs_ensemble'])
self.is_append_ensemble_name_var.set(loaded_setting['is_append_ensemble_name'])
self.choose_algorithm_var.set(loaded_setting['choose_algorithm'])
self.time_stretch_rate_var.set(loaded_setting['time_stretch_rate'])
2023-09-26 00:11:08 +02:00
self.pitch_rate_var.set(loaded_setting['pitch_rate'])#
self.is_time_correction_var.set(loaded_setting['is_time_correction'])#
2022-12-19 04:18:56 +01:00
self.is_primary_stem_only_var.set(loaded_setting['is_primary_stem_only'])
self.is_secondary_stem_only_var.set(loaded_setting['is_secondary_stem_only'])
2023-09-26 00:11:08 +02:00
self.is_testing_audio_var.set(loaded_setting['is_testing_audio'])#
self.is_auto_update_model_params_var.set(loaded_setting['is_auto_update_model_params'])
2022-12-19 04:18:56 +01:00
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_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'])
2023-09-26 00:11:08 +02:00
self.semitone_shift_var.set(loaded_setting['semitone_shift'])#
2022-12-19 04:18:56 +01:00
self.save_format_var.set(loaded_setting['save_format'])
2023-10-16 02:27:38 +02:00
self.wav_type_set_var.set(loaded_setting['wav_type_set'])#
self.cuda_set_var.set(loaded_setting['cuda_set'])#
2022-12-19 04:18:56 +01:00
self.user_code_var.set(loaded_setting['user_code'])
2023-09-26 00:11:08 +02:00
self.phase_option_var.set(loaded_setting['phase_option'])#
self.phase_shifts_var.set(loaded_setting['phase_shifts'])#
self.is_save_align_var.set(loaded_setting['is_save_align'])#i
self.time_window_var.set(loaded_setting['time_window'])#
self.is_match_silence_var.set(loaded_setting['is_match_silence'])#
self.is_spec_match_var.set(loaded_setting['is_spec_match'])#
self.intro_analysis_var.set(loaded_setting['intro_analysis'])#
self.db_analysis_var.set(loaded_setting['db_analysis'])#
self.fileOneEntry_var.set(loaded_setting['fileOneEntry'])#
self.fileOneEntry_Full_var.set(loaded_setting['fileOneEntry_Full'])#
self.fileTwoEntry_var.set(loaded_setting['fileTwoEntry'])#
self.fileTwoEntry_Full_var.set(loaded_setting['fileTwoEntry_Full'])#
self.DualBatch_inputPaths = []
2022-12-19 04:18:56 +01:00
self.is_gpu_conversion_var.set(loaded_setting['is_gpu_conversion'])
2023-09-26 00:11:08 +02:00
self.is_normalization_var.set(loaded_setting['is_normalization'])#
self.is_wav_ensemble_var.set(loaded_setting['is_wav_ensemble'])#
2022-12-19 04:18:56 +01:00
self.help_hints_var.set(loaded_setting['help_hints_var'])
2023-09-26 00:11:08 +02:00
self.is_wav_ensemble_var.set(loaded_setting['is_wav_ensemble'])
self.set_vocal_splitter_var.set(loaded_setting['set_vocal_splitter'])
self.is_set_vocal_splitter_var.set(loaded_setting['is_set_vocal_splitter'])#
self.is_save_inst_set_vocal_splitter_var.set(loaded_setting['is_save_inst_set_vocal_splitter'])#
self.deverb_vocal_opt_var.set(loaded_setting['deverb_vocal_opt'])#
self.voc_split_save_opt_var.set(loaded_setting['voc_split_save_opt'])#
self.is_deverb_vocals_var.set(loaded_setting['is_deverb_vocals'])#
2022-12-19 04:18:56 +01:00
self.model_sample_mode_var.set(loaded_setting['model_sample_mode'])
self.model_sample_mode_duration_var.set(loaded_setting['model_sample_mode_duration'])
self.model_sample_mode_duration_checkbox_var.set(SAMPLE_MODE_CHECKBOX(self.model_sample_mode_duration_var.get()))
2023-09-26 00:11:08 +02:00
self.model_sample_mode_duration_label_var.set(f'{self.model_sample_mode_duration_var.get()} Seconds')
2023-10-12 06:30:24 +02:00
def save_values(self, app_close=True, is_restart=False, is_auto_save=False):
2022-12-19 04:18:56 +01:00
"""Saves application data"""
# -Save Data-
main_settings={
'vr_model': self.vr_model_var.get(),
'aggression_setting': self.aggression_setting_var.get(),
'window_size': self.window_size_var.get(),
2023-09-26 00:11:08 +02:00
'mdx_segment_size': self.mdx_segment_size_var.get(),
2022-12-19 04:18:56 +01:00
'batch_size': self.batch_size_var.get(),
'crop_size': self.crop_size_var.get(),
'is_tta': self.is_tta_var.get(),
'is_output_image': self.is_output_image_var.get(),
'is_post_process': self.is_post_process_var.get(),
'is_high_end_process': self.is_high_end_process_var.get(),
2022-12-21 11:18:16 +01:00
'post_process_threshold': self.post_process_threshold_var.get(),
2022-12-19 04:18:56 +01:00
'vr_voc_inst_secondary_model': self.vr_voc_inst_secondary_model_var.get(),
'vr_other_secondary_model': self.vr_other_secondary_model_var.get(),
'vr_bass_secondary_model': self.vr_bass_secondary_model_var.get(),
'vr_drums_secondary_model': self.vr_drums_secondary_model_var.get(),
'vr_is_secondary_model_activate': self.vr_is_secondary_model_activate_var.get(),
'vr_voc_inst_secondary_model_scale': self.vr_voc_inst_secondary_model_scale_var.get(),
'vr_other_secondary_model_scale': self.vr_other_secondary_model_scale_var.get(),
'vr_bass_secondary_model_scale': self.vr_bass_secondary_model_scale_var.get(),
'vr_drums_secondary_model_scale': self.vr_drums_secondary_model_scale_var.get(),
'demucs_model': self.demucs_model_var.get(),
'segment': self.segment_var.get(),
'overlap': self.overlap_var.get(),
2023-09-26 00:11:08 +02:00
'overlap_mdx': self.overlap_mdx_var.get(),
'overlap_mdx23': self.overlap_mdx23_var.get(),
2022-12-19 04:18:56 +01:00
'shifts': self.shifts_var.get(),
'chunks_demucs': self.chunks_demucs_var.get(),
'margin_demucs': self.margin_demucs_var.get(),
'is_chunk_demucs': self.is_chunk_demucs_var.get(),
2023-03-31 12:15:39 +02:00
'is_chunk_mdxnet': self.is_chunk_mdxnet_var.get(),
2022-12-19 04:18:56 +01:00
'is_primary_stem_only_Demucs': self.is_primary_stem_only_Demucs_var.get(),
'is_secondary_stem_only_Demucs': self.is_secondary_stem_only_Demucs_var.get(),
'is_split_mode': self.is_split_mode_var.get(),
2023-09-26 00:11:08 +02:00
'is_demucs_combine_stems': self.is_demucs_combine_stems_var.get(),#
'is_mdx23_combine_stems': self.is_mdx23_combine_stems_var.get(),#
2022-12-19 04:18:56 +01:00
'demucs_voc_inst_secondary_model': self.demucs_voc_inst_secondary_model_var.get(),
'demucs_other_secondary_model': self.demucs_other_secondary_model_var.get(),
'demucs_bass_secondary_model': self.demucs_bass_secondary_model_var.get(),
'demucs_drums_secondary_model': self.demucs_drums_secondary_model_var.get(),
'demucs_is_secondary_model_activate': self.demucs_is_secondary_model_activate_var.get(),
'demucs_voc_inst_secondary_model_scale': self.demucs_voc_inst_secondary_model_scale_var.get(),
'demucs_other_secondary_model_scale': self.demucs_other_secondary_model_scale_var.get(),
'demucs_bass_secondary_model_scale': self.demucs_bass_secondary_model_scale_var.get(),
'demucs_drums_secondary_model_scale': self.demucs_drums_secondary_model_scale_var.get(),
'demucs_pre_proc_model': self.demucs_pre_proc_model_var.get(),
'is_demucs_pre_proc_model_activate': self.is_demucs_pre_proc_model_activate_var.get(),
'is_demucs_pre_proc_model_inst_mix': self.is_demucs_pre_proc_model_inst_mix_var.get(),
'mdx_net_model': self.mdx_net_model_var.get(),
'chunks': self.chunks_var.get(),
'margin': self.margin_var.get(),
'compensate': self.compensate_var.get(),
2023-09-26 00:11:08 +02:00
'denoise_option': self.denoise_option_var.get(),#
'is_match_frequency_pitch': self.is_match_frequency_pitch_var.get(),#
'phase_option': self.phase_option_var.get(),#
'phase_shifts': self.phase_shifts_var.get(),#
'is_save_align': self.is_save_align_var.get(),#
'is_match_silence': self.is_match_silence_var.get(),#
'is_spec_match': self.is_spec_match_var.get(),#
'is_mdx_c_seg_def': self.is_mdx_c_seg_def_var.get(),#
'is_invert_spec': self.is_invert_spec_var.get(),#
'is_deverb_vocals': self.is_deverb_vocals_var.get(),##,
'deverb_vocal_opt': self.deverb_vocal_opt_var.get(),#
'voc_split_save_opt': self.voc_split_save_opt_var.get(),##,
2023-03-31 12:15:39 +02:00
'is_mixer_mode': self.is_mixer_mode_var.get(),
'mdx_batch_size':self.mdx_batch_size_var.get(),
2022-12-19 04:18:56 +01:00
'mdx_voc_inst_secondary_model': self.mdx_voc_inst_secondary_model_var.get(),
'mdx_other_secondary_model': self.mdx_other_secondary_model_var.get(),
'mdx_bass_secondary_model': self.mdx_bass_secondary_model_var.get(),
'mdx_drums_secondary_model': self.mdx_drums_secondary_model_var.get(),
'mdx_is_secondary_model_activate': self.mdx_is_secondary_model_activate_var.get(),
'mdx_voc_inst_secondary_model_scale': self.mdx_voc_inst_secondary_model_scale_var.get(),
'mdx_other_secondary_model_scale': self.mdx_other_secondary_model_scale_var.get(),
'mdx_bass_secondary_model_scale': self.mdx_bass_secondary_model_scale_var.get(),
'mdx_drums_secondary_model_scale': self.mdx_drums_secondary_model_scale_var.get(),
'is_save_all_outputs_ensemble': self.is_save_all_outputs_ensemble_var.get(),
'is_append_ensemble_name': self.is_append_ensemble_name_var.get(),
'chosen_audio_tool': self.chosen_audio_tool_var.get(),
'choose_algorithm': self.choose_algorithm_var.get(),
'time_stretch_rate': self.time_stretch_rate_var.get(),
2023-09-26 00:11:08 +02:00
'pitch_rate': self.pitch_rate_var.get(),#
'is_time_correction': self.is_time_correction_var.get(),#
2022-12-19 04:18:56 +01:00
'is_gpu_conversion': self.is_gpu_conversion_var.get(),
'is_primary_stem_only': self.is_primary_stem_only_var.get(),
'is_secondary_stem_only': self.is_secondary_stem_only_var.get(),
2023-09-26 00:11:08 +02:00
'is_testing_audio': self.is_testing_audio_var.get(),#
'is_auto_update_model_params': self.is_auto_update_model_params_var.get(),
2022-12-19 04:18:56 +01:00
'is_add_model_name': self.is_add_model_name_var.get(),
2023-09-26 00:11:08 +02:00
'is_accept_any_input': self.is_accept_any_input_var.get(),
2022-12-19 04:18:56 +01:00
'is_task_complete': self.is_task_complete_var.get(),
2023-09-26 00:11:08 +02:00
'is_normalization': self.is_normalization_var.get(),#
'is_wav_ensemble': self.is_wav_ensemble_var.get(),#
2022-12-19 04:18:56 +01:00
'is_create_model_folder': self.is_create_model_folder_var.get(),
'mp3_bit_set': self.mp3_bit_set_var.get(),
2023-09-26 00:11:08 +02:00
'semitone_shift': self.semitone_shift_var.get(),#
2022-12-19 04:18:56 +01:00
'save_format': self.save_format_var.get(),
2023-10-16 02:27:38 +02:00
'wav_type_set': self.wav_type_set_var.get(),#
'cuda_set': self.cuda_set_var.get(),#
2022-12-19 04:18:56 +01:00
'user_code': self.user_code_var.get(),
'help_hints_var': self.help_hints_var.get(),
2023-09-26 00:11:08 +02:00
'set_vocal_splitter': self.set_vocal_splitter_var.get(),
'is_set_vocal_splitter': self.is_set_vocal_splitter_var.get(),#
'is_save_inst_set_vocal_splitter': self.is_save_inst_set_vocal_splitter_var.get(),#
2022-12-19 04:18:56 +01:00
'model_sample_mode': self.model_sample_mode_var.get(),
'model_sample_mode_duration': self.model_sample_mode_duration_var.get()
}
other_data = {
'chosen_process_method': self.chosen_process_method_var.get(),
'input_paths': self.inputPaths,
'lastDir': self.lastDir,
'export_path': self.export_path_var.get(),
2023-09-26 00:11:08 +02:00
'time_window': self.time_window_var.get(),
'intro_analysis': self.intro_analysis_var.get(),
'db_analysis': self.db_analysis_var.get(),
'fileOneEntry': self.fileOneEntry_var.get(),
'fileOneEntry_Full': self.fileOneEntry_Full_var.get(),
'fileTwoEntry': self.fileTwoEntry_var.get(),
'fileTwoEntry_Full': self.fileTwoEntry_Full_var.get(),
'DualBatch_inputPaths': self.DualBatch_inputPaths,
#'model_hash_table': model_hash_table,
2022-12-19 04:18:56 +01:00
}
user_saved_extras = {
2023-09-26 00:11:08 +02:00
'demucs_stems': self.demucs_stems_var.get(),
'mdx_stems': self.mdxnet_stems_var.get()}
2022-12-19 04:18:56 +01:00
if app_close:
save_data(data={**main_settings, **other_data})
if self.thread_check(self.active_download_thread):
self.error_dialoge(EXIT_DOWNLOAD_ERROR)
return
if self.thread_check(self.active_processing_thread):
if self.is_process_stopped:
self.error_dialoge(EXIT_HALTED_PROCESS_ERROR)
else:
self.error_dialoge(EXIT_PROCESS_ERROR)
return
remove_temps(ENSEMBLE_TEMP_PATH)
remove_temps(SAMPLE_CLIP_PATH)
self.delete_temps()
2023-09-26 00:11:08 +02:00
if is_restart:
try:
subprocess.Popen(f'UVR_Launcher.exe')
except Exception:
subprocess.Popen(f'python "{__file__}"', shell=True)
2022-12-19 04:18:56 +01:00
self.destroy()
2023-10-12 06:30:24 +02:00
elif is_auto_save:
save_data(data={**main_settings, **other_data})
2022-12-19 04:18:56 +01:00
else:
return {**main_settings, **user_saved_extras}
2022-12-19 23:26:47 +01:00
def get_settings_list(self):
settings_dict = self.save_values(app_close=False)
settings_list = '\n'.join(''.join(f"{key}: {value}") for key, value in settings_dict.items() if not key == 'user_code')
2023-09-26 00:11:08 +02:00
return f"\n{FULL_APP_SET_TEXT}:\n\n{settings_list}"
2023-03-31 12:15:39 +02:00
2023-09-26 00:11:08 +02:00
def read_bulliten_text_mac(path, data):
try:
with open(path, 'w') as f:
f.write(data)
if os.path.isfile(path):
with open(path, 'r') as file :
data = file.read().replace("~", "")
except Exception as e:
data = 'No information available.'
return data
def open_link(event, link=None):
webbrowser.open(link)
def auto_hyperlink(text_widget:tk.Text):
content = text_widget.get('1.0', tk.END)
2022-12-19 04:18:56 +01:00
2023-09-26 00:11:08 +02:00
# Regular expression to identify URLs
urls = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', content)
for url in urls:
start_idx = content.find(url)
end_idx = start_idx + len(url)
# Convert indices to tk.Text widget format
start_line = content.count('\n', 0, start_idx) + 1
start_char = start_idx - content.rfind('\n', 0, start_idx) - 1
end_line = content.count('\n', 0, end_idx) + 1
end_char = end_idx - content.rfind('\n', 0, end_idx) - 1
start_tag = f"{start_line}.{start_char}"
end_tag = f"{end_line}.{end_char}"
# Tag the hyperlink text and configure it
text_widget.tag_add(url, start_tag, end_tag)
text_widget.tag_configure(url, foreground=FG_COLOR, underline=True)
text_widget.tag_bind(url, "<Button-1>", lambda e, link=url: open_link(e, link))
text_widget.tag_bind(url, "<Enter>", lambda e: text_widget.config(cursor="hand2"))
text_widget.tag_bind(url, "<Leave>", lambda e: text_widget.config(cursor="arrow"))
2022-12-19 04:18:56 +01:00
def vip_downloads(password, link_type=VIP_REPO):
"""Attempts to decrypt VIP model link with given input code"""
try:
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=link_type[0],
iterations=390000,)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
key = base64.urlsafe_b64encode(kdf.derive(bytes(password, 'utf-8')))
f = Fernet(key)
return str(f.decrypt(link_type[1]), 'UTF-8')
except Exception:
return NO_CODE
2023-09-26 00:11:08 +02:00
def extract_stems(audio_file_base, export_path):
filenames = [file for file in os.listdir(export_path) if file.startswith(audio_file_base)]
pattern = r'\(([^()]+)\)(?=[^()]*\.wav)'
stem_list = []
for filename in filenames:
match = re.search(pattern, filename)
if match:
stem_list.append(match.group(1))
counter = Counter(stem_list)
filtered_lst = [item for item in stem_list if counter[item] > 1]
return list(set(filtered_lst))
2022-12-19 04:18:56 +01:00
if __name__ == "__main__":
try:
windll.user32.SetThreadDpiAwarenessContext(wintypes.HANDLE(-1))
except Exception as e:
2022-12-30 04:07:23 +01:00
if OPERATING_SYSTEM == 'Windows':
print(e)
2023-09-26 00:11:08 +02:00
2022-12-19 04:18:56 +01:00
root = MainWindow()
root.update_checkbox_text()
2023-09-26 00:11:08 +02:00
root.is_root_defined_var.set(True)
root.is_check_splash = True
root.update() if is_windows else root.update_idletasks()
root.deiconify()
root.configure(bg=BG_COLOR)
2023-09-29 09:04:35 +02:00
root.mainloop()