Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update python versions in CI. Replace point-in-polygon algorithm. #345

Merged
merged 15 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'
Expand Down
3 changes: 0 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/adaptive_filter_stft_domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/adaptive_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/beamforming_delay_and_sum.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/bss_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/raytracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/room_L_shape_3d_rt.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

The simulation is done using the hybrid ISM/RT simulator.
"""

from __future__ import print_function

import time
Expand Down
1 change: 1 addition & 0 deletions examples/room_complex_wall_materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

2022 (c) @noahdeetzers, @fakufaku
"""

import matplotlib.pyplot as plt
import numpy as np

Expand Down
1 change: 1 addition & 0 deletions examples/room_from_rt60.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions examples/room_from_stl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

The STL file was kindly provided by Diego Di Carlo (@Chutlhu).
"""

import argparse
import os
from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/adaptive/lms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion pyroomacoustics/adaptive/subband_lms.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@


class SubbandLMS:

"""
Frequency domain implementation of LMS. Adaptive filter for each
subband.
Expand Down
1 change: 0 additions & 1 deletion pyroomacoustics/beamforming.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ def circular_microphone_array_xyplane(


class MicrophoneArray(object):

"""Microphone array class."""

def __init__(self, R, fs, directivity=None):
Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/datasets/cmu_arctic.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

URL: http://www.festvox.org/cmu_arctic/
"""

import os

import numpy as np
Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/datasets/tests/test_corpus_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Example of the basic operations with ``pyroomacoustics.datasets.Dataset``
and ``pyroomacoustics.datasets.Sample`` classes
"""

from pyroomacoustics.datasets import Dataset, Sample


Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/doa/grid.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/doa/plotters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
A collection of functions to plot maps and points on circles and spheres.
"""

import numpy as np


Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/doa/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions pyroomacoustics/experimental/signals.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
A few test signals like sweeps and stuff.
"""

from __future__ import division, print_function

import numpy as np
Expand Down
117 changes: 60 additions & 57 deletions pyroomacoustics/libroom_src/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<float,2,Eigen::Dynamic> &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
Expand All @@ -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<float, 2, Eigen::Dynamic> &corners)
{
/*
Expand Down
9 changes: 3 additions & 6 deletions pyroomacoustics/libroom_src/libroom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<py::gil_scoped_release>());
m.def("delay_sum", &delay_sum, "Delay and sum",
py::call_guard<py::gil_scoped_release>());
m.def("fractional_delay", &fractional_delay, "Fractional delays",
py::call_guard<py::gil_scoped_release>());
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");
}
Loading
Loading