diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 83cf6f89..48f9c0d4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,7 +26,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.8 + python-version: 3.9 - name: Install Python dependencies run: pip install black flake8 isort diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index ff9bca0b..1bf62e2d 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -10,8 +10,13 @@ jobs: fail-fast: false max-parallel: 12 matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.7, 3.8, 3.9, "3.10"] + os: [ubuntu-latest, macos-13, macos-latest, windows-latest] + python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] + exclude: + - os: macos-latest + python-version: 3.8 + - os: macos-latest + python-version: 3.9 steps: - uses: actions/checkout@v3 - name: Checkout submodules @@ -40,17 +45,17 @@ jobs: python -m pip install -e . - name: Test with pytest run: | - pip install -U pytest setuptools wheel twine + pip install -U pytest setuptools build wheel twine pytest - name: Test the universal wheels if: matrix.os == 'ubuntu-latest' run: | - python setup.py sdist + python -m build --sdist twine check dist/* - name: Test the binary wheels if: matrix.os != 'ubuntu-latest' run: | - python setup.py bdist_wheel + python -m build --wheel twine check dist/* - name: Publish sdist to pypi if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') && matrix.os == 'ubuntu-latest' diff --git a/README.rst b/README.rst index 8ccf797e..a4831685 100755 --- a/README.rst +++ b/README.rst @@ -1,12 +1,9 @@ .. image:: https://github.com/LCAV/pyroomacoustics/raw/master/logo/pyroomacoustics_logo_horizontal.png - :scale: 80 % :alt: Pyroomacoustics logo :align: left ------------------------------------------------------------------------------ -.. image:: https://travis-ci.org/LCAV/pyroomacoustics.svg?branch=pypi-release - :target: https://travis-ci.org/LCAV/pyroomacoustics .. image:: https://readthedocs.org/projects/pyroomacoustics/badge/?version=pypi-release :target: http://pyroomacoustics.readthedocs.io/en/pypi-release/ :alt: Documentation Status diff --git a/examples/adaptive_filter_stft_domain.py b/examples/adaptive_filter_stft_domain.py index 256fe1ef..be64e57f 100644 --- a/examples/adaptive_filter_stft_domain.py +++ b/examples/adaptive_filter_stft_domain.py @@ -5,6 +5,7 @@ In this example, we will run adaptive filters for system identification, but in the frequeny domain. """ + from __future__ import division, print_function import matplotlib.pyplot as plt diff --git a/examples/adaptive_filters.py b/examples/adaptive_filters.py index ab27296d..e4b0df0e 100644 --- a/examples/adaptive_filters.py +++ b/examples/adaptive_filters.py @@ -4,6 +4,7 @@ In this example, we will run adaptive filters for system identification. """ + from __future__ import division, print_function import matplotlib.pyplot as plt diff --git a/examples/beamforming_delay_and_sum.py b/examples/beamforming_delay_and_sum.py index 4a83f1ec..9e882af2 100644 --- a/examples/beamforming_delay_and_sum.py +++ b/examples/beamforming_delay_and_sum.py @@ -1,6 +1,7 @@ """ This example shows how to create delay and sum beamformers """ + from __future__ import division, print_function import matplotlib.pyplot as plt diff --git a/examples/bss_example.py b/examples/bss_example.py index 22ead9b2..f16eb099 100755 --- a/examples/bss_example.py +++ b/examples/bss_example.py @@ -54,6 +54,7 @@ This script requires the `mir_eval` to run, and `tkinter` and `sounddevice` packages for the GUI option. """ + import time import numpy as np diff --git a/examples/datasets.py b/examples/datasets.py index 2e747359..ab9e1644 100644 --- a/examples/datasets.py +++ b/examples/datasets.py @@ -2,6 +2,7 @@ Example of the basic operations with ``pyroomacoustics.datasets.Dataset`` and ``pyroomacoustics.datasets.Sample`` classes """ + from pyroomacoustics.datasets import Dataset, Sample # Prepare a few artificial samples diff --git a/examples/raytracing.py b/examples/raytracing.py index f29410bb..59c414e5 100644 --- a/examples/raytracing.py +++ b/examples/raytracing.py @@ -2,6 +2,7 @@ This example program demonstrates the use of ray tracing for the simulation of rooms of different sizes. """ + from __future__ import print_function import argparse diff --git a/examples/room_L_shape_3d_rt.py b/examples/room_L_shape_3d_rt.py index 396be3d8..089acaa8 100644 --- a/examples/room_L_shape_3d_rt.py +++ b/examples/room_L_shape_3d_rt.py @@ -7,6 +7,7 @@ The simulation is done using the hybrid ISM/RT simulator. """ + from __future__ import print_function import time diff --git a/examples/room_complex_wall_materials.py b/examples/room_complex_wall_materials.py index fc9a2359..41bb1905 100644 --- a/examples/room_complex_wall_materials.py +++ b/examples/room_complex_wall_materials.py @@ -4,6 +4,7 @@ 2022 (c) @noahdeetzers, @fakufaku """ + import matplotlib.pyplot as plt import numpy as np diff --git a/examples/room_from_rt60.py b/examples/room_from_rt60.py index b97681b8..d33141e0 100644 --- a/examples/room_from_rt60.py +++ b/examples/room_from_rt60.py @@ -4,6 +4,7 @@ The simulation is pure image source method. The audio sample with the reverb added is saved back to `examples/samples/guitar_16k_reverb.wav`. """ + import argparse import matplotlib.pyplot as plt diff --git a/examples/room_from_stl.py b/examples/room_from_stl.py index 12d49086..12063d94 100644 --- a/examples/room_from_stl.py +++ b/examples/room_from_stl.py @@ -5,6 +5,7 @@ The STL file was kindly provided by Diego Di Carlo (@Chutlhu). """ + import argparse import os from pathlib import Path diff --git a/pyroomacoustics/adaptive/lms.py b/pyroomacoustics/adaptive/lms.py index a36446b2..dac915b8 100644 --- a/pyroomacoustics/adaptive/lms.py +++ b/pyroomacoustics/adaptive/lms.py @@ -5,6 +5,7 @@ Implementations of adaptive filters from the LMS class. These algorithms have a low complexity and reliable behavior with a somewhat slower convergence. """ + from __future__ import absolute_import, division, print_function import numpy as np diff --git a/pyroomacoustics/adaptive/subband_lms.py b/pyroomacoustics/adaptive/subband_lms.py index d9c0479c..70c0cf92 100644 --- a/pyroomacoustics/adaptive/subband_lms.py +++ b/pyroomacoustics/adaptive/subband_lms.py @@ -26,7 +26,6 @@ class SubbandLMS: - """ Frequency domain implementation of LMS. Adaptive filter for each subband. diff --git a/pyroomacoustics/beamforming.py b/pyroomacoustics/beamforming.py index 2cf0846b..f5d5fdf6 100644 --- a/pyroomacoustics/beamforming.py +++ b/pyroomacoustics/beamforming.py @@ -348,7 +348,6 @@ def circular_microphone_array_xyplane( class MicrophoneArray(object): - """Microphone array class.""" def __init__(self, R, fs, directivity=None): diff --git a/pyroomacoustics/datasets/cmu_arctic.py b/pyroomacoustics/datasets/cmu_arctic.py index a3e42e96..f9836197 100644 --- a/pyroomacoustics/datasets/cmu_arctic.py +++ b/pyroomacoustics/datasets/cmu_arctic.py @@ -29,6 +29,7 @@ URL: http://www.festvox.org/cmu_arctic/ """ + import os import numpy as np diff --git a/pyroomacoustics/datasets/tests/test_corpus_base.py b/pyroomacoustics/datasets/tests/test_corpus_base.py index 4d356b24..b49a7b27 100644 --- a/pyroomacoustics/datasets/tests/test_corpus_base.py +++ b/pyroomacoustics/datasets/tests/test_corpus_base.py @@ -2,6 +2,7 @@ Example of the basic operations with ``pyroomacoustics.datasets.Dataset`` and ``pyroomacoustics.datasets.Sample`` classes """ + from pyroomacoustics.datasets import Dataset, Sample diff --git a/pyroomacoustics/doa/grid.py b/pyroomacoustics/doa/grid.py index 6cf965ce..09d1e22b 100644 --- a/pyroomacoustics/doa/grid.py +++ b/pyroomacoustics/doa/grid.py @@ -1,6 +1,7 @@ """ Routines to perform grid search on the sphere """ + from __future__ import absolute_import, division, print_function from abc import ABCMeta, abstractmethod diff --git a/pyroomacoustics/doa/plotters.py b/pyroomacoustics/doa/plotters.py index 8b1846bc..764f3d24 100644 --- a/pyroomacoustics/doa/plotters.py +++ b/pyroomacoustics/doa/plotters.py @@ -1,6 +1,7 @@ """ A collection of functions to plot maps and points on circles and spheres. """ + import numpy as np diff --git a/pyroomacoustics/doa/utils.py b/pyroomacoustics/doa/utils.py index e738c96a..3bb4af9a 100644 --- a/pyroomacoustics/doa/utils.py +++ b/pyroomacoustics/doa/utils.py @@ -2,6 +2,7 @@ This module contains useful functions to compute distances and errors on on circles and spheres. """ + from __future__ import division import numpy as np diff --git a/pyroomacoustics/experimental/signals.py b/pyroomacoustics/experimental/signals.py index e6659af0..24359110 100644 --- a/pyroomacoustics/experimental/signals.py +++ b/pyroomacoustics/experimental/signals.py @@ -1,6 +1,7 @@ """ A few test signals like sweeps and stuff. """ + from __future__ import division, print_function import numpy as np diff --git a/pyroomacoustics/libroom_src/geometry.cpp b/pyroomacoustics/libroom_src/geometry.cpp index 1c612278..26bdb098 100644 --- a/pyroomacoustics/libroom_src/geometry.cpp +++ b/pyroomacoustics/libroom_src/geometry.cpp @@ -233,20 +233,55 @@ Eigen::Vector3f cross(Eigen::Vector3f v1, Eigen::Vector3f v2) return v1.cross(v2); } +bool on_segment(const Eigen::Vector2f &c1, const Eigen::Vector2f &c2, const Eigen::Vector2f &p) { + // Given three collinear points c1, c2, p, the function checks if + // point p lies on line segment c1 <-> c2 + + float x_down, x_up, y_down, y_up; + x_down = fminf(c1.coeff(0), c2.coeff(0)); + x_up = fmaxf(c1.coeff(0), c2.coeff(0)); + y_down = fminf(c1.coeff(1), c2.coeff(1)); + y_up = fmaxf(c1.coeff(1), c2.coeff(1)); + return (x_down <= p.coeff(0) && p.coeff(0) <= x_up && y_down <= p.coeff(1) && p.coeff(1) <= y_up); +} -int is_inside_2d_polygon(const Eigen::Vector2f &p, +inline int is_left(const Eigen::Vector2f &P0, const Eigen::Vector2f &P1, const Eigen::Vector2f &P2) +{ + // isLeft(): tests if a point is Left|On|Right of an infinite line. + // on the line is defined as within epsilon + // Input: three points P0, P1, and P2 + // Return: >0 for P2 left of the line through P0 and P1 + // =0 for P2 on the line + // <0 for P2 right of the line + // See: Algorithm 1 "Area of Triangles and Polygons" + float test_value = ( + (P1.coeff(0) - P0.coeff(0)) * (P2.coeff(1) - P0.coeff(1)) + - (P2.coeff(0) - P0.coeff(0)) * (P1.coeff(1) - P0.coeff(1)) + ); + + if (fabsf(test_value) < libroom_eps) + return 0; + else if (test_value > 0) + return 1; + else + return -1; +} + +int is_inside_2d_polygon(const Eigen::Vector2f &p_test, const Eigen::Matrix &corners) { /* - Checks if a given point is inside a given polygon in 2D. + Checks if a given point is inside a given polygon in 2D using the winding + number method. This function checks if a point (defined by its coordinates) is inside a polygon (defined by an array of coordinates of its corners) by counting - the number of intersections between the borders and a segment linking - the given point with a computed point outside the polygon. - A boolean is also returned to indicate if a point is on a border of the - polygon (the point is still considered inside), which can be useful for - limit cases computations. + the number of left intersections between the edges and a half-line starting from + the test point. + + This is Dave Sunday's winding number algorithm described here: + http://profs.ic.uff.br/~anselmo/cursos/CGI/slidesNovos/Inclusion%20of%20a%20Point%20in%20a%20Polygon.pdf + It was modified to explicitely check for points on the edges of the polygon. p: (array size 2) coordinates of the point corners: (array size 2xN, N>2) coordinates of the corners of the polygon @@ -257,67 +292,35 @@ int is_inside_2d_polygon(const Eigen::Vector2f &p, 0 : the point is inside 1 : the point is on the boundary */ - - bool is_inside = false; // initialize point not in the polygon - int c1c2p, c1c2p0, pp0c1, pp0c2; int n_corners = corners.cols(); - - // find a point outside the polygon - int i_min; - corners.row(0).minCoeff(&i_min); - Eigen::Vector2f p_out; - p_out.resize(2); - p_out.coeffRef(0) = corners.coeff(0,i_min) - 1; - p_out.coeffRef(1) = p.coeff(1); - - // Now count intersections + int wn = 0; // the winding number counter + // loop through all edges of the polygon for (int i = 0, j = n_corners-1 ; i < n_corners ; j=i++) { - - // Check first if the point is on the segment - // We count the border as inside the polygon - c1c2p = ccw3p(corners.col(i), corners.col(j), p); - if (c1c2p == 0) + if (ccw3p(corners.col(j), corners.col(i), p_test) == 0 && on_segment(corners.col(j), corners.col(i), p_test)) { - // Here we know that p is co-linear with the two corners - float x_down, x_up, y_down, y_up; - x_down = fminf(corners.coeff(0,i), corners.coeff(0,j)); - x_up = fmaxf(corners.coeff(0,i), corners.coeff(0,j)); - y_down = fminf(corners.coeff(1,i), corners.coeff(1,j)); - y_up = fmaxf(corners.coeff(1,i), corners.coeff(1,j)); - if (x_down <= p.coeff(0) && p.coeff(0) <= x_up && y_down <= p.coeff(1) && p.coeff(1) <= y_up) - return 1; + // point is on the edge, we consider it inside + return 1; } - - // Now check intersection with standard method - c1c2p0 = ccw3p(corners.col(i), corners.col(j), p_out); - if (c1c2p == c1c2p0) // no intersection - continue; - - pp0c1 = ccw3p(p, p_out, corners.col(i)); - pp0c2 = ccw3p(p, p_out, corners.col(j)); - if (pp0c1 == pp0c2) // no intersection - continue; - - // at this point we are sure there is an intersection - - // the second condition takes care of horizontal edges and intersection on vertex - float c_max = fmaxf(corners.coeff(1,i), corners.coeff(1,j)); - if (p.coeff(1) + libroom_eps < c_max) - { - is_inside = !is_inside; + if (corners.coeff(1,j) <= p_test.coeff(1)) { // start y <= P.y + if (corners.coeff(1,i) > p_test.coeff(1)) { // an upward crossing + if (is_left(corners.col(j), corners.col(i), p_test) > 0) // P left of edge + ++wn; // have a valid up intersect + } + } else { // start y > P.y (no test needed) + if (corners.coeff(1, i) <= p_test.coeff(1)) { // a downward crossing + if (is_left(corners.col(j), corners.col(i), p_test) < 0) // P right of edge + --wn; // have a valid down intersect + } } - } - // for a odd number of intersections, the point is in the polygon - if (is_inside) - return 0; // point strictly inside + if (wn == 0) + return -1; else - return -1; // point is outside + return 0; } - float area_2d_polygon(const Eigen::Matrix &corners) { /* diff --git a/pyroomacoustics/libroom_src/libroom.cpp b/pyroomacoustics/libroom_src/libroom.cpp index 300a5395..444c6be2 100644 --- a/pyroomacoustics/libroom_src/libroom.cpp +++ b/pyroomacoustics/libroom_src/libroom.cpp @@ -282,10 +282,7 @@ PYBIND11_MODULE(libroom, m) { m.def("dist_line_point", &dist_line_point, "Computes the distance between a point and an infinite line"); - m.def("rir_builder", &rir_builder, "RIR builder", - py::call_guard()); - m.def("delay_sum", &delay_sum, "Delay and sum", - py::call_guard()); - m.def("fractional_delay", &fractional_delay, "Fractional delays", - py::call_guard()); + m.def("rir_builder", &rir_builder, "RIR builder"); + m.def("delay_sum", &delay_sum, "Delay and sum"); + m.def("fractional_delay", &fractional_delay, "Fractional delays"); } diff --git a/pyroomacoustics/libroom_src/rir_builder.cpp b/pyroomacoustics/libroom_src/rir_builder.cpp index 5b599aa3..36cf0821 100644 --- a/pyroomacoustics/libroom_src/rir_builder.cpp +++ b/pyroomacoustics/libroom_src/rir_builder.cpp @@ -44,11 +44,12 @@ constexpr T get_pi() { template void threaded_rir_builder_impl( py::array_t rir, - const py::array_t time, - const py::array_t alpha, + const py::array_t &time, + const py::array_t &alpha, const py::array_t - visibility, + &visibility, int fs, size_t fdl, size_t lut_gran, size_t num_threads) { + auto pi = get_pi(); // accessors for the arrays @@ -110,6 +111,9 @@ void threaded_rir_builder_impl( std::vector rir_out(num_threads * rir_len); size_t block_size = size_t(std::ceil(double(n_times) / double(num_threads))); + // relase the GIL from here on + py::gil_scoped_release release; + // build the RIR ThreadPool pool(num_threads); std::vector> results; @@ -166,9 +170,10 @@ void threaded_rir_builder_impl( for (auto &&result : sum_results) result.get(); } -void rir_builder(py::buffer rir, const py::buffer time, const py::buffer alpha, - const py::buffer visibility, int fs, size_t fdl, +void rir_builder(py::buffer rir, const py::buffer &time, const py::buffer &alpha, + const py::buffer &visibility, int fs, size_t fdl, size_t lut_gran, size_t num_threads) { + // dispatch to correct implementation depending on input type auto buf = pybind11::array::ensure(rir); if (py::isinstance>(buf)) { @@ -214,6 +219,9 @@ void threaded_delay_sum_impl( std::vector out_buffers(num_threads * out_len, 0); size_t block_size = size_t(std::ceil(double(n_irs) / double(num_threads))); + // release the GIL from here on + py::gil_scoped_release release; + // build the RIR ThreadPool pool(num_threads); std::vector> results; @@ -315,6 +323,9 @@ void threaded_fractional_delay_impl( // divide into equal size blocks for thread processing size_t block_size = size_t(std::ceil(double(n_times) / double(num_threads))); + // relase the GIL from here on + py::gil_scoped_release release; + // build the RIR ThreadPool pool(num_threads); std::vector> results; diff --git a/pyroomacoustics/libroom_src/rir_builder.hpp b/pyroomacoustics/libroom_src/rir_builder.hpp index f665123a..f4802a4c 100644 --- a/pyroomacoustics/libroom_src/rir_builder.hpp +++ b/pyroomacoustics/libroom_src/rir_builder.hpp @@ -7,8 +7,8 @@ namespace py = pybind11; -void rir_builder(py::buffer rir, const py::buffer time, const py::buffer alpha, - const py::buffer visibility, int fs, size_t fdl, +void rir_builder(py::buffer rir, const py::buffer &time, const py::buffer &alpha, + const py::buffer &visibility, int fs, size_t fdl, size_t lut_gran, size_t num_threads); void delay_sum(const py::buffer irs, const py::buffer delays, py::buffer output, diff --git a/pyroomacoustics/libroom_src/room.cpp b/pyroomacoustics/libroom_src/room.cpp index 3f9431af..540ccc85 100644 --- a/pyroomacoustics/libroom_src/room.cpp +++ b/pyroomacoustics/libroom_src/room.cpp @@ -729,7 +729,7 @@ std::tuple < Vectorf, int, float > Room::next_wall_hit( Wall & w = scattered_ray ? walls[obstructing_walls[i]] : walls[i]; // To store the result of this iteration - Vectorf temp_hit; + Vectorf temp_hit = Vectorf::Zero(); // As a side effect, temp_hit gets a value (VectorXf) here int ret = w.intersection(start, end, temp_hit); @@ -948,6 +948,7 @@ void Room::simul_ray( auto p_hit = (1 - sqrt(1 - mic_radius_sq / std::max(mic_radius_sq, r_sq))); energy = transmitted / (r_sq * p_hit); // energy = transmitted / (travel_dist_at_mic - sqrtf(fmaxf(0.f, travel_dist_at_mic * travel_dist_at_mic - mic_radius_sq))); + microphones[k].log_histogram(travel_dist_at_mic, energy, start); } } diff --git a/pyroomacoustics/tests/test_bandpass_filterbank.py b/pyroomacoustics/tests/test_bandpass_filterbank.py index 07c9c94d..1522d2bb 100644 --- a/pyroomacoustics/tests/test_bandpass_filterbank.py +++ b/pyroomacoustics/tests/test_bandpass_filterbank.py @@ -1,6 +1,7 @@ """ This tests the construction of a bank of octave filters """ + import numpy as np from scipy.signal import sosfreqz diff --git a/pyroomacoustics/tests/test_build_rir.py b/pyroomacoustics/tests/test_build_rir.py index b1afc709..c28c7e14 100644 --- a/pyroomacoustics/tests/test_build_rir.py +++ b/pyroomacoustics/tests/test_build_rir.py @@ -285,7 +285,7 @@ def measure_runtime(dtype=np.float32, num_threads=4): td = np.round(tt).astype(np.int32) tf = (tt - td).astype(dtype) irs = np.zeros((tt.shape[0], fdl), dtype=dtype) - fractional_delay(irs, tf, 20, num_threads) + libroom.fractional_delay(irs, tf, 20, num_threads) irs *= alpha[:, None] libroom.delay_sum(irs, td, rir, num_threads) tock_2steps = (time.perf_counter() - tick) / n_repeat diff --git a/pyroomacoustics/tests/test_issue_22.py b/pyroomacoustics/tests/test_issue_22.py index 76f3cb66..31df1b8a 100644 --- a/pyroomacoustics/tests/test_issue_22.py +++ b/pyroomacoustics/tests/test_issue_22.py @@ -14,6 +14,7 @@ If the C module is not installed (pure python fallback version), then nothing is done. """ + import numpy as np import pyroomacoustics diff --git a/pyroomacoustics/tests/test_materials.py b/pyroomacoustics/tests/test_materials.py index 141d1d3d..a0954c35 100644 --- a/pyroomacoustics/tests/test_materials.py +++ b/pyroomacoustics/tests/test_materials.py @@ -2,6 +2,7 @@ Just run the Material command with a bunch of inputs to make sure it works as expected """ + import pyroomacoustics as pra scat_test = { diff --git a/pyroomacoustics/tests/test_random_ism.py b/pyroomacoustics/tests/test_random_ism.py index bcb809a4..43bc6743 100644 --- a/pyroomacoustics/tests/test_random_ism.py +++ b/pyroomacoustics/tests/test_random_ism.py @@ -5,6 +5,7 @@ Script to test removal of sweeping echoes with randomized image method """ + import pyroomacoustics as pra from pyroomacoustics import metrics as met diff --git a/pyroomacoustics/tests/test_room_mix.py b/pyroomacoustics/tests/test_room_mix.py index 336ebb3c..6cac9989 100644 --- a/pyroomacoustics/tests/test_room_mix.py +++ b/pyroomacoustics/tests/test_room_mix.py @@ -1,6 +1,7 @@ """ Tests the mixing function of ``Room.simulate`` """ + import unittest import numpy as np diff --git a/pyroomacoustics/tests/test_rt60.py b/pyroomacoustics/tests/test_rt60.py index 56d698fd..bb700ad4 100644 --- a/pyroomacoustics/tests/test_rt60.py +++ b/pyroomacoustics/tests/test_rt60.py @@ -2,7 +2,7 @@ import pyroomacoustics as pra -eps = 1e-10 +eps = 1e-6 room_dim = [10, 7.5, 3.5] # meters fs = 16000 diff --git a/pyroomacoustics/tests/tests_libroom/test_is_inside_2d_polygon.py b/pyroomacoustics/tests/tests_libroom/test_is_inside_2d_polygon.py index 8841eb15..3a6a8a63 100644 --- a/pyroomacoustics/tests/tests_libroom/test_is_inside_2d_polygon.py +++ b/pyroomacoustics/tests/tests_libroom/test_is_inside_2d_polygon.py @@ -30,18 +30,8 @@ polygons = [ np.array( [ # this one is clockwise - [ - 0, - 4, - 4, - 0, - ], - [ - 0, - 0, - 4, - 4, - ], + [0, 4, 4, 0], + [0, 0, 4, 4], ] ), np.array( diff --git a/pyroomacoustics/tests/tests_libroom/test_ray_energy.py b/pyroomacoustics/tests/tests_libroom/test_ray_energy.py index 440b7815..7189c92f 100644 --- a/pyroomacoustics/tests/tests_libroom/test_ray_energy.py +++ b/pyroomacoustics/tests/tests_libroom/test_ray_energy.py @@ -83,10 +83,10 @@ def test_square_room(self): print("Creating the python room (polyhedral)") walls_corners = [ - np.array([[0, 2, 2, 0], [0, 0, 0, 0], [0, 0, 2, 2]]), # left - np.array([[0, 0, 2, 2], [2, 2, 2, 2], [0, 2, 2, 0]]), # right - np.array([[0, 0, 0, 0], [0, 2, 2, 0], [0, 0, 2, 2]]), # front` - np.array([[2, 2, 2, 2], [0, 0, 2, 2], [0, 2, 2, 0]]), # back + np.array([[0, 2, 2, 0], [0, 0, 0, 0], [0, 0, 2, 2]]), # front + np.array([[0, 0, 2, 2], [2, 2, 2, 2], [0, 2, 2, 0]]), # back + np.array([[0, 0, 0, 0], [0, 2, 2, 0], [0, 0, 2, 2]]), # left` + np.array([[2, 2, 2, 2], [0, 0, 2, 2], [0, 2, 2, 0]]), # right np.array( [ [0, 2, 2, 0], @@ -157,8 +157,8 @@ def test_square_room(self): histogram_rt_poly = np.array(h_poly[0])[: len(histogram_gt)] histogram_rt_cube = np.array(h_cube[0])[: len(histogram_gt)] - self.assertTrue(np.allclose(histogram_rt_poly, histogram_gt)) - self.assertTrue(np.allclose(histogram_rt_cube, histogram_gt)) + self.assertTrue(np.allclose(histogram_rt_poly, histogram_gt, atol=1e-5)) + self.assertTrue(np.allclose(histogram_rt_cube, histogram_gt, atol=1e-5)) if __name__ == "__main__": diff --git a/pyroomacoustics/tests/tests_libroom/test_shoebox_simple.py b/pyroomacoustics/tests/tests_libroom/test_shoebox_simple.py index e0110d05..10d94b47 100644 --- a/pyroomacoustics/tests/tests_libroom/test_shoebox_simple.py +++ b/pyroomacoustics/tests/tests_libroom/test_shoebox_simple.py @@ -7,6 +7,7 @@ It was created to address Issue #293 on github. https://github.com/LCAV/pyroomacoustics/issues/293 """ + import numpy as np import pytest diff --git a/pyroomacoustics/transform/__init__.py b/pyroomacoustics/transform/__init__.py index 00559f93..e11fb411 100644 --- a/pyroomacoustics/transform/__init__.py +++ b/pyroomacoustics/transform/__init__.py @@ -15,7 +15,6 @@ """ - from . import stft from .dft import DFT from .stft import STFT diff --git a/setup.py b/setup.py index 8acd3a6f..a91a0746 100644 --- a/setup.py +++ b/setup.py @@ -188,8 +188,8 @@ def build_extensions(self): ], cmdclass={"build_ext": BuildExt}, # taken from pybind11 example zip_safe=False, - test_suite="nose.collector", - tests_require=["nose"], + test_suite="pytest", + tests_require=["pytest"], classifiers=[ # How mature is this project? Common values are # 3 - Alpha @@ -207,14 +207,11 @@ def build_extensions(self): "License :: OSI Approved :: MIT License", # Specify the Python versions you support here. In particular, ensure # that you indicate whether you support Python 2, Python 3 or both. - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - #'Programming Language :: Python :: 3.3', - #'Programming Language :: Python :: 3.4', - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ], # What does your project relate to? keywords="room acoustics signal processing doa beamforming adaptive",