-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathMainUI.py
286 lines (229 loc) · 10.6 KB
/
MainUI.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
from qgui import CreateQGUI, MessageBox
from qgui.banner_tools import GitHub
from qgui.notebook_tools import *
from layouts.SingleTab import SingleTab
from layouts.MultipleTab import MultipleTab
from layouts.SettingsTab import SettingsTab
from SepProcessor import get_paths, separate_file, separate_dir
LOCAL_CHECKPOINTS_DIR = os.path.join(os.getcwd(), "models")
class MainLayout:
'''
UI part
'''
def __init__(self):
self.GUI = None
self.tab1 = None
self.tab2 = None
self.tab3 = None
self.setup_base()
self.setup_layout()
self.setup_bind_func()
self.setup_construct()
def setup_base(self):
self.GUI = CreateQGUI( title="Music Separation",
tab_names=["Single", "Batch", "Settings"])
self.GUI.add_banner_tool(
GitHub(url="https://github.com/bytedance/music_source_separation",
name="Original Repo")
)
self.GUI.add_banner_tool(
GitHub(url="https://github.com/Freddd13/music-seperation-gui",
name="GUI Repo")
)
self.GUI.set_navigation_about(
author="Freddd13",
version="0.0.4",
github_url="https://github.com/Freddd13",
other_info=["GUI for bytesep"]
)
self.GUI.set_navigation_about(
author="qiuqiangkong",
version="21-12-25",
github_url="https://github.com/qiuqiangkong",
other_info=["Bytesep core"]
)
def setup_layout(self):
self.tab1 = SingleTab()
self.tab2 = MultipleTab()
self.tab3 = SettingsTab()
def setup_construct(self):
self.construct(self.tab1)
self.construct(self.tab2)
self.construct(self.tab3)
def construct(self, obj):
for elem in obj.retrieve():
self.GUI.add_notebook_tool(elem)
def setup_bind_func(self):
return NotImplementedError
class MainBind(MainLayout):
'''
UI-relevant callback function bind
'''
def __init__(self):
super().__init__()
self.vocal_ckpt_yaml, self.vocal_ckpt_file = get_paths("vocals", "ResUNet143_Subbandtime")
self.accomp_ckpt_yaml, self.accomp_ckpt_file = get_paths("accompaniment", "ResUNet143_Subbandtime")
self.single_source_type_vocal = False
self.single_source_type_accomp = True
self.multiple_source_type_vocal = False
self.multiple_source_type_accomp = True
self.open_after_generation = True
self.single_output_extension = ""
self.multiple_output_extension = ""
def setup_bind_func(self):
# bind save setting
self.tab3.save_button = self.update_ckpt_and_yaml
# bind source selection
self.tab1.check_button = self.update_single_source_type
self.tab2.check_button = self.update_multiple_source_type
# bind open target
self.tab1.open_button = self.open_single_target_folder
self.tab2.open_button = self.open_multiple_target_folder
self.tab1.toggle_button = self.change_single_after_open
self.tab2.toggle_button = self.change_multiple_after_open
# extension -> allback err!!!
# self.tab1.combo.bind_func = self.update_single_extension
# self.tab2.combo.bind_func = self.update_multiple_extension
# bind run separation
self.tab1.run_button = self.run_single
self.tab2.run_button = self.run_multiple
############### bind_funcs ################
def update_single_source_type(self, args):
self.single_source_type_vocal = int(
args[self.tab1.check_button.name + "-Vocals"].get()
)
self.single_source_type_accomp = int(
args[self.tab1.check_button.name + "-Accompaniment"].get()
)
def update_multiple_source_type(self, args):
self.multiple_source_type_vocal = int(
args[self.tab2.check_button.name + "-Vocals"].get()
)
self.multiple_source_type_accomp = int(
args[self.tab2.check_button.name + "-Accompaniment"].get()
)
# ui-operating callbacks
def do_simple_progress(self, value):
self.tab1.processbar.get_arg_info().set(value)
def do_multiple_progress(self, value):
self.tab2.processbar.get_arg_info().set(value)
def open_single_target_folder(self, args):
single_aim_dir = args[self.tab1.aim_dir.name].get()
if not os.path.exists(single_aim_dir):
single_aim_dir = '.'
os.startfile(single_aim_dir)
def open_multiple_target_folder(self, args):
multiple_aim_dir = args[self.tab2.aim_dir_button.name].get()
if not os.path.exists(multiple_aim_dir):
multiple_aim_dir = '.'
os.startfile(multiple_aim_dir)
def change_single_after_open(self, args):
self.open_after_generation = bool( int( args[self.tab1.toggle_button.name + '-'].get() ) )
def change_multiple_after_open(self, args):
self.open_after_generation = bool( int( args[self.tab2.toggle_button.name + '-'].get() ) )
def update_ckpt_and_yaml(self, args):
vocal_ckpt = args[self.tab3.vocal_ckpt_button.name].get()
vocal_yaml = args[self.tab3.vocal_yaml_button.name].get()
accomp_ckpt = args[self.tab3.accomp_ckpt_button.name].get()
accomp_yaml = args[self.tab3.accomp_yaml_button.name].get()
self.vocal_ckpt_file = vocal_ckpt if vocal_ckpt != "auto" else self.vocal_ckpt_file
self.vocal_ckpt_yaml = vocal_yaml if vocal_yaml != "auto" else self.vocal_ckpt_yaml
self.accomp_ckpt_file = accomp_ckpt if accomp_ckpt != "auto" else self.accomp_ckpt_file
self.accomp_ckpt_yaml = accomp_yaml if accomp_yaml != "auto" else self.accomp_ckpt_yaml
MessageBox.info(f"Set vocal ckpt to {self.vocal_ckpt_file}.\n" + \
f"Set vocal yaml to {self.vocal_ckpt_yaml}.\n" + \
f"Set accomp ckpt to {self.accomp_ckpt_file}.\n" + \
f"Set accomp yaml to {self.accomp_ckpt_yaml}.\n"
)
# sep-operating functions
def run_single(self, args):
return NotImplementedError
def run_multiple(self, args):
return not NotImplementedError
class MainWindow(MainBind):
'''
Interact with UI and separator
'''
def __init__(self):
super().__init__()
self.init_environment()
def init_environment(self):
os.environ["PATH"] += os.pathsep + os.path.join(os.getcwd(), "tools")
def run_single(self, args):
single_source_file = args[self.tab1.source_button.name].get()
single_aim_dir = args[self.tab1.aim_dir.name].get()
if not ( os.path.exists(single_source_file) and os.path.exists(single_aim_dir) ):
MessageBox.info("Please specify both the source file and aim file!")
return
if self.single_source_type_accomp and self.single_source_type_vocal:
source_type = "both"
checkpoint_paths = [self.vocal_ckpt_file, self.accomp_ckpt_file]
config_yamls = [self.vocal_ckpt_yaml, self.accomp_ckpt_yaml]
elif self.single_source_type_vocal:
source_type = "vocal"
checkpoint_paths = [self.vocal_ckpt_file]
config_yamls = [self.vocal_ckpt_yaml]
elif self.single_source_type_accomp:
source_type = "accompaniment"
checkpoint_paths = [self.accomp_ckpt_file]
config_yamls = [self.accomp_ckpt_yaml]
else:
MessageBox.info("Please choose at least one source type!")
return
# fucking callback error forces me to do this
extension = self.tab1.combo.get_arg_info().get()
if extension == "Same as source":
extension = None
separate_file(
config_yamls = config_yamls,
checkpoint_paths = checkpoint_paths,
audio_path = single_source_file,
output_path = single_aim_dir,
scale_volume = False,
cpu = False,
extension = extension,
source_type=source_type,
progress = self
)
if self.open_after_generation:
os.startfile(single_aim_dir)
def run_multiple(self, args):
multiple_source_dir = args[self.tab2.source_dir_button.name].get()
multiple_aim_dir = args[self.tab2.aim_dir_button.name].get()
if not ( os.path.exists(multiple_source_dir) and os.path.exists(multiple_aim_dir) ):
MessageBox.info("Please specify both the source dir and aim dir!")
return
if self.multiple_source_type_accomp and self.multiple_source_type_vocal:
source_type = "both"
checkpoint_paths = [self.vocal_ckpt_file, self.accomp_ckpt_file]
config_yamls = [self.vocal_ckpt_yaml, self.accomp_ckpt_yaml]
elif self.multiple_source_type_vocal:
source_type = "vocal"
checkpoint_paths = [self.vocal_ckpt_file]
config_yamls = [self.vocal_ckpt_yaml]
elif self.multiple_source_type_accomp:
source_type = "accompaniment"
checkpoint_paths = [self.accomp_ckpt_file]
config_yamls = [self.accomp_ckpt_yaml]
else:
MessageBox.info("Please choose at least one source type!!")
return
extension = self.tab2.combo.get_arg_info().get()
if extension == "Same as source":
extension = None
separate_dir(
config_yamls = config_yamls,
checkpoint_paths = checkpoint_paths,
audios_dir = multiple_source_dir,
outputs_dir = multiple_aim_dir,
scale_volume = False,
cpu = False,
extension = extension,
source_type=source_type,
progress = self
)
if self.open_after_generation:
os.startfile(multiple_aim_dir)
if __name__ == '__main__':
M = MainWindow()
M.GUI.run()