Refactor, improve: use pathlib, allow audios other than wavs in resample

This commit is contained in:
litagin02
2024-03-15 11:10:23 +09:00
parent 5c1e791b9a
commit 867855ace9
2 changed files with 50 additions and 54 deletions

View File

@@ -1,18 +1,19 @@
import argparse import argparse
import os from concurrent.futures import ThreadPoolExecutor, as_completed
from concurrent.futures import ThreadPoolExecutor
from multiprocessing import cpu_count from multiprocessing import cpu_count
from pathlib import Path
from typing import Any
import librosa import librosa
import pyloudnorm as pyln import pyloudnorm as pyln
import soundfile import soundfile
from numpy.typing import NDArray
from tqdm import tqdm from tqdm import tqdm
from config import config from config import config
from style_bert_vits2.logging import logger from style_bert_vits2.logging import logger
from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT from style_bert_vits2.utils.stdout_wrapper import SAFE_STDOUT
DEFAULT_BLOCK_SIZE: float = 0.400 # seconds DEFAULT_BLOCK_SIZE: float = 0.400 # seconds
@@ -20,32 +21,37 @@ class BlockSizeException(Exception):
pass pass
def normalize_audio(data, sr): def normalize_audio(data: NDArray[Any], sr: int):
meter = pyln.Meter(sr, block_size=DEFAULT_BLOCK_SIZE) # create BS.1770 meter meter = pyln.Meter(sr, block_size=DEFAULT_BLOCK_SIZE) # create BS.1770 meter
try: try:
loudness = meter.integrated_loudness(data) loudness = meter.integrated_loudness(data)
except ValueError as e: except ValueError as e:
raise BlockSizeException(e) raise BlockSizeException(e)
# logger.info(f"loudness: {loudness}")
data = pyln.normalize.loudness(data, loudness, -23.0) data = pyln.normalize.loudness(data, loudness, -23.0)
return data return data
def process(item): def resample(file: Path, output_dir: Path, target_sr: int, normalize: bool, trim: bool):
spkdir, wav_name, args = item try:
wav_path = os.path.join(args.in_dir, spkdir, wav_name) # librosaが読めるファイルかチェック
if os.path.exists(wav_path) and wav_path.lower().endswith(".wav"): # wav以外にもmp3やoggやflacなども読める
wav, sr = librosa.load(wav_path, sr=args.sr) wav: NDArray[Any]
if args.normalize: sr: int
wav, sr = librosa.load(file, sr=target_sr)
if normalize:
try: try:
wav = normalize_audio(wav, sr) wav = normalize_audio(wav, sr)
except BlockSizeException: except BlockSizeException:
print("")
logger.info( logger.info(
f"Skip normalize due to less than {DEFAULT_BLOCK_SIZE} second audio: {wav_path}" f"Skip normalize due to less than {DEFAULT_BLOCK_SIZE} second audio: {file}"
) )
if args.trim: if trim:
wav, _ = librosa.effects.trim(wav, top_db=30) wav, _ = librosa.effects.trim(wav, top_db=30)
soundfile.write(os.path.join(args.out_dir, spkdir, wav_name), wav, sr) soundfile.write(output_dir / file.with_suffix(".wav").name, wav, sr)
except Exception as e:
logger.warning(f"Cannot load file, so skipping: {file}, {e}")
if __name__ == "__main__": if __name__ == "__main__":
@@ -57,14 +63,14 @@ if __name__ == "__main__":
help="sampling rate", help="sampling rate",
) )
parser.add_argument( parser.add_argument(
"--in_dir", "--input_dir",
"-i", "-i",
type=str, type=str,
default=config.resample_config.in_dir, default=config.resample_config.in_dir,
help="path to source dir", help="path to source dir",
) )
parser.add_argument( parser.add_argument(
"--out_dir", "--output_dir",
"-o", "-o",
type=str, type=str,
default=config.resample_config.out_dir, default=config.resample_config.out_dir,
@@ -88,46 +94,36 @@ if __name__ == "__main__":
default=False, default=False,
help="trim silence (start and end only)", help="trim silence (start and end only)",
) )
args, _ = parser.parse_known_args() args = parser.parse_args()
# autodl 无卡模式会识别出46个cpu
if args.num_processes == 0: if args.num_processes == 0:
processes = cpu_count() - 2 if cpu_count() > 4 else 1 processes = cpu_count() - 2 if cpu_count() > 4 else 1
else: else:
processes = args.num_processes processes: int = args.num_processes
tasks = [] input_dir = Path(args.input_dir)
output_dir = Path(args.output_dir)
sr = int(args.sr)
normalize: bool = args.normalize
trim: bool = args.trim
for dirpath, _, filenames in os.walk(args.in_dir): # 後でlibrosaに読ませて有効な音声ファイルかチェックするので、全てのファイルを取得
# 子级目录 original_files = [f for f in input_dir.rglob("*") if f.is_file()]
spk_dir = os.path.relpath(dirpath, args.in_dir)
spk_dir_out = os.path.join(args.out_dir, spk_dir)
if not os.path.isdir(spk_dir_out):
os.makedirs(spk_dir_out, exist_ok=True)
for filename in filenames:
if filename.lower().endswith(".wav"):
twople = (spk_dir, filename, args)
tasks.append(twople)
if len(tasks) == 0: if len(original_files) == 0:
logger.error(f"No wav files found in {args.in_dir}") logger.error(f"No files found in {input_dir}")
raise ValueError(f"No wav files found in {args.in_dir}") raise ValueError(f"No files found in {input_dir}")
# pool = Pool(processes=processes) output_dir.mkdir(parents=True, exist_ok=True)
# for _ in tqdm(
# pool.imap_unordered(process, tasks), file=SAFE_STDOUT, total=len(tasks)
# ):
# pass
# pool.close()
# pool.join()
with ThreadPoolExecutor(max_workers=processes) as executor: with ThreadPoolExecutor(max_workers=processes) as executor:
_ = list( futures = [
tqdm( executor.submit(resample, file, output_dir, sr, normalize, trim)
executor.map(process, tasks), for file in original_files
total=len(tasks), ]
file=SAFE_STDOUT, for future in tqdm(
) as_completed(futures), total=len(original_files), file=SAFE_STDOUT
) ):
pass
logger.info("Resampling Done!") logger.info("Resampling Done!")

View File

@@ -129,14 +129,14 @@ def initialize(
def resample(model_name, normalize, trim, num_processes): def resample(model_name, normalize, trim, num_processes):
logger.info("Step 2: start resampling...") logger.info("Step 2: start resampling...")
dataset_path, _, _, _, _ = get_path(model_name) dataset_path, _, _, _, _ = get_path(model_name)
in_dir = os.path.join(dataset_path, "raw") input_dir = os.path.join(dataset_path, "raw")
out_dir = os.path.join(dataset_path, "wavs") output_dir = os.path.join(dataset_path, "wavs")
cmd = [ cmd = [
"resample.py", "resample.py",
"--in_dir", "-i",
in_dir, input_dir,
"--out_dir", "-o",
out_dir, output_dir,
"--num_processes", "--num_processes",
str(num_processes), str(num_processes),
"--sr", "--sr",