Spaces:
Sleeping
Sleeping
Commit
•
a2d4fa4
1
Parent(s):
3e80b7b
returning all stems
Browse files- src/main.py +75 -65
- src/webui.py +5 -7
src/main.py
CHANGED
@@ -193,9 +193,9 @@ def preprocess_song(song_input, mdx_model_params, song_id, is_webui, input_type,
|
|
193 |
def voice_change(voice_model, vocals_path, output_path, pitch_change, f0_method, index_rate, filter_radius, rms_mix_rate, protect, crepe_hop_length, is_webui):
|
194 |
rvc_model_path, rvc_index_path = get_rvc_model(voice_model, is_webui)
|
195 |
device = 'cpu'
|
196 |
-
config = Config(device,
|
197 |
hubert_model = load_hubert(device, config.is_half, os.path.join(rvc_models_dir, 'hubert_base.pt'))
|
198 |
-
cpt, version, net_g, tgt_sr, vc = get_vc(device,
|
199 |
|
200 |
# convert main vocals
|
201 |
rvc_infer(rvc_index_path, index_rate, vocals_path, output_path, pitch_change, f0_method, cpt, version, net_g, filter_radius, tgt_sr, rms_mix_rate, protect, crepe_hop_length, vc, hubert_model)
|
@@ -238,82 +238,85 @@ def song_cover_pipeline(song_input, voice_model, pitch_change, keep_files,
|
|
238 |
rms_mix_rate=0.25, f0_method='rmvpe', crepe_hop_length=128, protect=0.33, pitch_change_all=0,
|
239 |
reverb_rm_size=0.15, reverb_wet=0.2, reverb_dry=0.8, reverb_damping=0.7, output_format='mp3',
|
240 |
progress=gr.Progress()):
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
display_progress('[~] Starting AI Cover Generation Pipeline...', 0, is_webui, progress)
|
246 |
-
|
247 |
-
with open(os.path.join(mdxnet_models_dir, 'model_data.json')) as infile:
|
248 |
-
mdx_model_params = json.load(infile)
|
249 |
-
|
250 |
-
# if youtube url
|
251 |
-
if urlparse(song_input).scheme == 'https':
|
252 |
-
input_type = 'yt'
|
253 |
-
song_id = get_youtube_video_id(song_input)
|
254 |
-
if song_id is None:
|
255 |
-
error_msg = 'Invalid YouTube url.'
|
256 |
-
raise_exception(error_msg, is_webui)
|
257 |
-
|
258 |
-
# local audio file
|
259 |
-
else:
|
260 |
-
input_type = 'local'
|
261 |
-
song_input = song_input.strip('\"')
|
262 |
-
if os.path.exists(song_input):
|
263 |
-
song_id = get_hash(song_input)
|
264 |
-
else:
|
265 |
-
error_msg = f'{song_input} does not exist.'
|
266 |
-
song_id = None
|
267 |
-
raise_exception(error_msg, is_webui)
|
268 |
|
269 |
-
|
270 |
|
271 |
-
|
272 |
-
|
273 |
-
orig_song_path, vocals_path, instrumentals_path, main_vocals_path, backup_vocals_path, main_vocals_dereverb_path = preprocess_song(song_input, mdx_model_params, song_id, is_webui, input_type, progress)
|
274 |
|
275 |
-
|
276 |
-
|
277 |
-
|
|
|
|
|
|
|
|
|
278 |
|
279 |
-
#
|
280 |
-
if any(path is None for path in paths) or keep_files:
|
281 |
-
orig_song_path, vocals_path, instrumentals_path, main_vocals_path, backup_vocals_path, main_vocals_dereverb_path = preprocess_song(song_input, mdx_model_params, song_id, is_webui, input_type, progress)
|
282 |
else:
|
283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
|
|
|
|
292 |
|
293 |
-
|
294 |
-
|
|
|
295 |
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
backup_vocals_path = pitch_shift(backup_vocals_path, pitch_change_all)
|
300 |
|
301 |
-
|
302 |
-
|
303 |
|
304 |
-
if not keep_files:
|
305 |
-
display_progress('[~] Removing intermediate audio files...', 0.95, is_webui, progress)
|
306 |
-
intermediate_files = [vocals_path, main_vocals_path, ai_vocals_mixed_path]
|
307 |
if pitch_change_all != 0:
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
os.remove(file)
|
312 |
|
313 |
-
|
|
|
314 |
|
315 |
-
|
316 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
|
318 |
|
319 |
if __name__ == '__main__':
|
@@ -343,7 +346,8 @@ if __name__ == '__main__':
|
|
343 |
if not os.path.exists(os.path.join(rvc_models_dir, rvc_dirname)):
|
344 |
raise Exception(f'The folder {os.path.join(rvc_models_dir, rvc_dirname)} does not exist.')
|
345 |
|
346 |
-
cover_path = song_cover_pipeline(args.song_input, rvc_dirname, args.pitch_change, args.keep_files,
|
|
|
347 |
main_gain=args.main_vol, backup_gain=args.backup_vol, inst_gain=args.inst_vol,
|
348 |
index_rate=args.index_rate, filter_radius=args.filter_radius,
|
349 |
rms_mix_rate=args.rms_mix_rate, f0_method=args.pitch_detection_algo,
|
@@ -352,4 +356,10 @@ if __name__ == '__main__':
|
|
352 |
reverb_rm_size=args.reverb_size, reverb_wet=args.reverb_wetness,
|
353 |
reverb_dry=args.reverb_dryness, reverb_damping=args.reverb_damping,
|
354 |
output_format=args.output_format)
|
|
|
355 |
print(f'[+] Cover generated at {cover_path}')
|
|
|
|
|
|
|
|
|
|
|
|
193 |
def voice_change(voice_model, vocals_path, output_path, pitch_change, f0_method, index_rate, filter_radius, rms_mix_rate, protect, crepe_hop_length, is_webui):
|
194 |
rvc_model_path, rvc_index_path = get_rvc_model(voice_model, is_webui)
|
195 |
device = 'cpu'
|
196 |
+
config = Config(device, True)
|
197 |
hubert_model = load_hubert(device, config.is_half, os.path.join(rvc_models_dir, 'hubert_base.pt'))
|
198 |
+
cpt, version, net_g, tgt_sr, vc = get_vc(device, config.is_half, config, rvc_model_path)
|
199 |
|
200 |
# convert main vocals
|
201 |
rvc_infer(rvc_index_path, index_rate, vocals_path, output_path, pitch_change, f0_method, cpt, version, net_g, filter_radius, tgt_sr, rms_mix_rate, protect, crepe_hop_length, vc, hubert_model)
|
|
|
238 |
rms_mix_rate=0.25, f0_method='rmvpe', crepe_hop_length=128, protect=0.33, pitch_change_all=0,
|
239 |
reverb_rm_size=0.15, reverb_wet=0.2, reverb_dry=0.8, reverb_damping=0.7, output_format='mp3',
|
240 |
progress=gr.Progress()):
|
241 |
+
|
242 |
+
try:
|
243 |
+
if not song_input or not voice_model:
|
244 |
+
raise_exception('Ensure that the song input field and voice model field is filled.', is_webui)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
|
246 |
+
display_progress('[~] Starting AI Cover Generation Pipeline...', 0, is_webui, progress)
|
247 |
|
248 |
+
with open(os.path.join(mdxnet_models_dir, 'model_data.json')) as infile:
|
249 |
+
mdx_model_params = json.load(infile)
|
|
|
250 |
|
251 |
+
# if youtube url
|
252 |
+
if urlparse(song_input).scheme == 'https':
|
253 |
+
input_type = 'yt'
|
254 |
+
song_id = get_youtube_video_id(song_input)
|
255 |
+
if song_id is None:
|
256 |
+
error_msg = 'Invalid YouTube url.'
|
257 |
+
raise_exception(error_msg, is_webui)
|
258 |
|
259 |
+
# local audio file
|
|
|
|
|
260 |
else:
|
261 |
+
input_type = 'local'
|
262 |
+
song_input = song_input.strip('\"')
|
263 |
+
if os.path.exists(song_input):
|
264 |
+
song_id = get_hash(song_input)
|
265 |
+
else:
|
266 |
+
error_msg = f'{song_input} does not exist.'
|
267 |
+
song_id = None
|
268 |
+
raise_exception(error_msg, is_webui)
|
269 |
+
|
270 |
+
song_dir = os.path.join(output_dir, song_id)
|
271 |
+
|
272 |
+
if not os.path.exists(song_dir):
|
273 |
+
os.makedirs(song_dir)
|
274 |
+
orig_song_path, vocals_path, instrumentals_path, main_vocals_path, backup_vocals_path, main_vocals_dereverb_path = preprocess_song(song_input, mdx_model_params, song_id, is_webui, input_type, progress)
|
275 |
|
276 |
+
else:
|
277 |
+
vocals_path, main_vocals_path = None, None
|
278 |
+
paths = get_audio_paths(song_dir)
|
279 |
|
280 |
+
# if any of the audio files aren't available or keep intermediate files, rerun preprocess
|
281 |
+
if any(path is None for path in paths) or keep_files:
|
282 |
+
orig_song_path, vocals_path, instrumentals_path, main_vocals_path, backup_vocals_path, main_vocals_dereverb_path = preprocess_song(song_input, mdx_model_params, song_id, is_webui, input_type, progress)
|
283 |
+
else:
|
284 |
+
orig_song_path, instrumentals_path, main_vocals_dereverb_path, backup_vocals_path = paths
|
285 |
|
286 |
+
pitch_change = pitch_change * 12 + pitch_change_all
|
287 |
+
ai_vocals_path = os.path.join(song_dir, f'{os.path.splitext(os.path.basename(orig_song_path))[0]}_{voice_model}_p{pitch_change}_i{index_rate}_fr{filter_radius}_rms{rms_mix_rate}_pro{protect}_{f0_method}{"" if f0_method != "mangio-crepe" else f"_{crepe_hop_length}"}.wav')
|
288 |
+
ai_cover_path = os.path.join(song_dir, f'{os.path.splitext(os.path.basename(orig_song_path))[0]} ({voice_model} Ver).{output_format}')
|
289 |
|
290 |
+
if not os.path.exists(ai_vocals_path):
|
291 |
+
display_progress('[~] Converting voice using RVC...', 0.5, is_webui, progress)
|
292 |
+
voice_change(voice_model, main_vocals_dereverb_path, ai_vocals_path, pitch_change, f0_method, index_rate, filter_radius, rms_mix_rate, protect, crepe_hop_length, is_webui)
|
|
|
293 |
|
294 |
+
display_progress('[~] Applying audio effects to Vocals...', 0.8, is_webui, progress)
|
295 |
+
ai_vocals_mixed_path = add_audio_effects(ai_vocals_path, reverb_rm_size, reverb_wet, reverb_dry, reverb_damping)
|
296 |
|
|
|
|
|
|
|
297 |
if pitch_change_all != 0:
|
298 |
+
display_progress('[~] Applying overall pitch change', 0.85, is_webui, progress)
|
299 |
+
instrumentals_path = pitch_shift(instrumentals_path, pitch_change_all)
|
300 |
+
backup_vocals_path = pitch_shift(backup_vocals_path, pitch_change_all)
|
|
|
301 |
|
302 |
+
display_progress('[~] Combining AI Vocals and Instrumentals...', 0.9, is_webui, progress)
|
303 |
+
combine_audio([ai_vocals_mixed_path, backup_vocals_path, instrumentals_path], ai_cover_path, main_gain, backup_gain, inst_gain, output_format)
|
304 |
|
305 |
+
if not keep_files:
|
306 |
+
display_progress('[~] Removing intermediate audio files...', 0.95, is_webui, progress)
|
307 |
+
intermediate_files = [vocals_path, main_vocals_path, ai_vocals_mixed_path]
|
308 |
+
if pitch_change_all != 0:
|
309 |
+
intermediate_files += [instrumentals_path, backup_vocals_path]
|
310 |
+
for file in intermediate_files:
|
311 |
+
if file and os.path.exists(file):
|
312 |
+
os.remove(file)
|
313 |
+
|
314 |
+
# Returning the stems: AI cover, original vocal, original instrumental, AI generated vocal
|
315 |
+
|
316 |
+
return ai_cover_path, vocals_path, instrumentals_path, ai_vocals_path
|
317 |
+
|
318 |
+
except Exception as e:
|
319 |
+
raise_exception(str(e), is_webui)
|
320 |
|
321 |
|
322 |
if __name__ == '__main__':
|
|
|
346 |
if not os.path.exists(os.path.join(rvc_models_dir, rvc_dirname)):
|
347 |
raise Exception(f'The folder {os.path.join(rvc_models_dir, rvc_dirname)} does not exist.')
|
348 |
|
349 |
+
cover_path, original_vocals, original_instrumentals, ai_vocals= song_cover_pipeline(args.song_input, rvc_dirname, args.pitch_change, args.keep_files,
|
350 |
+
#cover_path, original_vocals = song_cover_pipeline(args.song_input, rvc_dirname, args.pitch_change, args.keep_files,
|
351 |
main_gain=args.main_vol, backup_gain=args.backup_vol, inst_gain=args.inst_vol,
|
352 |
index_rate=args.index_rate, filter_radius=args.filter_radius,
|
353 |
rms_mix_rate=args.rms_mix_rate, f0_method=args.pitch_detection_algo,
|
|
|
356 |
reverb_rm_size=args.reverb_size, reverb_wet=args.reverb_wetness,
|
357 |
reverb_dry=args.reverb_dryness, reverb_damping=args.reverb_damping,
|
358 |
output_format=args.output_format)
|
359 |
+
|
360 |
print(f'[+] Cover generated at {cover_path}')
|
361 |
+
print(f'[+] Original vocals at {original_vocals}')
|
362 |
+
print(f'[+] Original instrumentals at {original_instrumentals}')
|
363 |
+
print(f'[+] AI vocals at {ai_vocals}')
|
364 |
+
|
365 |
+
|
src/webui.py
CHANGED
@@ -170,10 +170,6 @@ if __name__ == '__main__':
|
|
170 |
|
171 |
gr.Label('AICoverGen WebUI created with ❤️', show_label=False)
|
172 |
|
173 |
-
gr.Markdown("AI-Cover-Gen-No-UI [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ardha27/AICoverGen-NoUI-Colab/blob/main/CoverGen_No_UI.ipynb)")
|
174 |
-
gr.Markdown("Duplicate the space for use in private")
|
175 |
-
gr.Markdown("[![Duplicate this Space](https://huggingface.co/datasets/huggingface/badges/raw/main/duplicate-this-space-sm-dark.svg)](https://huggingface.co/spaces/r3gm/AICoverGen?duplicate=true)\n\n")
|
176 |
-
|
177 |
# main tab
|
178 |
with gr.Tab("Generate"):
|
179 |
|
@@ -184,7 +180,7 @@ if __name__ == '__main__':
|
|
184 |
ref_btn = gr.Button('Refresh Models 🔁', variant='primary')
|
185 |
|
186 |
with gr.Column() as yt_link_col:
|
187 |
-
song_input = gr.Text(label='Song input', info='Link to a song on YouTube or full path to a local file. For file upload, click the button below.
|
188 |
show_file_upload_button = gr.Button('Upload file instead')
|
189 |
|
190 |
with gr.Column(visible=False) as file_upload_col:
|
@@ -232,7 +228,9 @@ if __name__ == '__main__':
|
|
232 |
clear_btn = gr.ClearButton(value='Clear', components=[song_input, rvc_model, keep_files, local_file])
|
233 |
generate_btn = gr.Button("Generate", variant='primary')
|
234 |
ai_cover = gr.Audio(label='AI Cover', show_share_button=False)
|
235 |
-
|
|
|
|
|
236 |
ref_btn.click(update_models_list, None, outputs=rvc_model)
|
237 |
is_webui = gr.Number(value=1, visible=False)
|
238 |
generate_btn.click(song_cover_pipeline,
|
@@ -240,7 +238,7 @@ if __name__ == '__main__':
|
|
240 |
inst_gain, index_rate, filter_radius, rms_mix_rate, f0_method, crepe_hop_length,
|
241 |
protect, pitch_all, reverb_rm_size, reverb_wet, reverb_dry, reverb_damping,
|
242 |
output_format],
|
243 |
-
outputs=[ai_cover])
|
244 |
clear_btn.click(lambda: [0, 0, 0, 0, 0.5, 3, 0.25, 0.33, 'rmvpe', 128, 0, 0.15, 0.2, 0.8, 0.7, 'mp3', None],
|
245 |
outputs=[pitch, main_gain, backup_gain, inst_gain, index_rate, filter_radius, rms_mix_rate,
|
246 |
protect, f0_method, crepe_hop_length, pitch_all, reverb_rm_size, reverb_wet,
|
|
|
170 |
|
171 |
gr.Label('AICoverGen WebUI created with ❤️', show_label=False)
|
172 |
|
|
|
|
|
|
|
|
|
173 |
# main tab
|
174 |
with gr.Tab("Generate"):
|
175 |
|
|
|
180 |
ref_btn = gr.Button('Refresh Models 🔁', variant='primary')
|
181 |
|
182 |
with gr.Column() as yt_link_col:
|
183 |
+
song_input = gr.Text(label='Song input', info='Link to a song on YouTube or full path to a local file. For file upload, click the button below.')
|
184 |
show_file_upload_button = gr.Button('Upload file instead')
|
185 |
|
186 |
with gr.Column(visible=False) as file_upload_col:
|
|
|
228 |
clear_btn = gr.ClearButton(value='Clear', components=[song_input, rvc_model, keep_files, local_file])
|
229 |
generate_btn = gr.Button("Generate", variant='primary')
|
230 |
ai_cover = gr.Audio(label='AI Cover', show_share_button=False)
|
231 |
+
original_vocals =gr.Audio(label='original_vocals', show_share_button=False)
|
232 |
+
original_instrumentals = gr.Audio(label='original_instrumentals', show_share_button=False)
|
233 |
+
ai_vocals =gr.Audio(label='ai_vocals', show_share_button=False)
|
234 |
ref_btn.click(update_models_list, None, outputs=rvc_model)
|
235 |
is_webui = gr.Number(value=1, visible=False)
|
236 |
generate_btn.click(song_cover_pipeline,
|
|
|
238 |
inst_gain, index_rate, filter_radius, rms_mix_rate, f0_method, crepe_hop_length,
|
239 |
protect, pitch_all, reverb_rm_size, reverb_wet, reverb_dry, reverb_damping,
|
240 |
output_format],
|
241 |
+
outputs=[ai_cover, original_vocals, original_instrumentals, ai_vocals])
|
242 |
clear_btn.click(lambda: [0, 0, 0, 0, 0.5, 3, 0.25, 0.33, 'rmvpe', 128, 0, 0.15, 0.2, 0.8, 0.7, 'mp3', None],
|
243 |
outputs=[pitch, main_gain, backup_gain, inst_gain, index_rate, filter_radius, rms_mix_rate,
|
244 |
protect, f0_method, crepe_hop_length, pitch_all, reverb_rm_size, reverb_wet,
|