CoverGen-RVC / src /main.py
Politrees's picture
Upload 29 files
e976963 verified
raw
history blame
3.63 kB
import gc
import hashlib
import os
import shlex
import subprocess
import librosa
import numpy as np
import soundfile as sf
import gradio as gr
from rvc import Config, load_hubert, get_vc, rvc_infer
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
rvc_models_dir = os.path.join(BASE_DIR, 'rvc_models')
output_dir = os.path.join(BASE_DIR, 'song_output')
def get_rvc_model(voice_model):
model_dir = os.path.join(rvc_models_dir, voice_model)
rvc_model_path = next((os.path.join(model_dir, f) for f in os.listdir(model_dir) if f.endswith('.pth')), None)
rvc_index_path = next((os.path.join(model_dir, f) for f in os.listdir(model_dir) if f.endswith('.index')), None)
if rvc_model_path is None:
error_msg = f'В каталоге {model_dir} отсутствует файл модели.'
raise Exception(error_msg)
return rvc_model_path, rvc_index_path
def convert_to_stereo(audio_path):
wave, sr = librosa.load(audio_path, mono=False, sr=44100)
if type(wave[0]) != np.ndarray:
stereo_path = f'Voice_stereo.wav'
command = shlex.split(f'ffmpeg -y -loglevel error -i "{audio_path}" -ac 2 -f wav "{stereo_path}"')
subprocess.run(command)
return stereo_path
else:
return audio_path
def get_hash(filepath):
with open(filepath, 'rb') as f:
file_hash = hashlib.blake2b()
while chunk := f.read(8192):
file_hash.update(chunk)
return file_hash.hexdigest()[:11]
def display_progress(percent, message, progress=gr.Progress()):
progress(percent, desc=message)
def voice_change(voice_model, vocals_path, output_path, pitch_change, f0_method, index_rate, filter_radius, rms_mix_rate, protect, crepe_hop_length):
rvc_model_path, rvc_index_path = get_rvc_model(voice_model)
device = 'cuda:0'
config = Config(device, True)
hubert_model = load_hubert(device, config.is_half, os.path.join(rvc_models_dir, 'hubert_base.pt'))
cpt, version, net_g, tgt_sr, vc = get_vc(device, config.is_half, config, rvc_model_path)
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)
del hubert_model, cpt
gc.collect()
def song_cover_pipeline(uploaded_file, voice_model, pitch_change, index_rate=0.5, filter_radius=3, rms_mix_rate=0.25, f0_method='rmvpe',
crepe_hop_length=128, protect=0.33, output_format='mp3', progress=gr.Progress()):
if not uploaded_file or not voice_model:
raise Exception('Убедитесь, что поле ввода песни и поле модели голоса заполнены.')
display_progress(0, '[~] Запуск конвейера генерации AI-кавера...', progress)
if not os.path.exists(uploaded_file):
error_msg = f'{uploaded_file} не существует.'
raise Exception(error_msg)
song_id = get_hash(uploaded_file)
song_dir = os.path.join(output_dir, song_id)
os.makedirs(song_dir, exist_ok=True)
orig_song_path = convert_to_stereo(uploaded_file)
ai_cover_path = os.path.join(song_dir, f'Converted_Voice.{output_format}')
if os.path.exists(ai_cover_path):
os.remove(ai_cover_path)
display_progress(0.5, '[~] Преобразование вокала...', progress)
voice_change(voice_model, orig_song_path, ai_cover_path, pitch_change, f0_method, index_rate,
filter_radius, rms_mix_rate, protect, crepe_hop_length)
return ai_cover_path