Room acoustics (dsptoolbox.room_acoustics)¶
Room Acoustics¶
Here are contained some functions that are related to room acoustics.
reverb_time()
find_modes()
convolve_rir_on_signal()
find_ir_start()
generate_synthetic_rir()
descriptors()
ShoeboxRoom: class for shoebox rooms. It can be passed to generate_synthetic_rir.
- class dsptoolbox.room_acoustics.ReverbTime(*values)¶
Bases:
EnumTypes of computation of the reverberation time:
Adaptive: adapts the computation to the best linear fit of energy decay.
EDT: Early decay time.
- Adaptive = 1¶
- EDT = 5¶
- T20 = 2¶
- T30 = 3¶
- T60 = 4¶
- class dsptoolbox.room_acoustics.RoomAcousticsDescriptor(*values)¶
Bases:
EnumDescriptors:
D50: Definition. It takes values between [0, 1] and should correlate (positively) with speech inteligibility.
C80: Clarity. It is a value in dB. The higher, the more energy arrives in the early part of the RIR compared to the later part.
BassRatio: It exposes the ratio of reverberation times of the lower-frequency octave bands (125, 250) to the higher ones (500, 1000). T20 is always used.
CenterTime: It is the first-order moment RIR’s energy.
- BassRatio = 3¶
- C80 = 2¶
- CenterTime = 4¶
- D50 = 1¶
- class dsptoolbox.room_acoustics.ShoeboxRoom(dimensions_m, t60_s: float | None = None, absorption_coefficient: float | None = None)¶
Bases:
RoomClass for a shoebox room.
- Attributes:
- area
- volume
Methods
add_detailed_absorption(detailed_absorption)This method allows for the room to take in a more complex description of the absorption in each wall.
check_if_in_room(coordinates_m)Checks if a given point is inside the room.
get_analytical_transfer_function(source_pos, ...)Compute and return the analytical transfer function for the room.
get_mixing_time([mode, n_reflections, c])Computes and returns mixing time defined as the time where early reflections end and late reflections start.
get_room_modes([max_order, c])Computes and returns room modes for a shoebox room assuming hard reflecting walls.
modal_density(f_hz[, c])Compute and return the modal density for a given cut-off frequency and speed of sound.
- add_detailed_absorption(detailed_absorption: dict)¶
This method allows for the room to take in a more complex description of the absorption in each wall. This updates the attributes t60_s and absorption_coefficient.
The dictionary detailed_absorption must have keys ‘north’, ‘south’, ‘east’, ‘west’, ‘floor’, ‘ceiling’. These represent the six walls of the room (south, west and floor start at origin). For each key, absorption coefficients for up to 8 octave bands (with center frequencies 125, 250, 500, 1000, 2000, 4000, 8000, 16000) must be passed as an array. The total number of bands is derived from the longest coefficients array passed. Alternatively, only one absorption coefficient can be passed and it is then regarded as a frequency-independent absorption for that particular wall. If one wall has more than one value but less than another band, its last value is used for the rest of the frequency bands.
The method get_analytical_transfer_function uses the updated coefficients and generate_synthetic_rir can also use them.
- Parameters:
- detailed_absorptiondict
Dictionary containing the absorption coefficients for 8 octave bands of each wall of the room. A valid dictionary would be:
detailed_absorption = { 'north': [0.5, 0.2, 0.3, 0.4], 'south': 0.47, 'east': [0.3, 0.1], # This wall would be completed as # [0.3, 0.1, 0.1, 0.1] 'west': ... ,}
and so forth for the remaining bands.
Notes
All computed parameters get saved in the detailed_absorption dictionary of the ShoeboxRoom. This dictionary also has a ‘README’ key with an information string about all other keys.
- check_if_in_room(coordinates_m) bool¶
Checks if a given point is inside the room.
- Parameters:
- coordinates_marray-like
Coordinates of point in meters. It is assumed that the order is x, y, z.
- Returns:
- bool
True if point is in the room, False otherwise.
- get_analytical_transfer_function(source_pos, receiver_pos, freqs, max_mode_order: int = 10, generate_plot: bool = True, c: float = 343)¶
Compute and return the analytical transfer function for the room.
- Parameters:
- source_posarray-like
Source position in meters. It must be inside the room, otherwise an assertion error is raised.
- receiver_posarray-like
Receiver position in meters. It must be inside the room, otherwise an assertion error is raised.
- freqsNDArray[np.float64]
Frequency vector for which to compute the transfer function.
- max_mode_orderint, optional
Maximum mode order to be regarded. It should be high enough to represent the frequency response at the relevant frequencies. Default: 10.
- generate_plotbool, optional
Generates and returns a plot showing the transfer function (normalized by peak value). Default: True.
- cfloat, optional
Speed of sound in meters/seconds. Default: 343.
- Returns:
- pNDArray[np.float64]
Complex transfer function, non-normalized.
- modesNDArray[np.float64]
Modes for which the transfer function was computed. It has shape (mode, frequency and order xyz) and it is sorted by frequency.
- plottuple
When generate_plot=True, this is a tuple containing two entries: (matplotlib.figure.Figure, matplotlib.axes.Axes). When False, None is returned as the content of the tuple
- get_mixing_time(mode: str = 'perceptual', n_reflections: int = 400, c: float = 343) float¶
Computes and returns mixing time defined as the time where early reflections end and late reflections start. For this, two options are implemented: either a perceptual estimation presented in [1] (eq. 13) or a physical model that takes into account the reflections density after which the late reverberant tail of the IR starts (corresponds to eq.1 in [1]).
The result will be saved in the mixing_time_s object’s property.
- Parameters:
- modestr, optional
Choose from ‘perceptual’ or ‘physical’. Default: ‘perceptual’.
- n_reflectionsint, optional
Necessary only when mode=’physical’. This is the reflections density that is reached when the late reverberation starts. Default: 400.
- cfloat, optional
Necessary only when mode=’physical’. Speed of sound. Default: 343.
- Returns:
- mixing_time_sfloat
Mixing time in seconds.
References
[1]: Lindau A.; Kosanke, L.; Weinzierl S. (2012): “Perceptual evaluation of model- and signalbased predictors of the mixing time in binaural room impulse responses”, In: J. Audio Eng. Soc. 60 (11), pp. 887-898.
- get_room_modes(max_order: int = 6, c: float = 343.0) ndarray[tuple[Any, ...], dtype[float64]]¶
Computes and returns room modes for a shoebox room assuming hard reflecting walls.
The result is returned and saved in the modes_hz property of this ShoeboxRoom.
- Parameters:
- max_orderint, optional
Maximum mode order to compute. Default: 6.
- cfloat, optional
Speed of sound in meters/seconds. Default: 343.
- Returns:
- modesNDArray[np.float64]
Array containing the frequencies of the room modes as well as their characteristics (orders in each room dimension. This is necessary to know if it is an axial, a tangential or oblique mode). Its shape is (mode frequency, order x, order y, order z).
- dsptoolbox.room_acoustics.convolve_rir_on_signal(signal: Signal, rir: Signal, keep_peak_level: bool = True, keep_length: bool = True) Signal¶
Applies an RIR to a given signal. The RIR should also be a signal object with a single channel containing the RIR time data. Signal type should also be set to IR or RIR. By default, all channels are convolved with the RIR.
- Parameters:
- signalSignal
Signal to which the RIR is applied. All channels are affected.
- rirSignal
Single-channel impulse response containing the RIR.
- keep_peak_levelbool, optional
When True, output signal is normalized to the peak level of the original signal. Default: True.
- keep_lengthbool, optional
When True, the original length is kept after convolution, otherwise the output signal is longer than the input one. Default: True.
- Returns:
- new_sigSignal
Convolved signal with RIR.
- dsptoolbox.room_acoustics.descriptors(rir: ImpulseResponse | MultiBandSignal, descriptor: RoomAcousticsDescriptor, automatic_trimming_rir: bool = True)¶
Returns a desired room acoustics descriptor from an RIR.
- Parameters:
- rirImpulseResponse or MultiBandSignal
Room impulse response. If it is a multi-channel signal, the descriptor given back has the shape (channel). If it is a MultiBandSignal, the descriptor has shape (band, channel).
- descriptorRoomAcousticsDescriptor
This defines the descriptor to be computed.
- automatic_trimming_rirbool, optional
When True, the RIR is automatically trimmed after a certain energy threshold relative to the peak value has been surpassed. See notes for details on the algorithm. This parameter is ignored when computing the bass ratio. Default: True.
- Returns:
- output_descriptorNDArray[np.float64]
Array containing the output descriptor. If RIR is a Signal, it has shape (channel). If RIR is a MultiBandSignal, the array has shape (band, channel).
Notes
For defining the ending of the IR automatically, trim_rir is used. Refer to the documentation for more details.
- dsptoolbox.room_acoustics.find_ir_start(signal: ImpulseResponse, threshold_dbfs: float = -20) ndarray[tuple[Any, ...], dtype[int64]]¶
This function finds the start of an IR defined as the first sample before a certain threshold is surpassed. For room impulse responses, -20 dB relative to peak level is recommended according to [1].
- Parameters:
- signalImpulseResponse
IR.
- threshold_dbfsfloat, optional
Threshold that should be passed (in dBFS). Default: -20.
- Returns:
- start_indexNDArray[np.int_]
Index of IR start for each channel.
References
[1]: ISO 3382-1:2009-10, Acoustics - Measurement of the reverberation time of rooms with reference to other acoustical parameters. pp. 22.
- dsptoolbox.room_acoustics.find_modes(signal: ImpulseResponse, f_range_hz=[50, 200], dist_hz: float = 5, prominence_db: float | None = None, antiresonances: bool = False) ndarray[tuple[Any, ...], dtype[float64]]¶
Finds the room modes of a set of RIR using the peaks of the complex mode indicator function (CMIF).
- Parameters:
- signalImpulseResponse
Signal containing the RIR’S from which to find the modes.
- f_range_hzarray-like, optional
Vector setting range for mode search. Default: [50, 200].
- dist_hzfloat, optional
Minimum distance (in Hz) between modes. Default: 5.
- prominence_dbfloat, optional
Prominence of the peaks in dB of the CMIF in order to be classified as modes. Pass None to avoid checking prominence. Default: None.
- antiresonancesbool, optional
When True, the spectra are inverted so that antiresonances are found instead of resonances. Default: False.
- Returns:
- f_modesNDArray[np.float64]
Vector containing frequencies where modes have been localized.
Notes
This function finds the resonant modes but not the antiresonants.
References
- dsptoolbox.room_acoustics.generate_synthetic_rir(room: ShoeboxRoom, source_position, receiver_position, sampling_rate_hz: int, total_length_seconds: float = 0.5, add_noise_reverberant_tail: bool = False, apply_bandpass: bool = False, use_detailed_absorption: bool = False, max_order: int | None = None) ImpulseResponse¶
This function returns a synthetized RIR in a shoebox-room using the image source model. The implementation is based on Brinkmann, et al. See References for limitations and advantages of this method.
- Parameters:
- roomShoeboxRoom
Room object with the information about the room properties.
- source_positionarray-like
Vector with length 3 corresponding to the source’s position (x, y, z) in meters.
- receiver_positionarray-like
Vector with length 3 corresponding to the receiver’s position (x, y, z) in meters.
- sampling_rate_hzint
Sampling rate of the generated impulse (in Hz). Default: None.
- total_length_secondsfloat, optional
Total length of the output RIR in seconds. Default: 0.5.
- add_noise_reverberant_tailbool, optional
When True, decaying noise is added to the IR in order to model the late reflections of the room. Default: True.
- apply_bandpassbool, optional
When True, a bandpass filter is applied to signal in order to obtain a realistic audio representation of the RIR. Default: True.
- use_detailed_absorptionbool, optional
When True, The detailed absorption data of the room is used to generate the impulse response. This allows a more realistic RIR but at the expense of a much higher computational cost. Default: False.
- max_orderint, optional
This gives the option to limit the order of reflections computed for the method. This is specially useful when detailed absorption is used and the room has a long reverberation time, since this kind of setting will take a specially long time to run. Pass None to use an automatic estimation for the maximum order. Default: None.
- Returns:
- rirImpulseResponse
Newly generated RIR.
Notes
Depending on the computer and the given reverberation time, this function can take a relatively long runtime. If a faster or more flexible implementation is needed, please refer to the pyroomacoustics package (see references).
References
Brinkmann, Fabian & Erbes, Vera & Weinzierl, Stefan. (2018). Extending the closed form image source model for source directivity.
pyroomacoustics: https://github.com/LCAV/pyroomacoustics
- dsptoolbox.room_acoustics.reverb_time(signal: ImpulseResponse | MultiBandSignal, mode: ReverbTime = ReverbTime.Adaptive, ir_start: int | ndarray[tuple[Any, ...], dtype[int64]] | None = None, automatic_trimming: bool = True) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]¶
Computes reverberation time. Topt, T20, T30, T60 and EDT.
- Parameters:
- signalImpulseResponse or MultiBandSignal
IR for which to compute reverberation times.
- modeReverbTime, optional
Reverberation time mode. Default: Adaptive.
- ir_startint or array-like, NDArray[np.int_], optional
If it is an integer, it is assumed as the start of the IR for all channels (and all bands). For more specific cases, pass a 1d-array containing the start indices for each channel or a 2d-array with shape (band, channel) for a MultiBandSignal. Pass None for an automatic detection of the start. See notes for details. Default: None.
- automatic_trimmingbool, optional
When set to True, the IR is trimmed using transfer_functions.trim_ir independently for each channel. This can influence significantly the energy decay curve and, therefore, the reverberation time. See notes for more details. Default: True.
- Returns:
- reverberation_timesNDArray[np.float64]
Reverberation times for each channel. Shape is (band, channel) if MultiBandSignal object is passed.
- correlation_coefficientNDArray[np.float64]
Pearson correlation coefficient to determine the accuracy of the reverberation time estimation. It has shape (channels) or (band, channels) if MultiBandSignal object is passed. See notes for more details.
Notes
The start of the IR is determined by the last sample below -20 dB relative to peak. This is in accordance with [1].
The end of the IR is found by transfer_functions.trim_ir. This is then used as the intersection time as explained in [2].
The energy decay curve is computed while removing the noise energy according to [3] and regarding the compensation energy as explained by [1] and [2]. If too much noise is detected, its removal is avoided.
The method “Adaptive” is implemented as explained by the documentation of [4].
A correlation coefficient of -1 means there is a perfectly linear relation between time and energy decay, which is an optimal estimation. Coefficients larger than -0.9 might mean that the estimation is not valid.
In order to compare EDT to the other measures, it must be multiplied by 6.
References
[1]: DIN EN ISO 3382-1:2009-10, Acoustics - Measurement of the reverberation time of rooms with reference to other acoustical parameters.
[2]: Lundeby, Virgran, Bietz and Vorlaender - Uncertainties of Measurements in Room Acoustics - ACUSTICA Vol. 81 (1995).
[3]: W. T. Chu. “Comparison of reverberation measurements using Schroeder’s impulse method and decay-curve averaging method”. In: Journal of the Acoustical Society of America 63.5 (1978), pp. 1444–1450.
[4]: Room-EQ-Wizard for Topt.