Directional Sources and Microphones

Real-world microphones and sound sources usually exhibit directional responses. That is, the impulse response (or frequency response) depends on the emission or reception angle (for sources and microphones, respectively). A concrete example is the human ear attached to the head. The left ear is typically more sensitive to sounds coming from the left side than from the right.

This sub-module provides an interface to add such directional responses to microphones and sources in the room impulse response simulation.

Warning

Directional responses are only supported for 3D rooms.

The directivities are described by an object of a class derived from Directivity.

Let’s dive right in with an example. Here, we simulate a shoebox room with a cardioid source and a dummy head receiver with two ears (i.e., microphones). This simulates a binaural response.

import pyroomacoustics as pra

room = pra.ShoeBox(
    p=[5, 3, 3],
    materials=pra.Material(energy_absorption),
    fs=16000,
    max_order=40,
)

# add a cardioid source
dir = pra.directivities.Cardioid(
    DirectionVector(azimuth=-65, colatitude=90) , gain=1.0
)
room.add_source([3.75, 2.13, 1.41], directivity=dir)

# add a dummy head receiver from the MIT KEMAR database
hrtf = MeasuredDirectivityFile(
    path="mit_kemar_normal_pinna.sofa",  # SOFA file is in the database
    fs=room.fs,
    interp_order=12,  # interpolation order
    interp_n_points=1000,  # number of points in the interpolation grid
)

# provide the head rotation
orientation = Rotation3D([90.0, 30.0], "yz", degrees=True)

# choose and interpolate the directivities
dir_left = hrtf.get_mic_directivity("left", orientation=orientation)
dir_right = hrtf.get_mic_directivity("right", orientation=orientation)

# for a head-related transfer function, the microphone should be co-located
mic_pos = [1.05, 1.74, 1.81]
room.add_microphone(mic_pos, directivity=dir)
room.add_microphone(mic_pos, directivity=dir)

Analytic Directional Responses

A class of directional responses can be defined analytically. Such respones include in particular the cardioid family of patterns that describes cardioid, super-cardioid, and figure-of-eight microphones, (see cardioid family, under Polar patterns, with cardioid, hypercardioid, cardioid, subcardioid, figure-eight, and omnidirectional). In three dimensions, for an orientation given by unit vector \(\boldsymbol{d}\), a parameter \(p \in [0, 1]\), and a gain \(G\), the response to direction \(\boldsymbol{r}\) (also a unit vector) is given by the following equation.

\[f(\boldsymbol{r}\,;\,\boldsymbol{d}, p, G) = G (p + (1 - p) \boldsymbol{d}^\top \boldsymbol{r}),\]

Note that \(\boldsymbol{d}^\top \boldsymbol{r}\) is the inner product of two unit vectors, that is, the cosine of the angle between them.

Different values of \(p\) correspond to different patterns: 0 for figure-eight, 0.25 for hyper-cardioid, 0.5 for cardioid, 0.75 for sub-cardioid, and 1 for omni.

Specialized objects Cardioid, FigureEight, SubCardioid, HyperCardioid, and Omnidirectional are provided for the different patterns. The class CardioidFamily can be used to make a pattern with arbitrary parameter \(p\).

# a cardioid pointing toward the ``z`` direction
from pyroomacoustics.directivities import CardioidFamily

dir = Cardioid([0, 0, 1], gain=1.0)
class pyroomacoustics.directivities.analytic.Cardioid(orientation, gain=1.0)

Bases: CardioidFamily

Cardioid directivity pattern.

Parameters:
  • orientation (DirectionVector) – Indicates direction of the pattern.

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

class pyroomacoustics.directivities.analytic.CardioidEnergyDistribution(loc=None, p=None, gain=1.0)

Bases: Distribution

This object draws samples from a cardioid shaped distribution on the sphere

Parameters:
  • loc (array_like or None) – The unit vector pointing in the main direction of the cardioid. If None, the location defaults to [1, 0, 0].

  • p (float or None) – Parameter of the cardioid pattern. A value of 0 corresponds to a figure-eight pattern, 0.5 to a cardioid pattern, and 1 to an omni pattern. When None, p is set to 0.5. The parameter must be between 0 and 1

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

