Wizard Notes

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

Python:Pyroomacousticsを使ってインパルス応答を作成

Pyroomacoustics はPython向けの音響アレイ信号処理のラピッドプロトタイピングプラットフォームです。

github.com

Pyroomacoustics の便利な機能の一つとして、僅かな行数のスクリプト多面体の部屋の室内インパルス応答を生成することができます。

インパルス応答の生成スクリプト

import numpy as np
import soundfile as sf
import matplotlib.pyplot as plt
import pyroomacoustics as pra

# パラメタ
fs = 44100       # サンプリング周波数
absorption = 0.2 # 反射率
max_order = 10    # 次数

# 3次元の部屋形状生成
corners = np.array([[0,0], [0,3], [5,3], [5,1], [3,1], [3,0]]).T
room = pra.Room.from_corners(
        corners, 
        max_order=max_order, 
        fs=fs, 
        absorption=absorption
    )
room.extrude(2.) # 高さを設定

# 音源位置を設定
room.add_source([1., 1., 1.])
# マイク位置を設定
room.add_microphone([1., 0.7, 1.2])

# 部屋形状、音源・マイク位置プロット
fig, ax = room.plot()
ax.set_xlim([0, 5])
ax.set_ylim([0, 3])
ax.set_zlim([0, 2])
plt.show()


# インパルス応答を計算
room.compute_rir()
# インパルス応答の波形データを保存
ir_signal = room.rir[0][0]
ir_signal /= np.max(np.abs(ir_signal)) # 可視化のため正規化
sf.write(f"ir{fs}.wav", ir_signal, fs)

# IRプロット
room.plot_rir()
plt.show()

部屋が単純な直方体を作る場合、以下のようにxy座標を指定するだけでroomオブジェクトを作ることもできます。

# 3次元の部屋形状生成
room = pra.ShoeBox(
        [5.0, 6], 
        max_order=8, 
        fs=fs, 
        absorption=0.8
    )
room.extrude(3.) # 高さを設定

インパルス応答の畳み込み

LibROSAの音声に対して、生成したインパルス応答を畳み込みます.

import scipy
import librosa
x, sr = librosa.load(librosa.ex('libri1', hq=True), sr=fs, mono=True)
x_filtered = scipy.signal.oaconvolve(x, ir_signal, mode="full")
sf.write(f"test_x.wav", x, fs)
sf.write(f"test_x_filtered.wav", x_filtered, fs)

print(x.shape, x_filtered.shape)
plt.subplot(2,1,1)
plt.plot(x)
plt.xlim([0, 700000])
plt.ylim([-1.0, 1.0])
plt.grid()
plt.title("x")
plt.subplot(2,1,2)
plt.plot(x_filtered)
plt.xlim([0, 700000])
plt.ylim([-1.0, 1.0])
plt.grid()
plt.title("x_filtered")
plt.tight_layout()
plt.show()

参考文献

www.hiromasa.info mybinder.org pyroomacoustics.readthedocs.io github.com