librosaとPyTorchを用いて、Pythonで音声/音楽データ(波形)のリサンプリングを行う。Numpyのndarray配列をリサンプリングしたい場合はlibrosaを用い、PyTorchのTensor配列をリサンプリングしたい場合は、PyTorchを用いる。
用いるサンプル音源を、_sample_dataフォルダにダウンロードする。
import os
import requests
_SAMPLE_DIR = "_sample_data"
SAMPLE_WAV_URL = "https://pytorch-tutorial-assets.s3.amazonaws.com/steam-train-whistle-daniel_simon.wav"
SAMPLE_WAV_PATH = os.path.join(_SAMPLE_DIR, "steam.wav")
os.makedirs(_SAMPLE_DIR, exist_ok=True)
with open(SAMPLE_WAV_PATH, 'wb') as f:
f.write(requests.get(SAMPLE_WAV_URL).content)
librosa.resampleの使い方【Numpy ndarray】
librosaでリサンプルするには、librosa.resampleを使う。第一引数yにリサンプルするndarray配列、第二引数orig_srに元のサンプリング周波数、第三引数target_srにリサンプル後のサンプリング周波数を指定する。リサンプル後の波形がndarray配列として返ってくる。
import librosa
y, sr = librosa.load(SAMPLE_WAV_PATH, sr=None, mono=False)
print(y.shape)
# (2, 109368)
print(sr)
# 44100
re_sr = 8000
y_8k = librosa.resample(y=y, orig_sr=sr, target_sr=re_sr)
print(y_8k.shape)
# (2, 19840)
サンプリング周波数を44100Hzから8000Hzにリサンプリングしたことによって、信号長が短くなっていることが確認できる。
第四引数res_typeを指定することで、リサンプリングの手法変えることができる。デフォルトは、‘kaiser_best’で他以下方法から選択が可能である。
- ‘kaiser_best’ (default)
- ‘kaiser_fast’
- ‘fft’ or ‘scipy’
- ‘polyphase’
- ‘linear’
- ‘zero_order_hold’
- ‘sinc_best’, ‘sinc_medium’ or ‘sinc_fastest’
- ‘soxr_vhq’, ‘soxr_hq’, ‘soxr_mq’ or ‘soxr_lq’
- ‘soxr_qq’
y_8k_kaiser_fast = librosa.resample(y=y, orig_sr=sr, target_sr=re_sr, res_type='kaiser_fast')
torchaudio.functional.resample/torchaudio.transforms.Resampleの使い方【PyTorch Tensor】
PyTorch Tensor配列として音源を読み込む。
import torch
import torchaudio
waveform, sample_rate = torchaudio.load(filepath=SAMPLE_WAV_PATH)
print(waveform.shape)
# torch.Size([2, 109368])
print(sample_rate)
# 44100
torchaudio.functional.resample
torchaudio.functional.resampleの第一引数waveformにリサンプルするTensor配列、第二引数orig_freqに元のサンプリング周波数、第三引数new_freqにリサンプル後のサンプリング周波数を指定する。リサンプル後の波形がTensor配列として返ってくる。
import torchaudio.functional as F
re_sample_rate = 8000
resampled_waveform = F.resample(waveform=waveform, orig_freq=sample_rate, new_freq=re_sample_rate)
print(resampled_waveform.shape)
# torch.Size([2, 19840])
リサンプルの補間方法は、引数resampling_methodを指定する。以下から選択できる。
- sinc_interpolation(default)
- kaiser_window
resampled_waveform_kaiser = F.resample(waveform=waveform, orig_freq=sample_rate, new_freq=re_sample_rate, resampling_method='kaiser_window')
torchaudio.transforms.Resample
torchaudio.transforms.Resampleもtorchaudio.functional.resampleとほぼ同様の使い方で、インスタンスを事前に生成して使う。
import torchaudio.transforms as T
resampler = T.Resample(orig_freq=sample_rate, new_freq=re_sample_rate, resampling_method='kaiser_window')
resampled_waveform = resampler(waveform)
print(resampled_waveform.shape)
# torch.Size([2, 19840])
torchaudio.transforms.Resampleは、リサンプリングに使用されるカーネルを事前計算してキャッシュして使うため、都度計算するtorchaudio.functional.resampleよりも、同じパラメータで計算を複数回行うときに早くなります。下記、速度計測結果でもかなり速度に差があることが分かります。
%%timeit
for _ in range(10):
resampled_waveform_kaiser = F.resample(waveform=waveform, orig_freq=sample_rate, new_freq=re_sample_rate, resampling_method='kaiser_window')
# 10 loops, best of 5: 198 ms per loop
%%timeit
for _ in range(10):
resampled_waveform = resampler(waveform)
# 100 loops, best of 5: 11.7 ms per loop
コメント