オーディオ信号の再生速度・音高の変更はよく利用される処理です。
そのアルゴリズムはいくつかありますが、リアルタイム処理向けの手法としてはフェーズボコーダという手法があります。
Pythonでは、音楽信号分析ライブラリLibROSAにおいてフェーズボコーダが用意されていますが、ナイーブな実装のため音質があまりよくないという問題があります。
ところで、高品質な再生速度・音高の変更が可能なフェーズボコーダ(タイムストレッチ・ピッチシフト)のライブラリとしてRubberBand
が知られています。
このライブラリ自体はC++用ですが、実はPythonラッパーpyrubberband
があるためPythonで利用可能です。
そこで、本記事では```pyrubberband```のインストール方法と使い方を紹介したいと思います。
検証環境
Windows 10 64-bit Python 3.8.8
関連Webサイト
GitHub - bmcfee/pyrubberband: python wrapper for rubberband
なお、pyrubberband
の作者であるBrian McFee氏は音楽信号分析ライブラリLibROSAやリサンプリングライブラリResampyの作者でもあります。
従って、pyrubberband
のピッチシフト・タイムストレッチ関数の仕様は LibROSA
のピッチシフト・タイムストレッチ関数とだいたい同じです。
依存関係・ライセンス
- rubberband: ISC License
- pyrubberband: GPL
インストール方法 (Windows)
1. pyrubberband をインストール
Pythonでrubberbandを呼び出すライブラリであるpyrubberband
を導入します。
pip install pyrubberband
基本的にはsubprocess
でrubberband
を実行するくらいの役割なので、自分で書くことも可能だとうは思います。
実際、pyrubberband
は 250行強程度のコードなので、実行ファイルをPythonで呼び出すライブラリを実装する際の良い参考になると思います。
気になる方はpyrubberband
のコードを見てみてください。
2. rubberband をインストール
Windowsの場合、こちらでビルド済みの実行ファイルが配布されているので、それを使います。
ダウンロード後、解凍して適当な場所に置き、そのrubberbandの実行ファイルがあるフォルダのパスを環境変数に追加すればOKです。
使い方
タイムストレッチ
pyrb.time_stretch(元信号Numpy配列, サンプリング周波数, 倍率) となります。
import numpy as np import matplotlib.pyplot as plt import soundfile as sf import pyrubberband as pyrb x, sr = sf.read("mono_sin_50Hz.wav") # time_stretch y1 = pyrb.time_stretch(x, sr, 2.0) y2 = pyrb.time_stretch(x, sr, 0.5) plt.clf() plt.plot(x, alpha=0.4, label="Original") plt.plot(y1, alpha=0.4, label="time_stretch x2.0") plt.plot(y2, alpha=0.4, label="time_stretch x0.5") plt.legend() plt.grid() plt.show()
ピッチシフト
pyrb.pitch_shift(元信号Numpy配列, サンプリング周波数, n_steps
) となります。
こちらは明らかに音楽信号処理向けの仕様となっており、n_steps=1
とすると1半音ピッチが高くなります。
つまり、n_steps=12
ならば1オクターブ高くなります。
import numpy as np import matplotlib.pyplot as plt import soundfile as sf import pyrubberband as pyrb x, sr = sf.read("mono_sin_50Hz.wav") # time_stretch y1 = pyrb.pitch_shift(x, sr, 12.0) y2 = pyrb.pitch_shift(x, sr, -12.0) plt.clf() plt.plot(x, alpha=0.4, label="Original") plt.plot(y1, alpha=0.4, label="pitch_shift +12 semitones") plt.plot(y2, alpha=0.4, label="pitch_shift -12 semitones") plt.legend() plt.grid() plt.show()
まとめ
高品質フェーズボコーダ rubberband のPythonラッパーである pyrubberband
のインストール方法と使い方を紹介しました。
タイムストレッチやピッチシフトはとても実用的な音響信号処理なので、是非一度触って音を聞き比べてみてください。