OpenDAFF C++ API  v1.7
Directional Audio File Format
DAFFSCTransform.cpp
Go to the documentation of this file.
1 #include <DAFFSCTransform.h>
2 
3 #include "Utils.h"
4 #include <DAFFUtils.h>
5 
6 #include <cmath>
7 
9 {
10  setOrientation( orient );
11 }
12 
14 {
15  orient = m_orient;
16 }
17 
19 {
20  m_orient = orient;
21  m_orient_index = 0;
22  m_const.Init( m_orient.fYawAngleDeg, m_orient.fPitchAngleDeg, m_orient.fRollAngleDeg );
23 }
24 
25 /* Transformation functions
26 
27  These transformations perform angular conversions between two spherical coordinate systems,
28  which are rotated against each other by yaw-pitch-roll convention. So basically what we do here,
29  is to express a yaw-pitch-roll rotation within spherical coordinates - this is not trivial.
30 
31  The formulas for the rotation can be derived by introducing a cartesian coordinate system
32  (e.g. right-handed OpenGL, where Z is up) as an intermediate format. Then rotations are applied
33  in the cartesian domainn. Finally we transform this result back into spherical coordinates.
34 
35  Many of the terms for the conversion only depend on the rotation angles itself (yaw, pitch and roll).
36  Therefore we calculate these constants once and cache them for later reuse.
37 
38  For the angular calculations double precision floating points are necessary to maintain
39  a low numerical error.
40 
41 
42  Operation count:
43 
44  4 trigenometric (2 sin, 2 cos)
45  2 muls (subexpressions)
46  9 muls (calculation)
47  6 adds (calculation)
48  2 inverse trigenometric (1 atan2, 1 asin)
49  -----------------------------------------
50  Total: 6 trigenometric + 17 madds
51 
52  [Frank Wefers, 2010-02-01]
53 
54  */
55 void DAFFSCTransform::transformOSC2DSC( float azimuth_in, float elevation_in, float& alpha_out, float& beta_out ) const
56 {
57  double a, b;
58  transformOSC2DSC( double( azimuth_in ), double( elevation_in ), a, b );
59  alpha_out = float( a );
60  beta_out = float( b );
61 }
62 
63 void DAFFSCTransform::transformOSC2DSC( double azimuth_in, double elevation_in, double& alpha_out, double& beta_out ) const
64 {
65  // Internally in this method we use radians (not degrees)
66  double ai = DAFFUtils::grad2rad( azimuth_in ), ei = DAFFUtils::grad2rad( elevation_in );
67  double ao, eo;
68 
69  // Base terms
70  double sa = sin( ai ), ca = cos( ai );
71  double se = sin( ei ), ce = cos( ei );
72 
73  // Common subexpressions
74  double sa_ce = sa*ce;
75  double ca_ce = ca*ce;
76 
77  ao = atan2( m_const.t1*sa_ce - m_const.t2*se + m_const.t3*ca_ce,
78  m_const.t4*sa_ce - m_const.t5*se + m_const.t6*ca_ce );
79  eo = asin( m_const.t7*sa_ce + m_const.t8*se + m_const.t9*ca_ce );
80 
81  alpha_out = DAFFUtils::rad2grad( ao );
82  beta_out = DAFFUtils::rad2grad( eo ) + 90.0F; // Translate into DSC (b=e+90)
83 }
84 
85 void DAFFSCTransform::transformDSC2OSC( float alpha_in, float beta_in, float& azimuth_out, float& elevation_out ) const
86 {
87  double a, e;
88  transformDSC2OSC( double( alpha_in ), double( beta_in ), a, e );
89  azimuth_out = float( a );
90  elevation_out = float( e );
91 }
92 
93 void DAFFSCTransform::transformDSC2OSC( double alpha_in, double beta_in, double& azimuth_out, double& elevation_out ) const
94 {
95  // Internally in this method we use radians (not degrees)
96  double ai = DAFFUtils::grad2rad( alpha_in ), ei = DAFFUtils::grad2rad( beta_in - 90.0F ); // Translate into OSC (e=b-90)
97  double ao, eo;
98 
99  // Base terms
100  double sa = sin( ai ), ca = cos( ai );
101  double se = sin( ei ), ce = cos( ei );
102 
103  // Common subexpressions
104  double sa_ce = sa*ce;
105  double ca_ce = ca*ce;
106 
107  ao = atan2( m_const.t1*sa_ce + m_const.t7*se + m_const.t4*ca_ce,
108  m_const.t3*sa_ce + m_const.t9*se + m_const.t6*ca_ce );
109  eo = -asin( m_const.t2*sa_ce - m_const.t8*se + m_const.t5*ca_ce );
110 
111  azimuth_out = DAFFUtils::rad2grad( ao );
112  elevation_out = DAFFUtils::rad2grad( eo );
113 }
114 
115 void DAFFSCTransform::RotationConstants::Init( double yaw, double pitch, double roll )
116 {
117  double y = DAFFUtils::grad2rad( yaw );
118  double p = DAFFUtils::grad2rad( pitch );
119  double r = DAFFUtils::grad2rad( roll );
120 
121  double sy = sin( y ), cy = cos( y );
122  double sp = sin( p ), cp = cos( p );
123  double sr = sin( r ), cr = cos( r );
124 
125  t1 = ( cy*cr - sy*sp*sr );
126  t2 = ( cy*sr + sy*sp*cr );
127  t3 = sy*cp;
128  t4 = ( -sy*cr - cy*sp*sr );
129  t5 = ( -sy*sr + cy*sp*cr );
130  t6 = cy*cp;
131  t7 = cp*sr;
132  t8 = cp*cr;
133  t9 = sp;
134 }
float fPitchAngleDeg
Pitch angle (degrees)
Definition: DAFFDefs.h:142
void transformOSC2DSC(float azimuth_in, float elevation_in, float &alpha_out, float &beta_out) const
Transform coordinates from OSC -> DSC (including coordinate system rotation)
void getOrientation(DAFFOrientationYPR &orient) const
Return the OSC->DSC orientation (yaw-pitch-roll)
void setOrientation(const DAFFOrientationYPR &orient)
Sets the OSC->DSC orientation (yaw-pitch-roll)
float fRollAngleDeg
Roll angle (degrees)
Definition: DAFFDefs.h:143
static double rad2grad(double phi)
Definition: DAFFUtils.h:114
float fYawAngleDeg
Yaw angle (degrees)
Definition: DAFFDefs.h:141
static double grad2rad(double phi)
Definition: DAFFUtils.h:109
DAFFSCTransform()
Constructor.
void transformDSC2OSC(float alpha_in, float beta_in, float &azimuth_out, float &elevation_out) const
Transform coordinates from DSC -> OSC (including coordinate system rotation)
Data class for orientations in yaw-pitch-roll (YPR) angles (right-handed OpenGL coordinate system) ...
Definition: DAFFDefs.h:138
OpenDAFF is a project from the Institute of Technical Acoustics, RWTH Aachen University, Germany.