| from multiprocessing import cpu_count |
| import os |
| import sys |
|
|
| from scipy import signal |
| from scipy.io import wavfile |
| import librosa |
| import numpy as np |
|
|
| now_directory = os.getcwd() |
| sys.path.append(now_directory) |
|
|
| from rvc.lib.utils import load_audio |
| from rvc.train.slicer import Slicer |
|
|
| experiment_directory = sys.argv[1] |
| input_root = sys.argv[2] |
| sampling_rate = int(sys.argv[3]) |
| percentage = float(sys.argv[4]) |
| num_processes = cpu_count() |
|
|
| import multiprocessing |
|
|
|
|
| class PreProcess: |
| def __init__(self, sr, exp_dir, per=3.0): |
| self.slicer = Slicer( |
| sr=sr, |
| threshold=-42, |
| min_length=1500, |
| min_interval=400, |
| hop_size=15, |
| max_sil_kept=500, |
| ) |
| self.sr = sr |
| self.b_high, self.a_high = signal.butter(N=5, Wn=48, btype="high", fs=self.sr) |
| self.per = per |
| self.overlap = 0.3 |
| self.tail = self.per + self.overlap |
| self.max_amplitude = 0.9 |
| self.alpha = 0.75 |
| self.exp_dir = exp_dir |
| self.gt_wavs_dir = f"{exp_dir}/0_gt_wavs" |
| self.wavs16k_dir = f"{exp_dir}/1_16k_wavs" |
| os.makedirs(self.exp_dir, exist_ok=True) |
| os.makedirs(self.gt_wavs_dir, exist_ok=True) |
| os.makedirs(self.wavs16k_dir, exist_ok=True) |
|
|
| def normalize_and_write(self, tmp_audio, idx0, idx1): |
| tmp_max = np.abs(tmp_audio).max() |
| if tmp_max > 2.5: |
| print(f"{idx0}-{idx1}-{tmp_max}-filtered") |
| return |
| tmp_audio = (tmp_audio / tmp_max * (self.max_amplitude * self.alpha)) + ( |
| 1 - self.alpha |
| ) * tmp_audio |
| wavfile.write( |
| f"{self.gt_wavs_dir}/{idx0}_{idx1}.wav", |
| self.sr, |
| tmp_audio.astype(np.float32), |
| ) |
| tmp_audio = librosa.resample( |
| tmp_audio, orig_sr=self.sr, target_sr=16000 |
| ) |
| wavfile.write( |
| f"{self.wavs16k_dir}/{idx0}_{idx1}.wav", |
| 16000, |
| tmp_audio.astype(np.float32), |
| ) |
|
|
| def process_audio(self, path, idx0): |
| try: |
| audio = load_audio(path, self.sr) |
| audio = signal.lfilter(self.b_high, self.a_high, audio) |
|
|
| idx1 = 0 |
| for audio_segment in self.slicer.slice(audio): |
| i = 0 |
| while 1: |
| start = int(self.sr * (self.per - self.overlap) * i) |
| i += 1 |
| if len(audio_segment[start:]) > self.tail * self.sr: |
| tmp_audio = audio_segment[ |
| start : start + int(self.per * self.sr) |
| ] |
| self.normalize_and_write(tmp_audio, idx0, idx1) |
| idx1 += 1 |
| else: |
| tmp_audio = audio_segment[start:] |
| idx1 += 1 |
| break |
| self.normalize_and_write(tmp_audio, idx0, idx1) |
| except Exception as error: |
| print(f"{path}: {error}") |
|
|
| def process_audio_multiprocessing(self, infos): |
| for path, idx0 in infos: |
| self.process_audio(path, idx0) |
|
|
| def process_audio_multiprocessing_input_directory(self, input_root, num_processes): |
| try: |
| infos = [ |
| (f"{input_root}/{name}", idx) |
| for idx, name in enumerate(sorted(list(os.listdir(input_root)))) |
| ] |
| processes = [] |
| for i in range(num_processes): |
| p = multiprocessing.Process( |
| target=self.process_audio_multiprocessing, |
| args=(infos[i::num_processes],), |
| ) |
| processes.append(p) |
| p.start() |
| for i in range(num_processes): |
| processes[i].join() |
| except Exception as error: |
| print(error) |
|
|
|
|
| def preprocess_training_set(input_root, sr, num_processes, exp_dir, per): |
| pp = PreProcess(sr, exp_dir, per) |
| print("Starting preprocessing...") |
| pp.process_audio_multiprocessing_input_directory(input_root, num_processes) |
| print("Preprocessing completed!") |
|
|
|
|
| if __name__ == "__main__": |
| preprocess_training_set( |
| input_root, sampling_rate, num_processes, experiment_directory, percentage |
| ) |
|
|