pdf(x)
sample(size=None, rng=None)
property total_energy
class pyroomacoustics.directivities.analytic.CardioidFamily(orientation, p, gain=1.0)

Bases: Directivity

Object for directivities coming from the cardioid family. In three dimensions, for an orientation given by unit vector \(\boldsymbol{d}\), a parameter \(p \in [0, 1]\), and a gain \(G\), the pattern is given by the following equation.

\[f(\boldsymbol{r}\,;\,\boldsymbol{d}, p, G) = G (p + (1 - p) \boldsymbol{d}^\top \boldsymbol{r}),\]

Different values of \(p\) correspond to different patterns: 0 for figure-eight, 0.25 for hyper-cardioid, 0.5 for cardioid, 0.75 for sub-cardioid, and 1 for omni.

Note that all the patterns are cylindrically symmetric around the orientation vector.

Parameters:
  • orientation (DirectionVector or numpy.ndarray) – Indicates direction of the pattern.

  • p (float) – Parameter of the cardioid pattern. A value of 0 corresponds to a figure-eight pattern, 0.5 to a cardioid pattern, and 1 to an omni pattern The parameter must be between 0 and 1

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

property directivity_pattern

Name of cardioid directivity pattern.

property filter_len_ir

When is_impulse_response returns True, this property returns the lengths of the impulse responses returned. All impulse responses are assumed to have the same length.

get_azimuth(degrees=True)
get_colatitude(degrees=True)
get_response(azimuth, colatitude=None, magnitude=False, degrees=True)

Get response for provided angles.

Parameters:
  • azimuth (array_like) – Azimuth

  • colatitude (array_like, optional) – Colatitude. Default is to be on XY plane.

  • magnitude (bool, optional) – Whether to return magnitude of response.

  • degrees (bool, optional) – If True, azimuth and colatitude are in degrees. Otherwise, they are in radians.

Returns:

resp – Response at provided angles.

Return type:

ndarray

get_response_cartesian(directions, magnitude=False)

Get response for provided direction cartesian vectors.

Parameters:
  • cartesian (np.ndarray, (n_points, 3)) – The direction of the desired responses

  • magnitude (bool) – Ignored

Returns:

resp – Response at provided directions.

Return type:

ndarray

property is_impulse_response

Indicates whether the array contains coefficients for octave bands (returns False) or is a full-size impulse response (returns True).

plot_response(azimuth, colatitude=None, degrees=True, ax=None, offset=None)

Plot directivity response at specified angles.

Parameters:
  • azimuth (array_like) – Azimuth values for plotting.

  • colatitude (array_like, optional) – Colatitude values for plotting. If not provided, 2D plot.

  • degrees (bool) – Whether provided values are in degrees (True) or radians (False).

  • ax (axes object)

  • offset (list) – 3-D coordinates of the point where the response needs to be plotted.

Returns:

ax

Return type:

Axes

sample_rays(n_rays, rng=None)

This method samples unit vectors from the sphere according to the distribution of the source

Parameters:
  • n_rays (int) – The number of rays to sample

  • rng (numpy.random.Generator or None, optional) – A random number generator object from numpy or None. If None is passed numpy.random.default_rng is used to create a Generator object.

Returns:

  • ray_directions (numpy.ndarray, shape (n_rays, n_dim)) – An array containing the unit vectors in its columns

  • energies (numpy.ndarray, shape (n_rays, n_bands)) – An energy carried per ray so that the expectation over all the rays is the energy of the band, i.e., np.mean(energies) == band energy.

set_orientation(orientation)

Set orientation of directivity pattern.

Parameters:

orientation (DirectionVector) – New direction for the directivity pattern.

class pyroomacoustics.directivities.analytic.FigureEight(orientation, gain=1.0)

Bases: CardioidFamily

Figure-of-eight directivity pattern.

Parameters:
  • orientation (DirectionVector) – Indicates direction of the pattern.

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

class pyroomacoustics.directivities.analytic.HyperCardioid(orientation, gain=1.0)

Bases: CardioidFamily

Hyper-cardioid directivity pattern.

Parameters:
  • orientation (DirectionVector) – Indicates direction of the pattern.

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

class pyroomacoustics.directivities.analytic.Omnidirectional(gain=1.0)

Bases: CardioidFamily

Hyper-cardioid directivity pattern.

Parameters:
  • orientation (DirectionVector) – Indicates direction of the pattern.

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

class pyroomacoustics.directivities.analytic.SubCardioid(orientation, gain=1.0)

Bases: CardioidFamily

Sub-cardioid directivity pattern.

Parameters:
  • orientation (DirectionVector) – Indicates direction of the pattern.

  • gain (float) – The linear gain of the directivity pattern (default is 1.0)

pyroomacoustics.directivities.analytic.cardioid_energy(p, gain=1.0)

This function gives the exact value of the surface integral of the cardioid (family) function on the unit sphere

\[E(p, G) = \iint_{\mathbb{S}^2} G^2 \left( p + (1 - p) \boldsymbol{d}^\top \boldsymbol{r} \right)^2 d\boldsymbol{r} = \frac{4 \pi}{3} G^2 \left( 4 p^2 - 2 p + 1 \right).\]

This can be used to normalize the energy sent/received.

Parameters:
  • p (float) – The parameter of the cardioid function (between 0 and 1)

  • gain (float) – The gain of the cardioid function

pyroomacoustics.directivities.analytic.cardioid_func(x, direction, p, gain=1.0, normalize=True, magnitude=False)

One-shot function for computing cardioid response.

Parameters:
  • x (array_like, shape (n_dim, ...)) – Cartesian coordinates

  • direction (array_like, shape (n_dim)) – Direction vector, should be normalized

  • p (float) – Parameter for the cardioid function (between 0 and 1)

  • gain (float) – The gain

  • normalize (bool) – Whether to normalize coordinates and direction vector

  • magnitude (bool) – Whether to return magnitude, default is False

Returns:

resp – Response at provided angles for the speficied cardioid function.

Return type:

ndarray

Real Spherical Harmonics Directivities

This class can be used to set a Real Spherical Harmonics directivities.

Real Spherical Harmonics are used in the Ambisonic file format, which can be used to represent and restore a sound field at a given point.

Here is a simple example of capturing room impulse response using real spherical harmonics directivities:

# Simple example recording the different Harmonics as different microphones.
order = 2
azimuth = np.deg2rad(50)

room = pra.AnechoicRoom(fs=16000)
room.add_source([np.cos(azimuth), np.sin(azimuth), 1.0])

for m, n in zip(*get_mn_in_acn_order(order)):
    room.add_microphone(
        [0.0, 0.0, 1.0],
        directivity=pra.directivities.RealSphericalHarmonicsDirectivity(
            m, n),
    )

room.compute_rir()
class pyroomacoustics.directivities.harmonics.RealSphericalHarmonicsDirectivity(m, n, condon_shortley_phase: bool = False)

Bases: Directivity

A class for real spherical harmonic directivity patterns.

Parameters:
  • m (int) – Order of the spherical harmonic.

  • n (int) – Degree of the spherical harmonic.

  • condon_shortley_phase (bool, optional) – If True, includes the Condon-Shortley phase factor (-1)^m. Default is False.

property filter_len_ir

When is_impulse_response returns True, this property returns the lengths of the impulse responses returned. All impulse responses are assumed to have the same length.

get_response(azimuth, colatitude=None, magnitude=False, frequency=None, degrees=True)

Get response for provided (azimuth, colatitude) pairs.

Parameters:
  • azimuth (array_like, shape (n_directions,)) – Azimuth angles to compute the response at.

  • colatitude (array_like, optional, shape (n_directions,)) – Corresponding colatitude angles. If None, the default is colatitude = np.pi / 2.0, i.e., all directions are on the xy-plane.

  • magnitude (bool, optional) – Whether to return magnitude of response.

  • degrees (bool, optional) – If True (default), azimuth and colatitude are interpreted as in degrees. Otherwise, they are in radians.

Returns:

resp – Response at requested directions. See the class docstring for the shape.

Return type:

ndarray

get_response_cartesian(directions, magnitude=False, frequency=None)

Get response for provided direction cartesian vectors.

Parameters:
  • directions (np.ndarray, (n_points, 3)) – The directions of the desired responses expressed as Cartesian unit vectors stacked in the rows of a matrix.

  • magnitude (bool) – Ignored

Returns:

resp – Response at provided directions. See the class docstring for the shape.

Return type:

ndarray

property is_impulse_response

Indicates whether the array contains coefficients for octave bands (returns False) or is a full-size impulse response (returns True).

sample_rays(n_rays, rng=None)

Not yet implemented.

pyroomacoustics.directivities.harmonics.get_mn_in_acn_order(degree)

Calculates the order-degree (m,n) pairs in the Ambisonic Channel Number (ACN) format up to a given degree.

Parameters:

degree (int) – Maximum degree of the spherical harmonics.

Returns:

  • all_m (ndarray) – Array of orders m in ACN order.

  • all_n (ndarray) – Array of degrees n in ACN order.

pyroomacoustics.directivities.harmonics.real_sph_harm(n, m, theta, phi, condon_shortley_phase=False)

Calculates the real spherical harmonics.

Parameters:
  • n (int) – Degree of the spherical harmonic.

  • m (int) – Order of the spherical harmonic.

  • theta (array_like) – Polar (colatitudinal) coordinate in radians.

  • phi (array_like) – Azimuthal coordinate in radians.

  • condon_shortley_phase (bool, optional) – If True, includes the Condon-Shortley phase factor (-1)^m. Default is False.

Returns:

y_real – Real spherical harmonics evaluated at the given angles.

Return type:

ndarray

Measured Directivities

Source and microphone directivities can be measured in an anechoic chamber. Such measurements result in a collection of impulse responses or transfer functions each associated with a specific source and receiver (i.e., microphone) location. The SOFA file format has been proposed as a standard for the storage of such measurements.

This sub-module offers a way to read such measurements from (SOFA) files and use the measurement to obtain a more faithful simulation.

The workhorse of this module is the class MeasuredDirectivityFile which reads the content of a file and standardize the data for futher use. A single SOFA file can contain multiple measurements (for example corresponding to different devices). The class provies a method to retrieve measurements from individual sources and turn them into a py:class:MeasuredDirectivity object that can be used to create a py:class:pyroomacoustics.MicrophoneArray object with this directivity.

Such measurements do not provide impulse responses for every possible impinging direction. Instead, during simulation the impulse response closest to the desired direction is used instead. To avoid sharp transitions, the py:class:MeasuredDirectivityFile provides an interpolation method in the spherical harmonics domain. This can be activated by providing an order for the interpolation, e.g, interp_order=12.

Here is an example of loading a head-related transfer function and load the directivities for left and right ears of a dummy head HRTF.

from pyroomacoustics.directivities import MeasuredDirectivityFile, Rotation3D

# the file reader object reads the file and optionally performs interpolation
# if the file contains multiple directivities, they are all read
hrtf = MeasuredDirectivityFile(
    path="mit_kemar_normal_pinna.sofa",  # SOFA file is in the database
    fs=fs,
    interp_order=12,
    interp_n_points=1000,
)

# orientations can be provided as rotation matrices
orientation = Rotation3D([colatitude_deg, azimuth_deg], "yz", degrees=True)

# we can then choose which directivities we want from the file
dir_left = hrtf.get_mic_directivity("left", orientation=orientation)
dir_right = hrtf.get_mic_directivity("right", orientation=orientation)
class pyroomacoustics.directivities.measured.MeasuredDirectivity(orientation, grid, impulse_responses, fs)

Bases: Directivity

A class to store directivity patterns obtained by measurements.

Parameters:
  • orientation (Rotation3D) – A rotation to apply to the pattern

  • grid (doa.Grid) – The grid of unit vectors where the measurements were taken

  • impulse_responses (np.ndarray, (n_grid, n_ir)) – The impulse responses corresponding to the grid points

  • fs (int) – The sampling frequency of the impulse responses

property filter_len_ir

Length of the impulse response in samples

get_direction_vectors()

Get the direction vectors of the measurements.

Return type:

A (n_directions, 3) numpy ndarray of unit vectors.

get_response(azimuth, colatitude=None, magnitude=False, degrees=True)

Get response for provided angles.

Parameters:
  • azimuth (np.ndarray, (n_points,)) – The azimuth of the desired responses

  • colatitude (np.ndarray, (n_points,)) – The colatitude of the desired responses

  • magnitude (bool) – Ignored

  • degrees (bool) – If True, indicates that azimuth and colatitude are provided in degrees

get_response_cartesian(directions, magnitude=False)

Get response for provided direction cartesian vectors.

Parameters:
  • cartesian (np.ndarray, (n_points, 3)) – The direction of the desired responses

  • magnitude (bool) – Ignored

Returns:

resp – Response at provided directions.

Return type:

ndarray

property is_impulse_response

Indicates whether the array contains coefficients for octave bands (returns False) or is a full-size impulse response (returns True).

plot(freq_bin=0, n_grid=100, ax=None, depth=False, offset=None)

Plot the directivity pattern at a given frequency.

Parameters:
  • freq_bin (int) – The frequency bin to plot

  • n_grid (int) – The number of points to use for the interpolation grid

  • ax (matplotlib.axes.Axes, optional) – The axes to plot on. If not provided, a new figure is created

  • depth (bool) – If True, directive response is both depicted by color and depth of the surface. If False, then only the color map denotes the intensity. (default False)

  • offset (float) – An offset to apply to the directivity pattern

Returns:

ax – The axes on which the directivity is plotted

Return type:

matplotlib.axes.Axes

sample_rays(n_rays, rng=None)

This method samples unit vectors from the sphere according to the distribution of the source

Parameters:
  • n_rays (int) – The number of rays to sample

  • rng (numpy.random.Generator or None, optional) – A random number generator object from numpy or None. If None is passed numpy.random.default_rng is used to create a Generator object.

Returns:

  • ray_directions (numpy.ndarray, shape (n_rays, n_dim)) – An array containing the unit vectors in its columns

  • energies (numpy.ndarray, shape (n_rays, n_bands)) – An energy carried per ray so that the expectation over all the rays is the energy of the band, i.e., np.mean(energies) == band energy.

set_orientation(orientation)

Set orientation of directivity pattern.

Parameters:

orientation (Rotation3D) – New direction for the directivity pattern.

class pyroomacoustics.directivities.measured.MeasuredDirectivityEnergyDistribution(kdtree, energy, areas=None)

Bases: Distribution

This object draws samples from the distribution defined by the energy of the measured directional response object.

Parameters:
  • kdtree (array_like) – A kd-tree for the measurement points in cartesian coordinates.

  • energy (array_like) – The energy measured at each measurement point.

  • areas (array_like) – The areas of the spherical voronoi of the kd-tree. If not provided, they are computed.

pdf(x)
sample(size=None, rng=None)
class pyroomacoustics.directivities.measured.MeasuredDirectivityFile(path, fs=None, interp_order=None, interp_n_points=1000, file_reader_callback=None, mic_labels=None, source_labels=None)

Bases: object

This class reads measured directivities from a SOFA format file. Optionally, it can perform interpolation of the impulse responses onto a finer grid. The interpolation is done in the spherical harmonics domain.

