Loading lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ #define ISM_BITRATE_SWITCHING /* Issue 115: Support for Bitrate Switching in ISM */ #define SBA_SPAR_HARM /* Issue 92: maintenance of the SBA SPAR functions */ #define FIX_155_HP20_ISSUE /* Issue 155: apply hp20 on all input channels instead of just 2 channels */ #define EFAP_FIX_POLY /* Issue 167: fix bug in EFAP polygon selection */ Loading lib_dec/ivas_efap.c +100 −6 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ static void get_poly_gains( const float azi, const float ele, const float aziPol static float get_tri_gain( const float A[2], const float B[2], const float C[2], const float P_minus_A[2] ); #if defined( DEBUG_EFAP_POLY_TOFILE ) #ifdef DEBUG_EFAP_POLY_TOFILE static void get_poly_select( EFAP_POLYSET_DATA *polyData ); #endif Loading @@ -96,11 +96,13 @@ static void add_vertex( EFAP_VERTEX *vtxArray, const float azi, const float ele, static void efap_sort_s( int16_t *x, int16_t *idx, const int16_t len ); static float vertex_distance( const EFAP_VERTEX *vtxArray, const EFAP_LS_TRIANGLE tri, const int16_t vtxIdx ); static float point_plane_distance( const float P1[3], const float P2[3], const float P3[3], const float X[3] ); #ifdef EFAP_FIX_POLY static float point_poly_distance( const EFAP_POLYSET poly, const float X[3] ); #endif static void efap_crossp( const float *v1, const float *v2, float *v ); static int16_t find_int_in_tri( const EFAP_LS_TRIANGLE *tri, const int16_t n, const int16_t r, int16_t *pos ); Loading @@ -125,6 +127,9 @@ static int16_t in_poly( const float P[2], const EFAP_POLYSET poly ); static int16_t in_tri( float A[2], float B[2], float C[2], float P_minus_A[2] ); #ifdef EFAP_FIX_POLY static void sph2cart( const float azi, const float ele, float *pos ); #endif /*-----------------------------------------------------------------------* * Global function definitions Loading Loading @@ -462,14 +467,14 @@ static ivas_error poly_init( efap->polyData.numPoly = finalLength; #if defined( DEBUG_EFAP_POLY_TOFILE ) #ifdef DEBUG_EFAP_POLY_TOFILE get_poly_select( &efap->polyData ); #endif return error; } #if defined( DEBUG_EFAP_POLY_TOFILE ) #ifdef DEBUG_EFAP_POLY_TOFILE static void get_poly_select( EFAP_POLYSET_DATA *polyData /* o : Polygon data structure */ ) Loading Loading @@ -1497,9 +1502,13 @@ static void add_vertex( vtxArray[pos].ele = ( ( -180.0f > tmp ) ? -180.0f : tmp ); /* Converting spherical coordinates to cartesians, assuming radius = 1 */ #ifdef EFAP_FIX_POLY sph2cart( vtxArray[pos].azi, vtxArray[pos].ele, &vtxArray[pos].pos[0] ); #else vtxArray[pos].pos[0] = cosf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 ); vtxArray[pos].pos[1] = sinf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 ); vtxArray[pos].pos[2] = sinf( vtxArray[pos].ele * PI_OVER_180 ); #endif /* Computing the index defined by idx = idxAziTmp + 181 * idxEleTmp */ Loading Loading @@ -1591,11 +1600,32 @@ static float vertex_distance( return point_plane_distance( A, B, C, P ); } #ifdef EFAP_FIX_POLY /*-------------------------------------------------------------------------* * point_plane_distance() * * Compute the signed distance between a point and polygon *-------------------------------------------------------------------------*/ static float point_poly_distance( const EFAP_POLYSET poly, /* i : The polygon which forms a plane */ const float X[3] /* i : Cartesian coordinates of the point of interest */ ) { float P1[3], P2[3], P3[3]; sph2cart( poly.polyAzi[0], poly.polyEle[0], &P1[0] ); sph2cart( poly.polyAzi[1], poly.polyEle[1], &P2[0] ); sph2cart( poly.polyAzi[2], poly.polyEle[2], &P3[0] ); return point_plane_distance( P1, P2, P3, X ); } #endif /*-------------------------------------------------------------------------* * point_plane_distance() * * Compute the signed distance between a point a given plane * Compute the signed distance between a point and a given plane *-------------------------------------------------------------------------*/ static float point_plane_distance( Loading Loading @@ -2082,16 +2112,63 @@ static int16_t get_poly_num( ) { int16_t i; #ifdef EFAP_FIX_POLY int16_t num_poly, found_poly; int16_t poly_tmp[9], poly_dist[9]; float dist_tmp; float pos[3]; num_poly = 0; sph2cart( P[0], P[1], &pos[0] ); /* Filter the polygon list with a fast 2d check */ #endif for ( i = 0; i < polyData->numPoly; ++i ) { if ( in_poly( P, polyData->polysetArray[i] ) ) { #ifdef EFAP_FIX_POLY /* select only polygons which are visible from the point */ dist_tmp = point_poly_distance( polyData->polysetArray[i], pos ); if ( dist_tmp == 0 ) { return i; } else if ( dist_tmp > 0 ) { poly_tmp[num_poly] = i; poly_dist[num_poly] = dist_tmp; num_poly++; } #else return i; #endif } } #ifdef EFAP_FIX_POLY if ( num_poly == 0 ) { return -1; } /* select the polygon with the smallest distance */ found_poly = poly_tmp[0]; dist_tmp = poly_dist[0]; for ( i = 1; i < num_poly; i++ ) { if ( poly_dist[i] < dist_tmp ) { found_poly = poly_tmp[i]; dist_tmp = poly_dist[i]; } } return found_poly; #else return -1; #endif } Loading Loading @@ -2226,3 +2303,20 @@ static int16_t in_tri( return 1; } } /*-------------------------------------------------------------------------* * sph2cart() * * Converts a vertex position to cartesian coordinates *-------------------------------------------------------------------------*/ static void sph2cart( const float azi, /* i : Azimuth in degrees */ const float ele, /* i : Elevation in degrees */ float *pos /* o : Cartesian coordinates vector (x, y, z) */ ) { pos[0] = cosf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 ); pos[1] = sinf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 ); pos[2] = sinf( ele * PI_OVER_180 ); } scripts/pyaudio3dtools/EFAP.py +28 −6 Original line number Diff line number Diff line Loading @@ -744,18 +744,40 @@ class EFAP: raise ValueError(f"Angles cannot be NaNs : ({azimuth}, {elevation})") azimuth, elevation = wrap_angles(azimuth, elevation) point_pos = [ np.cos(np.deg2rad(azimuth)) * np.cos(np.deg2rad(elevation)), np.sin(np.deg2rad(azimuth)) * np.cos(np.deg2rad(elevation)), np.sin(np.deg2rad(elevation)), ] # find the polygon corresponding to the given point found_poly = None mod = None # filter the polygon list with a quick 2d check found_polys = [] for poly in self.polys: in_poly, mod = self._in_polygon(azimuth, elevation, poly) if in_poly: found_poly = poly break else: found_polys.append((poly, mod)) if not found_polys: raise AssertionError("Unexpected error during panning") # find a visible polygon with the smallest distance dist = [] for poly, mod in found_polys: surface = self.verts[poly] d = self._point_plane_dist( surface[0].pos, surface[1].pos, surface[2].pos, point_pos, ) if d >= 0: dist.append(d) else: dist.append(np.inf) found_poly, mod = found_polys[np.argmin(dist)] # compute gains for the polygon vertices poly_gain = self._pan_EFAP_poly(azimuth, elevation, found_poly, mod) Loading Loading
lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ #define ISM_BITRATE_SWITCHING /* Issue 115: Support for Bitrate Switching in ISM */ #define SBA_SPAR_HARM /* Issue 92: maintenance of the SBA SPAR functions */ #define FIX_155_HP20_ISSUE /* Issue 155: apply hp20 on all input channels instead of just 2 channels */ #define EFAP_FIX_POLY /* Issue 167: fix bug in EFAP polygon selection */ Loading
lib_dec/ivas_efap.c +100 −6 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ static void get_poly_gains( const float azi, const float ele, const float aziPol static float get_tri_gain( const float A[2], const float B[2], const float C[2], const float P_minus_A[2] ); #if defined( DEBUG_EFAP_POLY_TOFILE ) #ifdef DEBUG_EFAP_POLY_TOFILE static void get_poly_select( EFAP_POLYSET_DATA *polyData ); #endif Loading @@ -96,11 +96,13 @@ static void add_vertex( EFAP_VERTEX *vtxArray, const float azi, const float ele, static void efap_sort_s( int16_t *x, int16_t *idx, const int16_t len ); static float vertex_distance( const EFAP_VERTEX *vtxArray, const EFAP_LS_TRIANGLE tri, const int16_t vtxIdx ); static float point_plane_distance( const float P1[3], const float P2[3], const float P3[3], const float X[3] ); #ifdef EFAP_FIX_POLY static float point_poly_distance( const EFAP_POLYSET poly, const float X[3] ); #endif static void efap_crossp( const float *v1, const float *v2, float *v ); static int16_t find_int_in_tri( const EFAP_LS_TRIANGLE *tri, const int16_t n, const int16_t r, int16_t *pos ); Loading @@ -125,6 +127,9 @@ static int16_t in_poly( const float P[2], const EFAP_POLYSET poly ); static int16_t in_tri( float A[2], float B[2], float C[2], float P_minus_A[2] ); #ifdef EFAP_FIX_POLY static void sph2cart( const float azi, const float ele, float *pos ); #endif /*-----------------------------------------------------------------------* * Global function definitions Loading Loading @@ -462,14 +467,14 @@ static ivas_error poly_init( efap->polyData.numPoly = finalLength; #if defined( DEBUG_EFAP_POLY_TOFILE ) #ifdef DEBUG_EFAP_POLY_TOFILE get_poly_select( &efap->polyData ); #endif return error; } #if defined( DEBUG_EFAP_POLY_TOFILE ) #ifdef DEBUG_EFAP_POLY_TOFILE static void get_poly_select( EFAP_POLYSET_DATA *polyData /* o : Polygon data structure */ ) Loading Loading @@ -1497,9 +1502,13 @@ static void add_vertex( vtxArray[pos].ele = ( ( -180.0f > tmp ) ? -180.0f : tmp ); /* Converting spherical coordinates to cartesians, assuming radius = 1 */ #ifdef EFAP_FIX_POLY sph2cart( vtxArray[pos].azi, vtxArray[pos].ele, &vtxArray[pos].pos[0] ); #else vtxArray[pos].pos[0] = cosf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 ); vtxArray[pos].pos[1] = sinf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 ); vtxArray[pos].pos[2] = sinf( vtxArray[pos].ele * PI_OVER_180 ); #endif /* Computing the index defined by idx = idxAziTmp + 181 * idxEleTmp */ Loading Loading @@ -1591,11 +1600,32 @@ static float vertex_distance( return point_plane_distance( A, B, C, P ); } #ifdef EFAP_FIX_POLY /*-------------------------------------------------------------------------* * point_plane_distance() * * Compute the signed distance between a point and polygon *-------------------------------------------------------------------------*/ static float point_poly_distance( const EFAP_POLYSET poly, /* i : The polygon which forms a plane */ const float X[3] /* i : Cartesian coordinates of the point of interest */ ) { float P1[3], P2[3], P3[3]; sph2cart( poly.polyAzi[0], poly.polyEle[0], &P1[0] ); sph2cart( poly.polyAzi[1], poly.polyEle[1], &P2[0] ); sph2cart( poly.polyAzi[2], poly.polyEle[2], &P3[0] ); return point_plane_distance( P1, P2, P3, X ); } #endif /*-------------------------------------------------------------------------* * point_plane_distance() * * Compute the signed distance between a point a given plane * Compute the signed distance between a point and a given plane *-------------------------------------------------------------------------*/ static float point_plane_distance( Loading Loading @@ -2082,16 +2112,63 @@ static int16_t get_poly_num( ) { int16_t i; #ifdef EFAP_FIX_POLY int16_t num_poly, found_poly; int16_t poly_tmp[9], poly_dist[9]; float dist_tmp; float pos[3]; num_poly = 0; sph2cart( P[0], P[1], &pos[0] ); /* Filter the polygon list with a fast 2d check */ #endif for ( i = 0; i < polyData->numPoly; ++i ) { if ( in_poly( P, polyData->polysetArray[i] ) ) { #ifdef EFAP_FIX_POLY /* select only polygons which are visible from the point */ dist_tmp = point_poly_distance( polyData->polysetArray[i], pos ); if ( dist_tmp == 0 ) { return i; } else if ( dist_tmp > 0 ) { poly_tmp[num_poly] = i; poly_dist[num_poly] = dist_tmp; num_poly++; } #else return i; #endif } } #ifdef EFAP_FIX_POLY if ( num_poly == 0 ) { return -1; } /* select the polygon with the smallest distance */ found_poly = poly_tmp[0]; dist_tmp = poly_dist[0]; for ( i = 1; i < num_poly; i++ ) { if ( poly_dist[i] < dist_tmp ) { found_poly = poly_tmp[i]; dist_tmp = poly_dist[i]; } } return found_poly; #else return -1; #endif } Loading Loading @@ -2226,3 +2303,20 @@ static int16_t in_tri( return 1; } } /*-------------------------------------------------------------------------* * sph2cart() * * Converts a vertex position to cartesian coordinates *-------------------------------------------------------------------------*/ static void sph2cart( const float azi, /* i : Azimuth in degrees */ const float ele, /* i : Elevation in degrees */ float *pos /* o : Cartesian coordinates vector (x, y, z) */ ) { pos[0] = cosf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 ); pos[1] = sinf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 ); pos[2] = sinf( ele * PI_OVER_180 ); }
scripts/pyaudio3dtools/EFAP.py +28 −6 Original line number Diff line number Diff line Loading @@ -744,18 +744,40 @@ class EFAP: raise ValueError(f"Angles cannot be NaNs : ({azimuth}, {elevation})") azimuth, elevation = wrap_angles(azimuth, elevation) point_pos = [ np.cos(np.deg2rad(azimuth)) * np.cos(np.deg2rad(elevation)), np.sin(np.deg2rad(azimuth)) * np.cos(np.deg2rad(elevation)), np.sin(np.deg2rad(elevation)), ] # find the polygon corresponding to the given point found_poly = None mod = None # filter the polygon list with a quick 2d check found_polys = [] for poly in self.polys: in_poly, mod = self._in_polygon(azimuth, elevation, poly) if in_poly: found_poly = poly break else: found_polys.append((poly, mod)) if not found_polys: raise AssertionError("Unexpected error during panning") # find a visible polygon with the smallest distance dist = [] for poly, mod in found_polys: surface = self.verts[poly] d = self._point_plane_dist( surface[0].pos, surface[1].pos, surface[2].pos, point_pos, ) if d >= 0: dist.append(d) else: dist.append(np.inf) found_poly, mod = found_polys[np.argmin(dist)] # compute gains for the polygon vertices poly_gain = self._pan_EFAP_poly(azimuth, elevation, found_poly, mod) Loading