Wizard Notes

Pythonを使った音楽信号分析の技術録、作曲活動に関する雑記

Python: 高品質フェーズボコーダ pyrubberband でタイムストレッチ・ピッチシフト

f:id:Kurene:20210903223629p:plain:w300

オーディオ信号の再生速度・音高の変更はよく利用される処理です。

そのアルゴリズムはいくつかありますが、リアルタイム処理向けの手法としてはフェーズボコーダという手法があります。

Pythonでは、音楽信号分析ライブラリLibROSAにおいてフェーズボコーダが用意されていますが、ナイーブな実装のため音質があまりよくないという問題があります。

ところで、高品質な再生速度・音高の変更が可能なフェーズボコーダ(タイムストレッチ・ピッチシフト)のライブラリとしてRubberBandが知られています。

このライブラリ自体はC++用ですが、実はPythonラッパーpyrubberbandがあるためPythonで利用可能です。

そこで、本記事では```pyrubberband```のインストール方法と使い方を紹介したいと思います。

検証環境

Windows 10 64-bit Python 3.8.8

関連Webサイト

github.com

GitHub - bmcfee/pyrubberband: python wrapper for rubberband

pyrubberband.readthedocs.io

なお、pyrubberbandの作者であるBrian McFee氏は音楽信号分析ライブラリLibROSAやリサンプリングライブラリResampyの作者でもあります。

従って、pyrubberbandのピッチシフト・タイムストレッチ関数の仕様は LibROSAピッチシフトタイムストレッチ関数とだいたい同じです。

依存関係・ライセンス

  • rubberband: ISC License
  • pyrubberband: GPL

インストール方法 (Windows)

1. pyrubberband をインストール

Pythonでrubberbandを呼び出すライブラリであるpyrubberbandを導入します。

pip install pyrubberband

基本的にはsubprocessrubberbandを実行するくらいの役割なので、自分で書くことも可能だとうは思います。

実際、pyrubberbandは 250行強程度のコードなので、実行ファイルをPythonで呼び出すライブラリを実装する際の良い参考になると思います。

気になる方はpyrubberbandのコードを見てみてください。

github.com

2. rubberband をインストール

Windowsの場合、こちらでビルド済みの実行ファイルが配布されているので、それを使います。

ダウンロード後、解凍して適当な場所に置き、そのrubberbandの実行ファイルがあるフォルダのパスを環境変数に追加すればOKです。

f:id:Kurene:20210904005136p:plain:w400

使い方

タイムストレッチ

pyrb.time_stretch(元信号Numpy配列, サンプリング周波数, 倍率) となります。

f:id:Kurene:20210904010842p:plain:w400

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オクターブ高くなります。

f:id:Kurene:20210904012315p:plain:w400

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 のインストール方法と使い方を紹介しました。

タイムストレッチやピッチシフトはとても実用的な音響信号処理なので、是非一度触って音を聞き比べてみてください。