diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index c6e8e08b..d067bd31 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -1,105 +1,186 @@ name: pyroomacoustics -on: [push, pull_request] +on: + push: + branches: [master] + tags: ["v*", "test-*"] + pull_request: + types: [opened, synchronize, reopened, labeled] + workflow_dispatch: -jobs: - build: +permissions: + contents: read - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - max-parallel: 12 - matrix: - # switch temporarily to windows-2019 due to a breaking - # change making mutex constexpr - # a crash occurs if python and the extension are built - # with different versions - # over time, this should hopefully resolves itself - # ref: https://github.com/microsoft/STL/issues/4875 - os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest] - python-version: [3.9, "3.10", "3.11", "3.12", "3.13", "3.14"] - exclude: - - os: macos-latest - python-version: 3.8 - - os: macos-latest - python-version: 3.9 +jobs: + setup-sofa: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - # ➡️ CRITICAL FIX: Set a short temporary directory - - name: Set short temp path for Windows build - if: matrix.os == 'windows-latest' - shell: powershell - run: | - $short_temp = "C:\T" - mkdir $short_temp -Force - echo "TEMP=$short_temp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "TMP=$short_temp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - name: Checkout submodules - shell: bash - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - name: Cache SOFA data + uses: actions/cache@v4 + with: + path: pyroomacoustics/data/sofa + key: sofa-data-${{ hashFiles('pyroomacoustics/data/sofa_files.json') }} + + build_sdist: + needs: setup-sofa + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v6 with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip + python-version: "3.9" + - name: Build sdist run: | python -m pip install --upgrade pip - - name: Workaround for windows and python 3.8 - if: matrix.os == 'windows-latest' && matrix.python-version == 3.8 - run: | - pip install netCDF4<=1.5.8 - # There is no binary package of netCF4>=1.6.0 for windows and python 3.7 - # the largest supported version is 1.5.8 - - name: Install dependencies - run: | - pip install -r requirements.txt - - name: Build package - run: | - python -m pip install -e . - - name: Test with pytest - run: | - pip install -U pytest setuptools build wheel twine - pytest - - name: Test the universal wheels - if: matrix.os == 'ubuntu-latest' - run: | + pip install -U setuptools setuptools_scm build twine python -m build --sdist twine check dist/* - - name: Test the binary wheels - if: matrix.os != 'ubuntu-latest' - run: | - 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' - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - twine upload --skip-existing dist/* - - name: Publish bdist to pypi - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') && matrix.os != 'ubuntu-latest' - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - twine upload --skip-existing dist/* - - name: Publish sdist to pypi-test - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/test-') && matrix.os == 'ubuntu-latest' + - uses: actions/upload-artifact@v6 + with: + name: sdist + path: dist/*.tar.gz + + build_wheels_pr: + if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'full-build') + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + cibw_build: "cp314-manylinux_x86_64" + cibw_archs: "x86_64" + - os: macos-latest + cibw_build: "cp314-macosx_universal2" + cibw_archs: "universal2" + - os: windows-latest + cibw_build: "cp314-win_amd64" + cibw_archs: "AMD64" + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + fetch-depth: 0 + - name: Restore SOFA data + uses: actions/cache/restore@v4 + with: + path: pyroomacoustics/data/sofa + key: sofa-data-${{ hashFiles('pyroomacoustics/data/sofa_files.json') }} + - uses: pypa/cibuildwheel@v3.4.0 env: - TWINE_USERNAME: ${{ secrets.PYPITEST_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPITEST_PASSWORD }} - TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/ - run: | - twine upload --skip-existing dist/* - - name: Publish bdist to pypi-test - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/test-') && matrix.os != 'ubuntu-latest' + CIBW_BUILD: ${{ matrix.cibw_build }} + CIBW_ARCHS: ${{ matrix.cibw_archs }} + CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 + CIBW_TEST_REQUIRES: "pytest numpy scipy matplotlib python-sofa soxr" + CIBW_TEST_COMMAND: "pytest {project}/tests" + CIBW_ENVIRONMENT: PYROOMACOUSTICS_DATA_PATH={project}/pyroomacoustics/data/sofa + + build_wheels: + needs: setup-sofa + if: >- + github.event_name == 'push' || + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'full-build')) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + # Linux x86_64 + - { os: ubuntu-latest, python: "cp39-*", arch: "x86_64" } + - { os: ubuntu-latest, python: "cp310-*", arch: "x86_64" } + - { os: ubuntu-latest, python: "cp311-*", arch: "x86_64" } + - { os: ubuntu-latest, python: "cp312-*", arch: "x86_64" } + - { os: ubuntu-latest, python: "cp313-*", arch: "x86_64" } + - { os: ubuntu-latest, python: "cp314-*", arch: "x86_64" } + # Linux aarch64 + - { os: ubuntu-latest, python: "cp311-*", arch: "aarch64" } + - { os: ubuntu-latest, python: "cp312-*", arch: "aarch64" } + - { os: ubuntu-latest, python: "cp313-*", arch: "aarch64" } + - { os: ubuntu-latest, python: "cp314-*", arch: "aarch64" } + # MacOS (universal2 builds both x86_64 and arm64) + - { os: macos-latest, python: "cp39-*", arch: "universal2" } + - { os: macos-latest, python: "cp310-*", arch: "universal2" } + - { os: macos-latest, python: "cp311-*", arch: "universal2" } + - { os: macos-latest, python: "cp312-*", arch: "universal2" } + - { os: macos-latest, python: "cp313-*", arch: "universal2" } + - { os: macos-latest, python: "cp314-*", arch: "universal2" } + # Windows + - { os: windows-latest, python: "cp39-*", arch: "AMD64" } + - { os: windows-latest, python: "cp310-*", arch: "AMD64" } + - { os: windows-latest, python: "cp311-*", arch: "AMD64" } + - { os: windows-latest, python: "cp312-*", arch: "AMD64" } + - { os: windows-latest, python: "cp313-*", arch: "AMD64" } + - { os: windows-latest, python: "cp314-*", arch: "AMD64" } + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + fetch-depth: 0 + - name: Set up QEMU + if: runner.os == 'Linux' && matrix.arch == 'aarch64' + uses: docker/setup-qemu-action@v3 + with: + platforms: all + - name: Restore SOFA data + uses: actions/cache/restore@v4 + with: + path: pyroomacoustics/data/sofa + key: sofa-data-${{ hashFiles('pyroomacoustics/data/sofa_files.json') }} + - uses: pypa/cibuildwheel@v3.4.0 env: - TWINE_USERNAME: ${{ secrets.PYPITEST_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPITEST_PASSWORD }} - TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/ - run: | - twine upload --skip-existing dist/* + CIBW_BUILD: ${{ matrix.python }} + CIBW_ARCHS: ${{ matrix.arch }} + CIBW_SKIP: "*-musllinux_*" + CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 + CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28 + CIBW_TEST_REQUIRES: "pytest numpy scipy matplotlib python-sofa soxr" + CIBW_TEST_COMMAND: "pytest {project}/tests" + CIBW_TEST_SKIP: "cp314-*" + CIBW_ENVIRONMENT: PYROOMACOUSTICS_DATA_PATH={project}/pyroomacoustics/data/sofa + - uses: actions/upload-artifact@v6 + with: + name: cibw-wheels-${{ matrix.os }}-${{ matrix.arch }}-${{ strategy.job-index }} + path: wheelhouse/*.whl + + publish: + needs: [build_sdist, build_wheels] + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') + environment: pypi + permissions: + id-token: write # MANDATORY for OIDC publishing + steps: + - uses: actions/download-artifact@v4 + with: + path: dist + merge-multiple: true + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + verbose: true + attestations: false + + publish-test: + needs: [build_sdist, build_wheels] + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/test-') + environment: testpypi + permissions: + id-token: write # MANDATORY for OIDC publishing + steps: + - uses: actions/download-artifact@v4 + with: + path: dist + merge-multiple: true + - name: Publish to PyPI Test + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + verbose: true + attestations: false diff --git a/.gitignore b/.gitignore index bd81b87b..08d6525b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ pyroomacoustics.egg-info/ pyroomacoustics/build_rir.c pyroomacoustics/**/*.so pyroomacoustics/directivities/tests/data/*.pdf +# version file generated by setuptools_scm +pyroomacoustics/version.py diff --git a/.gitmodules b/.gitmodules index 05df7510..e69de29b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +0,0 @@ -[submodule "pyroomacoustics/libroom_src/ext/eigen"] - path = pyroomacoustics/libroom_src/ext/eigen - url = https://github.com/eigenteam/eigen-git-mirror.git -[submodule "pyroomacoustics/libroom_src/ext/nanoflann"] - path = pyroomacoustics/libroom_src/ext/nanoflann - url = https://github.com/jlblancoc/nanoflann.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d92b6c9..e6800ab1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,13 +6,13 @@ repos: rev: 7.0.0 hooks: - id: isort - files: ^(pyroomacoustics/|examples/|setup\.py) + files: ^(pyroomacoustics/|examples/|tests/|setup\.py) - repo: https://github.com/psf/black rev: 26.1.0 hooks: - id: black - files: ^(pyroomacoustics/|examples/|setup\.py) + files: ^(pyroomacoustics/|examples/|tests/|setup\.py) # - repo: https://github.com/pycqa/flake8 # rev: 7.3.0 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9caa6361..0367ff39 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,7 +11,18 @@ adheres to `Semantic Versioning `_. `Unreleased`_ ------------- -Nothing yet. +Changed +~~~~~~~ + +- Modernized the build system to use ``pyproject.toml`` and ``CMake``. +- External dependencies (``Eigen``, ``nanoflann``, ``pybind11``) are now + automatically managed via CMake's ``FetchContent``. +- Switched to dynamic versioning using ``setuptools_scm``. +- Relocated the test suite from the source package to a top-level ``tests/`` directory. +- Update the continuous integration to use cibuildwheel to handle all platforms + including manylinux. +- The location of the SOFA files can be specified by the + ``PYROOMACOUSTICS_DATA_PATH`` environment variable. `0.10.0`_ - 2026-04-01 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..56c2d0ad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.15) +set(CMAKE_POLICY_VERSION_MINIMUM 3.5) + +project(pyroomacoustics) + +# Find pybind11 (handled by external/CMakeLists.txt via FetchContent) +set(PYBIND11_FINDPYTHON ON) + +# adds the external dependencies +add_subdirectory(external) + +# Source directory for libroom +set(LIBROOM_SRC_DIR pyroomacoustics/libroom_src) + +# Collect source files +set(LIBROOM_SOURCES + ${LIBROOM_SRC_DIR}/libroom.cpp +) + +# Define the extension module +pybind11_add_module(libroom ${LIBROOM_SOURCES}) + +# Include directories +target_include_directories(libroom PRIVATE + . + ${LIBROOM_SRC_DIR} +) + +# Link dependencies from FetchContent +target_link_libraries(libroom PRIVATE + Eigen3::Eigen + nanoflann::nanoflann +) + +# Compile options +if(MSVC) + target_compile_options(libroom PRIVATE /EHsc) +else() + target_compile_options(libroom PRIVATE -O3 -Wall -fvisibility=hidden) +endif() + +# Eigen definitions +target_compile_definitions(libroom PRIVATE EIGEN_MPL2_ONLY EIGEN_NO_DEBUG) + +# Setting the output name and location +set_target_properties(libroom PROPERTIES + PREFIX "" + OUTPUT_NAME "libroom" +) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 47bcf57c..d25b0eec 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -24,16 +24,24 @@ We try to stick to `PEP8 `__ as much as possible. Variables, functions, modules and packages should be in lowercase with underscores. Class names in CamelCase. -We use `Black `__ to format the code and `isort `__ to sort the imports. -The format will be automatically checked when doing a pull request so it is -recommended to regularly run Black on the code. -Please format your code as follows prior to commiting. +We use `pre-commit `__ to manage code quality hooks, +including `Black `__ for formatting and +`isort `__ for sorting imports. +The hooks will be automatically checked during pull requests. + +To set up the pre-commit hooks locally: + +.. code-block:: shell + + pip install pre-commit + pre-commit install + +Once installed, the hooks will run automatically on every commit. +You can also run them manually on all files: .. code-block:: shell - pip install black isort - black . - isort --profile black . + pre-commit run --all-files Documentation ~~~~~~~~~~~~~ @@ -51,79 +59,56 @@ We recommend the following steps for generating the documentation: - Build and view the documentation locally with: ``make html`` - Open in your browser: ``docs/_build/html/index.html`` -Develop Locally -~~~~~~~~~~~~~~~ - -It can be convenient to develop and run tests locally. In contrast to only +It can be convenient to develop and run tests locally. In contrast to only using the package, you will then also need to compile the C++ extension for -that. On Mac and Linux, GCC is required, while Visual C++ 14.0 is necessary for -`windows `__. - -1. Get the source code. Use recursive close so that Eigen (a sub-module of this - repository) is also downloaded. - - .. code-block:: shell +that. - git clone --recursive git@github.com:LCAV/pyroomacoustics.git +Requirements: +- C++ compiler: GCC or Clang on Mac/Linux, Visual C++ 14.0+ on Windows. +- **CMake** (version 3.10 or higher). +- **pre-commit** - Alternatively, you can clone without the `--recursive` flag and directly - install the Eigen library. For macOS, you can find installation instruction - here: https://stackoverflow.com/a/35658421. After installation you can - create a symbolic link as such: - - .. code-block:: shell - - ln -s PATH_TO_EIGEN pyroomacoustics/libroom_src/ext/eigen/Eigen - -2. Install a few pre-requisites - - .. code-block:: shell - - pip install numpy Cython pybind11 - -3. Compile locally +1. Get the source code. .. code-block:: shell - python setup.py build_ext --inplace - - On recent Mac OS (Mojave), it is necessary in some cases to add a - higher deployment target + git clone git@github.com:LCAV/pyroomacoustics.git - .. code-block:: shell + External dependencies (`Eigen`, `nanoflann`, `pybind11`) are automatically + downloaded during the build process using CMake's `FetchContent`. - MACOSX_DEPLOYMENT_TARGET=10.9 python setup.py build_ext --inplace +2. Install in editable mode. -4. Update ``$PYTHONPATH`` so that python knows where to find the local package + Editable mode is recommended for local development as it correctly links + the source files and compiled extensions. .. code-block:: shell - # Linux/Mac - export PYTHONPATH=:$PYTHONPATH + pip install -U -e . - For windows, see `this question `__ - on stackoverflow. + The build process uses CMake to compile the C++ extensions. + The ``-U`` flag ensures that the package is upgraded to the latest version. + Make sure to re-run this command when changing the C++ code. -5. Install the dependencies listed in ``requirements.txt`` + On macOS, if necessary, you can set the deployment target: .. code-block:: shell - pip install -r requirements.txt + MACOSX_DEPLOYMENT_TARGET=11.0 pip install -U -e . -6. Now fire up ``python`` or ``ipython`` and check that the package can be - imported +3. Verify the installation. - .. code-block:: python + .. code-block:: shell - import pyroomacoustics as pra + python -c "import pyroomacoustics as pra; print(pra.__version__)" Unit Tests ~~~~~~~~~~ As much as possible, for every new function added to the code base, add -a short test script in ``pyroomacoustics/tests``. The names of the +a short test script in the top-level ``tests/`` directory. The names of the script and the functions running the test should be prefixed by -``test_``. The tests are started by running ``nosetests`` at the root of +``test_``. The tests are started by running ``pytest`` at the root of the package. How to make a clean pull request @@ -167,18 +152,18 @@ How to deploy a new version to pypi 1. git checkout pypi-release 2. git merge master -3. Change version number in ``pyroomacoustics/version.py`` to new version number vX.Y.Z -4. Edit ``CHANGELOG.rst`` as follows +3. Edit ``CHANGELOG.rst`` as follows - Add new title ``X.Y.Z_ - YEAR-MONTH-DAY`` under ``Unreleased``, add "Nothing yet" in the unreleased section. - - Edit appropriately the lists of links at the bottom of the file. -5. git commit -6. git tag vX.Y.Z -7. git push origin vX.Y.Z -8. git push -9. git checkout master -10. git merge pypi-release -11. git push origin master + - Edit appropriately the list of links at the bottom of the file. +4. git commit +5. Tag the new version (e.g., vX.Y.Z). Version strings are automatically + generated from git tags using `setuptools_scm`. +6. git push origin vX.Y.Z +7. git push +8. git checkout master +9. git merge pypi-release +10. git push origin master Reference --------- diff --git a/MANIFEST.in b/MANIFEST.in index c497c5bf..db60ae10 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,28 +7,35 @@ include pyroomacoustics/libroom_src/*.h include pyroomacoustics/libroom_src/*.hpp include pyroomacoustics/libroom_src/*.cpp -# The compiled extension code rely on Eigen and nanoflann, -# which are included -include pyroomacoustics/libroom_src/ext/eigen/COPYING.* -graft pyroomacoustics/libroom_src/ext/eigen/Eigen -graft pyroomacoustics/libroom_src/ext/nanoflann/include +# CMake build files +include CMakeLists.txt +graft external include pyproject.toml include requirements.txt include LICENSE # Keep the test files too -graft pyroomacoustics/tests -graft pyroomacoustics/adaptive/tests -graft pyroomacoustics/bss/tests -graft pyroomacoustics/datasets/tests -graft pyroomacoustics/denoise/tests -graft pyroomacoustics/directivities/tests -graft pyroomacoustics/doa/tests -graft pyroomacoustics/experimental/tests -graft pyroomacoustics/libroom_src/tests -graft pyroomacoustics/phase/tests -graft pyroomacoustics/transform/tests +graft tests +graft tests/adaptive +graft tests/bss +graft tests/datasets +graft tests/denoise +graft tests/directivities +graft tests/doa +graft tests/experimental +graft tests/libroom +graft tests/phase +graft tests/transform global-exclude *.py[co] global-exclude __pycache__ + +# Exclude large data files from sdist to keep it under 100MB +recursive-exclude pyroomacoustics/data/sofa *.sofa +recursive-exclude examples * +recursive-exclude notebooks * +recursive-exclude logo * +recursive-exclude offline_packages * +recursive-exclude docs * +recursive-exclude build_debug * diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 00000000..4df7d600 --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,37 @@ +include(FetchContent) + +# eigen +FetchContent_Declare( + eigen + GIT_REPOSITORY https://gitlab.com/libeigen/eigen + GIT_TAG 5.0.1 +) + +# nanoflann +FetchContent_Declare( + nanoflann + GIT_REPOSITORY https://github.com/jlblancoc/nanoflann + GIT_TAG v1.9.0 +) + +# pybind11 +FetchContent_Declare( + pybind11 + GIT_REPOSITORY https://github.com/pybind/pybind11 + GIT_TAG v3.0.1 +) + +# eigen +set(EIGEN_BUILD_PKGCONFIG OFF CACHE BOOL "Disable Eigen pkg-config") +set(EIGEN_BUILD_TESTING OFF CACHE BOOL "Disable Eigen testing") +set(BUILD_TESTING OFF CACHE BOOL "Disable testing") + +# nanoflann +set(NANOFLANN_BUILD_EXAMPLES OFF CACHE BOOL "Disable nanoflann examples" FORCE) +set(NANOFLANN_BUILD_TESTS OFF CACHE BOOL "Disable nanoflann tests" FORCE) +set(BUILD_BENCHMARKS OFF CACHE BOOL "Disable nanoflann benchmarks" FORCE) + +# pybind11 +set(PYBIND11_TEST OFF CACHE BOOL "Disable pybind11 tests") + +FetchContent_MakeAvailable(eigen nanoflann pybind11) diff --git a/pyproject.toml b/pyproject.toml index d6903457..39f30b4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,78 @@ [build-system] -# Minimum requirements for the build system to execute. -requires = ["setuptools", "wheel", "numpy>=1.13.0", "Cython", "pybind11>=2.2"] # PEP 508 specifications. +requires = ["setuptools>=61", "setuptools-scm>=8", "wheel", "numpy>=1.13.0", "Cython", "cmake"] +build-backend = "setuptools.build_meta" + +[project] +name = "pyroomacoustics" +dynamic = ["version", "readme"] +description = "A simple framework for room acoustics and audio processing in Python." +authors = [ + { name = "Laboratory for Audiovisual Communications, EPFL", email = "fakufaku@gmail.ch" } +] +license = { file = "LICENSE" } +keywords = ["room", "acoustics", "signal processing", "doa", "beamforming", "adaptive"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "Intended Audience :: Information Technology", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Multimedia :: Sound/Audio :: Speech", + "Topic :: Multimedia :: Sound/Audio :: Analysis", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] +dependencies = [ + "Cython", + "numpy>=1.13.0", + "scipy>=0.18.0", +] +requires-python = ">=3.9" + +[project.urls] +Homepage = "https://github.com/LCAV/pyroomacoustics" +Repository = "https://github.com/LCAV/pyroomacoustics.git" +Documentation = "https://pyroomacoustics.readthedocs.io/en/pypi-release/" +Issues = "https://github.com/LCAV/pyroomacoustics/issues" +Changelog = "https://github.com/LCAV/pyroomacoustics/blob/master/CHANGELOG.rst" + + +[tool.setuptools.dynamic] +readme = { file = ["README.rst"], content-type = "text/x-rst" } + +[tool.setuptools] +packages = [ + "pyroomacoustics", + "pyroomacoustics.adaptive", + "pyroomacoustics.bss", + "pyroomacoustics.datasets", + "pyroomacoustics.denoise", + "pyroomacoustics.directivities", + "pyroomacoustics.doa", + "pyroomacoustics.experimental", + "pyroomacoustics.phase", + "pyroomacoustics.random", + "pyroomacoustics.simulation", + "pyroomacoustics.transform", +] + +[tool.setuptools.package-data] +pyroomacoustics = [ + "*.pxd", + "*.pyx", + "data/materials.json", + "data/sofa_files.json", +] + +[tool.setuptools_scm] +write_to = "pyroomacoustics/version.py" [tool.pytest.ini_options] +testpaths = ["tests"] filterwarnings = [ 'ignore:Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.:UserWarning' ] diff --git a/pyroomacoustics/datasets/cmu_arctic.py b/pyroomacoustics/datasets/cmu_arctic.py index f9836197..a20f2dcb 100644 --- a/pyroomacoustics/datasets/cmu_arctic.py +++ b/pyroomacoustics/datasets/cmu_arctic.py @@ -210,7 +210,7 @@ def build_corpus(self, **kwargs): speaker=speaker, tag=tag, text=info["text"], - **cmu_arctic_speakers[speaker] + **cmu_arctic_speakers[speaker], ) # it there is a match, add it diff --git a/pyroomacoustics/datasets/sofa.py b/pyroomacoustics/datasets/sofa.py index 6e2594b0..9f6e3f1f 100644 --- a/pyroomacoustics/datasets/sofa.py +++ b/pyroomacoustics/datasets/sofa.py @@ -67,9 +67,15 @@ for more details. + +The default location for the SOFA files is in the ``data/sofa`` folder of +the ``pyroomacoustics`` package. This location can be overridden by setting the +environment variable ``PYROOMACOUSTICS_DATA_PATH`` to a different path. + """ import json +import os import typing as tp from dataclasses import dataclass from pathlib import Path @@ -77,7 +83,9 @@ from .utils import AttrDict, download_multiple _pra_data_folder = Path(__file__).parents[1] / "data" -DEFAULT_SOFA_PATH = _pra_data_folder / "sofa" +DEFAULT_SOFA_PATH = Path( + os.environ.get("PYROOMACOUSTICS_DATA_PATH", _pra_data_folder / "sofa") +) SOFA_INFO = _pra_data_folder / "sofa_files.json" _DIRPAT_FILES = [ diff --git a/pyroomacoustics/directivities/measured.py b/pyroomacoustics/directivities/measured.py index 894bd6eb..900af3dc 100644 --- a/pyroomacoustics/directivities/measured.py +++ b/pyroomacoustics/directivities/measured.py @@ -301,8 +301,9 @@ def plot(self, freq_bin=0, n_grid=100, ax=None, depth=False, offset=None): Parameters ---------- - freq_bin: int - The frequency bin to plot + freq_bin: int or float + The frequency bin to plot if an int. Normalized frequency ``freq_hz / fs`` + if a float. n_grid: int The number of points to use for the interpolation grid ax: matplotlib.axes.Axes, optional @@ -321,6 +322,14 @@ def plot(self, freq_bin=0, n_grid=100, ax=None, depth=False, offset=None): """ import matplotlib.pyplot as plt + if isinstance(freq_bin, float): + n_fft = self._irs.shape[-1] + freq_bin = int(freq_bin * n_fft) + elif not isinstance(freq_bin, int): + raise TypeError( + f"freq_bin should be of type int or float (got {type(freq_bin)})." + ) + cart = self._grid.cartesian.T length = np.abs(np.fft.rfft(self._irs, axis=-1)[:, freq_bin]) diff --git a/pyroomacoustics/doa/cssm.py b/pyroomacoustics/doa/cssm.py index c40adcdb..9f4ce7ba 100644 --- a/pyroomacoustics/doa/cssm.py +++ b/pyroomacoustics/doa/cssm.py @@ -59,7 +59,7 @@ def __init__( azimuth=None, colatitude=None, num_iter=5, - **kwargs + **kwargs, ): MUSIC.__init__( self, @@ -72,7 +72,7 @@ def __init__( r=r, azimuth=azimuth, colatitude=colatitude, - **kwargs + **kwargs, ) self.iter = num_iter diff --git a/pyroomacoustics/doa/doa.py b/pyroomacoustics/doa/doa.py index 132b70cb..31ea4578 100644 --- a/pyroomacoustics/doa/doa.py +++ b/pyroomacoustics/doa/doa.py @@ -189,7 +189,7 @@ def __init__( n_grid=None, dim=2, *args, - **kwargs + **kwargs, ): if dim > L.shape[0]: raise ValueError("Microphones locations missing dimensions.") diff --git a/pyroomacoustics/doa/frida.py b/pyroomacoustics/doa/frida.py index 6e51a0e6..1c1dac57 100644 --- a/pyroomacoustics/doa/frida.py +++ b/pyroomacoustics/doa/frida.py @@ -91,7 +91,7 @@ def __init__( verbose=False, symb=True, use_cache=False, - **kwargs + **kwargs, ): DOA.__init__(self, L, fs, nfft, c=c, num_src=num_src, mode="far", **kwargs) diff --git a/pyroomacoustics/doa/music.py b/pyroomacoustics/doa/music.py index 07cf6a6d..05589204 100644 --- a/pyroomacoustics/doa/music.py +++ b/pyroomacoustics/doa/music.py @@ -53,7 +53,7 @@ def __init__( azimuth=None, colatitude=None, frequency_normalization=False, - **kwargs + **kwargs, ): DOA.__init__( self, @@ -66,7 +66,7 @@ def __init__( r=r, azimuth=azimuth, colatitude=colatitude, - **kwargs + **kwargs, ) self.Pssl = None diff --git a/pyroomacoustics/doa/normmusic.py b/pyroomacoustics/doa/normmusic.py index b91a1eb1..d6e0bc2d 100644 --- a/pyroomacoustics/doa/normmusic.py +++ b/pyroomacoustics/doa/normmusic.py @@ -48,7 +48,7 @@ def __init__( azimuth=None, colatitude=None, frequency_normalization=True, - **kwargs + **kwargs, ): super().__init__( L, @@ -61,5 +61,5 @@ def __init__( azimuth, colatitude, frequency_normalization, - **kwargs + **kwargs, ) diff --git a/pyroomacoustics/doa/plotters.py b/pyroomacoustics/doa/plotters.py index 764f3d24..8d134bd3 100644 --- a/pyroomacoustics/doa/plotters.py +++ b/pyroomacoustics/doa/plotters.py @@ -397,7 +397,7 @@ def sph_plot_diracs( colatitude_grid=None, azimuth_grid=None, file_name="sph_recon_2d_dirac.pdf", - **kwargs + **kwargs, ): """ This function plots the dirty image with sources locations on diff --git a/pyroomacoustics/doa/srp.py b/pyroomacoustics/doa/srp.py index 7bc8438e..b206a7a0 100644 --- a/pyroomacoustics/doa/srp.py +++ b/pyroomacoustics/doa/srp.py @@ -49,7 +49,7 @@ def __init__( r=None, azimuth=None, colatitude=None, - **kwargs + **kwargs, ): DOA.__init__( self, @@ -62,7 +62,7 @@ def __init__( r=r, azimuth=azimuth, colatitude=colatitude, - **kwargs + **kwargs, ) self.num_pairs = self.M * (self.M - 1) / 2 diff --git a/pyroomacoustics/doa/tools_fri_doa_plane.py b/pyroomacoustics/doa/tools_fri_doa_plane.py index 255685b4..6cfaee88 100644 --- a/pyroomacoustics/doa/tools_fri_doa_plane.py +++ b/pyroomacoustics/doa/tools_fri_doa_plane.py @@ -1738,7 +1738,7 @@ def pt_src_recon_multiband( G_lst=None, GtG_lst=None, GtG_inv_lst=None, - **kwargs + **kwargs, ): """ reconstruct point sources on the circle from the visibility measurements @@ -1920,7 +1920,7 @@ def pt_src_recon( update_G=False, verbose=False, signal_type="visibility", - **kwargs + **kwargs, ): """ reconstruct point sources on the circle from the visibility measurements @@ -2026,7 +2026,7 @@ def pt_src_recon_rotate( num_rotation=1, verbose=False, signal_type="visibility", - **kwargs + **kwargs, ): """ reconstruct point sources on the circle from the visibility measurements. diff --git a/pyroomacoustics/doa/tops.py b/pyroomacoustics/doa/tops.py index 7a9eb0c4..eb2d6f91 100644 --- a/pyroomacoustics/doa/tops.py +++ b/pyroomacoustics/doa/tops.py @@ -59,7 +59,7 @@ def __init__( r=None, azimuth=None, colatitude=None, - **kwargs + **kwargs, ): MUSIC.__init__( self, @@ -72,7 +72,7 @@ def __init__( r=r, azimuth=azimuth, colatitude=colatitude, - **kwargs + **kwargs, ) def _process(self, X): diff --git a/pyroomacoustics/doa/waves.py b/pyroomacoustics/doa/waves.py index e0510262..d87ac4cd 100644 --- a/pyroomacoustics/doa/waves.py +++ b/pyroomacoustics/doa/waves.py @@ -58,7 +58,7 @@ def __init__( azimuth=None, colatitude=None, num_iter=5, - **kwargs + **kwargs, ): MUSIC.__init__( self, @@ -71,7 +71,7 @@ def __init__( r=r, azimuth=azimuth, colatitude=colatitude, - **kwargs + **kwargs, ) self.iter = num_iter diff --git a/pyroomacoustics/libroom_src/common.hpp b/pyroomacoustics/libroom_src/common.hpp index 8d1ef382..664ae1eb 100644 --- a/pyroomacoustics/libroom_src/common.hpp +++ b/pyroomacoustics/libroom_src/common.hpp @@ -29,6 +29,8 @@ #define __COMMON_HPP__ #include +#include +#include #include extern float libroom_eps; // epsilon is the precision for floating point computations. It is defined in libroom.cpp diff --git a/pyroomacoustics/libroom_src/ext/eigen b/pyroomacoustics/libroom_src/ext/eigen deleted file mode 160000 index a1b9c26c..00000000 --- a/pyroomacoustics/libroom_src/ext/eigen +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a1b9c26c5e62cb8c17836e601edd64b92aa8e5ae diff --git a/pyroomacoustics/libroom_src/ext/nanoflann b/pyroomacoustics/libroom_src/ext/nanoflann deleted file mode 160000 index b3e81831..00000000 --- a/pyroomacoustics/libroom_src/ext/nanoflann +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b3e81831b847a77473e0da2ad7ee266b4f4e0d9a diff --git a/pyroomacoustics/phase/gl.py b/pyroomacoustics/phase/gl.py index e31d02a4..98df942c 100644 --- a/pyroomacoustics/phase/gl.py +++ b/pyroomacoustics/phase/gl.py @@ -159,7 +159,7 @@ def griffin_lim( hop=hop, analysis_window=analysis_window, synthesis_window=synthesis_window, - **stft_kwargs + **stft_kwargs, ) # Initialize the signal diff --git a/pyroomacoustics/transform/stft.py b/pyroomacoustics/transform/stft.py index 73dd75f2..30c62ccb 100644 --- a/pyroomacoustics/transform/stft.py +++ b/pyroomacoustics/transform/stft.py @@ -84,7 +84,7 @@ def __init__( transform="numpy", streaming=True, precision="double", - **kwargs + **kwargs, ): # initialize parameters self.num_samples = N # number of samples per frame diff --git a/pyroomacoustics/utilities.py b/pyroomacoustics/utilities.py index 3b9bf9ea..9837e9a0 100644 --- a/pyroomacoustics/utilities.py +++ b/pyroomacoustics/utilities.py @@ -26,6 +26,7 @@ import fractions import functools import itertools +import math import warnings import numpy as np @@ -935,9 +936,16 @@ def resample(data, old_fs, new_fs, backend=None, *args, **kwargs): if backend == "soxr": resampled_data = soxr.resample(data, old_fs, new_fs, *args, **kwargs) elif backend == "samplerate": - resampled_data = samplerate.resample( - data, new_fs / old_fs, "sinc_best", *args, **kwargs - ) + # Split into arrays of 128 channels to accomodate a limitation of samplerate. + block = 128 + data_inputs = [ + data[:, i : i + block].copy() for i in range(0, data.shape[1], block) + ] + data_outputs = [ + samplerate.resample(d, new_fs / old_fs, "sinc_best", *args, **kwargs) + for d in data_inputs + ] + resampled_data = np.concatenate(data_outputs, axis=1) else: # first, simplify the fraction rate_frac = fractions.Fraction(int(new_fs), int(old_fs)) @@ -947,7 +955,7 @@ def resample(data, old_fs, new_fs, backend=None, *args, **kwargs): down=rate_frac.denominator, axis=0, *args, - **kwargs + **kwargs, ) # restore the original shape of the data diff --git a/pyroomacoustics/version.py b/pyroomacoustics/version.py deleted file mode 100644 index 61fb31ca..00000000 --- a/pyroomacoustics/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.10.0" diff --git a/setup.py b/setup.py index 6a2246ba..71a26dfc 100644 --- a/setup.py +++ b/setup.py @@ -1,240 +1,166 @@ -#!/usr/bin/env python -from __future__ import print_function +# Compile and install the python-samplerate package +# +# Script based on the cmake_example of pybind11 by Dean Moldovan +# https://github.com/pybind/cmake_example import os +import subprocess import sys +from pathlib import Path -# To use a consistent encoding -from os import path - -# import version from file -with open("pyroomacoustics/version.py") as f: - exec(f.read()) - -try: - from setuptools import Extension, distutils, setup - from setuptools.command.build_ext import build_ext -except ImportError: - print("Setuptools unavailable. Falling back to distutils.") - import distutils - from distutils.command.build_ext import build_ext - from distutils.core import setup - from distutils.extension import Extension - - -class get_pybind_include(object): - """Helper class to determine the pybind11 include path - - The purpose of this class is to postpone importing pybind11 - until it is actually installed, so that the ``get_include()`` - method can be invoked.""" - - def __init__(self, user=False): - self.user = user - - def __str__(self): - import pybind11 - - return pybind11.get_include(self.user) - - -# build C extension for image source model -libroom_src_dir = "pyroomacoustics/libroom_src" -libroom_files = [ - os.path.join(libroom_src_dir, f) - for f in [ - "room.hpp", - "room.cpp", - "wall.hpp", - "wall.cpp", - "microphone.hpp", - "geometry.hpp", - "geometry.cpp", - "common.hpp", - "rir_builder.cpp", - "rir_builder.hpp", - "libroom.cpp", - "threadpool.hpp", - ] -] -ext_modules = [ - Extension( - "pyroomacoustics.libroom", - [os.path.join(libroom_src_dir, f) for f in ["libroom.cpp"]], - depends=libroom_files, - include_dirs=[ - ".", - libroom_src_dir, - str(get_pybind_include()), - str(get_pybind_include(user=True)), - os.path.join(libroom_src_dir, "ext/eigen"), - os.path.join(libroom_src_dir, "ext/nanoflann/include"), - ], - language="c++", - extra_compile_args=[ - "-DEIGEN_MPL2_ONLY", - "-Wall", - "-O3", - "-DEIGEN_NO_DEBUG", - ], - ), - Extension( - "pyroomacoustics.build_rir", - ["pyroomacoustics/build_rir.pyx"], - language="c", - extra_compile_args=[], - ), -] - -here = path.abspath(path.dirname(__file__)) - -# Get the long description from the README file -with open(path.join(here, "README.rst"), encoding="utf-8") as f: - long_description = f.read() +from setuptools import Extension, setup +from setuptools.command.build_ext import build_ext +# Convert distutils Windows platform specifiers to CMake -A arguments +PLAT_TO_CMAKE = { + "win32": "Win32", + "win-amd64": "x64", + "win-arm32": "ARM", + "win-arm64": "ARM64", +} -### Build Tools (taken from pybind11 example) ### +# A CMakeExtension needs a sourcedir instead of a file list. +# The name must be the _single_ output extension from the CMake build. +# If you need multiple extensions, see scikit-build. +class CMakeExtension(Extension): + def __init__(self, name: str, sourcedir: str = "") -> None: + super().__init__(name, sources=[]) + self.sourcedir = os.fspath(Path(sourcedir).resolve()) -# As of Python 3.6, CCompiler has a `has_flag` method. -# cf http://bugs.python.org/issue26689 -def has_flag(compiler, flagname): - """Return a boolean indicating whether a flag name is supported on - the specified compiler. - """ - import tempfile - with tempfile.NamedTemporaryFile("w", suffix=".cpp") as f: - f.write("int main (int argc, char **argv) { return 0; }") +class CMakeBuild(build_ext): + def run(self): try: - compiler.compile([f.name], extra_postargs=[flagname]) - except distutils.errors.CompileError: - return False - return True - - -def cpp_flag(compiler): - """Return the -std=c++[11/14] compiler flag. - - The c++14 is prefered over c++11 (when it is available). - """ - if has_flag(compiler, "-std=c++14"): - return "-std=c++14" - elif has_flag(compiler, "-std=c++11"): - return "-std=c++11" - else: - raise RuntimeError( - "Unsupported compiler -- at least C++11 support " "is needed!" + subprocess.check_output(["cmake", "--version"]) + except OSError: + raise RuntimeError( + "CMake must be installed to build the following extensions: " + + ", ".join( + e.name for e in self.extensions if isinstance(e, CMakeExtension) + ) + ) + + super().run() + + def build_extension(self, ext: Extension) -> None: + # This is needed to build the Cython extension. + if not isinstance(ext, CMakeExtension): + super().build_extension(ext) + return + + # Must be in this form due to bug in .resolve() only fixed in Python 3.10+ + ext_fullpath = Path.cwd() / self.get_ext_fullpath(ext.name) + extdir = ext_fullpath.parent.resolve() + + # Using this requires trailing slash for auto-detection & inclusion of + # auxiliary "native" libs + + debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug + cfg = "Debug" if debug else "Release" + + # CMake lets you override the generator - we need to check this. + # Can be set with Conda-Build, for example. + cmake_generator = os.environ.get("CMAKE_GENERATOR", "") + + # EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code + # from Python. + cmake_args = [ + f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}{os.sep}", + f"-DPython_EXECUTABLE={sys.executable}", + f"-DCMAKE_BUILD_TYPE={cfg}", # not used on MSVC, but no harm + ] + build_args = [] + # Adding CMake arguments set as environment variable + # (needed e.g. to build for ARM OSx on conda-forge) + if "CMAKE_ARGS" in os.environ: + cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item] + + # In this example, we pass in the version to C++. You might not need to. + cmake_args += [f"-DPACKAGE_VERSION_INFO={self.distribution.get_version()}"] + + if self.compiler.compiler_type != "msvc": + # Using Ninja-build since it a) is available as a wheel and b) + # multithreads automatically. MSVC would require all variables be + # exported for Ninja to pick it up, which is a little tricky to do. + # Users can override the generator with CMAKE_GENERATOR in CMake + # 3.15+. + if not cmake_generator or cmake_generator == "Ninja": + try: + import ninja + + ninja_executable_path = Path(ninja.BIN_DIR) / "ninja" + cmake_args += [ + "-GNinja", + f"-DCMAKE_MAKE_PROGRAM:FILEPATH={ninja_executable_path}", + ] + except ImportError: + pass + + else: + # Single config generators are handled "normally" + single_config = any(x in cmake_generator for x in {"NMake", "Ninja"}) + + # CMake allows an arch-in-generator style for backward compatibility + contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"}) + + # Specify the arch if using MSVC generator, but only if it doesn't + # contain a backward-compatibility arch spec already in the + # generator name. + if not single_config and not contains_arch: + cmake_args += ["-A", PLAT_TO_CMAKE[self.plat_name]] + + # Multi-config generators have a different way to specify configs + if not single_config: + cmake_args += [ + f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{cfg.upper()}={extdir}" + ] + build_args += ["--config", cfg] + + # When building universal2 wheels, we need to set the architectures for CMake. + if "universal2" in self.plat_name: + cmake_args += ["-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"] + + # Set MACOSX_DEPLOYMENT_TARGET for macOS builds. + if ( + self.plat_name.startswith("macosx-") + and "MACOSX_DEPLOYMENT_TARGET" not in os.environ + ): + target_version = self.plat_name.split("-")[1] + os.environ["MACOSX_DEPLOYMENT_TARGET"] = target_version + + # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level + # across all generators. + if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ: + # self.parallel is a Python 3 only way to set parallel jobs by hand + # using -j in the build_ext call, not supported by pip or PyPA-build. + if hasattr(self, "parallel") and self.parallel: + # CMake 3.12+ only. + build_args += [f"-j{self.parallel}"] + + build_temp = Path(self.build_temp) / ext.name + if not build_temp.exists(): + build_temp.mkdir(parents=True) + + subprocess.run( + ["cmake", ext.sourcedir, *cmake_args], cwd=build_temp, check=True + ) + subprocess.run( + ["cmake", "--build", ".", *build_args], cwd=build_temp, check=True ) -class BuildExt(build_ext): - """A custom build extension for adding compiler-specific options.""" - - c_opts = { - "msvc": ["/EHsc"], - "unix": [], - } - - if sys.platform == "darwin": - c_opts["unix"] += ["-stdlib=libc++", "-mmacosx-version-min=10.7"] - - def build_extensions(self): - ct = self.compiler.compiler_type - opts = self.c_opts.get(ct, []) - if ct == "unix": - opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version()) - opts.append(cpp_flag(self.compiler)) - if has_flag(self.compiler, "-fvisibility=hidden"): - opts.append("-fvisibility=hidden") - elif ct == "msvc": - opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version()) - for ext in self.extensions: - if ext.language == "c++": - ext.extra_compile_args += opts - ext.extra_link_args += opts - build_ext.build_extensions(self) - - -### Build Tools End ### - - -setup_kwargs = dict( - name="pyroomacoustics", - version=__version__, - description="A simple framework for room acoustics and audio processing in Python.", - long_description=long_description, - long_description_content_type="text/x-rst", - author="Laboratory for Audiovisual Communications, EPFL", - author_email="fakufaku@gmail.ch", - url="https://github.com/LCAV/pyroomacoustics", - license="MIT", - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - packages=[ - "pyroomacoustics", - "pyroomacoustics.adaptive", - "pyroomacoustics.bss", - "pyroomacoustics.datasets", - "pyroomacoustics.denoise", - "pyroomacoustics.directivities", - "pyroomacoustics.doa", - "pyroomacoustics.experimental", - "pyroomacoustics.phase", - "pyroomacoustics.random", - "pyroomacoustics.simulation", - "pyroomacoustics.transform", - ], - # Libroom C extension +ext_modules = [ + CMakeExtension("pyroomacoustics.libroom", sourcedir="."), + Extension( + "pyroomacoustics.build_rir", + ["pyroomacoustics/build_rir.pyx"], + language="c", + extra_compile_args=[], + ), +] + +setup( ext_modules=ext_modules, - # Necessary to keep the source files - package_data={ - "pyroomacoustics": [ - "*.pxd", - "*.pyx", - "data/materials.json", - "data/sofa_files.json", - "data/sofa/AKG_c480_c414_CUBE.sofa", - "data/sofa/EM32_Directivity.sofa", - "data/sofa/mit_kemar_large_pinna.sofa", - "data/sofa/mit_kemar_normal_pinna.sofa", - ] - }, - install_requires=[ - "Cython", - "numpy>=1.13.0", - "scipy>=0.18.0", - "pybind11>=2.2", - ], - cmdclass={"build_ext": BuildExt}, # taken from pybind11 example - zip_safe=False, - test_suite="pytest", - tests_require=["pytest"], - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - "Development Status :: 4 - Beta", - # Indicate who your project is intended for - "Intended Audience :: Science/Research", - "Intended Audience :: Information Technology", - "Topic :: Scientific/Engineering :: Information Analysis", - "Topic :: Scientific/Engineering :: Physics", - "Topic :: Multimedia :: Sound/Audio :: Speech", - "Topic :: Multimedia :: Sound/Audio :: Analysis", - # Pick your license as you wish (should match "license" above) - "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 :: 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", + cmdclass={"build_ext": CMakeBuild}, ) - -setup(**setup_kwargs) diff --git a/pyroomacoustics/adaptive/tests/test_adaptive.py b/tests/adaptive/test_adaptive.py similarity index 100% rename from pyroomacoustics/adaptive/tests/test_adaptive.py rename to tests/adaptive/test_adaptive.py diff --git a/pyroomacoustics/adaptive/tests/test_adaptive_frequency.py b/tests/adaptive/test_adaptive_frequency.py similarity index 100% rename from pyroomacoustics/adaptive/tests/test_adaptive_frequency.py rename to tests/adaptive/test_adaptive_frequency.py diff --git a/pyroomacoustics/bss/tests/test_bss.py b/tests/bss/test_bss.py similarity index 91% rename from pyroomacoustics/bss/tests/test_bss.py rename to tests/bss/test_bss.py index 24e0aee5..287470f7 100644 --- a/pyroomacoustics/bss/tests/test_bss.py +++ b/tests/bss/test_bss.py @@ -1,4 +1,5 @@ import unittest +from pathlib import Path import numpy as np from scipy.io import wavfile @@ -8,16 +9,17 @@ np.random.seed(0) # We use several sound samples for each source to have a long enough length +wav_root = Path(__file__).parent / "../../" wav_files = [ [ - "examples/input_samples/cmu_arctic_us_axb_a0004.wav", - "examples/input_samples/cmu_arctic_us_axb_a0005.wav", - "examples/input_samples/cmu_arctic_us_axb_a0006.wav", + wav_root / "examples/input_samples/cmu_arctic_us_axb_a0004.wav", + wav_root / "examples/input_samples/cmu_arctic_us_axb_a0005.wav", + wav_root / "examples/input_samples/cmu_arctic_us_axb_a0006.wav", ], [ - "examples/input_samples/cmu_arctic_us_aew_a0001.wav", - "examples/input_samples/cmu_arctic_us_aew_a0002.wav", - "examples/input_samples/cmu_arctic_us_aew_a0003.wav", + wav_root / "examples/input_samples/cmu_arctic_us_aew_a0001.wav", + wav_root / "examples/input_samples/cmu_arctic_us_aew_a0002.wav", + wav_root / "examples/input_samples/cmu_arctic_us_aew_a0003.wav", ], ] diff --git a/pyroomacoustics/bss/tests/test_trinicon.py b/tests/bss/test_trinicon.py similarity index 89% rename from pyroomacoustics/bss/tests/test_trinicon.py rename to tests/bss/test_trinicon.py index f023ff3d..599c23e2 100644 --- a/pyroomacoustics/bss/tests/test_trinicon.py +++ b/tests/bss/test_trinicon.py @@ -1,19 +1,22 @@ +from pathlib import Path + import numpy as np from scipy.io import wavfile import pyroomacoustics as pra # We use several sound samples for each source to have a long enough length +wav_root = Path(__file__).parent / "../../" wav_files = [ [ - "examples/input_samples/cmu_arctic_us_axb_a0004.wav", - "examples/input_samples/cmu_arctic_us_axb_a0005.wav", - "examples/input_samples/cmu_arctic_us_axb_a0006.wav", + wav_root / "examples/input_samples/cmu_arctic_us_axb_a0004.wav", + wav_root / "examples/input_samples/cmu_arctic_us_axb_a0005.wav", + wav_root / "examples/input_samples/cmu_arctic_us_axb_a0006.wav", ], [ - "examples/input_samples/cmu_arctic_us_aew_a0001.wav", - "examples/input_samples/cmu_arctic_us_aew_a0002.wav", - "examples/input_samples/cmu_arctic_us_aew_a0003.wav", + wav_root / "examples/input_samples/cmu_arctic_us_aew_a0001.wav", + wav_root / "examples/input_samples/cmu_arctic_us_aew_a0002.wav", + wav_root / "examples/input_samples/cmu_arctic_us_aew_a0003.wav", ], ] diff --git a/pyroomacoustics/datasets/tests/test_corpus_base.py b/tests/datasets/test_corpus_base.py similarity index 100% rename from pyroomacoustics/datasets/tests/test_corpus_base.py rename to tests/datasets/test_corpus_base.py diff --git a/pyroomacoustics/datasets/tests/test_download_uncompress.py b/tests/datasets/test_download_uncompress.py similarity index 100% rename from pyroomacoustics/datasets/tests/test_download_uncompress.py rename to tests/datasets/test_download_uncompress.py diff --git a/pyroomacoustics/denoise/tests/test_iterative_wiener.py b/tests/denoise/test_iterative_wiener.py similarity index 100% rename from pyroomacoustics/denoise/tests/test_iterative_wiener.py rename to tests/denoise/test_iterative_wiener.py diff --git a/pyroomacoustics/denoise/tests/test_subspace.py b/tests/denoise/test_subspace.py similarity index 100% rename from pyroomacoustics/denoise/tests/test_subspace.py rename to tests/denoise/test_subspace.py diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414A-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414K-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414N-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c414S-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-cardioid.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-cardioid.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-oneside.npy b/tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-oneside.npy rename to tests/directivities/data/AKG_c480_c414_CUBE-AKG_c480-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_False-cardioid.npy b/tests/directivities/data/EM32_Directivity-EM_32_0-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_False-cardioid.npy rename to tests/directivities/data/EM32_Directivity-EM_32_0-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_False-oneside.npy b/tests/directivities/data/EM32_Directivity-EM_32_0-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_False-oneside.npy rename to tests/directivities/data/EM32_Directivity-EM_32_0-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_True-cardioid.npy b/tests/directivities/data/EM32_Directivity-EM_32_0-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_True-cardioid.npy rename to tests/directivities/data/EM32_Directivity-EM_32_0-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_True-oneside.npy b/tests/directivities/data/EM32_Directivity-EM_32_0-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_0-minphase_True-oneside.npy rename to tests/directivities/data/EM32_Directivity-EM_32_0-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_False-cardioid.npy b/tests/directivities/data/EM32_Directivity-EM_32_31-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_False-cardioid.npy rename to tests/directivities/data/EM32_Directivity-EM_32_31-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_False-oneside.npy b/tests/directivities/data/EM32_Directivity-EM_32_31-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_False-oneside.npy rename to tests/directivities/data/EM32_Directivity-EM_32_31-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_True-cardioid.npy b/tests/directivities/data/EM32_Directivity-EM_32_31-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_True-cardioid.npy rename to tests/directivities/data/EM32_Directivity-EM_32_31-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_True-oneside.npy b/tests/directivities/data/EM32_Directivity-EM_32_31-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/EM32_Directivity-EM_32_31-minphase_True-oneside.npy rename to tests/directivities/data/EM32_Directivity-EM_32_31-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_False-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_False-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_False-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_False-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_True-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_True-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_True-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-AKG_c480_c414_CUBE-AKG_c480-minphase_True-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_False-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_False-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_False-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_False-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_True-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_True-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_True-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-EM32_Directivity-EM_32_31-minphase_True-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-cardioid.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-cardioid.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-oneside.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-oneside.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-cardioid.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-cardioid.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-oneside.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-oneside.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Genelec_8020-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_False-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_False-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_False-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_False-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_True-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_True-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_True-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-AKG_c480_c414_CUBE-AKG_c414K-minphase_True-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_False-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_False-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_False-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_False-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_True-twosides.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_True-twosides.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_True-twosides.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-EM32_Directivity-EM_32_0-minphase_True-twosides.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-cardioid.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-cardioid.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-oneside.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-oneside.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_False-oneside.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-cardioid.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-cardioid.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-cardioid.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-cardioid.npy diff --git a/pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-oneside.npy b/tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-oneside.npy similarity index 100% rename from pyroomacoustics/directivities/tests/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-oneside.npy rename to tests/directivities/data/LSPs_HATS_GuitarCabinets_Akustikmessplatz-Vibrolux_2x10inch-minphase_True-oneside.npy diff --git a/pyroomacoustics/directivities/tests/test_cardioid_energy.py b/tests/directivities/test_cardioid_energy.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_cardioid_energy.py rename to tests/directivities/test_cardioid_energy.py diff --git a/pyroomacoustics/directivities/tests/test_cardioid_energy_distribution.py b/tests/directivities/test_cardioid_energy_distribution.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_cardioid_energy_distribution.py rename to tests/directivities/test_cardioid_energy_distribution.py diff --git a/pyroomacoustics/directivities/tests/test_directive_energy_rt_vs_ism.py b/tests/directivities/test_directive_energy_rt_vs_ism.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_directive_energy_rt_vs_ism.py rename to tests/directivities/test_directive_energy_rt_vs_ism.py diff --git a/pyroomacoustics/directivities/tests/test_harmonics_directivities.py b/tests/directivities/test_harmonics_directivities.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_harmonics_directivities.py rename to tests/directivities/test_harmonics_directivities.py diff --git a/pyroomacoustics/directivities/tests/test_measured_energy_distribution.py b/tests/directivities/test_measured_energy_distribution.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_measured_energy_distribution.py rename to tests/directivities/test_measured_energy_distribution.py diff --git a/pyroomacoustics/directivities/tests/test_omni_global_delay.py b/tests/directivities/test_omni_global_delay.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_omni_global_delay.py rename to tests/directivities/test_omni_global_delay.py diff --git a/pyroomacoustics/directivities/tests/test_sofa_directivities.py b/tests/directivities/test_sofa_directivities.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_sofa_directivities.py rename to tests/directivities/test_sofa_directivities.py diff --git a/pyroomacoustics/directivities/tests/test_source_directivities.py b/tests/directivities/test_source_directivities.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_source_directivities.py rename to tests/directivities/test_source_directivities.py diff --git a/pyroomacoustics/directivities/tests/test_source_directivities_nonshoebox.py b/tests/directivities/test_source_directivities_nonshoebox.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_source_directivities_nonshoebox.py rename to tests/directivities/test_source_directivities_nonshoebox.py diff --git a/pyroomacoustics/directivities/tests/test_source_directivity_flipping.py b/tests/directivities/test_source_directivity_flipping.py similarity index 100% rename from pyroomacoustics/directivities/tests/test_source_directivity_flipping.py rename to tests/directivities/test_source_directivity_flipping.py diff --git a/pyroomacoustics/doa/tests/test_doa.py b/tests/doa/test_doa.py similarity index 100% rename from pyroomacoustics/doa/tests/test_doa.py rename to tests/doa/test_doa.py diff --git a/pyroomacoustics/doa/tests/test_grid.py b/tests/doa/test_grid.py similarity index 100% rename from pyroomacoustics/doa/tests/test_grid.py rename to tests/doa/test_grid.py diff --git a/pyroomacoustics/doa/tests/test_utils.py b/tests/doa/test_utils.py similarity index 100% rename from pyroomacoustics/doa/tests/test_utils.py rename to tests/doa/test_utils.py diff --git a/pyroomacoustics/experimental/tests/test_deconvolution.py b/tests/experimental/test_deconvolution.py similarity index 100% rename from pyroomacoustics/experimental/tests/test_deconvolution.py rename to tests/experimental/test_deconvolution.py diff --git a/pyroomacoustics/experimental/tests/test_measure_rt60.py b/tests/experimental/test_measure_rt60.py similarity index 100% rename from pyroomacoustics/experimental/tests/test_measure_rt60.py rename to tests/experimental/test_measure_rt60.py diff --git a/pyroomacoustics/tests/tests_libroom/test_ccw3p.py b/tests/libroom/test_ccw3p.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_ccw3p.py rename to tests/libroom/test_ccw3p.py diff --git a/pyroomacoustics/tests/tests_libroom/test_geometry_routines.py b/tests/libroom/test_geometry_routines.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_geometry_routines.py rename to tests/libroom/test_geometry_routines.py diff --git a/pyroomacoustics/tests/tests_libroom/test_is_inside_2d_polygon.py b/tests/libroom/test_is_inside_2d_polygon.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_is_inside_2d_polygon.py rename to tests/libroom/test_is_inside_2d_polygon.py diff --git a/pyroomacoustics/tests/tests_libroom/test_microphone.py b/tests/libroom/test_microphone.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_microphone.py rename to tests/libroom/test_microphone.py diff --git a/pyroomacoustics/tests/tests_libroom/test_ray_energy.py b/tests/libroom/test_ray_energy.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_ray_energy.py rename to tests/libroom/test_ray_energy.py diff --git a/pyroomacoustics/tests/tests_libroom/test_room_broadcast_n_bands.py b/tests/libroom/test_room_broadcast_n_bands.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_room_broadcast_n_bands.py rename to tests/libroom/test_room_broadcast_n_bands.py diff --git a/pyroomacoustics/tests/tests_libroom/test_room_construct.py b/tests/libroom/test_room_construct.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_room_construct.py rename to tests/libroom/test_room_construct.py diff --git a/pyroomacoustics/tests/tests_libroom/test_room_walls.py b/tests/libroom/test_room_walls.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_room_walls.py rename to tests/libroom/test_room_walls.py diff --git a/pyroomacoustics/tests/tests_libroom/test_sample_lambertian_reflection.py b/tests/libroom/test_sample_lambertian_reflection.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_sample_lambertian_reflection.py rename to tests/libroom/test_sample_lambertian_reflection.py diff --git a/pyroomacoustics/tests/tests_libroom/test_shoebox_simple.py b/tests/libroom/test_shoebox_simple.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_shoebox_simple.py rename to tests/libroom/test_shoebox_simple.py diff --git a/pyroomacoustics/tests/tests_libroom/test_wall_construct.py b/tests/libroom/test_wall_construct.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_wall_construct.py rename to tests/libroom/test_wall_construct.py diff --git a/pyroomacoustics/tests/tests_libroom/test_wall_intersection.py b/tests/libroom/test_wall_intersection.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_wall_intersection.py rename to tests/libroom/test_wall_intersection.py diff --git a/pyroomacoustics/tests/tests_libroom/test_wall_side_reflect.py b/tests/libroom/test_wall_side_reflect.py similarity index 100% rename from pyroomacoustics/tests/tests_libroom/test_wall_side_reflect.py rename to tests/libroom/test_wall_side_reflect.py diff --git a/pyroomacoustics/phase/tests/test_gl.py b/tests/phase/test_gl.py similarity index 94% rename from pyroomacoustics/phase/tests/test_gl.py rename to tests/phase/test_gl.py index 91d77699..039b5c70 100644 --- a/pyroomacoustics/phase/tests/test_gl.py +++ b/tests/phase/test_gl.py @@ -7,6 +7,7 @@ """ import unittest +from pathlib import Path import numpy as np from scipy.io import wavfile @@ -15,7 +16,9 @@ test_tol = 1e-2 -filename = "examples/input_samples/cmu_arctic_us_axb_a0004.wav" +filename = ( + Path(__file__).parent / "../../examples/input_samples/cmu_arctic_us_axb_a0004.wav" +) fs, audio = wavfile.read(filename) fft_size = 512 diff --git a/pyroomacoustics/random/tests/test_distributions.py b/tests/random/test_distributions.py similarity index 100% rename from pyroomacoustics/random/tests/test_distributions.py rename to tests/random/test_distributions.py diff --git a/pyroomacoustics/random/tests/test_rejection.py b/tests/random/test_rejection.py similarity index 100% rename from pyroomacoustics/random/tests/test_rejection.py rename to tests/random/test_rejection.py diff --git a/pyroomacoustics/random/tests/test_spherical.py b/tests/random/test_spherical.py similarity index 100% rename from pyroomacoustics/random/tests/test_spherical.py rename to tests/random/test_spherical.py diff --git a/pyroomacoustics/tests/test_air_absorption.py b/tests/test_air_absorption.py similarity index 100% rename from pyroomacoustics/tests/test_air_absorption.py rename to tests/test_air_absorption.py diff --git a/pyroomacoustics/tests/test_anechoic_room.py b/tests/test_anechoic_room.py similarity index 100% rename from pyroomacoustics/tests/test_anechoic_room.py rename to tests/test_anechoic_room.py diff --git a/pyroomacoustics/tests/test_angle_function.py b/tests/test_angle_function.py similarity index 100% rename from pyroomacoustics/tests/test_angle_function.py rename to tests/test_angle_function.py diff --git a/pyroomacoustics/tests/test_autocorr.py b/tests/test_autocorr.py similarity index 100% rename from pyroomacoustics/tests/test_autocorr.py rename to tests/test_autocorr.py diff --git a/pyroomacoustics/tests/test_bandpass_filterbank.py b/tests/test_bandpass_filterbank.py similarity index 100% rename from pyroomacoustics/tests/test_bandpass_filterbank.py rename to tests/test_bandpass_filterbank.py diff --git a/pyroomacoustics/tests/test_build_rir.py b/tests/test_build_rir.py similarity index 100% rename from pyroomacoustics/tests/test_build_rir.py rename to tests/test_build_rir.py diff --git a/pyroomacoustics/tests/test_create_noisy_signal.py b/tests/test_create_noisy_signal.py similarity index 99% rename from pyroomacoustics/tests/test_create_noisy_signal.py rename to tests/test_create_noisy_signal.py index 62da9972..f921bd8c 100644 --- a/pyroomacoustics/tests/test_create_noisy_signal.py +++ b/tests/test_create_noisy_signal.py @@ -13,7 +13,6 @@ signal_fp = os.path.join( os.path.dirname(__file__), "..", - "..", "examples", "input_samples", "cmu_arctic_us_aew_a0001.wav", diff --git a/pyroomacoustics/tests/test_from_corners_extrude.py b/tests/test_from_corners_extrude.py similarity index 100% rename from pyroomacoustics/tests/test_from_corners_extrude.py rename to tests/test_from_corners_extrude.py diff --git a/pyroomacoustics/tests/test_hpf.py b/tests/test_hpf.py similarity index 100% rename from pyroomacoustics/tests/test_hpf.py rename to tests/test_hpf.py diff --git a/pyroomacoustics/tests/test_issue_115.py b/tests/test_issue_115.py similarity index 100% rename from pyroomacoustics/tests/test_issue_115.py rename to tests/test_issue_115.py diff --git a/pyroomacoustics/tests/test_issue_162.py b/tests/test_issue_162.py similarity index 100% rename from pyroomacoustics/tests/test_issue_162.py rename to tests/test_issue_162.py diff --git a/pyroomacoustics/tests/test_issue_22.py b/tests/test_issue_22.py similarity index 100% rename from pyroomacoustics/tests/test_issue_22.py rename to tests/test_issue_22.py diff --git a/pyroomacoustics/tests/test_issue_235.py b/tests/test_issue_235.py similarity index 100% rename from pyroomacoustics/tests/test_issue_235.py rename to tests/test_issue_235.py diff --git a/pyroomacoustics/tests/test_issue_236.py b/tests/test_issue_236.py similarity index 100% rename from pyroomacoustics/tests/test_issue_236.py rename to tests/test_issue_236.py diff --git a/pyroomacoustics/tests/test_issue_313.py b/tests/test_issue_313.py similarity index 100% rename from pyroomacoustics/tests/test_issue_313.py rename to tests/test_issue_313.py diff --git a/pyroomacoustics/tests/test_issue_348.py b/tests/test_issue_348.py similarity index 100% rename from pyroomacoustics/tests/test_issue_348.py rename to tests/test_issue_348.py diff --git a/pyroomacoustics/tests/test_issue_353.py b/tests/test_issue_353.py similarity index 100% rename from pyroomacoustics/tests/test_issue_353.py rename to tests/test_issue_353.py diff --git a/pyroomacoustics/tests/test_issue_69.py b/tests/test_issue_69.py similarity index 100% rename from pyroomacoustics/tests/test_issue_69.py rename to tests/test_issue_69.py diff --git a/pyroomacoustics/tests/test_issue_87.py b/tests/test_issue_87.py similarity index 100% rename from pyroomacoustics/tests/test_issue_87.py rename to tests/test_issue_87.py diff --git a/pyroomacoustics/tests/test_materials.py b/tests/test_materials.py similarity index 100% rename from pyroomacoustics/tests/test_materials.py rename to tests/test_materials.py diff --git a/pyroomacoustics/tests/test_metrics.py b/tests/test_metrics.py similarity index 100% rename from pyroomacoustics/tests/test_metrics.py rename to tests/test_metrics.py diff --git a/pyroomacoustics/tests/test_microphone_array.py b/tests/test_microphone_array.py similarity index 100% rename from pyroomacoustics/tests/test_microphone_array.py rename to tests/test_microphone_array.py diff --git a/pyroomacoustics/tests/test_octave_bands.py b/tests/test_octave_bands.py similarity index 100% rename from pyroomacoustics/tests/test_octave_bands.py rename to tests/test_octave_bands.py diff --git a/pyroomacoustics/tests/test_rake_filters.py b/tests/test_rake_filters.py similarity index 100% rename from pyroomacoustics/tests/test_rake_filters.py rename to tests/test_rake_filters.py diff --git a/pyroomacoustics/tests/test_random_ism.py b/tests/test_random_ism.py similarity index 100% rename from pyroomacoustics/tests/test_random_ism.py rename to tests/test_random_ism.py diff --git a/pyroomacoustics/tests/test_resample.py b/tests/test_resample.py similarity index 100% rename from pyroomacoustics/tests/test_resample.py rename to tests/test_resample.py diff --git a/pyroomacoustics/tests/test_rir_hpf.py b/tests/test_rir_hpf.py similarity index 100% rename from pyroomacoustics/tests/test_rir_hpf.py rename to tests/test_rir_hpf.py diff --git a/pyroomacoustics/tests/test_room_add.py b/tests/test_room_add.py similarity index 100% rename from pyroomacoustics/tests/test_room_add.py rename to tests/test_room_add.py diff --git a/pyroomacoustics/tests/test_room_is_insided.py b/tests/test_room_is_insided.py similarity index 100% rename from pyroomacoustics/tests/test_room_is_insided.py rename to tests/test_room_is_insided.py diff --git a/pyroomacoustics/tests/test_room_mix.py b/tests/test_room_mix.py similarity index 100% rename from pyroomacoustics/tests/test_room_mix.py rename to tests/test_room_mix.py diff --git a/pyroomacoustics/tests/test_room_plot.py b/tests/test_room_plot.py similarity index 100% rename from pyroomacoustics/tests/test_room_plot.py rename to tests/test_room_plot.py diff --git a/pyroomacoustics/tests/test_room_scattering_rt60.py b/tests/test_room_scattering_rt60.py similarity index 100% rename from pyroomacoustics/tests/test_room_scattering_rt60.py rename to tests/test_room_scattering_rt60.py diff --git a/pyroomacoustics/tests/test_rt60.py b/tests/test_rt60.py similarity index 100% rename from pyroomacoustics/tests/test_rt60.py rename to tests/test_rt60.py diff --git a/pyroomacoustics/tests/test_rt_multiband_energy.py b/tests/test_rt_multiband_energy.py similarity index 99% rename from pyroomacoustics/tests/test_rt_multiband_energy.py rename to tests/test_rt_multiband_energy.py index bf8280a7..0a09ccee 100644 --- a/pyroomacoustics/tests/test_rt_multiband_energy.py +++ b/tests/test_rt_multiband_energy.py @@ -173,7 +173,7 @@ def test_energy_decay_ism_vs_rt(samplerate, scene_geometry, wall_material): assert irer_db >= 10.0, f"Failed IRER {irer_db:.2f} dB < 10.0" bws = room.octave_bands.get_bw() - tols = [0.30, 0.15, 0.08] + tols = [0.30, 0.20, 0.08] for b, bw in enumerate(np.sort(bws)): # Loop through every band rir_band_ism = room.octave_bands.analysis(rir_ism, band=b) rir_band_rt = room.octave_bands.analysis(rir_rt, band=b) diff --git a/pyroomacoustics/tests/test_shoebox_constants.py b/tests/test_shoebox_constants.py similarity index 100% rename from pyroomacoustics/tests/test_shoebox_constants.py rename to tests/test_shoebox_constants.py diff --git a/pyroomacoustics/tests/test_soundsource.py b/tests/test_soundsource.py similarity index 100% rename from pyroomacoustics/tests/test_soundsource.py rename to tests/test_soundsource.py diff --git a/pyroomacoustics/tests/test_sync.py b/tests/test_sync.py similarity index 100% rename from pyroomacoustics/tests/test_sync.py rename to tests/test_sync.py diff --git a/pyroomacoustics/tests/test_visibility_shoebox2d.py b/tests/test_visibility_shoebox2d.py similarity index 100% rename from pyroomacoustics/tests/test_visibility_shoebox2d.py rename to tests/test_visibility_shoebox2d.py diff --git a/pyroomacoustics/tests/test_visibility_shoebox3d.py b/tests/test_visibility_shoebox3d.py similarity index 100% rename from pyroomacoustics/tests/test_visibility_shoebox3d.py rename to tests/test_visibility_shoebox3d.py diff --git a/pyroomacoustics/tests/test_visibility_uroom.py b/tests/test_visibility_uroom.py similarity index 100% rename from pyroomacoustics/tests/test_visibility_uroom.py rename to tests/test_visibility_uroom.py diff --git a/pyroomacoustics/tests/test_volume_area.py b/tests/test_volume_area.py similarity index 100% rename from pyroomacoustics/tests/test_volume_area.py rename to tests/test_volume_area.py diff --git a/pyroomacoustics/transform/tests/test_dft.py b/tests/transform/test_dft.py similarity index 100% rename from pyroomacoustics/transform/tests/test_dft.py rename to tests/transform/test_dft.py diff --git a/pyroomacoustics/transform/tests/test_dft_timing.py b/tests/transform/test_dft_timing.py similarity index 100% rename from pyroomacoustics/transform/tests/test_dft_timing.py rename to tests/transform/test_dft_timing.py diff --git a/pyroomacoustics/transform/tests/test_stft.py b/tests/transform/test_stft.py similarity index 100% rename from pyroomacoustics/transform/tests/test_stft.py rename to tests/transform/test_stft.py diff --git a/pyroomacoustics/transform/tests/test_stft_oneshot.py b/tests/transform/test_stft_oneshot.py similarity index 100% rename from pyroomacoustics/transform/tests/test_stft_oneshot.py rename to tests/transform/test_stft_oneshot.py diff --git a/pyroomacoustics/transform/tests/test_stft_timing.py b/tests/transform/test_stft_timing.py similarity index 100% rename from pyroomacoustics/transform/tests/test_stft_timing.py rename to tests/transform/test_stft_timing.py