Parameters:
  • path ((string)) – Path towards the specific DIRPAT file

  • fs ((int)) – The desired sampling frequency. If the impulse responses were stored at a different sampling frequency, they are resampled at fs.

  • interp_order ((int)) – The order of spherical harmonics to use for interpolation. If None interpolation is not used.

  • interp_n_points ((int)) – Number of points for the interpolation grid. The interpolation grid is a Fibonnaci pseudo-uniform sampling of the sphere.

  • file_reader_callback ((callable)) – A callback function that reads the SOFA file and returns the impulse responses The signature should be the same as the function open_sofa_file

  • mic_labels ((list of strings)) – List of labels for the microphones. If not provided, the labels are simply the indices of the microphones in the array

  • source_labels ((list of strings)) – List of labels for the sources. If not provided, the labels are simply the indices of the measurements in the array

get_mic_directivity(measurement_id, orientation)

Get a directivity for a microphone

Parameters:
  • measurement_id (int or str) – The id of the microphone

  • orientation (Rotation3D) – The orientation of the directivity pattern

get_mic_position(measurement_id)

Get the position of source with id measurement_id

Parameters:

measurement_id (int or str) – The id of the source

get_source_directivity(measurement_id, orientation)

Get a directivity for a source

Parameters:
  • measurement_id (int or str) – The id of the source

  • orientation (Rotation3D) – The orientation of the directivity pattern

get_source_position(measurement_id)

Get the position of source with id measurement_id

Parameters:

measurement_id (int or str) – The id of the source

Built-in SOFA Files Database

Pyroomacoustics contains a small database of SOFA files that have been tested and can be used for simultions. The database can be loaded using the function SOFADatabase.

# load and display the list of available SOFA files and their content
from pyroomacoustics.datasets import SOFADatabase

db = SOFADatabase()
db.list()

The database contains the following files.

  • Three files from the DIRPAT database collected by Manuel Brandner, Matthias Frank, and Daniel Rudrich University of Music and Performing Arts, Graz.

    • AKG_c480_c414_CUBE.sofa containing the directive responses of a microphone with 4 different patterns.

    • EM32_Directivity.sofa that contains the directional response of the Eigenmike em32 microphone array.

    • LSPs_HATS_GuitarCabinets_Akustikmessplatz.sofa that contains 12 source directivities. This file is dynamically downloaded upon its first use.

    • The files are public domain (CC0), but if you use them in your research, please cite the following paper.

      M. Brandner, M. Frank, and D. Rudrich, "DirPat—Database and
      Viewer of 2D/3D Directivity Patterns of Sound Sources and Receivers,"
      in Audio Engineering Society Convention 144, Paper 425, 2018.
      
  • Two head-related transfer functions of the MIT KEMAR dummy head with normal and large pinna. The data was collected by Bill Gardner and Keith Martin from MIT and is free to use provided the authors are cited. See the full license for more details.

class pyroomacoustics.datasets.sofa.SOFADatabase(download=True)

A small database of SOFA files containing source/microphone directional impulse responses

The database object is a dictionary-like object where the keys are the names of the SOFA files and the values are objects with the following attributes:

db = SOFADatabase()

# type of device: 'sources' or 'microphones'
db["Soundfield_ST450_CUBE"].type

# list of the labels of the sources/microphones
db["Soundfield_ST450_CUBE"].contains
Parameters:

download (bool, optional) – If set to True, the SOFA files are downloaded if they are not already present in the default folder

property db_info_path

The path to the JSON file containing the SOFA files information

list()

Print a list of the available SOFA files and the labels of the different devices they contain

property root

The path to the folder containing the SOFA files

pyroomacoustics.datasets.sofa.get_sofa_db()

A helper function to quickly load the SOFA database

Reading Other or Custom File Types

It is possible to read other file types by providing a custom reader function to MeasuredDirectivityFile with the argument file_reader_callback. The function should have the same signature as open_sofa_file().

SOFA File Readers

SOFA is a very flexible file format for storing direction impulse responses. This module provides a function to read SOFA files and extract the impulse responses in a format that can be used for simulation.

pyroomacoustics.directivities.sofa.open_sofa_file(path, fs=16000)

Open a SOFA file and read the impulse responses

Parameters:
  • path (str or Path) – Path to the SOFA file

  • fs (int, optional) – The desired sampling frequency. If the impulse responses were stored at a different sampling frequency, they are resampled at fs.

