OpenDAFF C++ API  v1.7
Directional Audio File Format
Utils.cpp
Go to the documentation of this file.
1 #include "Utils.h"
2 
3 #include <DAFFUtils.h>
4 
5 #ifdef _MSC_VER
6 // Microsoft Visual Studio compilers
7 #include <windows.h>
8 #endif
9 
10 #include <cstdlib>
11 
12 #ifdef __APPLE__
13 // Different include path on MacOS
14 #include <sys/malloc.h>
15 #else
16 #include <malloc.h>
17 #endif
18 
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 
22 namespace DAFF
23 {
24  // --= Angle conversion and normalization =--
25 
26 
27  float anglef_proj_0_2PI( float alpha ) {
28  alpha = fmodf( alpha, 2 * PI_F );
29  if( alpha < 0 ) alpha += 2 * PI_F;
30  return alpha;
31  }
32 
33  float anglef_proj_0_360_DEG( float alpha ) {
35  }
36 
37  float anglef_mindiff_0_2PI( float alpha, float beta ) {
38  float gamma = anglef_proj_0_2PI( beta ) - anglef_proj_0_2PI( alpha );
39  if( gamma >= 0 )
40  return ( gamma <= PI_F ? gamma : gamma - 2 * PI_F );
41  else
42  return ( gamma >= -PI_F ? gamma : gamma + 2 * PI_F );
43  }
44 
45  float anglef_mindiff_abs_0_2PI( float alpha, float beta ) {
46  return fabs( anglef_mindiff_0_2PI( alpha, beta ) );
47  }
48 
49  float anglef_mindiff_0_360_DEG( float alpha, float beta ) {
51  }
52 
53  float anglef_mindiff_abs_0_360_DEG( float alpha, float beta ) {
55  }
56 
57 
58  // --= Complex number conversion =--
59 
60  float cabs( float Re, float Im ){
61  return sqrt( Re*Re + Im*Im );
62  }
63 
64  float carg( float Re, float Im ){
65  if( Re > 0 )
66  return atan( Im / Re );
67  else
68  return PI_F + atan( Im / Re );
69  }
70 
71  // --= Endianess conversion functions =--
72 
73 
74  // System endianess test (inspiration: http://www.gamedev.net/reference/articles/article2091.asp)
75  static const char cTest[ 4 ] = { 1, 0, 0, 0 };
76  static const int iTest = *( int* ) cTest;
77 
78  // Function forward declarations
79  void byteswap_2byte( void*, size_t );
80  void byteswap_3byte( void*, size_t );
81  void byteswap_4byte( void*, size_t );
82  void byteswap_8byte( void*, size_t );
83  void noswap( void*, size_t );
84 
85  // Function pointers
86  // Note: iTest == 1 => Little endian
87 
88  /* DEBUG:
89  void (*DAFF::le2se_2byte)(void* src, size_t count) = &noswap;
90  void (*DAFF::le2se_4byte)(void* src, size_t count) = &noswap;
91  void (*DAFF::le2se_8byte)(void* src, size_t count) = &noswap;
92  */
93 
94  /* DEBUG: Inverse
95  void (*DAFF::le2se_2byte)(void* src, size_t count) = &byteswap_2byte;
96  void (*DAFF::le2se_4byte)(void* src, size_t count) = &byteswap_4byte;
97  void (*DAFF::le2se_8byte)(void* src, size_t count) = &byteswap_8byte;
98  */
99 
100  void( *le2se_2byte )( void* src, size_t count ) = ( iTest == 1 ? &noswap : &byteswap_2byte );
101  void( *le2se_3byte )( void* src, size_t count ) = ( iTest == 1 ? &noswap : &byteswap_3byte );
102  void( *le2se_4byte )( void* src, size_t count ) = ( iTest == 1 ? &noswap : &byteswap_4byte );
103  void( *le2se_8byte )( void* src, size_t count ) = ( iTest == 1 ? &noswap : &byteswap_8byte );
104 
110  // Swap with temporary variable
111 #define SWAP(i,j) \
112  tmp = p[i]; \
113  p[i] = p[j]; \
114  p[j] = tmp;
115 
116  void byteswap_2byte( void* src, size_t count ) {
117 
118  // In: | B1 | B0 |
119  // Out: | B0 | B1 |
120 
121  char* p = ( char* ) src;
122  char tmp;
123 
124  for( size_t i = 0; i < count; i++ ) {
125  SWAP( 0, 1 );
126 
127  p = p + 2;
128  }
129  }
130 
131  void byteswap_3byte( void* src, size_t count ) {
132 
133  // In: | B2 | B1 | B0 |
134  // Out: | B0 | B1 | B2 |
135 
136  char* p = ( char* ) src;
137  char tmp;
138 
139  for( size_t i = 0; i < count; i++ ) {
140  SWAP( 0, 2 );
141 
142  p = p + 3;
143  }
144  }
145 
146  void byteswap_4byte( void* src, size_t count ) {
147 
148  // In: | B3 | B2 | B1 | B0 |
149  // Out: | B0 | B1 | B2 | B3 |
150 
151  char* p = ( char* ) src;
152  char tmp;
153 
154  for( size_t i = 0; i < count; i++ ) {
155  SWAP( 0, 3 );
156  SWAP( 1, 2 );
157 
158  p = p + 4;
159  }
160  }
161 
162  void byteswap_8byte( void* src, size_t count ) {
163 
164  // In: | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
165  // Out: | B0 | B1 | B2 | B3 | B4 | B5 | B6 | B7 |
166 
167  char* p = ( char* ) src;
168  char tmp;
169 
170  for( size_t i = 0; i < count; i++ ) {
171  SWAP( 0, 7 );
172  SWAP( 1, 6 );
173  SWAP( 2, 5 );
174  SWAP( 3, 4 );
175 
176  p = p + 8;
177  }
178  }
179 
180  // Do nothing
181  void noswap( void*, size_t ) {}
182 
183  // --= Memory (de)allocation =--
184 
185  void* malloc_aligned16( size_t bytes ) {
186 #ifdef WIN32
187  return _aligned_malloc( bytes, 16 );
188 #elif __APPLE__
189  // [fwe 2011-10-17] Manpage for malloc on MacOS tells that
190  // malloc returns data aligned on a memory boundary,
191  // so that AltiVec, SSE, etc. work on these…
192  // Let's hope they mean 16-Byte alignment.
193  // TODO: Recheck
194  return malloc(bytes);
195 #else
196  // Default
197  return memalign(16, bytes);
198 #endif
199  }
200 
201  void free_aligned16( void* ptr ) {
202 #ifdef WIN32
203  _aligned_free( ptr );
204 #else
205  free(ptr);
206 #endif
207  }
208 
209  // --= Sample type conversion =--
210 
211 
212  void stc_sint16_to_float( float* dest, const short* src, size_t count, int input_stride, int output_stride, float gain )
213  {
214  float c = gain / 32767.0F;
215  for( size_t i = 0; i < count; i++ )
216  dest[ i*output_stride ] = ( float ) src[ i*input_stride ] * c;
217  }
218 
219  void stc_sint16_to_float_add( float* dest, const short* src, size_t count, int input_stride, int output_stride, float gain ) {
220  float c = gain / 32767.0F;
221  for( size_t i = 0; i < count; i++ )
222  dest[ i*output_stride ] += ( float ) src[ i*input_stride ] * c;
223  }
224 
225  void stc_sint24_to_float( float* dest, const void* src, size_t count, int input_stride, int output_stride, float gain ) {
226 
227  const unsigned char* p = ( const unsigned char* ) src;
228 
229  union {
230  int ivalue;
231  unsigned char byte[ 4 ];
232  };
233 
234  float c = gain / 8388607.0F;
235 
236  if( iTest != 1 ) {
237  for( size_t i = 0; i < count; i++ ) {
238 
239  // Big endian
240  byte[ 1 ] = p[ 0 ];
241  byte[ 2 ] = p[ 1 ];
242  byte[ 3 ] = p[ 2 ];
243 
244  // Input value negative (MSB = 1)?
245  if( p[ 1 ] & 0x80 )
246  byte[ 0 ] = 0xFF;
247  else
248  byte[ 0 ] = 0x00;
249 
250  dest[ i*output_stride ] = ( float ) ivalue * c;
251 
252  p = p + input_stride * 3;
253  }
254  }
255  else {
256  for( size_t i = 0; i < count; i++ ) {
257 
258  // Little endian
259  byte[ 0 ] = p[ 0 ];
260  byte[ 1 ] = p[ 1 ];
261  byte[ 2 ] = p[ 2 ];
262 
263  // Input value negative (MSB = 1)?
264  if( p[ 2 ] & 0x80 )
265  byte[ 3 ] = 0xFF;
266  else
267  byte[ 3 ] = 0x00;
268 
269  dest[ i*output_stride ] = ( float ) ivalue * c;
270 
271  p = p + input_stride * 3;
272  }
273  }
274  }
275 
276  void stc_sint24_to_float_add( float* dest, const void* src, size_t count, int input_stride, int output_stride, float gain ) {
277 
278  const unsigned char* p = ( const unsigned char* ) src;
279 
280  union {
281  int ivalue;
282  unsigned char byte[ 4 ];
283  };
284 
285  float c = gain / 8388607.0F;
286 
287  if( iTest != 1 ) {
288  for( size_t i = 0; i < count; i++ ) {
289 
290  // Big endian
291  byte[ 1 ] = p[ 0 ];
292  byte[ 2 ] = p[ 1 ];
293  byte[ 3 ] = p[ 2 ];
294 
295  // Input value negative (MSB = 1)?
296  if( p[ 1 ] & 0x80 )
297  byte[ 0 ] = 0xFF;
298  else
299  byte[ 0 ] = 0x00;
300 
301  dest[ i*output_stride ] += ( float ) ivalue * c;
302 
303  p = p + input_stride * 3;
304  }
305  }
306  else {
307  for( size_t i = 0; i < count; i++ ) {
308 
309  // Little endian
310  byte[ 0 ] = p[ 0 ];
311  byte[ 1 ] = p[ 1 ];
312  byte[ 2 ] = p[ 2 ];
313 
314  // Input value negative (MSB = 1)?
315  if( p[ 2 ] & 0x80 )
316  byte[ 3 ] = 0xFF;
317  else
318  byte[ 3 ] = 0x00;
319 
320  dest[ i*output_stride ] += ( float ) ivalue * c;
321 
322  p = p + input_stride * 3;
323  }
324  }
325  }
326 
327 
328  // --= File system functions =--
329 
330 
331  int64_t getFileSize( const std::string& sFilename ) {
332  if( sFilename.empty() )
333  return -1;
334 
335 #ifdef _MSC_VER
336  // Microsoft Visual Studio compilers
337  struct _stat64 statinfo;
338  if( _stat64( sFilename.c_str(), &statinfo ) != 0 )
339  return -1;
340  return ( int64_t ) statinfo.st_size;
341 #else
342  // TODO: 64-bit support
343  struct stat statinfo;
344  if (stat(sFilename.c_str(), &statinfo) != 0)
345  return -1;
346  return (int64_t) statinfo.st_size;
347 #endif
348 
349  }
350 
351 } // End of namespace "DAFF"
float anglef_proj_0_2PI(float alpha)
Definition: Utils.cpp:27
static float rad2gradf(float phi)
Definition: DAFFUtils.h:104
int64_t getFileSize(const std::string &sFilename)
Größe einer Datei in Bytes zurückgeben (Gibt im Fehlerfall -1 zurück)
Definition: Utils.cpp:331
float anglef_proj_0_360_DEG(float alpha)
Definition: Utils.cpp:33
void byteswap_3byte(void *, size_t)
Definition: Utils.cpp:131
void(* le2se_2byte)(void *src, size_t count)
Definition: Utils.cpp:100
void(* le2se_3byte)(void *src, size_t count)
Definition: Utils.cpp:101
float anglef_mindiff_0_360_DEG(float alpha, float beta)
Definition: Utils.cpp:49
float anglef_mindiff_0_2PI(float alpha, float beta)
Definition: Utils.cpp:37
void stc_sint16_to_float(float *dest, const short *src, size_t count, int input_stride, int output_stride, float gain)
Convert signed integer 16-Bit -> single precision floating point (32-Bit)
Definition: Utils.cpp:212
void stc_sint24_to_float(float *dest, const void *src, size_t count, int input_stride, int output_stride, float gain)
Convert signed integer 24-Bit -> single precision floating point (32-Bit)
Definition: Utils.cpp:225
float carg(float Re, float Im)
Definition: Utils.cpp:64
void byteswap_2byte(void *, size_t)
Definition: Utils.cpp:116
void stc_sint16_to_float_add(float *dest, const short *src, size_t count, int input_stride, int output_stride, float gain)
Definition: Utils.cpp:219
void noswap(void *, size_t)
Definition: Utils.cpp:181
void byteswap_8byte(void *, size_t)
Definition: Utils.cpp:162
float anglef_mindiff_abs_0_360_DEG(float alpha, float beta)
Definition: Utils.cpp:53
static float grad2radf(float phi)
Definition: DAFFUtils.h:99
void(* le2se_4byte)(void *src, size_t count)
Definition: Utils.cpp:102
#define SWAP(i, j)
Definition: Utils.cpp:111
void byteswap_4byte(void *, size_t)
Definition: Utils.cpp:146
Definition: DAFFUtils.h:20
float cabs(float Re, float Im)
Definition: Utils.cpp:60
void * malloc_aligned16(size_t bytes)
Definition: Utils.cpp:185
float anglef_mindiff_abs_0_2PI(float alpha, float beta)
Definition: Utils.cpp:45
void stc_sint24_to_float_add(float *dest, const void *src, size_t count, int input_stride, int output_stride, float gain)
Definition: Utils.cpp:276
void(* le2se_8byte)(void *src, size_t count)
Definition: Utils.cpp:103
void free_aligned16(void *ptr)
Definition: Utils.cpp:201
OpenDAFF is a project from the Institute of Technical Acoustics, RWTH Aachen University, Germany.