使用python包(pyroomacoustic)给干净语音加混响。
Pyroomacoustics是一款旨在快速开发和测试音频阵列处理算法的软件包。包的内容可分为三个主要组成部分:
1、直观的Python面向对象接口,可快速构建2D和3D房间中涉及多个声源和麦克风的不同仿真场景;
2、快速c++实现一般多面体房间的镜像声源模型和光线追踪,有效地产生房间脉冲响应和模拟源与接收机之间的传播;
3、STFT、波束成型、测向、自适应滤波、声源分离和单通道去噪的流行算法的参考实现。
本次实验主要是用pyroomacoustic包实现房间脉冲响应(RIR)来给干净的语音信号加混响。
一、一个麦克风的情况:
房间尺寸:7×5×4(长×宽×高,单位:米);
人的位置:(1,1);
麦克风位置:(2,2);
麦克风数量:1个;
人与麦克风的距离:1.414米;
混响时间T60:550ms;
模拟的结果如下图所示:
房间样式
房间俯视图,其中:实心圆点为人的位置,十字符号为麦克风位置
房间脉冲响应时域波形
二、三个麦克风的情况:
房间尺寸:7×5×4(长×宽×高,单位:米);
人的位置:(1,1);
麦克风阵列圆心位置:(2,2);
麦克风数量:3个;
人与麦克风阵列的距离:1.414米;
混响时间T60:550ms;
模拟的结果如下图所示:
房间俯视图,其中:实心圆点为人的位置,三个十字符号代表三个麦克风位置,三个麦克风组成麦克风阵列
三个麦克风的房间脉冲响应时域波形
三、六个麦克风的情况:
房间尺寸:7×5×4(长×宽×高,单位:米);
人的位置:(1,1);
麦克风阵列圆心位置:(2,2);
麦克风数量:6个;
人与麦克风阵列的距离:1.414米;
混响时间T60:550ms;
模拟的结果如下图所示:
房间俯视图,其中:实心圆点为人的位置,六个十字符号代表六个麦克风位置,六个麦克风组成麦克风阵列
六个麦克风的房间脉冲响应时域波形
程序如下图所示:
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from scipy.signal import fftconvolve
import IPython
import pyroomacoustics as pra
import soundfile as sf
#/****************************/
# 创建一个尺寸为(7,5)的矩阵房间
corner = np.array([[0, 0], [7, 0], [7, 5], [0, 5]]).T
#corner = np.array([[0, 0], [3.15, 0], [3.15, 3.15], [0, 3.15]]).T
room = pra.Room.from_corners(corner)
'''
corner: 房间的四个角。`pra.Room.from_corners()`的函数文档中表示四个角的声明顺序必须逆时针。
'''
plt.figure(1)
fig, ax = room.plot()
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
plt.show()
#/***********************************/
plt.figure(2)
corner = np.array([[0, 0], [7, 0], [7, 5], [0, 5]]).T # 房间的长宽为7米,5米
#corner = np.array([[0, 0], [3.15, 0], [3.15, 3.15], [0, 3.15]]).T
room = pra.Room.from_corners(corner)
#room.extrude(3.) # 高为3米的房间
room.extrude(4.) # 高为4米的房间
fig, ax = room.plot()
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
ax.set_zlim([-1, 4])
plt.show()
#/********************************/
audio, sr = sf.read('HPYJY01.wav')
corners = np.array([[0, 0], [7, 0], [7, 5], [0, 5]]).T
#corners = np.array([[0, 0], [3.15, 0], [3.15, 3.15], [0, 3.15]]).T
room1 = pra.Room.from_corners(corners, fs=sr,
max_order=3,
materials=pra.Material(0.2, 0.15),# 0.2,0.15 / 0.45,0.33
ray_tracing=True, air_absorption=True)
room1.add_source([1, 1], signal=audio) # 人的位置
'add microphone'
#添加麦克风M表示麦克风数量
R = pra.circular_2D_array(center=[2.,2.], M=1, phi0=0, radius=0.3)
#R = pra.circular_2D_array(center=[2.,2.], M=1, phi0=0, radius=0.0)
# 人和麦克风距离是[(2-1)^2+(2-1)^2]开根号 = 根号下(2) = 1.414m
room1.add_microphone_array(pra.MicrophoneArray(R, room1.fs))
fig, ax = room1.plot()
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
#/********************************/
room1.image_source_model()
fig, ax = room.plot(img_order=3)
# fig.set_size_inches(18.5, 10.5)
#/***********************************/
room1.plot_rir()
fig = plt.gcf()
fig.set_size_inches(20, 10)
# t60 = pra.experimental.measure_rt60(room1.rir[0][0], fs=room1.fs, plot=True)
# print(f"The RT60 is {t60 * 1000:.0f} ms")
plt.show()
room1.simulate()
sf.write('HPYJY_wav.wav', room1.mic_array.signals.T, samplerate=sr)