pyroomacoustics能够在2D/3D房间中快速构建单/多个声源以及麦克风的模拟场景,借助image方法能够有效生成房间脉冲响应并模拟声源和麦克风之间的传播途径。接下来系列博文将主要介绍pyroomacoustics的使用。今天主要介绍利用pyroomacoustics生成房间脉冲相应(Room Impluse Response, RIR)。

在使用pyroomacoustics之前,首先确保已经正确安装,安装命令如下

pip install pyroomacoustics

安装成功后,打印版本信息可知所安装的pyroomacoustics的版本.我使用的版本是0.4.2

import pyroomacoustics as pra
print(pra.__version__)
'''
0.4.2
'''

使用pyroomacoustics生成RIR的一般流程如下:

创建room
添加microphoneroom
添加sourceroom
调用image_source_model()以及simulate()方法

创建room

pyroomacoustics可以创建2D房间尺寸和3D房间尺寸。创建3D房间尺寸也很简单,就是在2D房间上再增加一个高而已。接下来创建一个尺寸为(7,5)的矩阵房间,以矩阵左下角为坐标原点。那么使用如下代码可以创建2D房间

import numpy as np
import pyroomacoustics as pra
corner = np.array([[0, 0], [7, 0], [7, 5], [0, 5]]).T
room = pra.Room.from_corners(corner)
'''
corner: 房间的四个角。`pra.Room.from_corners()`的函数文档中表示四个角的声明顺序必须逆时针。
'''
fig, ax = room.plot()
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
fig.show()

pyroomacoustics–生成房间脉冲响应-风君雪科技博客

而下面的代码创建三维房间

import numpy as np
import pyroomacoustics as pra
corner = np.array([[0, 0], [7, 0], [7, 5], [0, 5]]).T
room = pra.Room.from_corners(corner)
room.extrude(3.)
fig, ax = room.plot()
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
ax.set_zlim([-1, 4])
fig.show()

pyroomacoustics–生成房间脉冲响应-风君雪科技博客

添加microphone/sourceroom

下面以创建的2D房间为例(与2D的差别在于,3D房间中麦克风位置只是多了一个坐标),pyroomacoustics中提供了声明麦克风阵列的函数,本例中以环阵为例,并完善上面创建房间的脚本(增加墙壁的反射系数)

import soundfile as sf
audio, sr = sf.read('1A3A29D5.wav')
corner = np.array([[0, 0], [7, 0], [7, 5], [0, 5]]).T

room = pra.Room.from_corners(corners, fs=sr,
                              max_order=3,
                              materials=pra.Material(0.2, 0.15),
                              ray_tracing=True, air_absorption=True)
room.add_source([1, 1], signal=audio)
'add microphone'
R = pra.circular_2D_array(center=[2.,2.], M=3, phi0=0, radius=0.3)
room.add_microphone_array(pra.MicrophoneArray(R, room.fs))
fig, ax = room1.plot()
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
fig.show()

pyroomacoustics–生成房间脉冲响应-风君雪科技博客

上图中圆点表示设置的声源位置,叉叉表示麦克风的位置。这里设置了三个麦克风。

调用image_source_model()以及simulate()方法

相应的参数设置完之后,接下来就是调用image方法了。

room.image_source_model()
fig, ax = room.plot(img_order=3)
# fig.set_size_inches(18.5, 10.5)
fig.show()

pyroomacoustics–生成房间脉冲响应-风君雪科技博客

通过以下代码查看经过RIR后的语音

room.plot_rir()
fig = plt.gcf()
fig.set_size_inches(20, 10)

pyroomacoustics–生成房间脉冲响应-风君雪科技博客

最后通过simulate()方法可以查看经过RIR后的语音以及保存语音

room.simulate()
sf.write('modi_wav.wav', room.mic_array.signals.T, samplerate=sr)

从听感来看,经过RIR后的语音有了明显的空间感。另外设置声源位置的时候,可以在极坐标系中设置声源角度和声源相对于麦克风阵列的距离,然后通过坐标变换到直角坐标系中。这样的好处就是可以任意设置角度。不对需要注意的是声源相对于麦克风的位置和声源在整个坐标系中的位置不是同一个坐标系,需要标定一下。

生成RIR只是pyroomacoustics中比较简单的一个功能,其它功能待摸索后再整理成博客。

文中有任何错误的地方,请随时联系我。