Room Simulation¶
Room¶
The three main classes are pyroomacoustics.room.Room
,
pyroomacoustics.soundsource.SoundSource
, and
pyroomacoustics.beamforming.MicrophoneArray
. On a high level, a
simulation scenario is created by first defining a room to which a few sound
sources and a microphone array are attached. The actual audio is attached to
the source as raw audio samples. The image source method (ISM) is then used to
find all image sources up to a maximum specified order and room impulse
responses (RIR) are generated from their positions. The microphone signals are
then created by convolving the audio samples associated to sources with the
appropriate RIR. Since the simulation is done on discrete-time signals, a
sampling frequency is specified for the room and the sources it contains.
Microphones can optionally operate at a different sampling frequency; a rate
conversion is done in this case.
Simulating a Shoebox Room¶
We will first walk through the steps to simulate a shoebox-shaped room in 3D.
Create the room¶
So-called shoebox rooms are pallelepipedic rooms with 4 or 6 walls (in 2D and 3D,
respectiely), all at right angles. They are defined by a single vector that contains
the lengths of the walls. They have the advantage of being simple to define and very
efficient to simulate. A 9m x 7.5m x 3.5m
room is simply defined like this
import pyroomacoustics as pra
room = pra.ShoeBox([9, 7.5, 3.5], fs=16000, absorption=0.35, max_order=17)
The second argument is the sampling frequency at which the RIR will be
generated. Note that the default value of fs
is 8 kHz. The third argument
is the absorption of the walls, namely reflections are multiplied by (1 -
absorption)
for every wall they hit. The fourth argument is the maximum
number of reflections allowed in the ISM.
The relationship between absorption
/max_order
and reverberation time (the T60 or RT60 in the
acoustics literature) is not straightforward. Sabine’s formula can be used to
some extent to set these parameters.
Add sources and microphones¶
Sources are fairly straighforward to create. They take their location as single
mandatory argument, and a signal and start time as optional arguments. Here we
create a source located at [2.5, 3.73, 1.76]
within the room, that will utter
the content of the wav file speech.wav
starting at 1.3 s
into the simulation.
# import a mono wavfile as the source signal
# the sampling frequency should match that of the room
from scipy.io import wavfile
_, audio = wavfile.read('speech.wav')
my_source = pra.SoundSource([2.5, 3.73, 1.76], signal=audio, delay=1.3)
# place the source in the room
room.add_source(my_source)
The locations of the microphones in the array should be provided in a numpy
nd-array
of size (ndim, nmics)
, that is each column contains the
coordinates of one microphone. This array is used to construct a
pyroomacoustics.beamforming.MicrophoneArray
object, together with the
sampling frequency for the microphone. Note that it can be different from that
of the room, in which case resampling will occur. Here, we create an array
with two microphones placed at [6.3, 4.87, 1.2]
and [6.3, 4.93, 1.2]
.
# define the location of the array
import numpy as np
R = np.c_[
[6.3, 4.87, 1.2], # mic 1
[6.3, 4.93, 1.2], # mic 2
]
# the fs of the microphones is the same as the room
mic_array = pra.MicrophoneArray(R, room.fs)
# finally place the array in the room
room.add_microphone_array(mic_array)
A number of routines exist to create regular array geometries in 2D.
Create the Room Impulse Response¶
At this point, the RIRs are simply created by invoking the ISM via
pyroomacoustics.room.Room.image_source_model()
. This function will
generate all the images sources up to the order required and use them to
generate the RIRs, which will be stored in the rir
attribute of room
.
The attribute rir
is a list of lists so that the outer list is on microphones
and the inner list over sources.
room.compute_rir()
# plot the RIR between mic 1 and source 0
import matplotlib.pyplot as plt
plt.plot(room.rir[1][0])
plt.show()
Simulate sound propagation¶
By calling pyroomacoustics.room.Room.simulate()
, a convolution of the
signal of each source (if not None
) will be performed with the
corresponding room impulse response. The output from the convolutions will be summed up
at the microphones. The result is stored in the signals
attribute of room.mic_array
with each row corresponding to one microphone.
room.simulate()
# plot signal at microphone 1
plt.plot(room.mic_array.signals[1,:])
Example
import numpy as np
import matplotlib.pyplot as plt
import pyroomacoustics as pra
# Create a 4 by 6 metres shoe box room
room = pra.ShoeBox([4,6])
# Add a source somewhere in the room
room.add_source([2.5, 4.5])
# Create a linear array beamformer with 4 microphones
# with angle 0 degrees and inter mic distance 10 cm
R = pra.linear_2D_array([2, 1.5], 4, 0, 0.04)
room.add_microphone_array(pra.Beamformer(R, room.fs))
# Now compute the delay and sum weights for the beamformer
room.mic_array.rake_delay_and_sum_weights(room.sources[0][:1])
# plot the room and resulting beamformer
room.plot(freq=[1000, 2000, 4000, 8000], img_order=0)
plt.show()
-
class
pyroomacoustics.room.
Room
(walls, fs=8000, t0=0.0, max_order=1, sigma2_awgn=None, sources=None, mics=None)¶ Bases:
object
A Room object has as attributes a collection of
pyroomacoustics.wall.Wall
objects, apyroomacoustics.beamforming.MicrophoneArray
array, and a list ofpyroomacoustics.soundsource.SoundSource
. The room can be two dimensional (2D), in which case the walls are simply line segments. A factory methodpyroomacoustics.room.Room.from_corners()
can be used to create the room from a polygon. In three dimensions (3D), the walls are two dimensional polygons, namely a collection of points lying on a common plane. Creating rooms in 3D is more tedious and for convenience a methodpyroomacoustics.room.Room.extrude()
is provided to lift a 2D room into 3D space by adding vertical walls and a parallel $B!H(Bceiling$B!I(B (see Figure 4b).The Room is sub-classed by :py:obj:pyroomacoustics.room.ShoeBox` which creates a rectangular (2D) or parallelepipedic (3D) room. Such rooms benefit from an efficient algorithm for the image source method.
Attribute walls: (Wall array) list of walls forming the room Attribute fs: (int) sampling frequency Attribute t0: (float) time offset Attribute max_order: (int) the maximum computed order for images Attribute sigma2_awgn: (float) ambient additive white gaussian noise level Attribute sources: (SoundSource array) list of sound sources Attribute mics: (MicrophoneArray) array of microphones Attribute normals: (numpy.ndarray 2xN or 3xN, N=number of walls) array containing normal vector for each wall, used for calculations Attribute corners: (numpy.ndarray 2xN or 3xN, N=number of walls) array containing a point belonging to each wall, used for calculations Attribute absorption: (numpy.ndarray size N, N=number of walls) array containing the absorption factor for each wall, used for calculations Attribute dim: (int) dimension of the room (2 or 3 meaning 2D or 3D) Attribute wallsId: (int dictionary) stores the mapping “wall name -> wall id (in the array walls)” -
add_microphone_array
(micArray)¶
-
add_source
(position, signal=None, delay=0)¶
-
check_visibility_for_all_images
(source, p, use_libroom=True)¶ Checks visibility from a given point for all images of the given source.
This function tests visibility for all images of the source and returns the results in an array.
Parameters: - source – (SoundSource) the sound source object (containing all its images)
- p – (np.array size 2 or 3) coordinates of the point where we check visibility
Returns: (int array) list of results of visibility for each image -1 : unchecked (only during execution of the function) 0 (False) : not visible 1 (True) : visible
-
compute_rir
()¶ Compute the room impulse response between every source and microphone
-
convex_hull
()¶ Finds the walls that are not in the convex hull
-
direct_snr
(x, source=0)¶ Computes the direct Signal-to-Noise Ratio
-
extrude
(height, v_vec=None, absorption=0.0)¶ Creates a 3D room by extruding a 2D polygon. The polygon is typically the floor of the room and will have z-coordinate zero. The ceiling
Parameters: - height (float) – The extrusion height
- v_vec (array-like 1D length 3, optionnal) – A unit vector. An orientation for the extrusion direction. The ceiling will be placed as a translation of the floor with respect to this vector (The default is [0,0,1]).
- absorption (float or array-like) – Absorption coefficients for all the walls. If a scalar, then all the walls will have the same absorption. If an array is given, it should have as many elements as there will be walls, that is the number of vertices of the polygon plus two. The two last elements are for the floor and the ceiling, respectively. (default 1)
-
first_order_images
(source_position)¶
-
classmethod
from_corners
(corners, absorption=0.0, fs=8000, t0=0.0, max_order=1, sigma2_awgn=None, sources=None, mics=None)¶ Creates a 2D room by giving an array of corners.
Parameters: - corners – (np.array dim 2xN, N>2) list of corners, must be antiClockwise oriented
- absorption – (float array or float) list of absorption factor for each wall or single value for all walls
Returns: (Room) instance of a 2D room
-
get_bbox
()¶ Returns a bounding box for the room
-
get_wall_by_name
(name)¶ Returns the instance of the wall by giving its name.
Parameters: name – (string) name of the wall Returns: (Wall) instance of the wall with this name
-
image_source_model
(use_libroom=True)¶
-
is_inside
(p, include_borders=True)¶ Checks if the given point is inside the room.
Parameters: - p (array_like, length 2 or 3) – point to be tested
- include_borders (bool, optional) – set true if a point on the wall must be considered inside the room
Returns: Return type: True if the given point is inside the room, False otherwise.
-
is_obstructed
(source, p, imageId=0)¶ Checks if there is a wall obstructing the line of sight going from a source to a point.
Parameters: - source – (SoundSource) the sound source (containing all its images)
- p – (np.array size 2 or 3) coordinates of the point where we check obstruction
- imageId – (int) id of the image within the SoundSource object
Returns: (bool) False (0) : not obstructed True (1) : obstructed
-
is_visible
(source, p, imageId=0)¶ Returns true if the given sound source (with image source id) is visible from point p.
Parameters: - source – (SoundSource) the sound source (containing all its images)
- p – (np.array size 2 or 3) coordinates of the point where we check visibility
- imageId – (int) id of the image within the SoundSource object
Returns: (bool) False (0) : not visible True (1) : visible
-
make_c_room
()¶ Wrapper around the C libroom
-
plot
(img_order=None, freq=None, figsize=None, no_axis=False, mic_marker_size=10, **kwargs)¶ Plots the room with its walls, microphones, sources and images
-
plot_rir
(FD=False)¶
-
print_wall_sequences
(source)¶
-
simulate
(recompute_rir=False)¶ Simulates the microphone signal at every microphone in the array
-
-
class
pyroomacoustics.room.
ShoeBox
(p, fs=8000, t0=0.0, absorption=0.0, max_order=1, sigma2_awgn=None, sources=None, mics=None)¶ Bases:
pyroomacoustics.room.Room
This class extends room for shoebox room in 3D space.
-
extrude
(height)¶ Overload the extrude method from 3D rooms
-