Version
menu_open
link
Wwise SDK 2022.1.12
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 #ifndef _AK_PLATFORM_FUNCS_H_
28 #define _AK_PLATFORM_FUNCS_H_
29 
31 #include <sce_atomic.h>
32 #include <sceerror.h>
33 #include <wchar.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <time.h>
37 #include <kernel/eventflag.h>
38 #include <unistd.h>
39 #include <sys/time.h>
40 #include <stdlib.h>
41 #include <cpuid.h>
42 
43 //-----------------------------------------------------------------------------
44 // Platform-specific thread properties definition.
45 //-----------------------------------------------------------------------------
47 {
48  int nPriority; ///< Thread priority
49  SceKernelCpumask dwAffinityMask; ///< Affinity mask
50  size_t uStackSize; ///< Thread stack size
51  int uSchedPolicy; ///< Thread scheduling policy
52 };
53 
54 //-----------------------------------------------------------------------------
55 // External variables.
56 //-----------------------------------------------------------------------------
57 // g_fFreqRatio is used by time helpers to return time values in milliseconds.
58 // It is declared and updated by the sound engine.
59 namespace AK
60 {
61  extern AkReal32 g_fFreqRatio;
62 }
63 
64 //-----------------------------------------------------------------------------
65 // Defines for PS4.
66 //-----------------------------------------------------------------------------
67 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) void* FuncName(void* lpParameter)
68 #define AK_THREAD_RETURN( _param_ ) return (_param_);
69 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
70 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
71 
72 #define AK_RETURN_THREAD_OK 0x00000000
73 #define AK_RETURN_THREAD_ERROR 0x00000001
74 #define AK_DEFAULT_STACK_SIZE (128*1024)
75 #define AK_VM_PAGE_SIZE (64*1024)
76 #define AK_VM_HUGE_PAGE_SIZE (2*1024*1024)
77 #define AK_THREAD_DEFAULT_SCHED_POLICY SCE_KERNEL_SCHED_FIFO
78 #define AK_THREAD_PRIORITY_NORMAL SCE_KERNEL_PRIO_FIFO_DEFAULT
79 #define AK_THREAD_PRIORITY_ABOVE_NORMAL SCE_KERNEL_PRIO_FIFO_HIGHEST
80 #define AK_THREAD_PRIORITY_BELOW_NORMAL SCE_KERNEL_PRIO_FIFO_LOWEST
81 
82 #define AK_THREAD_AFFINITY_ALL 63 // from binary 111111 setting the 6 available core to true. (ex: 4 << 1)
83 #define AK_THREAD_AFFINITY_DEFAULT AK_THREAD_AFFINITY_ALL
84 
85 // On PS4 this needs to be called regularly.
86 #define AK_RELEASE_GPU_OFFLINE_FRAME sce::Gnm::submitDone();
87 
88 // NULL objects
89 #define AK_NULL_THREAD NULL
90 
91 #define AK_INFINITE (AK_UINT_MAX)
92 
93 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2))
94 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2))
95 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x)))
96 
97 namespace AKPLATFORM
98 {
99 #ifndef AK_OPTIMIZED
100  // The same orientation must be used for all
101  // OutputDebugMsg (either char or wchar_t) since
102  // using both in the same stream is undefined behavior.
103 
104  /// Output a debug message on the console (Ansi string)
105  AkForceInline void OutputDebugMsg( const char* in_pszMsg )
106  {
107  fputs( in_pszMsg, stderr );
108  }
109  /// Output a debug message on the console (Unicode string)
110  AkForceInline void OutputDebugMsg( const wchar_t* in_pszMsg )
111  {
112  fputws( in_pszMsg, stderr );
113  }
114 
115  /// Output a debug message on the console (Unicode string) (variadic function)
116  template <int MaxSize = 0> // Unused
117  AkForceInline void OutputDebugMsgV( const wchar_t* in_pszFmt, ... )
118  {
119  va_list args;
120  va_start(args, in_pszFmt);
121  vfwprintf(stderr, in_pszFmt, args);
122  va_end(args);
123  }
124 
125  /// Output a debug message on the console (Ansi string) (variadic function)
126  template <int MaxSize = 0> // Unused
127  AkForceInline void OutputDebugMsgV( const char* in_pszFmt, ... )
128  {
129  va_list args;
130  va_start(args, in_pszFmt);
131  vfprintf(stderr, in_pszFmt, args);
132  va_end(args);
133  }
134 #else
135  inline void OutputDebugMsg( const wchar_t* ){}
136  inline void OutputDebugMsg( const char* ){}
137 
138  template <int MaxSize = 0> // Unused
139  inline void OutputDebugMsgV( const wchar_t*, ... ){}
140 
141  template <int MaxSize = 0> // Unused
142  inline void OutputDebugMsgV( const char*, ... ){}
143 #endif
144 
145 
146  // Simple automatic event API
147  // ------------------------------------------------------------------
148 
149  /// Platform Independent Helper
150  AkForceInline void AkClearEvent( AkEvent & out_event )
151  {
152  out_event = NULL;
153  }
154 
155  AkForceInline AKRESULT AkCreateNamedEvent( AkEvent & out_event, const char* in_szName )
156  {
157  // NOTE: AkWaitForEvent uses the SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT flag
158  // to get the same behavior as an auto-reset Win32 event
159  int ret = sceKernelCreateEventFlag(
160  &out_event,
161  in_szName,
162  SCE_KERNEL_EVF_ATTR_MULTI,
163  0 /* not signalled by default */,
164  NULL /* No optional params */ );
165 
166  if( ret == SCE_OK )
167  return AK_Success;
168 
169  AkClearEvent( out_event );
170  return AK_Fail;
171  }
172 
173  /// Platform Independent Helper
175  {
176  return AkCreateNamedEvent( out_event, "AkEvent" );
177  }
178 
179  /// Platform Independent Helper
180  AkForceInline void AkDestroyEvent( AkEvent & io_event )
181  {
182  sceKernelDeleteEventFlag(io_event);
183  AkClearEvent( io_event );
184  }
185 
186  /// Platform Independent Helper
187  AkForceInline void AkWaitForEvent( AkEvent & in_event )
188  {
189  AKVERIFY( sceKernelWaitEventFlag(
190  in_event,
191  1,
192  SCE_KERNEL_EVF_WAITMODE_OR | SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL,
193  SCE_NULL,
194  SCE_NULL) == 0 );
195  }
196 
197  /// Platform Independent Helper
198  AkForceInline void AkSignalEvent( const AkEvent & in_event )
199  {
200  AKVERIFY( sceKernelSetEventFlag( in_event, 1 ) == 0 );
201  }
202 
203  /// Platform Independent Helper
204  AkForceInline void AkClearSemaphore(AkSemaphore& io_semaphore)
205  {
206  io_semaphore = NULL;
207  }
208 
209  /// Platform Independent Helper
210  inline AKRESULT AkCreateSemaphore( AkSemaphore& out_semaphore, AkUInt32 in_initialCount )
211  {
212  int ret = sceKernelCreateSema(
213  &out_semaphore,
214  "AkSemaphore",
215  0,
216  in_initialCount,
217  INT_MAX,
218  NULL );
219 
220  return ( ret == SCE_OK ) ? AK_Success : AK_Fail;
221  }
222 
223  /// Platform Independent Helper
224  inline void AkDestroySemaphore(AkSemaphore& io_semaphore)
225  {
226  AKVERIFY(sceKernelDeleteSema(io_semaphore) == SCE_OK);
227  }
228 
229  /// 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.
230  inline void AkWaitForSemaphore(AkSemaphore& in_semaphore)
231  {
232  AKVERIFY(sceKernelWaitSema(in_semaphore, 1, NULL) == SCE_OK);
233  }
234 
235  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an arbitrary count.
236  inline void AkReleaseSemaphore(AkSemaphore& in_semaphore, AkUInt32 in_count)
237  {
238  AKVERIFY(sceKernelSignalSema(in_semaphore, in_count) == SCE_OK);
239  }
240 
241  // Virtual Memory
242  // ------------------------------------------------------------------
243 
244  AkForceInline void* AllocVM(size_t size, size_t* extra)
245  {
246  AKASSERT((size % AK_VM_PAGE_SIZE) == 0);
247  off_t directMemStart = 0;
248  void* ptr = NULL;
249 
250  int32_t err;
251  // if size lines up with huge pages, set alignment up similarly
252  int32_t alignment = (size % AK_VM_HUGE_PAGE_SIZE == 0) ? AK_VM_HUGE_PAGE_SIZE : AK_VM_PAGE_SIZE;
253  err = sceKernelAllocateMainDirectMemory(size, alignment, SCE_KERNEL_WB_ONION, &directMemStart);
254  if (err == SCE_OK)
255  {
256  err = sceKernelMapDirectMemory(&ptr, size, SCE_KERNEL_PROT_CPU_RW, 0, directMemStart, alignment);
257  AKASSERT(ptr);
258  AKASSERT(err == SCE_OK);
259 
260  *extra = (size_t)directMemStart;
261  }
262  return ptr;
263  }
264 
265  AkForceInline void FreeVM(void* address, size_t size, size_t extra, size_t release)
266  {
267  if (release)
268  {
269  AKASSERT(extra);
270  off_t directMemStart = (off_t)extra;
271  int32_t err = sceKernelReleaseDirectMemory(directMemStart, release);
272  AKASSERT(err == SCE_OK);
273  }
274  }
275 
276  // Threads
277  // ------------------------------------------------------------------
278 
279  /// Platform Independent Helper
281  {
282  return ( *in_pThread != AK_NULL_THREAD );
283  }
284 
285  /// Platform Independent Helper
286  AkForceInline void AkClearThread( AkThread * in_pThread )
287  {
288  *in_pThread = AK_NULL_THREAD;
289  }
290 
291  /// Platform Independent Helper
292  AkForceInline void AkCloseThread( AkThread * in_pThread )
293  {
294  AKASSERT( in_pThread );
295  AKASSERT( *in_pThread );
296 
297  // #define KILL_THREAD(t) do { void *ret; scePthreadJoin(t,&ret); } while(false)
298  // AKVERIFY( SCE_OK == sceKernelDeleteThread( *in_pThread ) );
299  AkClearThread( in_pThread );
300  }
301 
302  #define AkExitThread( _result ) return _result;
303 
304  /// Platform Independent Helper
306  {
307  out_threadProperties.uStackSize = AK_DEFAULT_STACK_SIZE;
308  out_threadProperties.uSchedPolicy = AK_THREAD_DEFAULT_SCHED_POLICY;
309  out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL;
310  out_threadProperties.dwAffinityMask = AK_THREAD_AFFINITY_DEFAULT;
311  }
312 
313  /// Platform Independent Helper
314  inline void AkCreateThread(
315  AkThreadRoutine pStartRoutine, // Thread routine.
316  void * pParams, // Routine params.
317  const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
318  AkThread * out_pThread, // Returned thread handle.
319  const char * in_szThreadName ) // Opt thread name.
320  {
321  AKASSERT( out_pThread != NULL );
322 
323  ScePthreadAttr attr;
324 
325  // Create the attr
326  AKVERIFY(!scePthreadAttrInit(&attr));
327  // Set the stack size
328  AKVERIFY(!scePthreadAttrSetstacksize(&attr,in_threadProperties.uStackSize));
329  AKVERIFY(!scePthreadAttrSetdetachstate(&attr, SCE_PTHREAD_CREATE_JOINABLE));
330  AKVERIFY(!scePthreadAttrSetinheritsched(&attr, SCE_PTHREAD_EXPLICIT_SCHED));
331  AKVERIFY(!scePthreadAttrSetaffinity(&attr,in_threadProperties.dwAffinityMask));
332 
333  // Try to set the thread policy
334  int sched_policy = in_threadProperties.uSchedPolicy;
335  if( scePthreadAttrSetschedpolicy( &attr, sched_policy ) )
336  {
337  AKASSERT( !"AKCreateThread invalid sched policy, will automatically set it to FIFO scheduling" );
338  sched_policy = AK_THREAD_DEFAULT_SCHED_POLICY;
339  AKVERIFY( !scePthreadAttrSetschedpolicy( &attr, sched_policy ));
340  }
341 
342  int minPriority, maxPriority;
343  minPriority = SCE_KERNEL_PRIO_FIFO_HIGHEST;
344  maxPriority = SCE_KERNEL_PRIO_FIFO_LOWEST;
345 
346  // Set the thread priority if valid
347  AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );
348  if( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority )
349  {
350  SceKernelSchedParam schedParam;
351  AKVERIFY( scePthreadAttrGetschedparam(&attr, &schedParam) == 0 );
352  schedParam.sched_priority = in_threadProperties.nPriority;
353  AKVERIFY( scePthreadAttrSetschedparam(&attr, &schedParam) == 0 );
354  }
355 
356  // Create the tread
357  int threadError = scePthreadCreate(out_pThread, &attr, pStartRoutine, pParams, in_szThreadName);
358  AKASSERT( threadError == 0 );
359  AKVERIFY(!scePthreadAttrDestroy(&attr));
360 
361  if( threadError != 0 )
362  {
363  AkClearThread( out_pThread );
364  return;
365  }
366 
367  // ::CreateThread() return NULL if it fails.
368  if ( !*out_pThread )
369  {
370  AkClearThread( out_pThread );
371  return;
372  }
373  }
374 
375  /// Platform Independent Helper
377  {
378  AKASSERT( in_pThread );
379  AKASSERT( *in_pThread );
380  AKVERIFY(!scePthreadJoin( *in_pThread, NULL ));
381  }
382 
384  {
385  return scePthreadSelf();
386  }
387 
388  /// Platform Independent Helper
389  AkForceInline void AkSleep( AkUInt32 in_ulMilliseconds )
390  {
391  usleep( in_ulMilliseconds * 1000 );
392  }
393 
394  // Optimized memory functions
395  // --------------------------------------------------------------------
396 
397  /// Platform Independent Helper
398  AkForceInline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize )
399  {
400  memcpy( pDest, pSrc, uSize );
401  }
402 
403  /// Platform Independent Helper
404  inline void AkMemMove( void* pDest, const void* pSrc, AkUInt32 uSize )
405  {
406  memmove( pDest, pSrc, uSize );
407  }
408 
409  /// Platform Independent Helper
410  AkForceInline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize )
411  {
412  memset( pDest, iVal, uSize );
413  }
414 
415  // Time functions
416  // ------------------------------------------------------------------
417 
418  /// Platform Independent Helper
419  AkForceInline void PerformanceCounter( AkInt64 * out_piLastTime )
420  {
421  uint64_t uTime = sceKernelGetProcessTimeCounter();
422  *out_piLastTime = (AkInt64)uTime;
423  }
424 
425  /// Frequency of the PerformanceCounter() (ticks per second)
426  AkForceInline void PerformanceFrequency( AkInt64 * out_piFreq )
427  {
428  *out_piFreq = (AkInt64)sceKernelGetProcessTimeCounterFrequency();
429  }
430 
431  /// Platform Independent Helper
433  {
434  AkInt64 iFreq;
435  PerformanceFrequency( &iFreq );
436  AK::g_fFreqRatio = (AkReal32)((AkReal64)iFreq / 1000);
437  }
438 
439  /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
440  AkForceInline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
441  {
442  return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
443  }
444 
445  /// String conversion helper
446  AkForceInline AkInt32 AkWideCharToChar( const wchar_t* in_pszUnicodeString,
447  AkUInt32 in_uiOutBufferSize,
448  char* io_pszAnsiString )
449  {
450  AKASSERT( io_pszAnsiString != NULL );
451 
452  mbstate_t state;
453  memset (&state, '\0', sizeof (state));
454 
455  return (AkInt32)wcsrtombs(io_pszAnsiString, // destination
456  &in_pszUnicodeString, // source
457  in_uiOutBufferSize, // destination length
458  &state); //
459 
460  }
461 
462  /// String conversion helper
463  AkForceInline AkInt32 AkCharToWideChar( const char* in_pszAnsiString,
464  AkUInt32 in_uiOutBufferSize,
465  void* io_pvUnicodeStringBuffer )
466  {
467  AKASSERT( io_pvUnicodeStringBuffer != NULL );
468 
469  mbstate_t state;
470  memset (&state, '\0', sizeof (state));
471 
472  return (AkInt32)mbsrtowcs((wchar_t*)io_pvUnicodeStringBuffer, // destination
473  &in_pszAnsiString, // source
474  in_uiOutBufferSize, // destination length
475  &state); //
476  }
477 
478  AkForceInline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String,
479  AkUInt32 in_uiOutBufferSize,
480  void* io_pvUnicodeStringBuffer )
481  {
482  return AkCharToWideChar( in_pszUtf8String, in_uiOutBufferSize, (wchar_t*)io_pvUnicodeStringBuffer );
483  }
484 
485  /// Safe unicode string copy.
486  AkForceInline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
487  {
488  size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
489  wcsncpy( in_pDest, in_pSrc, uSizeCopy );
490  in_pDest[uSizeCopy] = '\0';
491  }
492 
493  /// Safe ansi string copy.
494  AkForceInline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
495  {
496  size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
497  strncpy( in_pDest, in_pSrc, uSizeCopy );
498  in_pDest[uSizeCopy] = '\0';
499  }
500 
501  /// Safe unicode string concatenation.
502  AkForceInline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
503  {
504  size_t uAvailableSize = ( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
505  wcsncat( in_pDest, in_pSrc, AkMin( uAvailableSize, wcslen( in_pSrc ) ) );
506  }
507 
508  /// Safe ansi string concatenation.
509  AkForceInline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
510  {
511  size_t uAvailableSize = ( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
512  strncat( in_pDest, in_pSrc, AkMin( uAvailableSize, strlen( in_pSrc ) ) );
513  }
514 
515  inline int SafeStrFormat(wchar_t * in_pDest, size_t in_uDestMaxNumChars, const wchar_t* in_pszFmt, ...)
516  {
517  va_list args;
518  va_start(args, in_pszFmt);
519  int r = vswprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
520  va_end(args);
521  return r;
522  }
523 
524  inline int SafeStrFormat(char * in_pDest, size_t in_uDestMaxNumChars, const char* in_pszFmt, ...)
525  {
526  va_list args;
527  va_start(args, in_pszFmt);
528  int r = vsnprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
529  va_end(args);
530  return r;
531  }
532 
533  /// Stack allocations.
534  #define AkAlloca( _size_ ) alloca( _size_ )
535 
536 
537 
538  /// Converts a wchar_t string to an AkOSChar string.
539  /// \remark On some platforms the AkOSChar string simply points to the same string,
540  /// on others a new buffer is allocated on the stack using AkAlloca. This means
541  /// you must make sure that:
542  /// - The source string stays valid and unmodified for as long as you need the
543  /// AkOSChar string (for cases where they point to the same string)
544  /// - The AkOSChar string is used within this scope only -- for example, do NOT
545  /// return that string from a function (for cases where it is allocated on the stack)
546  #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) \
547  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + wcslen( _wstring_ )) * sizeof(AkOSChar) ); \
548  AKPLATFORM::AkWideCharToChar( _wstring_ , (AkUInt32)(1 + wcslen( _wstring_ )), (AkOSChar*)( _oscharstring_ ) )
549 
550 
551  /// Converts a char string to an AkOSChar string.
552  /// \remark On some platforms the AkOSChar string simply points to the same string,
553  /// on others a new buffer is allocated on the stack using AkAlloca. This means
554  /// you must make sure that:
555  /// - The source string stays valid and unmodified for as long as you need the
556  /// AkOSChar string (for cases where they point to the same string)
557  /// - The AkOSChar string is used within this scope only -- for example, do NOT
558  /// return that string from a function (for cases where it is allocated on the stack)
559  #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _astring_ )
560 
561  /// Converts a AkOSChar string into wide char string.
562  /// \remark On some platforms the AkOSChar string simply points to the same string,
563  /// on others a new buffer is allocated on the stack using AkAlloca. This means
564  /// you must make sure that:
565  /// - The source string stays valid and unmodified for as long as you need the
566  /// AkOSChar string (for cases where they point to the same string)
567  /// - The AkOSChar string is used within this scope only -- for example, do NOT
568  /// return that string from a function (for cases where it is allocated on the stack)
569  #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) \
570  _wstring_ = (wchar_t*)AkAlloca((1+strlen(_osstring_)) * sizeof(wchar_t)); \
571  AKPLATFORM::AkCharToWideChar( _osstring_, (AkUInt32)(1 + strlen(_osstring_ )), _wstring_ )
572 
573  /// Converts a AkOSChar string into char string.
574  /// \remark On some platforms the AkOSChar string simply points to the same string,
575  /// on others a new buffer is allocated on the stack using AkAlloca. This means
576  /// you must make sure that:
577  /// - The source string stays valid and unmodified for as long as you need the
578  /// AkOSChar string (for cases where they point to the same string)
579  /// - The AkOSChar string is used within this scope only -- for example, do NOT
580  /// return that string from a function (for cases where it is allocated on the stack)
581  #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) _astring_ = (char*)_osstring_
582 
583  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
584  /// \return The length, in characters, of the specified string (excluding terminating NULL)
585  AkForceInline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
586  {
587  return ( wcslen( in_pStr ) );
588  }
589 
590  /// Get the length, in characters, of a NULL-terminated AkOSChar string
591  /// \return The length, in characters, of the specified string (excluding terminating NULL)
592  AkForceInline size_t OsStrLen( const AkOSChar* in_pszString )
593  {
594  return ( strlen( in_pszString ) );
595  }
596 
597  /// AkOSChar version of sprintf().
598  #define AK_OSPRINTF snprintf
599 
600  /// Compare two NULL-terminated AkOSChar strings
601  /// \return
602  /// - < 0 if in_pszString1 < in_pszString2
603  /// - 0 if the two strings are identical
604  /// - > 0 if in_pszString1 > in_pszString2
605  /// \remark The comparison is case-sensitive
606  AkForceInline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
607  {
608  return ( strcmp( in_pszString1, in_pszString2 ) );
609  }
610 
611  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
612  /// \return
613  /// - < 0 if in_pszString1 < in_pszString2
614  /// - 0 if the two strings are identical
615  /// - > 0 if in_pszString1 > in_pszString2
616  /// \remark The comparison is case-sensitive
617  inline int OsStrNCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize )
618  {
619  return ( strncmp(in_pszString1, in_pszString2, in_MaxCountSize) );
620  }
621 
622  /// Detects whether the string represents an absolute path to a file
623  inline bool IsAbsolutePath(const AkOSChar* in_pszPath, size_t in_pathLen)
624  {
625  return in_pathLen >= 1 && in_pszPath[0] == '/';
626  }
627 
628  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
629  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
630  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
631  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
632  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
633  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
634  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
635 
636  // Use with AkOSChar.
637  #define AK_PATH_SEPARATOR ("/")
638  #define AK_LIBRARY_PREFIX ("")
639  #define AK_DYNAMIC_LIBRARY_EXTENSION (".prx")
640 
641  #define AK_FILEHANDLE_TO_UINTPTR(_h) ((AkUIntPtr)_h)
642  #define AK_SET_FILEHANDLE_TO_UINTPTR(_h,_u) _h = (AkFileHandle)_u
643 
644  /// Support to fetch the CPUID for the platform. Only valid for X86 targets
645  /// \remark Note that IAkProcessorFeatures should be preferred to fetch this data
646  /// as it will have already translated the feature bits into AK-relevant enums
647  inline void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
648  {
649  __get_cpuid_count( in_uLeafOpcode, in_uSubLeafOpcode,
650  &out_uCPUFeatures[0],
651  &out_uCPUFeatures[1],
652  &out_uCPUFeatures[2],
653  &out_uCPUFeatures[3]);
654  }
655 }
656 
657 #endif // _AK_PLATFORM_FUNCS_H_
#define AK_THREAD_DEFAULT_SCHED_POLICY
#define AkMin(x1, x2)
AKRESULT AkCreateSemaphore(AkSemaphore &out_semaphore, AkUInt32 in_initialCount)
Platform Independent Helper.
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Audiokinetic namespace.
@ AK_Fail
The operation failed.
Definition: AkTypes.h:202
semaphore_t AkEvent
Definition: AkTypes.h:84
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
#define AK_NULL_THREAD
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)
void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
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 AK_VM_PAGE_SIZE
#define NULL
Definition: AkTypes.h:46
#define AK_THREAD_PRIORITY_NORMAL
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.
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:87
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
#define AK_DEFAULT_STACK_SIZE
#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.
int OsStrNCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2, size_t in_MaxCountSize)
AkForceInline void AkMemSet(void *pDest, AkInt32 iVal, AkUInt32 uSize)
Platform Independent Helper.
void AkMemMove(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper.
SceKernelCpumask dwAffinityMask
Affinity mask.
AkReal32 g_fFreqRatio
#define AK_VM_HUGE_PAGE_SIZE
double AkReal64
64-bit floating point
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.
#define AK_THREAD_AFFINITY_DEFAULT
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.
int uSchedPolicy
Thread scheduling policy.
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 AKRESULT AkCreateNamedEvent(AkEvent &out_event, const char *in_szName)
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.
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