[Python / PyRoom Acoustics] Room acoustic simulation with Python

What is PyRoom Acoustics?

It is the strongest Python module of the acoustic system that supports all kinds of acoustic signal processing such as room acoustics, beamforming, sound source direction estimation, and sound source separation.

[Python / PyRoom Acoustics] Blind separation with ILRMA

PyRoom Acoustics makes it easy to simulate room acoustics. The simulation is performed with Image Source, and it seems that you can also experiment with a hybrid simulator using Image Source and Ray Tracing.

  1. Room settings
  2. Microphone placement
  3. Arrangement of sound sources
  4. Run the simulation

You can easily try the room acoustic simulation in 4 steps.

module.py


import pyroomacoustics as pra
import matplotlib.pyplot as plt
from IPython.display import display, Audio

(1) Room design

The room object allows you to set up a 2D or 3D room.

Create a shoebox-shaped room

Use the ShoeBox method to create a typical rectangular parallelepiped room. max_order refers to the upper limit of the number of reflections in the image method.

room.py


#Reverberation time and room dimensions
rt60 = 0.5  # seconds
room_dim = [9, 7.5, 3.5]  #meters If you make this two-dimensional, it will be a room with a quadratic plane.

#Determine the average sound absorption coefficient of the wall surface and the upper limit of the number of reflections by the mirror image method from the reverberation formula of Sabine.
e_absorption, max_order = pra.inverse_sabine(rt60, room_dim)

#Make a room
#fs is the sampling frequency of the generated impulse response. If there is a sound source to input, match it.
room = pra.ShoeBox(
    room_dim, fs=16000, materials=pra.Material(e_absorption), max_order=max_order
)

You can view the room with room.plot ().

plot.py


fig, ax = room.plot()

image.png

Even if you don't know the reverberation time or the sound absorption coefficient of the wall surface, you can select the material from the Material database. You can define a room.

material.py


m = pra.Material(energy_absorption="hard_surface")
room = pra.ShoeBox([9, 7.5, 3.5], fs=16000, materials=m, max_order=17)

You can also set different materials for each wall or ceiling in more detail.

material.py


m = pra.make_materials(
    ceiling="hard_surface",
    floor="6mm_carpet",
    east="brickwork",
    west="brickwork",
    north="brickwork",
    south="brickwork",
)
room = pra.ShoeBox(
    [9, 7.5, 3.5], fs=16000, materials=m, max_order=17
)

Make a room of any shape

You can also use Room.from_corners (corners) to set the room shape from the coordinates.

First, make a plan view. The arguments are the same as ShueBox.

corner.py


#Set the coordinates of the corner
corners = np.array([[0,0], [0,3], [5,3], [5,1], [3,1], [3,0]]).T  # [x,y]
#Make a room
room = pra.Room.from_corners(corners, materials=pra.Material(e_absorption), fs=16000, t0=0.0, max_order=1, sigma2_awgn=None, sources=None, mics=None, materials=None, **kwargs)

image.png

If you can, add height information with ʻextrude` and create a wall.

extrude.py


room.extrude(2.)

image.png

Option 1 Try a hybrid method of mirror image method and ray tracing

Max_order = 3 is recommended for the number of reflections of the mirror image method

raytracing.py


room = pra.ShoeBox(
    room_dim, fs=16000, materials=pra.Material(e_absorption), max_order=3,ray_tracing=True
)

#Activate ray tracing
room.set_ray_tracing()

Option 2 Consider air damping

In a huge space such as a concert hall, the sound is absorbed by the air, making it difficult to transmit from the high frequencies.

air_absorption.py


room = pra.ShoeBox(
    room_dim, fs=16000, materials=pra.Material(e_absorption), max_order=3,air_absorption=True
)

Other options

room.py


pyroomacoustics.room.Room(walls, fs=8000, t0=0.0, max_order=1, sigma2_awgn=None, sources=None, mics=None, temperature=None, humidity=None, air_absorption=False, ray_tracing=False)

You can also add various options such as temperature (Celsius), humidity humidity (relative humidity), and t0 simulation start time.

(2) Microphone settings

We will add a microphone array to the created room room. A microphone array means a sound collection system consisting of multiple microphones.

mic.py


#Give the coordinates of the microphone
mic_locs = np.c_[
    [6.3, 4.87, 1.2], [6.3, 4.93, 1.2],  # mic 1  # mic 2
]

#Add a microphone to the room
room.add_microphone_array(mic_locs)

If you want to arrange the microphones in a circle or in a straight line, there are functions that automatically calculate various microphone arrangements without having to calculate the coordinates. (However, since it only returns the coordinates in 2D, it is necessary to add the coordinates in the height direction and raise it.)

(Example) Circular microphone array

If you enter the location of the center of the microphone array in the room, the number of microphones, the counterclockwise rotation from the x-axis, and the microphone radius as arguments, the (x, y) coordinates of each microphone will be returned. If you want to use it in 3D, add the coordinates in the z-axis direction.

circular_2D_array.py


mic_locs = pra.circular_2D_array(center=[2.,2.], M=6, phi0=0, radius=0.1)

>>>array([[2.1, 2.05, 1.95, 1.9, 1.95,2.05],
       [2., 2.08660254, 2.08660254, 2., 1.91339746,1.91339746]])

Besides the circular arrangement linear_2D_array() circular_2D_array() square_2D_array() poisson_2D_array() spiral_2D_array() Please check from here.

When you want to add only one microphone

mic.py


mic_loc = [1.0,2.0,2.0]
room.add_microphone(mic_loc)

When you want to find out if the coordinates are in the room

To find out if the coordinates where you are trying to put the microphone or sound source are hot in the room, do the following. ʻInclude_borderswhether to include on the wall. If so, it returnsTrue, otherwise it returns False`.

