diff --git a/CHANGELOG.rst b/CHANGELOG.rst index deba4a8d..10d1aad7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,7 +11,15 @@ adheres to `Semantic Versioning `_. `Unreleased`_ ------------- -Nothing yet. +Bugfix +~~~~~~ + +- Fixes the default value of ``energy_thres`` in ``experimental.rt60`` to match the + previous behavior of the function (issue #358) +- Further fixes issue with cast reflections delays to float32 in room.py (#353) + which was not fully fixed by the previous update +- Fixes calls to deprecated API of ``scipy.linalg.eigh`` +- Fixes use of deprecated feature of numpy (conversion of singleton array to scalar) `0.7.5`_ - 2024-06-18 --------------------- diff --git a/pyroomacoustics/beamforming.py b/pyroomacoustics/beamforming.py index 0debe776..f385d205 100644 --- a/pyroomacoustics/beamforming.py +++ b/pyroomacoustics/beamforming.py @@ -1216,7 +1216,7 @@ def rake_max_udr_filters( SINR, v = la.eigh( A, b=B, - eigvals=(self.M * self.Lg - 1, self.M * self.Lg - 1), + subset_by_index=(self.M * self.Lg - 1, self.M * self.Lg - 1), overwrite_a=True, overwrite_b=True, check_finite=False, @@ -1316,7 +1316,7 @@ def rake_max_sinr_filters(self, source, interferer, R_n, epsilon=5e-3, delay=0.0 SINR, v = la.eigh( K_s, b=K_nq, - eigvals=(self.M * self.Lg - 1, self.M * self.Lg - 1), + subset_by_index=(self.M * self.Lg - 1, self.M * self.Lg - 1), overwrite_a=True, overwrite_b=True, check_finite=False, diff --git a/pyroomacoustics/doa/music.py b/pyroomacoustics/doa/music.py index 8bb85760..07cf6a6d 100644 --- a/pyroomacoustics/doa/music.py +++ b/pyroomacoustics/doa/music.py @@ -150,7 +150,7 @@ def _compute_spatial_spectrum(self, cross, k): Dc = np.array(self.mode_vec[k, :, n], ndmin=2).T Dc_H = np.conjugate(np.array(self.mode_vec[k, :, n], ndmin=2)) denom = np.linalg.multi_dot([Dc_H, cross, Dc]) - P[n] = 1 / abs(denom) + P[n] = 1 / abs(denom[0, 0]) return P diff --git a/pyroomacoustics/experimental/localization.py b/pyroomacoustics/experimental/localization.py index 169d58e5..e2485b2c 100644 --- a/pyroomacoustics/experimental/localization.py +++ b/pyroomacoustics/experimental/localization.py @@ -208,7 +208,7 @@ def edm_line_search(R, tdoa, bounds, steps): for i in range(d.shape[0]): D[-1, :-1] = D[:-1, -1] = (dif + d[i]) ** 2 w = np.sort(np.abs(la.eigh(D, eigvals_only=True))) - # w = la.eigh(D, eigvals_only=True, eigvals=(D.shape[0]-6,D.shape[0]-6)) + # w = la.eigh(D, eigvals_only=True, subset_by_index=(D.shape[0]-6,D.shape[0]-6)) cost[i] = np.sum(w[: D.shape[0] - 5]) return cost, d diff --git a/pyroomacoustics/experimental/rt60.py b/pyroomacoustics/experimental/rt60.py index b3634540..d9df7ee2 100644 --- a/pyroomacoustics/experimental/rt60.py +++ b/pyroomacoustics/experimental/rt60.py @@ -33,7 +33,7 @@ import numpy as np -def measure_rt60(h, fs=1, decay_db=60, energy_thres=0.95, plot=False, rt60_tgt=None): +def measure_rt60(h, fs=1, decay_db=60, energy_thres=1.0, plot=False, rt60_tgt=None): """ Analyze the RT60 of an impulse response. Optionaly plots some useful information. diff --git a/pyroomacoustics/room.py b/pyroomacoustics/room.py index 9f6dec50..4b8fd9a4 100644 --- a/pyroomacoustics/room.py +++ b/pyroomacoustics/room.py @@ -2283,7 +2283,13 @@ def compute_rir(self): N = int(math.ceil(t_max * self.fs / hbss) * hbss) # this is where we will compose the RIR - ir = np.zeros(N + fdl) + + # here we create an array of the right length to + # receiver the full RIR + # the +1 is due to some rare cases where numerical + # errors push the last sample over the end of the + # array + ir = np.zeros(N + fdl + 1) # This is the distance travelled wrt time distance_rir = np.arange(N) / self.fs * self.c diff --git a/pyroomacoustics/tests/test_issue_353.py b/pyroomacoustics/tests/test_issue_353.py index a363060d..db3b4dc9 100644 --- a/pyroomacoustics/tests/test_issue_353.py +++ b/pyroomacoustics/tests/test_issue_353.py @@ -16,6 +16,7 @@ """ import numpy as np +import pytest import pyroomacoustics as pra @@ -39,3 +40,104 @@ def test_issue_353(): room.add_microphone_array(mic_array_in_room) room.compute_rir() + + +def test_issue_353_2(): + rt60_tgt = 0.451734045124395 # seconds + room_dim = [2.496315595944846, 2.2147285947364708, 3.749472153652182] # meters + + fs = 16000 + + e_absorption, max_order = pra.inverse_sabine(rt60_tgt, room_dim) + + room = pra.ShoeBox( + room_dim, fs=fs, materials=pra.Material(e_absorption), max_order=max_order + ) + + room.add_source([0.24784311631630576, 1.690743273038349, 1.9570721698068267]) + + mic_array = np.array( + [ + [ + 0.46378325918698565, + ], + [ + 1.5657207092343373, + ], + [ + 3.015697444447528, + ], + ] + ) + + room.add_microphone_array(mic_array) + + room.compute_rir() + + +params = ( + ( + [4.57977238, 5.39054892, 2.82767573], + 0.18257819716723472, + [1.22812426, 1.2966769, 1.43330033], + [1.8020194, 0.76576269, 0.53980759], + 83, + ), + ( + [5.3997869, 6.34821279, 2.90299906], + 0.2217407971025793, + [4.05889913, 4.15230608, 2.39073375], + [2.45186073, 2.88844052, 1.39751034], + 70, + ), + ( + [5.45909408, 6.34962532, 2.77107005], + 0.27431416842419915, + [0.54511116, 2.82639397, 1.04676184], + [4.15744634, 2.82665472, 1.01958203], + 58, + ), + ( + [5.88430842, 5.74587181, 2.81243457], + 0.23546727398942446, + [5.2673113, 1.68109104, 2.13159967], + [2.03474247, 0.82147634, 1.25415523], + 66, + ), + ( + [5.8335965, 4.90706049, 2.5410871], + 0.25263067293986236, + [0.58218881, 3.25631355, 0.91775666], + [1.06434647, 3.3755251, 1.84040589], + 63, + ), + ( + [5.63150056, 5.21368813, 2.90971373], + 0.24979151070744487, + [4.30157587, 2.54104283, 2.22109155], + [1.47065101, 3.65191472, 1.64230692], + 61, + ), + ( + [6.24132556, 4.62941236, 2.52808349], + 0.23735500015498867, + [3.75099353, 3.82859854, 1.66480812], + [0.63880713, 1.93500295, 1.12386568], + 67, + ), +) + + +@pytest.mark.parametrize("room_dims, abs_coeff, spkr_pos, mic_pos, max_order", params) +def test_issue_353_3(room_dims, abs_coeff, spkr_pos, mic_pos, max_order): + room = pra.ShoeBox( + room_dims, + fs=16000, + materials=pra.Material(abs_coeff), + max_order=max_order, + use_rand_ism=False, + ) + room.add_source(spkr_pos) + room.add_microphone(mic_pos) + + room.compute_rir()