ノイズ処理のためには、長尺音源は分割したほうがメモリの観点で処理速度が速くなる。以下は300秒ごとに5秒ごとのオーバーラップ付きで分割する方法。300秒のところは尺にあわせて調整すべし。
import librosa import soundfile as sf import os import numpy as np # 入力ファイルと出力先 input_path = 'input.wav' output_dir = './split_audio' os.makedirs(output_dir, exist_ok=True) # ロード y, sr = librosa.load(input_path, sr=None, mono=False) # shape: (2, n_samples) # パラメータ chunk_duration = 300 # 秒 overlap = 5 # 秒 chunk_samples = int(chunk_duration * sr) overlap_samples = int(overlap * sr) step = chunk_samples - overlap_samples total_samples = y.shape[1] # 分割と保存 start = 0 index = 0 while start < total_samples: end = min(start + chunk_samples, total_samples) chunk = y[:, start:end] output_path = os.path.join(output_dir, f'chunk_{index:03}.wav') sf.write(output_path, chunk.T, sr) index += 1 start += step
分割した音源に何らかの処理を適用した想定で、オーバーラップの5秒部分をフェードしながら結合する。単純に係数 0-1、1-0でフェードして線形結合するだけ。natsort は pip install natsort でインストールする。
import soundfile as sf import numpy as np import glob import os from natsort import natsorted # パス設定 folder = "./split_audio" files = natsorted(glob.glob(os.path.join(folder, "*(Vocals).wav"))) output_path = "output.wav" # パラメータ sr = None fade_duration = 5 # 秒 fade_samples = None output = None for i, filepath in enumerate(files): y, sr = sf.read(filepath) # shape: (samples, channels) y = y.T # (channels, samples) if fade_samples is None: fade_samples = int(fade_duration * sr) if i == 0: output = y else: # 前の末尾と現在の先頭をフェード処理 prev = output[:, -fade_samples:] curr = y[:, :fade_samples] # フェード係数 fade_out = np.linspace(1, 0, fade_samples) fade_in = np.linspace(0, 1, fade_samples) # クロスフェード crossfaded = prev * fade_out + curr * fade_in # 結合 output = np.concatenate([output[:, :-fade_samples], crossfaded, y[:, fade_samples:]], axis=1) # 出力 sf.write(output_path, output.T, sr) # (samples, channels)