OpenDAFF C++ API  v1.7
Directional Audio File Format
DAFFUtils.cpp
Go to the documentation of this file.
1 #include <DAFFUtils.h>
2 
3 #include <DAFFDefs.h>
4 #include <DAFFMetadata.h>
5 
6 #include <cmath>
7 #include <cassert>
8 #include <cstring>
9 #include <iomanip>
10 #include <cmath>
11 
12 // Define necessary roundf for Microsoft compilers
13 #ifdef _MSC_VER
14 #define roundf(x) (x<0?ceil((x)-0.5f):floor((x)+0.5f));
15 #endif // _MSC_VER
16 
17 
19 {
20  // Version 0.1
21  version.iVersionMajor = 1;
22  version.iVersionMinor = 70;
23  version.sVersion = "1.7";
24 }
25 
26 // Helper function: Convert float => std::string (fixed format, but without trailing zeros)
27 std::string DAFFUtils::Float2StrNice( float f, int precision, bool showpos, int leadingzeros )
28 {
29  // First convert to fixed format (with enough digits)
30  std::stringstream ss;
31  if (showpos) ss << (f < 0.0f ? "-" : "+");
32  ss << std::fixed << std::setprecision(precision);
33  if (leadingzeros > 0) ss << std::setw(leadingzeros+precision+1) << std::setfill('0');
34  if (showpos) ss << fabs(f);
35  else ss << f;
36  std::string s = ss.str();
37 
38  // Then remove trailing zeros...
39  size_t n=s.length();
40  while ((n>0) && (s[n-1] == '0')) n--;
41 
42  // Special case: We reached the . => Remove this as well...
43  if ((n>1) && (s[n-1] == '.')) n--;
44 
45  return s.substr(0, n);
46 }
47 
48 // Helper function: Convert double => std::string (fixed format, but without trailing zeros)
49 std::string DAFFUtils::Double2StrNice( double d, int precision, bool showpos, int leadingzeros )
50 {
51  // First convert to fixed format (with enough digits)
52  std::stringstream ss;
53  if (showpos) ss << (d < 0.0f ? "-" : "+");
54  ss << std::fixed << std::setprecision(precision);
55  if (leadingzeros > 0) ss << std::setw(leadingzeros+precision+1) << std::setfill('0');
56  if (showpos) ss << fabs(d);
57  else ss << d;
58  std::string s = ss.str();
59 
60  // Then remove trailing zeros...
61  size_t n=s.length();
62  while ((n>0) && (s[n-1] == '0')) n--;
63 
64  // Special case: We reached the . => Remove this as well...
65  if ((n>1) && (s[n-1] == '.')) n--;
66 
67  return s.substr(0, n);
68 }
69 
70 std::string DAFFUtils::StrDirection( int iView, double dAngle1, double dAngle2, int precision, int leadingzeros )
71 {
72  std::stringstream ss;
73 
74  switch (iView) {
75  case DAFF_DATA_VIEW:
76  ss << std::fixed
77  << "( A" << Double2StrNice(dAngle1, precision, false, leadingzeros)
78  << "\xF8, B" << Double2StrNice(dAngle2, precision, false, leadingzeros) << "\xF8 )";
79  return ss.str();
80  break;
81 
82  case DAFF_OBJECT_VIEW:
83  ss << std::fixed << std::showpos
84  << "( P" << Double2StrNice(dAngle1, precision, true, leadingzeros)
85  << "\xF8, T" << Double2StrNice(dAngle2, precision, true, leadingzeros) << "\xF8 )";
86  return ss.str();
87  break;
88 
89  default:
90  // Invalid view
91  assert( false );
92  return "";
93  }
94  // we will never reach this point
95  return "";
96 }
97 
98 std::string DAFFUtils::StrDirectionCompact( int iView, double dAngle1, double dAngle2, int precision, int leadingzeros )
99 {
100  std::stringstream ss;
101 
102  switch (iView) {
103  case DAFF_DATA_VIEW:
104  ss << std::fixed
105  << "A" << Double2StrNice(dAngle1, precision, false, leadingzeros)
106  << "\xF8 B" << Double2StrNice(dAngle2, precision, false, leadingzeros) << "\xF8";
107  return ss.str();
108  break;
109 
110  case DAFF_OBJECT_VIEW:
111  ss << std::fixed << std::showpos
112  << "P" << Double2StrNice(dAngle1, precision, true, leadingzeros)
113  << "\xF8 T" << Double2StrNice(dAngle2, precision, true, leadingzeros) << "\xF8";
114  return ss.str();
115  break;
116 
117  default:
118  // Invalid view
119  assert( false );
120  return "";
121  }
122  // we will never reach this point
123  return "";
124 }
125 
126 std::string DAFFUtils::StrError( int iErrorcode )
127 {
128  switch( iErrorcode )
129  {
130  case DAFF_MODAL_ERROR:
131  return "Modal error";
132  case DAFF_FILE_CORRUPTED:
133  return "File corrupted";
135  return "File format version not supported";
136  case DAFF_FILE_NOT_FOUND:
137  return "File not found";
139  return "Metadata type unkown (valid: bool, int, double, string)";
140  case DAFF_INVALID_INDEX:
141  return "Invalid index";
143  return "Invalid main header parameter (num channels, etc. )";
144  case DAFF_FILE_INVALID:
145  return "Invalid file (wrong signature, etc.)";
147  return "File has unkown content type (IR, MS, DFT, etc)";
149  return "Invalid alpha angles or range problem";
151  return "Invalid beta angles or range problem";
153  return "Data uses unrecognized or wrong quantization";
155  return "Content parameter invalid (sampling rate, num supporting frequencies, etc)";
156 
157  default:
158  {
159  std::stringstream ss;
160  ss << "Undefined error code '" << iErrorcode << "' encountered";
161  return ss.str();
162  }
163  }
164 }
165 
166 std::string DAFFUtils::StrContentType( int iContentType )
167 {
168  switch( iContentType )
169  {
170  case DAFF_IMPULSE_RESPONSE: return "Impulse response";
171  case DAFF_MAGNITUDE_SPECTRUM: return "Magnitude spectrum";
172  case DAFF_PHASE_SPECTRUM: return "Phase spectrum";
173  case DAFF_MAGNITUDE_PHASE_SPECTRUM: return "Magnitude-phase spectrum";
174  case DAFF_DFT_SPECTRUM: return "Discrete Fourier-spectrum";
175  default: return "Invalid";
176  }
177 }
178 
179 std::string DAFFUtils::StrShortContentType( int iContentType )
180 {
181  switch (iContentType)
182  {
183  case DAFF_IMPULSE_RESPONSE: return "ir";
184  case DAFF_MAGNITUDE_SPECTRUM: return "ms";
185  case DAFF_PHASE_SPECTRUM: return "ps";
186  case DAFF_MAGNITUDE_PHASE_SPECTRUM: return "mps";
187  case DAFF_DFT_SPECTRUM: return "dft";
188  default: return "Invalid";
189  }
190 }
191 
192 std::string DAFFUtils::StrMetadataKeyType( int iKeyType )
193 {
194  switch (iKeyType) {
195 
196  case DAFFMetadata::DAFF_BOOL: return "Boolean";
197  case DAFFMetadata::DAFF_INT: return "Integer";
198  case DAFFMetadata::DAFF_FLOAT: return "Float";
199  case DAFFMetadata::DAFF_STRING: return "String";
200 
201  default: return "Invalid";
202  }
203 }
204 
205 std::string DAFFUtils::StrQuantizationType( int iQuantizationType )
206 {
207  switch (iQuantizationType) {
208 
209  case DAFF_INT16: return "16-bit signed integer";
210  case DAFF_INT24: return "24-bit signed integer";
211  case DAFF_FLOAT32: return "32-bit floating point";
212 
213  default: return "Invalid";
214  }
215 }
216 
217 void DAFFUtils::NormalizeDirection( int iView, float fAngle1In, float fAngle2In, float& fAngle1Out, float& fAngle2Out )
218 {
219  const float EPSILON = 0.00001F; // 10^-5 &deg;
220 
221  if( iView == DAFF_DATA_VIEW )
222  {
223 
224  /*
225  * - Alpha always within [0&deg;, +360&deg;)
226  * - Beta always within [0&deg;, +180&deg;]
227  * - At poles (beta=0&deg;|beta=180&deg;) default: alpha = 0
228  */
229 
230  float fAlpha = fAngle1In;
231  float fBeta = fmodf(fAngle2In, 360.0f);
232 
233  if (fBeta > 180.0f) {
234  fAlpha += 180.0f;
235  fBeta -= 180.0f;
236  }
237 
238  fAlpha = fmodf(fAlpha, 360.0f);
239  if (fAlpha < 0.0f)
240  fAlpha += 360.0f;
241 
242  // Note: We use thresholds here to work on wrongly rounded angles also
243  if ((std::abs( fBeta ) <= EPSILON) || // Beta == 0&deg;
244  (std::abs( fBeta-180.0f ) <= EPSILON)) // Beta == 180&deg;
245  fAlpha = 0.0f;
246 
247  fAngle1Out = roundf(fAlpha*1000.0f);
248  fAngle1Out /= 1000.0f;
249  fAngle2Out = roundf(fBeta*1000.0f);
250  fAngle2Out /= 1000.0f;
251 
252  return;
253  }
254 
255  if( iView == DAFF_OBJECT_VIEW )
256  {
257  /*
258  * - Azimuth always within (-180&deg;, +180&deg;]
259  * - Elevation always within [-90&deg;, +90&deg;]
260  * - At poles (elevation=+/-90&deg;) default: azimuth = 0
261  */
262 
263  float fAzimuth = fAngle1In;
264  float fElevation = fmodf(fAngle2In, 360.0F);
265 
266  if ((fElevation > 90.0F) && (fElevation < 270.0F)) {
267  fAzimuth += 180.0F;
268  fElevation = 180.0F - fElevation;
269  }
270 
271  // Project azimuth angle into (-180&deg;, +180&deg;]
272  fAzimuth = fmodf(fAzimuth + 180.0F, 360.0F) - 180.0F;
273  if (fAzimuth == -180.0F) fAzimuth = +180.0F;
274 
275  // Note: We use thresholds here to work on wrongly rounded angles also
276  if (std::abs(fElevation-90.0f) <= EPSILON) // Elevation == 90&deg;
277  fElevation = 90.0f;
278  if (std::abs(fElevation+90.0f) <= EPSILON) // Elevation == -90&deg;
279  fElevation = -90.0f;
280 
281  fAngle1Out = roundf(fAzimuth*1000.0f);
282  fAngle1Out /= 1000.0f;
283  fAngle2Out = roundf(fElevation*1000.0f);
284  fAngle2Out /= 1000.0f;
285 
286  return;
287  }
288 
289  // Invalid view
290  assert( false );
291 }
File has unkown content type (IR, MS, DFT, etc)
Definition: DAFFDefs.h:99
Discrete Fourier spectrum in the frequency-domain.
Definition: DAFFDefs.h:70
Invalid alpha angles or range problem.
Definition: DAFFDefs.h:100
int iVersionMinor
Minor version (example: 7 for version 1.7)
Definition: DAFFDefs.h:116
Given metadata type is unknown, use bool, int, double, string.
Definition: DAFFDefs.h:106
Invalid index (e.g. record index)
Definition: DAFFDefs.h:108
static std::string StrError(int iErrorcode)
Return the string corresponding to an errorcode.
Definition: DAFFUtils.cpp:126
static void NormalizeDirection(int iView, float fAngle1DegIn, float fAngle2DegIn, float &fAngle1DegOut, float &fAngle2DegOut)
Normalize a direction (angular pair)
Definition: DAFFUtils.cpp:217
static std::string StrShortContentType(int iContentType)
Returns a short form string corresponding to a content type e.g. ("ir", "ms", "dft"...)
Definition: DAFFUtils.cpp:179
Magnitude spectrum defined at discrete frequencies.
Definition: DAFFDefs.h:67
int iVersionMajor
Major version (example: 1 for version 1.7)
Definition: DAFFDefs.h:115
static std::string StrDirection(int iView, double dAngle1Deg, double dAngle2Deg, int precision=9, int leadingzeros=3)
Format a direction (angular pair) as a string canonically.
Definition: DAFFUtils.cpp:70
File format version is not supported by this library version.
Definition: DAFFDefs.h:103
Invalid beta angles or range problem.
Definition: DAFFDefs.h:101
Magnitude-phase spectrum defined at discrete frequencies.
Definition: DAFFDefs.h:69
static std::string StrQuantizationType(int iQuantizationType)
Returns a string corresponding to a quantization type.
Definition: DAFFUtils.cpp:205
Pure data class that covers version information.
Definition: DAFFDefs.h:113
Impulse response (IR) in the time-domain.
Definition: DAFFDefs.h:66
std::string sVersion
String of version (example: "1.7" for version 1.7)
Definition: DAFFDefs.h:117
Modal error (e.g. close a file that is not opened)
Definition: DAFFDefs.h:96
static void getLibraryVersion(DAFFVersion &version)
Get the library version.
Definition: DAFFUtils.cpp:18
static std::string Double2StrNice(double d, int precision, bool showpos, int leadingzeros=0)
Converts a double precision floating point into nice std::string.
Definition: DAFFUtils.cpp:49
Data reading error of an otherwise valid DAFF file.
Definition: DAFFDefs.h:107
static std::string StrDirectionCompact(int iView, double dAngle1Deg, double dAngle2Deg, int precision=9, int leadingzeros=3)
Format a direction (angular pair) as a string canonically and in more compact form.
Definition: DAFFUtils.cpp:98
Content parameter invalid (sampling rate, num supporting frequencies, etc)
Definition: DAFFDefs.h:104
16-Bit signed integer
Definition: DAFFDefs.h:77
static std::string StrMetadataKeyType(int iKeyType)
Returns a string corresponding to a metadata key datatype.
Definition: DAFFUtils.cpp:192
Invalid DAFF file, i.e. wrong signature.
Definition: DAFFDefs.h:97
32-Bit floating point
Definition: DAFFDefs.h:79
Data uses unrecognized or wrong quantization.
Definition: DAFFDefs.h:102
24-Bit signed integer
Definition: DAFFDefs.h:78
static std::string StrContentType(int iContentType)
Returns a string corresponding to a content type.
Definition: DAFFUtils.cpp:166
File not found.
Definition: DAFFDefs.h:105
Phase spectrum defined at discrete frequencies.
Definition: DAFFDefs.h:68
File has invalid main header parameter (num channels, etc)
Definition: DAFFDefs.h:98
static std::string Float2StrNice(float f, int precision, bool showpos, int leadingzeros=0)
Converts a single precision floating point into nice std::string.
Definition: DAFFUtils.cpp:27
Data-related view referring to data spherical coordinates (DSC)
Definition: DAFFDefs.h:86
Object-related view referring to object spherical coordinates (OSC)
Definition: DAFFDefs.h:87
OpenDAFF is a project from the Institute of Technical Acoustics, RWTH Aachen University, Germany.