Returns:

  • ir (np.ndarray (n_sources, n_mics, taps)) – The impulse responses

  • fs (int) – The sampling frequency of the impulse responses

  • source_dir (np.ndarray (3, n_sources)) – The direction of the sources in spherical coordinates

  • rec_loc (np.ndarray (3, n_mics)) – The location of the receivers in cartesian coordinates

  • source_labels (List[str]) – If available, a list of human readable labels for the sources is returned. Otherwise, None is returned

  • mic_labels (List[str]) – If available, a list of human readable labels for the microphones is returned. Otherwise, None is returned

Specifying Object Directions

Using directivities makes sources and microphones having a different response depending on the location of other objects. This means that their orientation in 3D space matters.

Some types of directivities such as CardioidFamily and derived classes are defined only by a vector (i.e., direction). The response is then symmetric around the axis defined by this vector.

However, in general, not all directivities are symmetric in this way. For the general case, the orientation can be defined by Euler angles. This is implemented in the class pyroomacoustics.direction.Rotation3D.

class pyroomacoustics.directivities.direction.DirectionVector(azimuth, colatitude=None, degrees=True)

Bases: object

Object for representing direction vectors in 3D, parameterized by an azimuth and colatitude angle.

Parameters:
  • azimuth (float)

  • colatitude (float, optional) – Default to PI / 2, only XY plane.

  • degrees (bool) – Whether provided values are in degrees (True) or radians (False).

property unit_vector

Direction vector in cartesian coordinates.

class pyroomacoustics.directivities.direction.Rotation3D(angles, rot_order='zyx', degrees=True)

Bases: object

An object representing 3D rotations by their Euler angles.

A rotation in 3D space can be fully described by 3 angles (i.e., the Euler angles). Each rotation is applied around one of the three axes and there are 12 possible ways of pickinig the order or the rotations.

This class can apply full or partial rotations to sets of points.

The angles are provided as an array angles. The axes of rotation for the angles are provided in rot_order as a string of three characters out of ["x", "y", "z"] or a list of three integers out of [0, 1, 2]. Each axis can be repeated. To obtain full rotations, the same axis should not be used twice in a row.

By default, the angles are specified in degrees. This can be changed by setting degrees=False. In that case, the angles are assumed to be in radians.

Parameters:
  • angles (array_like) – An array containing between 0 and 3 angles.

  • rot_order (str of List[int]) – The order of the rotations. The default is “zyx”. The order indicates around which axis the rotation is performed. For example, “zyx” means that the rotation is first around the z-axis, then the y-axis, and finally the x-axis.

  • degrees (bool) – Whether the angles are in degrees (True) or radians (False).

rotate(points)

Rotate a set of points.

Parameters:

points (array_like (3, ...)) – The points to rotate. The first dimension must be 3.

Returns:

rotated_points – The rotated points.

Return type:

np.ndarray

rotate_transpose(points)

Transposed rotations of a set of points.

Parameters:

points (array_like (3, ...)) – The points to rotate. The last dimension must be 3.

Returns:

rotated_points – The rotated points.

Return type:

np.ndarray

Creating New Types of Directivities

The Directivity class is an abstract class that can be subclassed to create new types of directivities. The class provides a common interface to access the directivity patterns.

The class should implement the following methods:

  • get_response_cartesian to get the response for a given direction..

  • get_response to get the response for a given (colatitude, azimuth) pair.

  • sample_rays returns rays and corresponding energy for the directivity.

  • is_impulse_response to indicate whether the directivity is an impulse response or just band coefficients.

  • filter_len_ir to return the length of the impulse response. This should return 1 if the directivity is not an impulse response.

class pyroomacoustics.directivities.base.Directivity

Bases: ABC

Abstract class for directivity patterns.

Directivity can be of three different types in the way it treats frequency. Depending on this type, the shape returned by get_response and get_response_cartesian differ.

  1. Frequency flat: the response is the same at all frequencies. In this case, is_impulse_response == False and the returned shape is (n_directions,).

  2. Octave bands: the response is provided per octave bands. Then is_impulse_response == False and shape == (n_directions, n_bands).

  3. Impulse response: there is a rich frequency response provided as an impulse response. Then, is_impulse_response == True and shape == (n_directions, n_taps).

For ray tracing, the ray energies are tracked only in octave bands. I.e., sample_rays returns an energy array with shape == (n_rays, n_bands).

abstract property filter_len_ir

When is_impulse_response returns True, this property returns the lengths of the impulse responses returned. All impulse responses are assumed to have the same length.

get_response(azimuth, colatitude=None, magnitude=False, degrees=True)

Get response for provided (azimuth, colatitude) pairs.

Parameters:
  • azimuth (array_like, shape (n_directions,)) – Azimuth angles to compute the response at.

  • colatitude (array_like, optional, shape (n_directions,)) – Corresponding colatitude angles. If None, the default is colatitude = np.pi / 2.0, i.e., all directions are on the xy-plane.

  • magnitude (bool, optional) – Whether to return magnitude of response.

  • degrees (bool, optional) – If True (default), azimuth and colatitude are interpreted as in degrees. Otherwise, they are in radians.

Returns:

resp – Response at requested directions. See the class docstring for the shape.

Return type:

ndarray

get_response_cartesian(directions, magnitude=False)

Get response for provided direction cartesian vectors.

Parameters:
  • directions (np.ndarray, (n_points, 3)) – The directions of the desired responses expressed as Cartesian unit vectors stacked in the rows of a matrix.

  • magnitude (bool) – Ignored

Returns:

resp – Response at provided directions. See the class docstring for the shape.

Return type:

ndarray

abstract property is_impulse_response

Indicates whether the array contains coefficients for octave bands (returns False) or is a full-size impulse response (returns True).

abstractmethod sample_rays(n_rays, rng=None)

This method samples unit vectors from the sphere according to the distribution of the source

Parameters:
  • n_rays (int) – The number of rays to sample

  • rng (numpy.random.Generator or None, optional) – A random number generator object from numpy or None. If None is passed numpy.random.default_rng is used to create a Generator object.

Returns:

  • ray_directions (numpy.ndarray, shape (n_rays, n_dim)) – An array containing the unit vectors in its columns

  • energies (numpy.ndarray, shape (n_rays, n_bands)) – An energy carried per ray so that the expectation over all the rays is the energy of the band, i.e., np.mean(energies) == band energy.

Spherical Interpolation

This module provides functions to interpolate impulse responses on a sphere. The interpolation is done in the spherical harmonics domain.

pyroomacoustics.directivities.interp.spherical_interpolation(grid, impulse_responses, new_grid, spherical_harmonics_order=12, axis=-2, nfft=None)
Parameters:
  • grid (pyroomacoustics.doa.GridSphere) – The grid of the measurements

  • impulse_responses (numpy.ndarray, (..., n_measurements, ..., n_samples)) – The impulse responses to interpolate, the last axis is time and one other axis should have dimension matching the length of the grid. By default, it is assumed to be second from the end, but can be specified with the axis argument.

  • new_grid (pyroomacoustics.doa.GridSphere) – Grid of points at which to interpolate

  • spherical_harmonics_order (int) – The order of spherical harmonics to use for interpolation

  • axis (int) – The axis of the grid in the impulse responses array

  • nfft (int) – The length of the FFT to use for the interpolation (default n_samples)

Numerical Spherical Integral

Provides a function to numerically integrate a function over the 3D unit-sphere (\(\mathbb{S}^2\)).

\[\iint_{\mathbb{S}^2} f(\mathbf{x})\, d\mathbf{x}\]
pyroomacoustics.directivities.integration.spherical_integral(func, n_points)

Numerically integrate a function over the sphere.

Parameters:
  • func (callable) – The function to integrate. It should take an array of shape (3, n_points) and return an array of shape (n_points,)

  • n_points (int) – The number of points to use for integration

Returns:

value – The value of the integral

Return type:

np.ndarray