Version
menu

Target Platform(s):
Wwise SDK 2024.1.5
AkPlatformFuncs.h
Go to the documentation of this file.
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  Copyright (c) 2025 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #ifndef _AK_PLATFORM_FUNCS_H_
28 #define _AK_PLATFORM_FUNCS_H_
29 
30 #if !defined(WIN32_LEAN_AND_MEAN)
31 #define WIN32_LEAN_AND_MEAN
32 #endif
33 #include <windows.h>
34 #include <malloc.h>
35 
37 #include <stdio.h>
38 
39 #if defined(_WIN64)
40 // on 64 bit, removes warning C4985: 'ceil': attributes not present on previous declaration.
41 // see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=294649
42 #include <math.h>
43 #endif // _WIN64
44 #include <intrin.h>
45 
46 //-----------------------------------------------------------------------------
47 // Platform-specific thread properties definition.
48 //-----------------------------------------------------------------------------
49 struct AkThreadProperties
50 {
51  int nPriority; ///< Thread priority
52  AkUInt32 dwAffinityMask; ///< Affinity mask
53  AkUInt32 uStackSize; ///< Thread stack size.
54 };
55 
56 //-----------------------------------------------------------------------------
57 // External variables.
58 //-----------------------------------------------------------------------------
59 // g_fFreqRatio is used by time helpers to return time values in milliseconds.
60 // It is declared and updated by the sound engine.
61 namespace AK
62 {
63  extern AkReal32 g_fFreqRatio;
64 }
65 
66 //-----------------------------------------------------------------------------
67 // Defines for Win32.
68 //-----------------------------------------------------------------------------
69 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) DWORD WINAPI FuncName(LPVOID lpParameter)
70 #define AK_THREAD_RETURN( _param_ ) return (_param_);
71 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
72 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
73 #define AK_RETURN_THREAD_OK 0x00000000
74 #define AK_RETURN_THREAD_ERROR 0x00000001
75 #define AK_DEFAULT_STACK_SIZE (128*1024)
76 #define AK_THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
77 #define AK_THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_ABOVE_NORMAL
78 #define AK_THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_BELOW_NORMAL
79 #define AK_THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_TIME_CRITICAL
80 #define AK_THREAD_MODE_BACKGROUND_BEGIN THREAD_MODE_BACKGROUND_BEGIN
81 
82 // NULL objects
83 #define AK_NULL_THREAD NULL
84 
85 #define AK_INFINITE INFINITE
86 
87 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2))
88 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2))
89 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x)))
90 
91 namespace AKPLATFORM
92 {
93  // Simple automatic event API
94  // ------------------------------------------------------------------
95 
96  /// Platform Independent Helper
97  inline void AkClearEvent( AkEvent & out_event )
98  {
99  out_event = NULL;
100  }
101 
102  /// Platform Independent Helper
103  inline AKRESULT AkCreateEvent( AkEvent & out_event )
104  {
105  out_event = ::CreateEvent( NULL, // No security attributes
106  false, // Reset type: automatic
107  false, // Initial signaled state: not signaled
108  NULL // No name
109  );
110  return ( out_event ) ? AK_Success : AK_Fail;
111  }
112 
113  /// Platform Independent Helper
114  inline void AkDestroyEvent( AkEvent & io_event )
115  {
116  if ( io_event )
117  ::CloseHandle( io_event );
118  io_event = NULL;
119  }
120 
121  /// Platform Independent Helper
122  inline void AkWaitForEvent( AkEvent & in_event )
123  {
124  AKVERIFY( ::WaitForSingleObject( in_event, INFINITE ) == WAIT_OBJECT_0 );
125  }
126 
127  /// Platform Independent Helper
128  inline void AkSignalEvent( const AkEvent & in_event )
129  {
130  AKVERIFY( ::SetEvent( in_event ) );
131  }
132 
133  /// Platform Independent Helper
134  AkForceInline void AkClearSemaphore(AkSemaphore& io_semaphore)
135  {
136  io_semaphore = NULL;
137  }
138 
139  /// Platform Independent Helper
140  inline AKRESULT AkCreateSemaphore(AkSemaphore& out_semaphore, AkUInt32 in_initialCount)
141  {
142  out_semaphore = ::CreateSemaphore(
143  NULL, // no security attributes
144  in_initialCount, // initial count
145  INT_MAX, // no maximum -- matches posix semaphore behaviour
146  NULL); // no name
147  return (out_semaphore) ? AK_Success : AK_Fail;
148  }
149 
150  /// Platform Independent Helper
151  inline void AkDestroySemaphore(AkSemaphore& io_semaphore)
152  {
153  ::CloseHandle(io_semaphore);
154  }
155 
156  /// Platform Independent Helper - Semaphore wait, aka Operation P. Decrements value of semaphore, and, if the semaphore would be less than 0, waits for the semaphore to be released.
157  inline void AkWaitForSemaphore(AkSemaphore& in_semaphore)
158  {
159  AKVERIFY(::WaitForSingleObject(in_semaphore, INFINITE) == WAIT_OBJECT_0);
160  }
161 
162  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an arbitrary count.
163  inline void AkReleaseSemaphore(AkSemaphore& in_semaphore, AkUInt32 in_count)
164  {
165  AKVERIFY(ReleaseSemaphore(in_semaphore, in_count, NULL) >= 0);
166  }
167 
168  // Threads
169  // ------------------------------------------------------------------
170 
171  /// Platform Independent Helper
172  inline bool AkIsValidThread( AkThread * in_pThread )
173  {
174  return (*in_pThread != AK_NULL_THREAD);
175  }
176 
177  /// Platform Independent Helper
178  inline void AkClearThread( AkThread * in_pThread )
179  {
180  *in_pThread = AK_NULL_THREAD;
181  }
182 
183  /// Platform Independent Helper
184  inline void AkCloseThread( AkThread * in_pThread )
185  {
186  AKASSERT( in_pThread );
187  AKASSERT( *in_pThread );
188  AKVERIFY( ::CloseHandle( *in_pThread ) );
189  AkClearThread( in_pThread );
190  }
191 
192 #define AkExitThread( _result ) return _result;
193 
194  /// Platform Independent Helper
195  inline void AkGetDefaultThreadProperties( AkThreadProperties & out_threadProperties )
196  {
197  out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL;
198  out_threadProperties.uStackSize= AK_DEFAULT_STACK_SIZE;
199  out_threadProperties.dwAffinityMask = 0;
200  }
201 
202  /// Set the name of a thread: see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
203  inline void AkSetThreadName( AkThread in_threadHnd, DWORD in_dwThreadID, LPCSTR in_szThreadName )
204  {
205  AK_UNUSEDVAR(in_threadHnd);
206  const DWORD MS_VC_EXCEPTION=0x406D1388;
207 
208 #pragma pack(push,8)
209  typedef struct tagTHREADNAME_INFO
210  {
211  DWORD dwType;
212  LPCSTR szName;
213  DWORD dwThreadID;
214  DWORD dwFlags;
215  } THREADNAME_INFO;
216 #pragma pack(pop)
217 
218  THREADNAME_INFO info;
219  info.dwType = 0x1000;
220  info.szName = in_szThreadName;
221  info.dwThreadID = in_dwThreadID;
222  info.dwFlags = 0;
223 
224  __try
225  {
226  RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
227  }
228 #pragma warning(suppress: 6312 6322)
229  __except(EXCEPTION_CONTINUE_EXECUTION)
230  {
231  }
232 
233 #if defined(AK_XBOX) || defined(_GAMING_DESKTOP) // also applicable on Windows when Win7 support is dropped. SetThreadDescription is a Win10 only API
234  wchar_t wszThreadName[32];
235  AkUInt32 maxStrLen = (sizeof(wszThreadName) / sizeof(wchar_t)) - 1;
236  AkUInt32 nameStrLen = AkMin((int)strlen(in_szThreadName), maxStrLen);
237  MultiByteToWideChar(CP_UTF8, 0, in_szThreadName, nameStrLen, wszThreadName, maxStrLen);
238  wszThreadName[nameStrLen] = '\0';
239  SetThreadDescription(in_threadHnd, wszThreadName);
240 #endif
241  }
242 
243  /// Platform Independent Helper
244  inline void AkCreateThread(
245  AkThreadRoutine pStartRoutine, // Thread routine.
246  void * pParams, // Routine params.
247  const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
248  AkThread * out_pThread, // Returned thread handle.
249  const char * in_szThreadName ) // Opt thread name.
250  {
251  AKASSERT( out_pThread != NULL );
252  AKASSERT( (in_threadProperties.nPriority >= THREAD_PRIORITY_LOWEST && in_threadProperties.nPriority <= THREAD_PRIORITY_HIGHEST)
253  || ( in_threadProperties.nPriority == THREAD_PRIORITY_TIME_CRITICAL )
254  || ( in_threadProperties.nPriority == THREAD_MODE_BACKGROUND_BEGIN ) );
255 
256  DWORD dwThreadID;
257  *out_pThread = ::CreateThread( NULL, // No security attributes
258  in_threadProperties.uStackSize, // StackSize (0 uses system default)
259  pStartRoutine, // Thread start routine
260  pParams, // Thread function parameter
261  CREATE_SUSPENDED, // Creation flags: create suspended so we can set priority/affinity before starting
262  &dwThreadID );
263 
264  // ::CreateThread() return NULL if it fails.
265  if ( !*out_pThread )
266  {
267  AkClearThread( out_pThread );
268  return;
269  }
270 
271  // Set thread name.
272  if (in_szThreadName)
273  {
274  AkSetThreadName(*out_pThread, dwThreadID, in_szThreadName);
275  }
276 
277  // Set properties.
278  if ( !::SetThreadPriority( *out_pThread, in_threadProperties.nPriority ) &&
279  in_threadProperties.nPriority != THREAD_MODE_BACKGROUND_BEGIN )
280  {
281  AKASSERT( !"Failed setting thread priority" );
282  AkCloseThread( out_pThread );
283  AkClearThread(out_pThread);
284  return;
285  }
286  if (in_threadProperties.dwAffinityMask)
287  {
288  AkUInt32 dwAffinityMask = in_threadProperties.dwAffinityMask;
289  DWORD_PTR procAffinity, sysAffinity;
290  if (::GetProcessAffinityMask(::GetCurrentProcess(), &procAffinity, &sysAffinity))
291  {
292  // To avoid errors in SetThreadAffinityMask, make sure the user-supplied mask is a subset of what is allowed by the process
293  dwAffinityMask &= procAffinity;
294  }
295  if (!::SetThreadAffinityMask(*out_pThread, dwAffinityMask))
296  {
297  AKASSERT(!"Failed setting thread affinity mask");
298  AkCloseThread(out_pThread);
299  AkClearThread(out_pThread);
300  return;
301  }
302  }
303 
304  // Thread is ready, start it up.
305  if (!::ResumeThread(*out_pThread))
306  {
307  AKASSERT(!"Failed to start the thread");
308  AkCloseThread(out_pThread);
309  AkClearThread(out_pThread);
310  return;
311  }
312  }
313 
314  /// Platform Independent Helper
315  inline void AkWaitForSingleThread( AkThread * in_pThread )
316  {
317  AKASSERT( in_pThread );
318  AKASSERT( *in_pThread );
319  ::WaitForSingleObject( *in_pThread, INFINITE );
320  }
321 
322  /// Returns the calling thread's ID.
323  inline AkThreadID CurrentThread()
324  {
325  return ::GetCurrentThreadId();
326  }
327 
328  /// Platform Independent Helper
329  inline void AkSleep( AkUInt32 in_ulMilliseconds )
330  {
331  ::Sleep( in_ulMilliseconds );
332  }
333 
334  // Time functions
335  // ------------------------------------------------------------------
336 
337  /// Platform Independent Helper
338  inline void PerformanceCounter( AkInt64 * out_piLastTime )
339  {
340  ::QueryPerformanceCounter( (LARGE_INTEGER*)out_piLastTime );
341  }
342 
343  /// Platform Independent Helper
344  inline void PerformanceFrequency( AkInt64 * out_piFreq )
345  {
346  ::QueryPerformanceFrequency( (LARGE_INTEGER*)out_piFreq );
347  }
348 
349  /// Platform Independent Helper
350  inline void UpdatePerformanceFrequency()
351  {
352  AkInt64 iFreq;
353  PerformanceFrequency( &iFreq );
354  AK::g_fFreqRatio = (AkReal32)((AkReal64)iFreq / 1000);
355  }
356 
357  /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
358  inline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
359  {
360  return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
361  }
362 
363  /// String conversion helper. If io_pszAnsiString is null, the function returns the required size.
364  inline AkInt32 AkWideCharToChar( const wchar_t* in_pszUnicodeString,
365  AkUInt32 in_uiOutBufferSize,
366  char* io_pszAnsiString )
367  {
368  if(!io_pszAnsiString)
369  return WideCharToMultiByte(CP_UTF8, 0, in_pszUnicodeString, -1, NULL, 0, NULL, NULL);
370 
371  int iWritten = ::WideCharToMultiByte(CP_UTF8, // code page
372  0, // performance and mapping flags
373  in_pszUnicodeString, // wide-character string
374  (int)AkMin( ( (AkUInt32)wcslen( in_pszUnicodeString )), in_uiOutBufferSize-1 ), // number of chars in string : -1 = NULL terminated string.
375  io_pszAnsiString, // buffer for new string
376  in_uiOutBufferSize, // size of buffer
377  NULL, // default for unmappable chars
378  NULL); // set when default char used
379  io_pszAnsiString[iWritten] = 0;
380  return iWritten;
381  }
382 
383  /// String conversion helper
384  inline AkInt32 AkCharToWideChar( const char* in_pszAnsiString,
385  AkUInt32 in_uiOutBufferSize,
386  void* io_pvUnicodeStringBuffer )
387  {
388  return ::MultiByteToWideChar( CP_UTF8, // code page
389  0, // performance and mapping flags
390  in_pszAnsiString, // wide-character string
391  -1, // number of chars in string : -1 = NULL terminated string.
392  (wchar_t*)io_pvUnicodeStringBuffer, // buffer for new string
393  in_uiOutBufferSize); // size of buffer
394  }
395 
396  /// String conversion helper
397  inline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String,
398  AkUInt32 in_uiOutBufferSize,
399  void* io_pvUnicodeStringBuffer )
400  {
401  return ::MultiByteToWideChar( CP_UTF8, // code page
402  0, // performance and mapping flags
403  in_pszUtf8String, // wide-character string
404  -1, // number of chars in string : -1 = NULL terminated string.
405  (wchar_t*)io_pvUnicodeStringBuffer, // buffer for new string
406  in_uiOutBufferSize); // size of buffer
407  }
408 
409  /// Safe unicode string copy.
410  inline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
411  {
412  size_t iSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
413  wcsncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy );
414  in_pDest[iSizeCopy] = '\0';
415  }
416 
417  /// Safe string copy.
418  inline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
419  {
420  size_t iSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
421  strncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy );
422  in_pDest[iSizeCopy] = '\0';
423  }
424 
425  /// Safe unicode string concatenation.
426  inline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
427  {
428  int iAvailableSize = (int)( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
429  wcsncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc, AkMin( iAvailableSize, (int)wcslen( in_pSrc ) ) );
430  }
431 
432  /// Safe string concatenation.
433  inline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
434  {
435  int iAvailableSize = (int)( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
436  strncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc, AkMin( iAvailableSize, (int)strlen( in_pSrc ) ) );
437  }
438 
439  inline int SafeStrFormat(wchar_t * in_pDest, size_t in_uDestMaxNumChars, const wchar_t* in_pszFmt, ...)
440  {
441  va_list args;
442  va_start(args, in_pszFmt);
443  int r = vswprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
444  va_end(args);
445  return r;
446  }
447 
448  inline int SafeStrFormat(char * in_pDest, size_t in_uDestMaxNumChars, const char* in_pszFmt, ...)
449  {
450  va_list args;
451  va_start(args, in_pszFmt);
452  int r = vsnprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
453  va_end(args);
454  return r;
455  }
456 
457  /// Stack allocations.
458  #define AkAlloca( _size_ ) _alloca( _size_ )
459 
460  /// Output a debug message on the console
461 #if ! defined(AK_OPTIMIZED)
462  inline void OutputDebugMsg( const wchar_t* in_pszMsg )
463  {
464  OutputDebugStringW( in_pszMsg );
465  }
466 
467  /// Output a debug message on the console
468  inline void OutputDebugMsg( const char* in_pszMsg )
469  {
470  OutputDebugStringA( in_pszMsg );
471  }
472 
473  /// Output a debug message on the console (variadic function).
474  /// Use MaxSize to specify the size to reserve for the message.
475  /// Warning: On Win32, OutputDebugMsgV with wchar_t will truncate the string
476  /// to MaxSize.
477  template <int MaxSize = 256>
478  inline void OutputDebugMsgV(const wchar_t* in_pszFmt, ...)
479  {
480  // No equivalent of snprintf for wide string so truncate if necessary
481  // vswprintf returns the number of characters written and not the numbers
482  // that would be written
483 
484  wchar_t* msg = (wchar_t*)AkAlloca(MaxSize * sizeof(wchar_t));
485  msg[MaxSize - 1] = '\0';
486 
487  va_list args;
488  va_start(args, in_pszFmt);
489  vswprintf(msg, MaxSize, in_pszFmt, args);
490  va_end(args);
491 
492  OutputDebugMsg(msg);
493  }
494 
495  /// Output a debug message on the console (variadic function).
496  /// Use MaxSize to specify the expected size of the message.
497  /// If the required size is superior to MaxSize, a new string
498  /// will be allocated on the stack with the required size.
499  template <int MaxSize = 256>
500  inline void OutputDebugMsgV(const char* in_pszFmt, ...)
501  {
502  int size = 0;
503  {
504  // Try with a reasonable guess first
505  char msg[MaxSize];
506  msg[MaxSize - 1] = '\0';
507 
508  va_list args;
509  va_start(args, in_pszFmt);
510  size = vsnprintf(msg, MaxSize, in_pszFmt, args);
511  va_end(args);
512 
513  // If it was enough, print to debug log
514  if (0 <= size && size <= MaxSize)
515  {
516  OutputDebugMsg(msg);
517  return;
518  }
519  }
520 
521  // Else, we need more memory to prevent truncation
522  {
523  // size + 1 more char for the last '\0'
524  size++;
525 
526  char* msg = (char*)AkAlloca((size) * sizeof(char));
527  msg[size - 1] = '\0';
528 
529  va_list args;
530  va_start(args, in_pszFmt);
531  vsnprintf(msg, size, in_pszFmt, args);
532  va_end(args);
533 
534  OutputDebugMsg(msg);
535  }
536  }
537 
538 #else
539  inline void OutputDebugMsg(const wchar_t*){}
540  inline void OutputDebugMsg(const char*){}
541 
542  template <int MaxSize = 0>
543  inline void OutputDebugMsgV(const wchar_t*, ...) {}
544 
545  template <int MaxSize = 0>
546  inline void OutputDebugMsgV(const char*, ...) {}
547 #endif
548 
549  /// Converts a wchar_t string to an AkOSChar string.
550  /// \remark On some platforms the AkOSChar string simply points to the same string,
551  /// on others a new buffer is allocated on the stack using AkAlloca. This means
552  /// you must make sure that:
553  /// - The source string stays valid and unmodified for as long as you need the
554  /// AkOSChar string (for cases where they point to the same string)
555  /// - The AkOSChar string is used within this scope only -- for example, do NOT
556  /// return that string from a function (for cases where it is allocated on the stack)
557  #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _wstring_ )
558 
559  /// Converts a char string to an AkOSChar string.
560  /// \remark On some platforms the AkOSChar string simply points to the same string,
561  /// on others a new buffer is allocated on the stack using AkAlloca. This means
562  /// you must make sure that:
563  /// - The source string stays valid and unmodified for as long as you need the
564  /// AkOSChar string (for cases where they point to the same string)
565  /// - The AkOSChar string is used within this scope only -- for example, do NOT
566  /// return that string from a function (for cases where it is allocated on the stack)
567  #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) \
568  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + strlen( _astring_ )) * sizeof(AkOSChar)); \
569  AKPLATFORM::AkCharToWideChar( _astring_, (AkUInt32)(1 + strlen(_astring_ )), (AkOSChar*)( _oscharstring_ ) )
570 
571  /// Converts a AkOSChar string into wide char string.
572  /// \remark On some platforms the AkOSChar string simply points to the same string,
573  /// on others a new buffer is allocated on the stack using AkAlloca. This means
574  /// you must make sure that:
575  /// - The source string stays valid and unmodified for as long as you need the
576  /// AkOSChar string (for cases where they point to the same string)
577  /// - The AkOSChar string is used within this scope only -- for example, do NOT
578  /// return that string from a function (for cases where it is allocated on the stack)
579  #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) _wstring_ = _osstring_
580 
581  /// Converts a AkOSChar string into char string.
582  /// \remark On some platforms the AkOSChar string simply points to the same string,
583  /// on others a new buffer is allocated on the stack using AkAlloca. This means
584  /// you must make sure that:
585  /// - The source string stays valid and unmodified for as long as you need the
586  /// AkOSChar string (for cases where they point to the same string)
587  /// - The AkOSChar string is used within this scope only -- for example, do NOT
588  /// return that string from a function (for cases where it is allocated on the stack)
589  #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) \
590  _astring_ = (char*)AkAlloca( 1 + AKPLATFORM::AkWideCharToChar( _osstring_, 0, NULL )); \
591  AKPLATFORM::AkWideCharToChar( _osstring_, AkUInt32(1 + AKPLATFORM::AkWideCharToChar( _osstring_, 0, NULL )), _astring_ );
592 
593  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
594  /// \return The length, in characters, of the specified string (excluding terminating NULL)
595  inline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
596  {
597  return ( wcslen( in_pStr ) );
598  }
599 
600  /// Get the length, in characters, of a NULL-terminated AkOSChar string
601  /// \return The length, in characters, of the specified string (excluding terminating NULL)
602  inline size_t OsStrLen( const AkOSChar* in_pszString )
603  {
604  return ( wcslen( in_pszString ) );
605  }
606 
607  /// AkOSChar version of sprintf().
608  #define AK_OSPRINTF swprintf_s
609 
610  /// Compare two NULL-terminated AkOSChar strings
611  /// \return
612  /// - < 0 if in_pszString1 < in_pszString2
613  /// - 0 if the two strings are identical
614  /// - > 0 if in_pszString1 > in_pszString2
615  /// \remark The comparison is case-sensitive
616  inline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
617  {
618  return ( wcscmp( in_pszString1, in_pszString2 ) );
619  }
620 
621  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
622  /// \return
623  /// - < 0 if in_pszString1 < in_pszString2
624  /// - 0 if the two strings are identical
625  /// - > 0 if in_pszString1 > in_pszString2
626  /// \remark The comparison is case-sensitive
627  inline int OsStrNCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize)
628  {
629  return wcsncmp(in_pszString1, in_pszString2, in_MaxCountSize);
630  }
631 
632  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
633  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
634  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
635  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
636  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
637  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
638  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
639 
640  /// Detects whether the string represents an absolute path to a file
641  inline bool IsAbsolutePath(const AkOSChar* in_pszPath, size_t in_pathLen)
642  {
643  return
644  (in_pathLen >= 3 && in_pszPath[1] == ':' && in_pszPath[2] == '\\') || // Classic "C:\..." DOS-style path
645  (in_pathLen >= 2 && in_pszPath[0] == '\\'); // Uncommon "\..." absolute path from current drive, or UNC "\\..."
646  }
647 
648  // Use with AkOSChar.
649  #define AK_PATH_SEPARATOR L"\\"
650  #define AK_LIBRARY_PREFIX L""
651  #define AK_DYNAMIC_LIBRARY_EXTENSION L".dll"
652 
653  #define AK_FILEHANDLE_TO_UINTPTR(_h) ((AkUIntPtr)_h)
654  #define AK_SET_FILEHANDLE_TO_UINTPTR(_h,_u) _h = (AkFileHandle)_u
655 
656 }
657 
658 #endif // _AK_PLATFORM_FUNCS_H_
AKRESULT AkCreateSemaphore(AkSemaphore &out_semaphore, AkUInt32 in_initialCount)
Platform Independent Helper.
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Definition of data structures for AkAudioObject.
@ AK_Fail
The operation failed.
Definition: AkTypes.h:137
#define AK_THREAD_PRIORITY_NORMAL
semaphore_t AkEvent
Definition: AkTypes.h:84
#define AK_DEFAULT_STACK_SIZE
int nPriority
Thread priority.
void AkClearEvent(AkEvent &out_event)
Platform Independent Helper.
AkForceInline void AkClearSemaphore(AkSemaphore &io_semaphore)
Platform Independent Helper.
Platform-dependent helpers.
void AkWaitForEvent(AkEvent &in_event)
Platform Independent Helper.
AkForceInline void UpdatePerformanceFrequency()
Platform Independent Helper.
int AkThreadID
Definition: AkTypes.h:69
AKRESULT
Standard function call result.
Definition: AkTypes.h:134
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
char AkOSChar
Generic character string.
Definition: AkTypes.h:60
int SafeStrFormat(wchar_t *in_pDest, size_t in_uDestMaxNumChars, const wchar_t *in_pszFmt,...)
#define NULL
Definition: AkTypes.h:46
AkThreadID CurrentThread()
Returns the calling thread's ID.
bool IsAbsolutePath(const AkOSChar *in_pszPath, size_t in_pathLen)
Detects whether the string represents an absolute path to a file.
float AkReal32
32-bit floating point
@ AK_Success
The operation was successful.
Definition: AkTypes.h:136
int32_t AkInt32
Signed 32-bit integer.
void AkCreateThread(AkThreadRoutine pStartRoutine, void *pParams, const AkThreadProperties &in_threadProperties, AkThread *out_pThread, const char *)
Platform Independent Helper.
AkUInt16 AkUtf16
Definition: AkTypes.h:61
void OutputDebugMsgV(const char *in_pszFmt,...)
Output a debug message on the console (variadic function).
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
AkUInt32 uStackSize
Thread stack size.
void AkSetThreadName(AkThread in_threadHnd, DWORD in_dwThreadID, LPCSTR in_szThreadName)
Set the name of a thread: see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx.
void AkDestroySemaphore(AkSemaphore &io_semaphore)
Platform Independent Helper.
void AkDestroyEvent(AkEvent &io_event)
Platform Independent Helper.
nn::os::ThreadFunction AkThreadRoutine
Thread routine.
Definition: AkTypes.h:90
AkForceInline bool AkIsValidThread(AkThread *in_pThread)
Platform Independent Helper.
#define AKASSERT(Condition)
Definition: AkAssert.h:67
#define AKVERIFY(x)
Definition: AkAssert.h:69
AkForceInline void AkSleep(AkUInt32 in_ulMilliseconds)
Platform Independent Helper.
AkForceInline void AkClearThread(AkThread *in_pThread)
Platform Independent Helper.
AkForceInline void AkGetDefaultThreadProperties(AkThreadProperties &out_threadProperties)
Platform Independent Helper.
#define AK_NULL_THREAD
int OsStrNCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2, size_t in_MaxCountSize)
SceKernelCpumask dwAffinityMask
Affinity mask.
AkReal32 g_fFreqRatio
double AkReal64
64-bit floating point
#define AkMin(x1, x2)
AKRESULT AkCreateEvent(AkEvent &out_event)
Platform Independent Helper.
AkForceInline void SafeStrCpy(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string copy.
int64_t AkInt64
Signed 64-bit integer.
AkUInt32 dwAffinityMask
Affinity mask.
void AkWaitForSemaphore(AkSemaphore &in_semaphore)
Platform Independent Helper - Semaphore wait, aka Operation P. Decrements value of semaphore,...
size_t uStackSize
Thread stack size.
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
AkForceInline AkInt32 AkCharToWideChar(const char *in_pszAnsiString, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper.
uint32_t AkUInt32
Unsigned 32-bit integer.
#define AK_UNUSEDVAR(x)
Definition: AkPlatforms.h:157
void AkReleaseSemaphore(AkSemaphore &in_semaphore, AkUInt32 in_count)
Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an ...
AkForceInline void SafeStrCat(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string concatenation.
AkForceInline AkInt32 AkWideCharToChar(const wchar_t *in_pszUnicodeString, AkUInt32 in_uiOutBufferSize, char *io_pszAnsiString)
String conversion helper.
AkForceInline void AkWaitForSingleThread(AkThread *in_pThread)
Platform Independent Helper.
#define AkAlloca(_size_)
Stack allocations.
void AkSignalEvent(const AkEvent &in_event)
Platform Independent Helper.
AkForceInline AkInt32 AkUtf8ToWideChar(const char *in_pszUtf8String, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper.
semaphore_t AkSemaphore
Definition: AkTypes.h:85
AkForceInline void AkCloseThread(AkThread *in_pThread)
Platform Independent Helper.
AkForceInline int OsStrCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2)
#define AkForceInline
Definition: AkTypes.h:63
AkForceInline size_t OsStrLen(const AkOSChar *in_pszString)
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.

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