Commit 9908aa4c authored by Michael Kohnen's avatar Michael Kohnen

added HOARemax, SHLinear2DegreeOrder and fixed elevation vs polar angle irritations in SH functions

parent 2801056f
......@@ -429,6 +429,12 @@ template< typename T > inline void linspace( std::vector< T >& dest, T a, T b, T
// (Note a and b must be powers of two, otherwise an exception is thrown)
ITA_BASE_API void pow2space( std::vector< int >& dest, const int a, const int b );
// returns the elevation angle (0 = frontal direction) in radians from a polar angle theta (0 = above)
ITA_BASE_API double theta2elevation(const double dThetaRAD);
// returns the polar angle theta (0 = above) in radians from a given elevation angle (0 = frontal direction)
ITA_BASE_API double elevation2theta(const double dElevationRAD);
// Calculates the factorial of an positive integer m
ITA_BASE_API int factorial( const int m );
......@@ -438,11 +444,17 @@ ITA_BASE_API double SHNormalizeConst( const int m, const int n );
//Calculates the Kronecker delta
ITA_BASE_API int SHKronecker( const int m );
// Returns the index of a basefunction with degree m and order n
// Returns the linear index of a basefunction with degree m and order n, linear indexing starts with 0
ITA_BASE_API int SHDegreeOrder2Linear( const int m, const int n );
// Returns degree and order of a basefunctions from a linear index, linear indexing starts with 0
ITA_BASE_API void SHLinear2DegreeOrder(const int iLinear, int &m, int &n);
// Calculates the remax weightings up to a given order
ITA_BASE_API std::vector<double> HOARemaxWeights(int iTruncationOrder);
//Calculates the realvalued Basefunctions of SH for e.g. Ambisonics
ITA_BASE_API std::vector<double> SHRealvaluedBasefunctions( const double elevation, const double azimuth, const int maxOrder );
ITA_BASE_API std::vector<double> SHRealvaluedBasefunctions( const double thetaRAD, const double azimuthRAD, const int maxOrder );
//Calculates the associated legendre polynomials
ITA_BASE_API std::vector<double> SHAssociatedLegendre( const int N, const double mu );
......
......@@ -434,6 +434,22 @@ void pow2space( std::vector<int>& dest, const int a, const int b )
}
}
double theta2elevation(const double dThetaRAD)
{
if (dThetaRAD<0 || dThetaRAD>ITAConstants::PI_D)
ITA_EXCEPT1(INVALID_PARAMETER, "thetaRAD is only valid between 0 and PI");
return ITAConstants::PI_D / 2 - dThetaRAD;
}
double elevation2theta(const double dElevationRAD)
{
if (abs(dElevationRAD)<ITAConstants::PI_D/2)
ITA_EXCEPT1(INVALID_PARAMETER, "elevationRAD is only valid between -PI/2 and PI/2");
return ITAConstants::PI_D / 2 - dElevationRAD;
}
int factorial( const int m )
{
if( m<0 )
......@@ -464,22 +480,25 @@ int SHKronecker( const int m )
return 0;
}
std::vector<double> SHRealvaluedBasefunctions( const double elevation, const double azimuth, const int maxOrder )
std::vector<double> SHRealvaluedBasefunctions(const double thetaRAD, const double azimuthRAD, const int maxOrder)
{
std::vector<double> Y;
Y.resize( ( maxOrder + 1 )*( maxOrder + 1 ) );
Y = SHAssociatedLegendre( maxOrder, cos( elevation ) );
//std::vector<double> dNormalizing;
int nmax = (maxOrder + 1)*(maxOrder + 1);
Y.resize(nmax);
//dNormalizing.resize(nmax);
//dNormalizing = SHNormalizeConst();
for( int n = 0; n <= maxOrder; n++ )
Y = SHAssociatedLegendre(maxOrder, cos(thetaRAD));
for (int n = 0; n <= maxOrder; n++)
{
//Y[SHDegreeOrder2Linear(0,n)]*=Y[SHDegreeOrder2Linear(0,n)]*SHNormalizeConst(0,n);
Y[ SHDegreeOrder2Linear( 0, n ) ] *= SHNormalizeConst( 0, n );
for( int m = 1; m <= n; m++ )
Y[SHDegreeOrder2Linear(0, n)] *= SHNormalizeConst(0, n);
for (int m = 1; m <= n; m++)
{
double Normalizing = SHNormalizeConst( m, n );
Y[ SHDegreeOrder2Linear( m, n ) ] *= cos( m*azimuth )*Normalizing;
Y[ SHDegreeOrder2Linear( -m, n ) ] *= sin( m*azimuth )*Normalizing;
double Normalizing = SHNormalizeConst(m, n);
Y[SHDegreeOrder2Linear(m, n)] *= cos(m*azimuthRAD)*Normalizing;
Y[SHDegreeOrder2Linear(-m, n)] *= sin(m*azimuthRAD)*Normalizing;
}
}
return Y;
......@@ -517,3 +536,31 @@ int SHDegreeOrder2Linear( const int m, const int n )
return ( n*n + n + m );
}
std::vector<double> HOARemaxWeights(int iTruncationOrder)
{
if (iTruncationOrder > 20)
ITA_EXCEPT1(INVALID_PARAMETER, "ReMAx decoding only implemented up to Truncatrion Order 20");
std::vector<double> vdRemax;
double dMaxRootTable[21] = { 0.993752, 0.993129, 0.992407, 0.991565, 0.990575, 0.989401, 0.987993, 0.986284, 0.984183, 0.978229, 0.978229, 0.973907, 0.96816, 0.96029, 0.949108, 0.93247, 0.90618, 0.861136, 0.774597, 0.57735, 0 };
double dMaxRoot = dMaxRootTable[21 - iTruncationOrder-1];
std::vector<double> vdAssoLegendre = (SHAssociatedLegendre(iTruncationOrder, dMaxRoot));
for (int k = 0; k <= iTruncationOrder; k++)
{
vdRemax.push_back(vdAssoLegendre[SHDegreeOrder2Linear(0,k)]);
}
return vdRemax;
}
void SHLinear2DegreeOrder(const int iLinear, int &m, int &n)
{
if (iLinear<0)
ITA_EXCEPT1(INVALID_PARAMETER, "The linear index has to be higher than one");
std::vector<int> nm;
n=(floor(sqrt(iLinear)));
m=(iLinear - n * n - n);
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment