Version

menu_open
Warning: you were redirected to the latest documentation corresponding to your major release ( 2022.1.15.8501 ). Should you wish to access your specific version's documentation, please download the offline documentation from the Audiokinetic Launcher and check the Offline Documentation option in Wwise Authoring.
Wwise SDK 2022.1.15
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) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #pragma once
28 
31 
32 #include <nn/os.h>
33 
34 #include <time.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <wchar.h>
39 
40 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2))
41 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2))
42 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x)))
43 
44 //-----------------------------------------------------------------------------
45 // Platform-specific thread properties definition.
46 //-----------------------------------------------------------------------------
47 struct AkThreadProperties
48 {
49  AkInt32 nPriority; ///< Thread priority. 0=highest, 31=lowest.
50  size_t uStackSize; ///< Thread stack size.
51  int iIdealCore; ///< Preferred core number: see nn::os::SetThreadCoreMask documentation.
52  nn::Bit64 affinityMask; ///< Affinity mask for each core: see nn::os::SetThreadCoreMask documentation.
53 };
54 
55 //-----------------------------------------------------------------------------
56 // External variables.
57 //-----------------------------------------------------------------------------
58 // g_fFreqRatio is used by time helpers to return time values in milliseconds.
59 // It is declared and updated by the sound engine.
60 namespace AK
61 {
62  extern AkReal32 g_fFreqRatio;
63 }
64 
65 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) void FuncName(void* lpParameter)
66 #define AK_THREAD_RETURN( _param_ ) return // (_param_)
67 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
68 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
69 
70 #define AK_NULL_THREAD nullptr
71 
72 #define AK_DEFAULT_STACK_SIZE (128*1024)
73 #define AK_THREAD_PRIORITY_NORMAL (nn::os::DefaultThreadPriority)
74 #define AK_THREAD_PRIORITY_ABOVE_NORMAL (nn::os::DefaultThreadPriority-1)
75 #define AK_THREAD_PRIORITY_BELOW_NORMAL (nn::os::LowestThreadPriority)
76 #define AK_THREAD_PRIORITY_TIME_CRITICAL (nn::os::HighestThreadPriority+1)
77 
78 
79 #define AK_THREAD_AFFINITY_ALL 7 // from binary 0b0111 setting the 3 available cores to available
80 #define AK_THREAD_AFFINITY_DEFAULT AK_THREAD_AFFINITY_ALL
81 #define AK_VM_PAGE_SIZE (64*1024)
82 #define AK_VM_HUGE_PAGE_SIZE (2*1024*1024)
83 
84 #define AK_INFINITE (-1)
85 
86 namespace AKPLATFORM
87 {
88 #ifndef AK_OPTIMIZED
89  /// Output a debug message on the console (Unicode string)
90  AkForceInline void OutputDebugMsg(const wchar_t* in_pszMsg)
91  {
92  wprintf(L"%ls", in_pszMsg);
93  }
94  /// Output a debug message on the console (Ansi string)
95  AkForceInline void OutputDebugMsg(const char* in_pszMsg)
96  {
97  printf("%s", in_pszMsg);
98  }
99 
100  /// Output a debug message on the console (variadic function).
101  template <int MaxSize = 0> // Unused
102  AkForceInline void OutputDebugMsgV(const wchar_t* in_pszFmt, ...)
103  {
104  va_list args;
105  va_start(args, in_pszFmt);
106  vwprintf(in_pszFmt, args);
107  va_end(args);
108  }
109 
110  /// Output a debug message on the console (variadic function).
111  template <int MaxSize = 0> // Unused
112  AkForceInline void OutputDebugMsgV(const char* in_pszFmt, ...)
113  {
114  va_list args;
115  va_start(args, in_pszFmt);
116  vprintf(in_pszFmt, args);
117  va_end(args);
118  }
119 #else
120  inline void OutputDebugMsg(const wchar_t*){}
121  inline void OutputDebugMsg(const char*){}
122 
123  template <int MaxSize = 0>
124  inline void OutputDebugMsgV(const wchar_t*, ...) {}
125 
126  template <int MaxSize = 0>
127  inline void OutputDebugMsgV(const char*, ...) {}
128 #endif
129 
130  // Simple automatic event API
131  // ------------------------------------------------------------------
132 
133  /// Platform Independent Helper
134  AkForceInline void AkClearEvent(AkEvent &out_event)
135  {
136  memset(&out_event, 0, sizeof(out_event));
137  }
138 
139  /// Platform Independent Helper
141  {
142  nn::os::InitializeEvent(&out_event, false, nn::os::EventClearMode_AutoClear);
143  return AK_Success;
144  }
145 
146  /// Platform Independent Helper
147  AkForceInline void AkDestroyEvent(AkEvent & io_event)
148  {
149  if (io_event._state == nn::os::EventType::State_Initialized)
150  nn::os::FinalizeEvent(&io_event);
151  }
152 
153  /// Platform Independent Helper
154  AkForceInline void AkWaitForEvent(AkEvent & in_event)
155  {
156  AKASSERT(in_event._state == nn::os::EventType::State_Initialized);
157  nn::os::WaitEvent(&in_event);
158  }
159 
160  /// Platform Independent Helper
162  {
163  AKASSERT(in_event._state == nn::os::EventType::State_Initialized);
164  nn::os::SignalEvent(&in_event);
165  }
166 
167  /// Platform Independent Helper
168  AkForceInline void AkClearSemaphore(AkSemaphore& io_semaphore)
169  {
170  memset(&io_semaphore, 0, sizeof(AkSemaphore));
171  }
172 
173  /// Platform Independent Helper
174  inline AKRESULT AkCreateSemaphore( AkSemaphore & out_semaphore, AkUInt32 in_initialCount )
175  {
176  nn::os::InitializeSemaphore(
177  &out_semaphore,
178  in_initialCount,
179  INT_MAX );
180  return AK_Success;
181  }
182 
183  /// Platform Independent Helper
184  inline void AkDestroySemaphore(AkSemaphore & io_semaphore)
185  {
186  AKASSERT(io_semaphore._state == nn::os::SemaphoreType::State_Initialized);
187  nn::os::FinalizeSemaphore(&io_semaphore);
188  }
189 
190  /// 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.
191  inline void AkWaitForSemaphore(AkSemaphore & in_semaphore)
192  {
193  AKASSERT(in_semaphore._state == nn::os::SemaphoreType::State_Initialized);
194  nn::os::AcquireSemaphore(&in_semaphore);
195  }
196 
197  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an arbitrary count.
198  inline void AkReleaseSemaphore(AkSemaphore& in_semaphore, AkUInt32 in_count)
199  {
200  AKASSERT(in_semaphore._state == nn::os::SemaphoreType::State_Initialized);
201  nn::os::ReleaseSemaphore(&in_semaphore, in_count);
202  }
203 
204  // Virtual Memory
205  // ------------------------------------------------------------------
206 
207  // On NX, virtual memory is OFF by default (and unavailable on NX32) : use aligned heap alloc for "VM" page allocations.
208 
209  //AkForceInline void* AllocVM(size_t size, size_t* extra)
210  //{
211  // size = (size + nn::os::MemoryPageSize - 1) / nn::os::MemoryPageSize * nn::os::MemoryPageSize;
212  // uintptr_t region;
213  // auto result = nn::os::AllocateAddressRegion(&region, size);
214  // if (result.IsFailure())
215  // {
216  // // Allocation of address space fails.
217  // return nullptr;
218  // }
219 
220  // result = nn::os::AllocateMemoryPages(region, size);
221  // if (result.IsFailure())
222  // {
223  // // Allocation of physical memory fails.
224  // return nullptr;
225  // }
226 
227  // return reinterpret_cast<void *>(region);
228  //}
229 
230  //AkForceInline void FreeVM(void* address, size_t size, size_t extra, size_t release)
231  //{
232  // if (release)
233  // {
234  // auto result = nn::os::FreeAddressRegion(reinterpret_cast<uintptr_t>(address));
235  // AKASSERT(!result.IsFailure());
236  // {
237  // // Freeing fails.
238  // return;
239  // }
240  // }
241  //}
242 
243  AkForceInline void* AllocVM(size_t size, size_t* /*extra*/)
244  {
245  return aligned_alloc(AK_VM_PAGE_SIZE, size);
246  }
247 
248  AkForceInline void FreeVM(void* address, size_t /*size*/, size_t /*extra*/, size_t release)
249  {
250  if (release)
251  {
252  free(address);
253  }
254  }
255 
256  // Threads
257  // ------------------------------------------------------------------
258 
259  /// Platform Independent Helper
260  AkForceInline bool AkIsValidThread(AkThread * in_pThread)
261  {
262  return in_pThread->thread._state != nn::os::ThreadType::State_NotInitialized;
263  }
264 
265  /// Platform Independent Helper
266  AkForceInline void AkClearThread(AkThread * in_pThread)
267  {
268  in_pThread->thread._state = nn::os::ThreadType::State_NotInitialized;
269  }
270 
271  /// Platform Independent Helper
272  AkForceInline void AkCloseThread(AkThread * in_pThread)
273  {
274  nn::os::DestroyThread(&in_pThread->thread);
275  FreeVM((void *)in_pThread->pStackAlloc, in_pThread->uStackSize, 1, in_pThread->sizExtra);
276  in_pThread->pStackAlloc = nullptr;
277  }
278 
279 #define AkExitThread( _result ) return
280 
281  /// Platform Independent Helper
283  {
284  out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL;
285  out_threadProperties.uStackSize = AK_DEFAULT_STACK_SIZE;
286  out_threadProperties.iIdealCore = nn::os::IdealCoreUseDefaultValue;
287  out_threadProperties.affinityMask = 0; // ignored when iIdealCore == nn::os::IdealCoreUseDefaultValue
288  }
289 
290  /// Platform Independent Helper
291  inline void AkCreateThread(
292  AkThreadRoutine pStartRoutine, // Thread routine.
293  void * in_pParams, // Routine params.
294  const AkThreadProperties & in_threadProperties, // Properties.
295  AkThread * out_pThread, // Returned thread handle.
296  const char * in_szThreadName) // Opt thread name.
297  {
298  AKASSERT(out_pThread != NULL);
299  AKASSERT(in_threadProperties.uStackSize > 0);
300  AKASSERT(in_threadProperties.nPriority >= nn::os::HighestThreadPriority && in_threadProperties.nPriority <= nn::os::LowestThreadPriority);
301 
302  out_pThread->pStackAlloc = (AkUInt8 *)AllocVM(in_threadProperties.uStackSize, &out_pThread->sizExtra);
303  if (!out_pThread->pStackAlloc)
304  return;
305 
306  out_pThread->uStackSize = in_threadProperties.uStackSize;
307 
308  nn::Result result;
309 
310  result = nn::os::CreateThread(&out_pThread->thread, pStartRoutine, in_pParams, out_pThread->pStackAlloc, out_pThread->uStackSize, in_threadProperties.nPriority);
311  if (!result.IsSuccess())
312  {
313  FreeVM((void *)out_pThread->pStackAlloc, out_pThread->uStackSize, out_pThread->uStackSize, out_pThread->sizExtra);
314  out_pThread->pStackAlloc = nullptr;
315  return;
316  }
317 
318  if (in_szThreadName)
319  {
320  nn::os::SetThreadName(&out_pThread->thread, in_szThreadName);
321  }
322 
323  nn::os::SetThreadCoreMask(&out_pThread->thread, in_threadProperties.iIdealCore, in_threadProperties.affinityMask);
324 
325  nn::os::StartThread(&out_pThread->thread);
326  }
327 
328  /// Platform Independent Helper
329  AkForceInline void AkWaitForSingleThread(AkThread * in_pThread)
330  {
331  nn::os::WaitThread(&in_pThread->thread);
332  }
333 
334  inline AkThreadID CurrentThread()
335  {
336  return nn::os::GetCurrentThread();
337  }
338 
339  /// Platform Independent Helper
340  AkForceInline void AkSleep(AkUInt32 in_ulMilliseconds)
341  {
342  nn::os::SleepThread(nn::TimeSpan::FromMilliSeconds(in_ulMilliseconds));
343  }
344 
345  // Optimized memory functions
346  // --------------------------------------------------------------------
347 
348  /// Platform Independent Helper
349  AkForceInline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize )
350  {
351  memcpy( pDest, pSrc, uSize );
352  }
353 
354  /// Platform Independent Helper
355  inline void AkMemMove(void* pDest, const void* pSrc, AkUInt32 uSize)
356  {
357  memmove( pDest, pSrc, uSize );
358  }
359 
360  /// Platform Independent Helper
361  AkForceInline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize )
362  {
363  memset( pDest, iVal, uSize );
364  }
365 
366  // Time functions
367  // ------------------------------------------------------------------
368 
369  /// Platform Independent Helper
370  AkForceInline void PerformanceCounter( AkInt64 * out_piLastTime )
371  {
372  *out_piLastTime = nn::os::GetSystemTick().GetInt64Value();
373  }
374 
375  /// Platform Independent Helper
376  AkForceInline void PerformanceFrequency( AkInt64 * out_piFreq )
377  {
378  *out_piFreq = nn::os::GetSystemTickFrequency();
379  }
380 
381  /// Platform Independent Helper
383  {
384  AkInt64 iFreq;
385  PerformanceFrequency(&iFreq);
386  AK::g_fFreqRatio = (AkReal32)((AkReal64)iFreq / 1000);
387  }
388 
389  /// Platform Independent Helper
390  /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
391  AkForceInline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
392  {
393  return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
394  }
395 
396 
397  /// String conversion helper
398  AkForceInline AkInt32 AkWideCharToChar(const wchar_t* in_pszUnicodeString,
399  AkUInt32 in_uiOutBufferSize,
400  char* io_pszAnsiString)
401  {
402  AKASSERT(io_pszAnsiString != NULL);
403 
404  mbstate_t state;
405  memset(&state, '\0', sizeof(state));
406 
407  return wcsrtombs(io_pszAnsiString, // destination
408  &in_pszUnicodeString, // source
409  in_uiOutBufferSize, // destination length
410  &state); //
411 
412  }
413 
414  /// String conversion helper
415  AkForceInline AkInt32 AkCharToWideChar(const char* in_pszAnsiString,
416  AkUInt32 in_uiOutBufferSize,
417  void* io_pvUnicodeStringBuffer)
418  {
419  AKASSERT(io_pvUnicodeStringBuffer != NULL);
420 
421  mbstate_t state;
422  memset(&state, '\0', sizeof(state));
423 
424  return mbsrtowcs((wchar_t*)io_pvUnicodeStringBuffer, // destination
425  &in_pszAnsiString, // source
426  in_uiOutBufferSize, // destination length
427  &state); //
428  }
429 
430  AkForceInline AkInt32 AkUtf8ToWideChar(const char* in_pszUtf8String,
431  AkUInt32 in_uiOutBufferSize,
432  void* io_pvUnicodeStringBuffer)
433  {
434  return AkCharToWideChar(in_pszUtf8String, in_uiOutBufferSize, io_pvUnicodeStringBuffer);
435  }
436 
437  /// Safe unicode string copy.
438  AkForceInline void SafeStrCpy(wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars)
439  {
440  size_t iSizeCopy = AkMin(in_uDestMaxNumChars - 1, wcslen(in_pSrc) + 1);
441  wcsncpy(in_pDest, in_pSrc, iSizeCopy);
442  in_pDest[iSizeCopy] = '\0';
443  }
444 
445  /// Safe ansi string copy.
446  AkForceInline void SafeStrCpy(char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars)
447  {
448  size_t iSizeCopy = AkMin(in_uDestMaxNumChars - 1, strlen(in_pSrc) + 1);
449  strncpy(in_pDest, in_pSrc, iSizeCopy);
450  in_pDest[iSizeCopy] = '\0';
451  }
452 
453  /// Safe unicode string concatenation.
454  AkForceInline void SafeStrCat(wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars)
455  {
456  size_t iAvailableSize = (int)(in_uDestMaxNumChars - wcslen(in_pDest) - 1);
457  wcsncat(in_pDest, in_pSrc, AkMin(iAvailableSize, (int)wcslen(in_pSrc)));
458  }
459 
460  /// Safe ansi string concatenation.
461  AkForceInline void SafeStrCat(char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars)
462  {
463  size_t iAvailableSize = (int)(in_uDestMaxNumChars - strlen(in_pDest) - 1);
464  strncat(in_pDest, in_pSrc, AkMin(iAvailableSize, (int)strlen(in_pSrc)));
465  }
466 
467  inline int SafeStrFormat(wchar_t * in_pDest, size_t in_uDestMaxNumChars, const wchar_t* in_pszFmt, ...)
468  {
469  va_list args;
470  va_start(args, in_pszFmt);
471  int r = vswprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
472  va_end(args);
473  return r;
474  }
475 
476  inline int SafeStrFormat(char * in_pDest, size_t in_uDestMaxNumChars, const char* in_pszFmt, ...)
477  {
478  va_list args;
479  va_start(args, in_pszFmt);
480  int r = vsnprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
481  va_end(args);
482  return r;
483  }
484 
485  /// Stack allocations.
486  #define AkAlloca( _size_ ) __builtin_alloca( _size_ )
487 
488 #if __BIGGEST_ALIGNMENT__ < AK_SIMD_ALIGNMENT
489 #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, AK_SIMD_ALIGNMENT*8 )
490 #endif
491 
492  /// Converts a wchar_t string to an AkOSChar string.
493  /// \remark On some platforms the AkOSChar string simply points to the same string,
494  /// on others a new buffer is allocated on the stack using AkAlloca. This means
495  /// you must make sure that:
496  /// - The source string stays valid and unmodified for as long as you need the
497  /// AkOSChar string (for cases where they point to the same string)
498  /// - The AkOSChar string is used within this scope only -- for example, do NOT
499  /// return that string from a function (for cases where it is allocated on the stack)
500 #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) \
501  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + wcslen( _wstring_ )) * sizeof(AkOSChar) ); \
502  AKPLATFORM::AkWideCharToChar( _wstring_ , (AkUInt32)(1 + wcslen( _wstring_ )), (AkOSChar*)( _oscharstring_ ) )
503 
504  /// Converts a char string to an AkOSChar string.
505  /// \remark On some platforms the AkOSChar string simply points to the same string,
506  /// on others a new buffer is allocated on the stack using AkAlloca. This means
507  /// you must make sure that:
508  /// - The source string stays valid and unmodified for as long as you need the
509  /// AkOSChar string (for cases where they point to the same string)
510  /// - The AkOSChar string is used within this scope only -- for example, do NOT
511  /// return that string from a function (for cases where it is allocated on the stack)
512 #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _astring_ )
513 
514  /// Converts a AkOSChar string into wide char string.
515  /// \remark On some platforms the AkOSChar string simply points to the same string,
516  /// on others a new buffer is allocated on the stack using AkAlloca. This means
517  /// you must make sure that:
518  /// - The source string stays valid and unmodified for as long as you need the
519  /// AkOSChar string (for cases where they point to the same string)
520  /// - The AkOSChar string is used within this scope only -- for example, do NOT
521  /// return that string from a function (for cases where it is allocated on the stack)
522 #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) \
523  _wstring_ = (wchar_t*)AkAlloca((1+strlen(_osstring_)) * sizeof(wchar_t)); \
524  AKPLATFORM::AkCharToWideChar( _osstring_, (AkUInt32)(1 + strlen(_osstring_ )), _wstring_ )
525 
526  /// Converts a AkOSChar string into char string.
527  /// \remark On some platforms the AkOSChar string simply points to the same string,
528  /// on others a new buffer is allocated on the stack using AkAlloca. This means
529  /// you must make sure that:
530  /// - The source string stays valid and unmodified for as long as you need the
531  /// AkOSChar string (for cases where they point to the same string)
532  /// - The AkOSChar string is used within this scope only -- for example, do NOT
533  /// return that string from a function (for cases where it is allocated on the stack)
534 #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) _astring_ = (char*)_osstring_
535 
536 
537  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
538  /// \return The length, in characters, of the specified string (excluding terminating NULL)
539  AkForceInline size_t AkUtf16StrLen(const AkUtf16* in_pStr)
540  {
541  size_t len = 0;
542  while (*in_pStr != 0)
543  {
544  in_pStr++;
545  len++;
546  }
547  return len;
548  }
549 
550  /// Get the length, in characters, of a NULL-terminated AkOSChar string
551  /// \return The length, in characters, of the specified string (excluding terminating NULL)
552  AkForceInline size_t OsStrLen(const AkOSChar* in_pszString)
553  {
554  return (strlen(in_pszString));
555  }
556 
557  /// AkOSChar version of snprintf().
558  #define AK_OSPRINTF snprintf
559 
560 
561  AkForceInline int OsStrCmp(const AkOSChar* in_pszString1, const AkOSChar* in_pszString2)
562  {
563  return (strcmp(in_pszString1, in_pszString2));
564  }
565 
566  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
567  /// \return
568  /// - < 0 if in_pszString1 < in_pszString2
569  /// - 0 if the two strings are identical
570  /// - > 0 if in_pszString1 > in_pszString2
571  /// \remark The comparison is case-sensitive
572  inline int OsStrNCmp(const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize)
573  {
574  return (strncmp(in_pszString1, in_pszString2, in_MaxCountSize));
575  }
576 
577  /// Detects whether the string represents an absolute path to a file
578  inline bool IsAbsolutePath(const AkOSChar* in_pszPath, size_t in_pathLen)
579  {
580  // An absolute path is of the form: "MOUNTNAME:/..."
581  return strstr(in_pszPath, ":/") != nullptr;
582  }
583 
584  template<class destType, class srcType>
585  inline size_t AkSimpleConvertString( destType* in_pdDest, const srcType* in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *) )
586  {
587  size_t i;
588  size_t lenToCopy = srcStrLen(in_pSrc);
589 
590  lenToCopy = (lenToCopy > in_MaxSize-1) ? in_MaxSize-1 : lenToCopy;
591  for(i = 0; i < lenToCopy; i++)
592  {
593  in_pdDest[i] = (destType) in_pSrc[i];
594  }
595  in_pdDest[lenToCopy] = (destType)0;
596 
597  return lenToCopy;
598  }
599 
600 #define CONVERT_UTF16_TO_CHAR(_astring_, _charstring_) \
601  _charstring_ = (char*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(char) ); \
602  AK_UTF16_TO_CHAR( _charstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
603 
604  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, wcslen, AKPLATFORM::AkUtf16StrLen )
605  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, wcslen )
606  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, strlen )
607  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
608  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
609  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen )
610  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkSimpleConvertString( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen )
611 
612  // Use with AkOSChar.
613  #define AK_PATH_SEPARATOR ("/")
614  #define AK_LIBRARY_PREFIX ("")
615  #define AK_DYNAMIC_LIBRARY_EXTENSION ("")
616 
617  #define AK_FILEHANDLE_TO_UINTPTR(_h) ((AkUIntPtr)_h.handle)
618  #define AK_SET_FILEHANDLE_TO_UINTPTR(_h,_u) _h.handle = (void*)_u
619 }
AkUInt8 * pStackAlloc
Definition: AkTypes.h:99
AKRESULT AkCreateSemaphore(AkSemaphore &out_semaphore, AkUInt32 in_initialCount)
Platform Independent Helper.
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Audiokinetic namespace.
semaphore_t AkEvent
Definition: AkTypes.h:84
#define AK_VM_PAGE_SIZE
AkForceInline void FreeVM(void *address, size_t size, size_t extra, size_t release)
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
nn::Bit64 affinityMask
Affinity mask for each core: see nn::os::SetThreadCoreMask documentation.
AKRESULT
Standard function call result.
Definition: AkTypes.h:199
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
AkForceInline void * AllocVM(size_t size, size_t *extra)
#define AK_THREAD_PRIORITY_NORMAL
char AkOSChar
Generic character string.
Definition: AkTypes.h:60
uint8_t AkUInt8
Unsigned 8-bit integer.
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:201
int32_t AkInt32
Signed 32-bit integer.
#define AkMin(x1, x2)
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.
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.
AkForceInline void AkMemCpy(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper.
#define AKASSERT(Condition)
Definition: AkAssert.h:67
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.
int OsStrNCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2, size_t in_MaxCountSize)
size_t sizExtra
Definition: AkTypes.h:100
AkForceInline void AkMemSet(void *pDest, AkInt32 iVal, AkUInt32 uSize)
Platform Independent Helper.
void AkMemMove(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper.
AkReal32 g_fFreqRatio
double AkReal64
64-bit floating point
AKRESULT AkCreateEvent(AkEvent &out_event)
Platform Independent Helper.
int iIdealCore
Preferred core number: see nn::os::SetThreadCoreMask documentation.
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.
nn::os::ThreadType thread
Definition: AkTypes.h:98
void AkWaitForSemaphore(AkSemaphore &in_semaphore)
Platform Independent Helper - Semaphore wait, aka Operation P. Decrements value of semaphore,...
AkUInt32 uStackSize
Definition: AkTypes.h:101
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.
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.
#define AK_DEFAULT_STACK_SIZE
AkForceInline void AkWaitForSingleThread(AkThread *in_pThread)
Platform Independent Helper.
AkInt32 nPriority
Thread priority. 0=highest, 31=lowest.
void AkSignalEvent(const AkEvent &in_event)
Platform Independent Helper.
size_t AkSimpleConvertString(destType *in_pdDest, const srcType *in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *))
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