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)