Version
menu_open
link
Target Platform(s):
Wwise SDK 2019.1.11
AkPlatformFuncs.h
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Version: <VERSION> Build: <BUILDNUMBER>
25  Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
26 *******************************************************************************/
27 
28 #ifndef _AK_PLATFORM_FUNCS_H_
29 #define _AK_PLATFORM_FUNCS_H_
30 
31 #include "malloc.h"
32 #include <AK/Tools/Common/AkAssert.h>
33 #include <AK/SoundEngine/Common/AkTypes.h>
34 #include <windows.h>
35 //#define AK_ENABLE_PERF_RECORDING
36 #if defined(AK_ENABLE_PERF_RECORDING)
37 #include <stdio.h>
38 #endif
39 
40 #if defined(_WIN64)
41 // on 64 bit, removes warning C4985: 'ceil': attributes not present on previous declaration.
42 // see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=294649
43 #include <math.h>
44 #endif // _WIN64
45 #include <intrin.h>
46 
47 //-----------------------------------------------------------------------------
48 // Platform-specific thread properties definition.
49 //-----------------------------------------------------------------------------
50 struct AkThreadProperties
51 {
52  int nPriority; ///< Thread priority
53 #ifdef AK_WIN_UNIVERSAL_APP
54  PROCESSOR_NUMBER processorNumber;///< Ideal processor (passed to SetThreadIdealProcessorEx)
55 #else
56  AkUInt32 dwAffinityMask; ///< Affinity mask
57 #endif
58  AkUInt32 uStackSize; ///< Thread stack size.
59 };
60 
61 //-----------------------------------------------------------------------------
62 // External variables.
63 //-----------------------------------------------------------------------------
64 // g_fFreqRatio is used by time helpers to return time values in milliseconds.
65 // It is declared and updated by the sound engine.
66 namespace AK
67 {
68  extern AkReal32 g_fFreqRatio;
69 }
70 
71 //-----------------------------------------------------------------------------
72 // Defines for Win32.
73 //-----------------------------------------------------------------------------
74 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) DWORD WINAPI FuncName(LPVOID lpParameter)
75 #define AK_THREAD_RETURN( _param_ ) return (_param_);
76 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
77 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
78 #define AK_RETURN_THREAD_OK 0x00000000
79 #define AK_RETURN_THREAD_ERROR 0x00000001
80 #define AK_DEFAULT_STACK_SIZE (128*1024)
81 #define AK_THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
82 #define AK_THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_ABOVE_NORMAL
83 #define AK_THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_TIME_CRITICAL
84 #define AK_THREAD_MODE_BACKGROUND_BEGIN THREAD_MODE_BACKGROUND_BEGIN
85 
86 // NULL objects
87 #define AK_NULL_THREAD NULL
88 
89 #define AK_INFINITE INFINITE
90 
91 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2))
92 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2))
93 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x)))
94 
95 namespace AKPLATFORM
96 {
97  // Simple automatic event API
98  // ------------------------------------------------------------------
99 
100  /// Platform Independent Helper
101  inline void AkClearEvent( AkEvent & out_event )
102  {
103  out_event = NULL;
104  }
105 
106  /// Platform Independent Helper
107  inline AKRESULT AkCreateEvent( AkEvent & out_event )
108  {
109 #ifdef AK_USE_UWP_API
110  out_event = CreateEventEx(nullptr, nullptr, 0, STANDARD_RIGHTS_ALL|EVENT_MODIFY_STATE);
111 #else
112  out_event = ::CreateEvent( NULL, // No security attributes
113  false, // Reset type: automatic
114  false, // Initial signaled state: not signaled
115  NULL // No name
116  );
117 #endif
118  return ( out_event ) ? AK_Success : AK_Fail;
119  }
120 
121  /// Platform Independent Helper
122  inline void AkDestroyEvent( AkEvent & io_event )
123  {
124  if ( io_event )
125  ::CloseHandle( io_event );
126  io_event = NULL;
127  }
128 
129  /// Platform Independent Helper
130  inline void AkWaitForEvent( AkEvent & in_event )
131  {
132 #ifdef AK_USE_UWP_API
133 #ifdef AK_ENABLE_ASSERTS
134  DWORD dwWaitResult =
135 #endif // AK_ENABLE_ASSERTS
136  ::WaitForSingleObjectEx( in_event, INFINITE, FALSE );
137  AKASSERT( dwWaitResult == WAIT_OBJECT_0 );
138 #else
139  AKVERIFY( ::WaitForSingleObject( in_event, INFINITE ) == WAIT_OBJECT_0 );
140 #endif
141  }
142 
143  /// Platform Independent Helper
144  inline void AkSignalEvent( const AkEvent & in_event )
145  {
146  AKVERIFY( ::SetEvent( in_event ) );
147  }
148 
149 
150  // Atomic Operations
151  // ------------------------------------------------------------------
152 
153  /// Platform Independent Helper
154  inline AkInt32 AkInterlockedIncrement(AkAtomic32 * pValue)
155  {
156  return InterlockedIncrement( pValue );
157  }
158 
159  /// Platform Independent Helper
160  inline AkInt32 AkInterlockedDecrement(AkAtomic32 * pValue)
161  {
162  return InterlockedDecrement( pValue );
163  }
164 
165 #if defined AK_POINTER_64
166  inline bool AkInterlockedCompareExchange( volatile AkAtomic64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal )
167  {
168  return _InterlockedCompareExchange64(io_pDest, in_newValue, in_expectedOldVal) == in_expectedOldVal;
169  }
170 #endif
171 
172  inline bool AkInterlockedCompareExchange(volatile AkAtomic32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal)
173  {
174  return InterlockedCompareExchange(io_pDest, in_newValue, in_expectedOldVal) == in_expectedOldVal;
175  }
176 
177 #if !defined AK_POINTER_64
178  inline bool AkInterlockedCompareExchange(volatile AkAtomicPtr* io_pDest, AkIntPtr in_newValue, AkIntPtr in_expectedOldVal)
179  {
180  return InterlockedCompareExchange((volatile LONG_PTR*)io_pDest, (LONG_PTR)in_newValue, (LONG_PTR)in_expectedOldVal) == in_expectedOldVal;
181  }
182 #endif
183 
184  //Ensure that all write operations are complete. Necessary only on platforms that don't garentee the order of writes.
185  inline void AkMemoryBarrier()
186  {
187  _ReadWriteBarrier();
188  }
189 
190  // Threads
191  // ------------------------------------------------------------------
192 
193  /// Platform Independent Helper
194  inline bool AkIsValidThread( AkThread * in_pThread )
195  {
196  return (*in_pThread != AK_NULL_THREAD);
197  }
198 
199  /// Platform Independent Helper
200  inline void AkClearThread( AkThread * in_pThread )
201  {
202  *in_pThread = AK_NULL_THREAD;
203  }
204 
205  /// Platform Independent Helper
206  inline void AkCloseThread( AkThread * in_pThread )
207  {
208  AKASSERT( in_pThread );
209  AKASSERT( *in_pThread );
210  AKVERIFY( ::CloseHandle( *in_pThread ) );
211  AkClearThread( in_pThread );
212  }
213 
214 #define AkExitThread( _result ) return _result;
215 
216  /// Platform Independent Helper
217  inline void AkGetDefaultThreadProperties( AkThreadProperties & out_threadProperties )
218  {
219  out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL;
220  out_threadProperties.uStackSize= AK_DEFAULT_STACK_SIZE;
221 #ifdef AK_WIN_UNIVERSAL_APP
222  out_threadProperties.processorNumber.Group = 0;
223  out_threadProperties.processorNumber.Number = MAXIMUM_PROCESSORS;
224  out_threadProperties.processorNumber.Reserved = 0;
225 #else
226  out_threadProperties.dwAffinityMask = 0;
227 #endif
228  }
229 
230  /// Set the name of a thread: see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
231  inline void AkSetThreadName( DWORD in_dwThreadID, LPCSTR in_szThreadName )
232  {
233  const DWORD MS_VC_EXCEPTION=0x406D1388;
234 
235 #pragma pack(push,8)
236  typedef struct tagTHREADNAME_INFO
237  {
238  DWORD dwType;
239  LPCSTR szName;
240  DWORD dwThreadID;
241  DWORD dwFlags;
242  } THREADNAME_INFO;
243 #pragma pack(pop)
244 
245  THREADNAME_INFO info;
246  info.dwType = 0x1000;
247  info.szName = in_szThreadName;
248  info.dwThreadID = in_dwThreadID;
249  info.dwFlags = 0;
250 
251  __try
252  {
253  RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
254  }
255 #pragma warning(suppress: 6312 6322)
256  __except(EXCEPTION_CONTINUE_EXECUTION)
257  {
258  }
259  }
260 
261  /// Platform Independent Helper
262  inline void AkCreateThread(
263  AkThreadRoutine pStartRoutine, // Thread routine.
264  void * pParams, // Routine params.
265  const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
266  AkThread * out_pThread, // Returned thread handle.
267  const char * in_szThreadName ) // Opt thread name.
268  {
269  AKASSERT( out_pThread != NULL );
270  AKASSERT( (in_threadProperties.nPriority >= THREAD_PRIORITY_LOWEST && in_threadProperties.nPriority <= THREAD_PRIORITY_HIGHEST)
271  || ( in_threadProperties.nPriority == THREAD_PRIORITY_TIME_CRITICAL )
272  || ( in_threadProperties.nPriority == THREAD_MODE_BACKGROUND_BEGIN ) );
273 
274  DWORD dwThreadID;
275  *out_pThread = ::CreateThread( NULL, // No security attributes
276  in_threadProperties.uStackSize, // StackSize (0 uses system default)
277  pStartRoutine, // Thread start routine
278  pParams, // Thread function parameter
279  0, // Creation flags: create running
280  &dwThreadID );
281 
282  // ::CreateThread() return NULL if it fails.
283  if ( !*out_pThread )
284  {
285  AkClearThread( out_pThread );
286  return;
287  }
288 
289  // Set thread name.
290  AkSetThreadName( dwThreadID, in_szThreadName );
291 
292  // Set properties.
293  if ( !::SetThreadPriority( *out_pThread, in_threadProperties.nPriority ) &&
294  in_threadProperties.nPriority != THREAD_MODE_BACKGROUND_BEGIN )
295  {
296  AKASSERT( !"Failed setting thread priority" );
297  AkCloseThread( out_pThread );
298  return;
299  }
300 #ifdef AK_WIN_UNIVERSAL_APP
301  if ( in_threadProperties.processorNumber.Number != MAXIMUM_PROCESSORS)
302  {
303  if ( !SetThreadIdealProcessorEx( *out_pThread, const_cast<PPROCESSOR_NUMBER>(&in_threadProperties.processorNumber), NULL) )
304  {
305  AKASSERT( !"Failed setting thread ideal processor" );
306  AkCloseThread( out_pThread );
307  }
308  }
309 #else
310  if (in_threadProperties.dwAffinityMask)
311  {
312  if (!::SetThreadAffinityMask(*out_pThread, in_threadProperties.dwAffinityMask))
313  {
314  AKASSERT(!"Failed setting thread affinity mask");
315  AkCloseThread(out_pThread);
316  }
317  }
318 #endif
319  }
320 
321  /// Platform Independent Helper
322  inline void AkWaitForSingleThread( AkThread * in_pThread )
323  {
324  AKASSERT( in_pThread );
325  AKASSERT( *in_pThread );
326 #ifdef AK_USE_UWP_API
327  ::WaitForSingleObjectEx( *in_pThread, INFINITE, FALSE );
328 #else
329  ::WaitForSingleObject( *in_pThread, INFINITE );
330 #endif
331  }
332 
333  /// Returns the calling thread's ID.
334  inline AkThreadID CurrentThread()
335  {
336  return ::GetCurrentThreadId();
337  }
338 
339  /// Platform Independent Helper
340  inline void AkSleep( AkUInt32 in_ulMilliseconds )
341  {
342  ::Sleep( in_ulMilliseconds );
343  }
344 
345  // Optimized memory functions
346  // --------------------------------------------------------------------
347 
348  /// Platform Independent Helper
349  inline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize )
350  {
351  memcpy( pDest, pSrc, uSize );
352  }
353 
354  /// Platform Independent Helper
355  inline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize )
356  {
357  memset( pDest, iVal, uSize );
358  }
359 
360  // Time functions
361  // ------------------------------------------------------------------
362 
363  /// Platform Independent Helper
364  inline void PerformanceCounter( AkInt64 * out_piLastTime )
365  {
366  ::QueryPerformanceCounter( (LARGE_INTEGER*)out_piLastTime );
367  }
368 
369  /// Platform Independent Helper
370  inline void PerformanceFrequency( AkInt64 * out_piFreq )
371  {
372  ::QueryPerformanceFrequency( (LARGE_INTEGER*)out_piFreq );
373  }
374 
375  /// Platform Independent Helper
376  inline void UpdatePerformanceFrequency()
377  {
378  AkInt64 iFreq;
379  PerformanceFrequency( &iFreq );
380  AK::g_fFreqRatio = (AkReal32)((AkReal64)iFreq / 1000);
381  }
382 
383  /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
384  inline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
385  {
386  return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
387  }
388 
389  /// String conversion helper. If io_pszAnsiString is null, the function returns the required size.
390  inline AkInt32 AkWideCharToChar( const wchar_t* in_pszUnicodeString,
391  AkUInt32 in_uiOutBufferSize,
392  char* io_pszAnsiString )
393  {
394  if(!io_pszAnsiString)
395  return WideCharToMultiByte(CP_UTF8, 0, in_pszUnicodeString, -1, NULL, 0, NULL, NULL);
396 
397  int iWritten = ::WideCharToMultiByte(CP_UTF8, // code page
398  0, // performance and mapping flags
399  in_pszUnicodeString, // wide-character string
400  (int)AkMin( ( (AkUInt32)wcslen( in_pszUnicodeString )), in_uiOutBufferSize-1 ), // number of chars in string : -1 = NULL terminated string.
401  io_pszAnsiString, // buffer for new string
402  in_uiOutBufferSize, // size of buffer
403  NULL, // default for unmappable chars
404  NULL); // set when default char used
405  io_pszAnsiString[iWritten] = 0;
406  return iWritten;
407  }
408 
409  /// String conversion helper
410  inline AkInt32 AkCharToWideChar( const char* in_pszAnsiString,
411  AkUInt32 in_uiOutBufferSize,
412  void* io_pvUnicodeStringBuffer )
413  {
414  return ::MultiByteToWideChar( CP_UTF8, // code page
415  0, // performance and mapping flags
416  in_pszAnsiString, // wide-character string
417  -1, // number of chars in string : -1 = NULL terminated string.
418  (wchar_t*)io_pvUnicodeStringBuffer, // buffer for new string
419  in_uiOutBufferSize); // size of buffer
420  }
421 
422  /// String conversion helper
423  inline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String,
424  AkUInt32 in_uiOutBufferSize,
425  void* io_pvUnicodeStringBuffer )
426  {
427  return ::MultiByteToWideChar( CP_UTF8, // code page
428  0, // performance and mapping flags
429  in_pszUtf8String, // wide-character string
430  -1, // number of chars in string : -1 = NULL terminated string.
431  (wchar_t*)io_pvUnicodeStringBuffer, // buffer for new string
432  in_uiOutBufferSize); // size of buffer
433  }
434 
435  /// Safe unicode string copy.
436  inline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
437  {
438  size_t iSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
439  wcsncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy );
440  in_pDest[iSizeCopy] = '\0';
441  }
442 
443  /// Safe string copy.
444  inline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
445  {
446  size_t iSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
447  strncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy );
448  in_pDest[iSizeCopy] = '\0';
449  }
450 
451  /// Safe unicode string concatenation.
452  inline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
453  {
454  int iAvailableSize = (int)( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
455  wcsncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc, AkMin( iAvailableSize, (int)wcslen( in_pSrc ) ) );
456  }
457 
458  /// Safe string concatenation.
459  inline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
460  {
461  int iAvailableSize = (int)( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
462  strncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc, AkMin( iAvailableSize, (int)strlen( in_pSrc ) ) );
463  }
464 
465  /// Stack allocations.
466  #define AkAlloca( _size_ ) _alloca( _size_ )
467 
468  /// Output a debug message on the console
469 #if ! ( defined(AK_USE_UWP_API) || defined(AK_OPTIMIZED) )
470  inline void OutputDebugMsg( const wchar_t* in_pszMsg )
471  {
472  OutputDebugStringW( in_pszMsg );
473  }
474 
475  /// Output a debug message on the console
476  inline void OutputDebugMsg( const char* in_pszMsg )
477  {
478  OutputDebugStringA( in_pszMsg );
479  }
480 #else
481  inline void OutputDebugMsg( const wchar_t* ){}
482  inline void OutputDebugMsg( const char* ){}
483 #endif
484 
485  /// Converts a wchar_t string to an AkOSChar string.
486  /// \remark On some platforms the AkOSChar string simply points to the same string,
487  /// on others a new buffer is allocated on the stack using AkAlloca. This means
488  /// you must make sure that:
489  /// - The source string stays valid and unmodified for as long as you need the
490  /// AkOSChar string (for cases where they point to the same string)
491  /// - The AkOSChar string is used within this scope only -- for example, do NOT
492  /// return that string from a function (for cases where it is allocated on the stack)
493  #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _wstring_ )
494 
495  /// Converts a char string to an AkOSChar string.
496  /// \remark On some platforms the AkOSChar string simply points to the same string,
497  /// on others a new buffer is allocated on the stack using AkAlloca. This means
498  /// you must make sure that:
499  /// - The source string stays valid and unmodified for as long as you need the
500  /// AkOSChar string (for cases where they point to the same string)
501  /// - The AkOSChar string is used within this scope only -- for example, do NOT
502  /// return that string from a function (for cases where it is allocated on the stack)
503  #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) \
504  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + strlen( _astring_ )) * sizeof(AkOSChar)); \
505  AKPLATFORM::AkCharToWideChar( _astring_, (AkUInt32)(1 + strlen(_astring_ )), (AkOSChar*)( _oscharstring_ ) )
506 
507  /// Converts a AkOSChar string into wide char string.
508  /// \remark On some platforms the AkOSChar string simply points to the same string,
509  /// on others a new buffer is allocated on the stack using AkAlloca. This means
510  /// you must make sure that:
511  /// - The source string stays valid and unmodified for as long as you need the
512  /// AkOSChar string (for cases where they point to the same string)
513  /// - The AkOSChar string is used within this scope only -- for example, do NOT
514  /// return that string from a function (for cases where it is allocated on the stack)
515  #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) _wstring_ = _osstring_
516 
517  /// Converts a AkOSChar string into char string.
518  /// \remark On some platforms the AkOSChar string simply points to the same string,
519  /// on others a new buffer is allocated on the stack using AkAlloca. This means
520  /// you must make sure that:
521  /// - The source string stays valid and unmodified for as long as you need the
522  /// AkOSChar string (for cases where they point to the same string)
523  /// - The AkOSChar string is used within this scope only -- for example, do NOT
524  /// return that string from a function (for cases where it is allocated on the stack)
525  #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) \
526  _astring_ = (char*)AkAlloca( 1 + wcslen( _osstring_ )); \
527  AKPLATFORM::AkWideCharToChar( _osstring_, AkUInt32(1 + wcslen( _osstring_ )), _astring_ );
528 
529  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
530  /// \return The length, in characters, of the specified string (excluding terminating NULL)
531  inline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
532  {
533  return ( wcslen( in_pStr ) );
534  }
535 
536  /// Get the length, in characters, of a NULL-terminated AkOSChar string
537  /// \return The length, in characters, of the specified string (excluding terminating NULL)
538  inline size_t OsStrLen( const AkOSChar* in_pszString )
539  {
540  return ( wcslen( in_pszString ) );
541  }
542 
543  /// AkOSChar version of sprintf().
544  #define AK_OSPRINTF swprintf_s
545 
546  /// Compare two NULL-terminated AkOSChar strings
547  /// \return
548  /// - < 0 if in_pszString1 < in_pszString2
549  /// - 0 if the two strings are identical
550  /// - > 0 if in_pszString1 > in_pszString2
551  /// \remark The comparison is case-sensitive
552  inline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
553  {
554  return ( wcscmp( in_pszString1, in_pszString2 ) );
555  }
556 
557  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
558  /// \return
559  /// - < 0 if in_pszString1 < in_pszString2
560  /// - 0 if the two strings are identical
561  /// - > 0 if in_pszString1 > in_pszString2
562  /// \remark The comparison is case-sensitive
563  inline int OsStrNCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize)
564  {
565  return wcsncmp(in_pszString1, in_pszString2, in_MaxCountSize);
566  }
567 
568  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
569  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
570  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
571  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
572  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
573  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
574 
575  // Use with AkOSChar.
576  #define AK_PATH_SEPARATOR (L"\\")
577  #define AK_LIBRARY_PREFIX (L"")
578  #define AK_DYNAMIC_LIBRARY_EXTENSION (L".dll")
579 
580  #if defined(AK_ENABLE_PERF_RECORDING)
581 
582  static AkUInt32 g_uAkPerfRecExecCount = 0;
583  static AkReal32 g_fAkPerfRecExecTime = 0.f;
584 
585  #define AK_PERF_RECORDING_RESET() \
586  AKPLATFORM::g_uAkPerfRecExecCount = 0;\
587  AKPLATFORM::g_fAkPerfRecExecTime = 0.f;
588 
589  #define AK_PERF_RECORDING_START( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ ) \
590  AkInt64 iAkPerfRecTimeBefore; \
591  if ( (AKPLATFORM::g_uAkPerfRecExecCount >= (__uExecutionCountStart__)) && (AKPLATFORM::g_uAkPerfRecExecCount <= (__uExecutionCountStop__)) ) \
592  AKPLATFORM::PerformanceCounter( &iAkPerfRecTimeBefore );
593 
594  #define AK_PERF_RECORDING_STOP( __StorageName__, __uExecutionCountStart__, __uExecutionCountStop__ ) \
595  if ( (AKPLATFORM::g_uAkPerfRecExecCount >= (__uExecutionCountStart__)) && (AKPLATFORM::g_uAkPerfRecExecCount <= (__uExecutionCountStop__)) ) \
596  { \
597  AkInt64 iAkPerfRecTimeAfter; \
598  AKPLATFORM::PerformanceCounter( &iAkPerfRecTimeAfter ); \
599  AKPLATFORM::g_fAkPerfRecExecTime += AKPLATFORM::Elapsed( iAkPerfRecTimeAfter, iAkPerfRecTimeBefore ); \
600  if ( AKPLATFORM::g_uAkPerfRecExecCount == (__uExecutionCountStop__) ) \
601  { \
602  AkReal32 fAverageExecutionTime = AKPLATFORM::g_fAkPerfRecExecTime/((__uExecutionCountStop__)-(__uExecutionCountStart__)); \
603  char str[256]; \
604  sprintf_s(str, 256, "%s average execution time: %f\n", __StorageName__, fAverageExecutionTime); \
605  AKPLATFORM::OutputDebugMsg( str ); \
606  } \
607  } \
608  AKPLATFORM::g_uAkPerfRecExecCount++;
609  #endif // AK_ENABLE_PERF_RECORDING
610 }
611 
612 #ifdef AK_ENABLE_INSTRUMENT
613  #ifdef AK_XBOXONE
614  #include <AK/Tools/XBoxOne/AkInstrument.h>
615  #endif
616 #endif
617 
618 #endif // _AK_PLATFORM_FUNCS_H_
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Definition: AkPlatformFuncs.h:493
Audiokinetic namespace.
int nPriority
Thread priority.
Definition: AkPlatformFuncs.h:50
void AkClearEvent(AkEvent &out_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:49
void AkWaitForEvent(AkEvent &in_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:98
AkForceInline void UpdatePerformanceFrequency()
Platform Independent Helper.
Definition: AkPlatformFuncs.h:358
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
Definition: AkPlatformFuncs.h:57
void AkMemoryBarrier()
Definition: AkPlatformFuncs.h:91
AkInt32 AkInterlockedIncrement(AkAtomic32 *pValue)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:70
AkInt32 AkInterlockedDecrement(AkAtomic32 *pValue)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:76
AkThreadID CurrentThread()
Returns the calling thread's ID.
Definition: AkPlatformFuncs.h:315
void AkCreateThread(AkThreadRoutine pStartRoutine, void *pParams, const AkThreadProperties &in_threadProperties, AkThread *out_pThread, const char *)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:145
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:106
AkUInt32 uStackSize
Thread stack size.
Definition: AkPlatformFuncs.h:58
void AkDestroyEvent(AkEvent &io_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:78
AkForceInline bool AkIsValidThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:212
AkForceInline void AkMemCpy(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:330
AkForceInline void AkSleep(AkUInt32 in_ulMilliseconds)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:321
AkForceInline void AkClearThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:218
AkForceInline void AkGetDefaultThreadProperties(AkThreadProperties &out_threadProperties)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:237
int OsStrNCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2, size_t in_MaxCountSize)
Definition: AkPlatformFuncs.h:525
AkForceInline void AkMemSet(void *pDest, AkInt32 iVal, AkUInt32 uSize)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:336
SceKernelCpumask dwAffinityMask
Affinity mask.
Definition: AkPlatformFuncs.h:51
AkReal32 g_fFreqRatio
Definition: AkPlatformFuncs.h:71
AKRESULT AkCreateEvent(AkEvent &out_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:55
AkForceInline void SafeStrCpy(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string copy.
Definition: AkPlatformFuncs.h:412
AkUInt32 dwAffinityMask
Affinity mask.
Definition: AkPlatformFuncs.h:56
size_t uStackSize
Thread stack size.
Definition: AkPlatformFuncs.h:52
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:43
AkForceInline AkInt32 AkCharToWideChar(const char *in_pszAnsiString, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper.
Definition: AkPlatformFuncs.h:389
AkForceInline void SafeStrCat(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string concatenation.
Definition: AkPlatformFuncs.h:428
AkForceInline AkInt32 AkWideCharToChar(const wchar_t *in_pszUnicodeString, AkUInt32 in_uiOutBufferSize, char *io_pszAnsiString)
String conversion helper.
Definition: AkPlatformFuncs.h:372
AkForceInline void AkWaitForSingleThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:308
bool AkInterlockedCompareExchange(volatile AkAtomic32 *io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal)
Definition: AkPlatformFuncs.h:81
void AkSignalEvent(const AkEvent &in_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:109
AkForceInline AkInt32 AkUtf8ToWideChar(const char *in_pszUtf8String, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper.
Definition: AkPlatformFuncs.h:404
AkForceInline void AkCloseThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:224
AkForceInline int OsStrCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2)
Definition: AkPlatformFuncs.h:514
void AkSetThreadName(DWORD in_dwThreadID, LPCSTR in_szThreadName)
Set the name of a thread: see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx.
Definition: AkPlatformFuncs.h:231
AkForceInline size_t OsStrLen(const AkOSChar *in_pszString)
Definition: AkPlatformFuncs.h:500
AkForceInline AkReal32 Elapsed(const AkInt64 &in_iNow, const AkInt64 &in_iStart)
Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
Definition: AkPlatformFuncs.h:366

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise