111 lines
4.4 KiB
Python
111 lines
4.4 KiB
Python
import gc
|
|
import os
|
|
|
|
import soundfile as sf
|
|
import sox
|
|
#from pedalboard import Pedalboard, Reverb, Compressor, HighpassFilter
|
|
#from pedalboard.io import AudioFile
|
|
|
|
from .rvc import Config, load_hubert, get_vc, rvc_infer
|
|
|
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
rvc_models_dir = os.path.join(BASE_DIR, 'rvc_models')
|
|
|
|
|
|
def get_rvc_model(voice_model):
|
|
rvc_model_filename, rvc_index_filename = None, None
|
|
model_dir = os.path.join(rvc_models_dir, voice_model)
|
|
for file in os.listdir(model_dir):
|
|
ext = os.path.splitext(file)[1]
|
|
if ext == '.pth':
|
|
rvc_model_filename = file
|
|
if ext == '.index':
|
|
rvc_index_filename = file
|
|
|
|
if rvc_model_filename is None:
|
|
error_msg = f'No model file exists in {model_dir}.'
|
|
raise NameError(error_msg)
|
|
|
|
return os.path.join(model_dir, rvc_model_filename), os.path.join(model_dir, rvc_index_filename) if rvc_index_filename else ''
|
|
|
|
|
|
def pitch_shift(audio_path, pitch_change):
|
|
output_path = f'{os.path.splitext(audio_path)[0]}_p{pitch_change}.wav'
|
|
if not os.path.exists(output_path):
|
|
y, sr = sf.read(audio_path)
|
|
tfm = sox.Transformer()
|
|
tfm.pitch(pitch_change)
|
|
y_shifted = tfm.build_array(input_array=y, sample_rate_in=sr)
|
|
sf.write(output_path, y_shifted, sr)
|
|
|
|
return output_path
|
|
|
|
|
|
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)
|
|
|
|
# convert main vocals
|
|
try:
|
|
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)
|
|
except Exception as err:
|
|
print(err)
|
|
finally:
|
|
del hubert_model, cpt
|
|
gc.collect()
|
|
|
|
'''
|
|
def add_audio_effects(audio_path, reverb_rm_size, reverb_wet, reverb_dry, reverb_damping):
|
|
output_path = f'{os.path.splitext(audio_path)[0]}_mixed.wav'
|
|
|
|
# Initialize audio effects plugins
|
|
board = Pedalboard(
|
|
[
|
|
HighpassFilter(),
|
|
Compressor(ratio=4, threshold_db=-15),
|
|
Reverb(room_size=reverb_rm_size, dry_level=reverb_dry, wet_level=reverb_wet, damping=reverb_damping)
|
|
]
|
|
)
|
|
|
|
with AudioFile(audio_path) as f:
|
|
with AudioFile(output_path, 'w', f.samplerate, f.num_channels) as o:
|
|
# Read one second of audio at a time, until the file is empty:
|
|
while f.tell() < f.frames:
|
|
chunk = f.read(int(f.samplerate))
|
|
effected = board(chunk, f.samplerate, reset=False)
|
|
o.write(effected)
|
|
|
|
return output_path
|
|
'''
|
|
|
|
|
|
def song_cover_pipeline(song_input, pitch_change_oct, voice_model='miku',
|
|
main_gain=0, backup_gain=0, inst_gain=0, index_rate=0.5, filter_radius=3,
|
|
rms_mix_rate=0.25, f0_method='rmvpe', crepe_hop_length=128, protect=0.33, pitch_change_sem=0,
|
|
reverb_rm_size=0.15, reverb_wet=0.2, reverb_dry=0.8, reverb_damping=0.7, output_format='mp3'):
|
|
try:
|
|
orig_vocals_path = song_input.strip('\"')
|
|
|
|
pitch_change = pitch_change_oct * 12 + pitch_change_sem
|
|
ai_vocals_path = os.path.join(
|
|
os.path.dirname(song_input),
|
|
f'{os.path.splitext(os.path.basename(orig_vocals_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'
|
|
)
|
|
print(f'Output file path will be: {ai_vocals_path}')
|
|
|
|
if not os.path.exists(ai_vocals_path):
|
|
print('[~] Converting voice using RVC...')
|
|
voice_change(voice_model, orig_vocals_path, ai_vocals_path, pitch_change, f0_method, index_rate, filter_radius, rms_mix_rate, protect, crepe_hop_length)
|
|
|
|
#display_progress('[~] Applying audio effects to Vocals...', 0.8, is_webui, progress)
|
|
#ai_vocals_mixed_path = add_audio_effects(ai_vocals_path, reverb_rm_size, reverb_wet, reverb_dry, reverb_damping)
|
|
|
|
return ai_vocals_path
|
|
|
|
except Exception as e:
|
|
print(e)
|