check_inside.py


p = [1.,2.5,12.2]
room.is_inside(p、include_borders = True )

(3) Sound source settings

As with the microphone, give the coordinates and the data of the sound source you want to place in addition to it. The sound source data can be your own signal, or you can input it from your own WAV file.

source.py


#I will read the wav file and place it
from scipy.io import wavfile
_, audio1 = wavfile.read('speech1.wav')
_, audio2 = wavfile.read('speech2.wav')
_, audio3 = wavfile.read('speech3.wav')

#Give coordinate information for each sound source,`room`I will add it to.
#You can optionally add a delay.
room.add_source([2.5, 3.73, 1.76], signal=audio1, delay=1.3)
room.add_source([1.0, 2.34, 2.12], signal=audio2)
room.add_source([3.2, 1.7, 5.2], signal=audio3, delay=2.)

If you add a microphone and a sound source and then room.plot (), it will be reflected in the figure. image.png

(4) Execution of simulation

Once you have the microphone and sound source in place, it's time to run the simulation. That's it for execution.

simulate.py


room.simulate()

If you want to take into account the effect of the SN ratio during execution, do as follows.

simulation.py


# S/N ratio
SNR = 90.
room.simulate(snr=SNR)

(5) Simulation results

Listen to the simulated sound

The sound that reaches each of the placed microphones can be extracted as follows. You can get the sampling frequency with room.fs.

result.py


simulation_data = room.mic_array.signals #Simulation sound source
display(Audio(simulation_data[0,:], rate=room.fs))

Check the impulse response

You can check the impulse response from all sound sources to the microphone. The impulse response is extracted as follows.

rir.py


impulse_responses =room.compute_rir()
display(Audio(impulse_responses[0][0], rate=room.fs))

Calculate the reverberation time in the room

rt60.py


rt60 = room.measure_rt60()
print("Reverberation time:{}".format(rt60))

This function can be calculated not only from the simulated impulse response, but also using your own impulse response.

rt60.py


rt60=pra.experimental.measure_rt60(impulse_responses[0][0],fs=rate)
print("Reverberation time:{}".format(rt60))

Visualize the image method

model.py


# compute image sources
room.image_source_model()

# visualize 3D polyhedron room and image sources
fig, ax = room.plot(img_order=3)

image.png

At the end

Well, is it like this for the time being? There are countless other options, so check them out. Docs » Room Simulation

reference

Official Documentation Official GitHub

Recommended Posts

[Python / PyRoom Acoustics] Room acoustic simulation with Python
Acoustic signal processing with Python (2)
Acoustic signal processing with Python
First neuron simulation with NEURON + Python
Try frequency control simulation with Python
FizzBuzz with Python3
Scraping with Python
Statistics with python
Scraping with Python
Python with Go
Integrate with Python
AES256 with python
Tested with Python
python starts with ()
ambisonics simulation python
with syntax (Python)
Bingo with python
Zundokokiyoshi with python
Excel with Python
Microcomputer with Python
Cast with python
Output 2D thermal diffusion simulation results with Python VTK
COVID-19 simulation with python (SIR model) ~~ with prefectural heat map ~~
Serial communication with Python
Zip, unzip with python
Primality test with Python
Python with eclipse + PyDev.
Socket communication with Python
Data analysis with python 2
Scraping with Python (preparation)
Try scraping with Python.
Sequential search with Python
"Object-oriented" learning with python
Run Python with VBA
Solve AtCoder 167 with python
Serial communication with python
[Python] Use JSON with Python
Learn Python with ChemTHEATER
Run prepDE.py with python3
Collecting tweets with Python
3. 3. AI programming with Python
Kernel Method with Python
Non-blocking with Python + uWSGI
Scraping with Python + PhantomJS
Posting tweets with python
Drive WebDriver with python
Use mecab with Python3
[Python] Redirect with CGIHTTPServer
Voice analysis with python
Think yaml with python
Operate Kinesis with Python
Getting Started with Python
Zundko getter with python
Handle Excel with python
Ohm's Law with Python
Primality test with python
Run Blender with python
Solve Sudoku with Python
Heatmap with Python + matplotlib
Multi-process asynchronously with python
Python programming with Atom