Table of Contents

Wwise SDK 2021.1.1
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  Version: v2021.1.1 Build: 7601
25  Copyright (c) 2006-2021 Audiokinetic Inc.
26 *******************************************************************************/
27 
28 #ifndef _AK_PLATFORM_FUNCS_H_
29 #define _AK_PLATFORM_FUNCS_H_
30 
32 #include <sce_atomic.h>
33 #include <sceerror.h>
34 #include <wchar.h>
35 #include <string.h>
36 #include <stdio.h>
37 #include <time.h>
38 #include <kernel/eventflag.h>
39 #include <unistd.h>
40 #include <sys/time.h>
41 #include <stdlib.h>
42 #include <cpuid.h>
43 
44 //-----------------------------------------------------------------------------
45 // Platform-specific thread properties definition.
46 //-----------------------------------------------------------------------------
48 {
49  int nPriority; ///< Thread priority
50  SceKernelCpumask dwAffinityMask; ///< Affinity mask
51  size_t uStackSize; ///< Thread stack size
52  int uSchedPolicy; ///< Thread scheduling policy
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 //-----------------------------------------------------------------------------
66 // Defines for PS4.
67 //-----------------------------------------------------------------------------
68 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) void* FuncName(void* lpParameter)
69 #define AK_THREAD_RETURN( _param_ ) return (_param_);
70 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
71 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
72 
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_VM_PAGE_SIZE (16*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 bool AkIsValidEvent(const AkEvent & in_event)
156  {
157  return (in_event != NULL);
158  }
159 
160  AkForceInline AKRESULT AkCreateNamedEvent( AkEvent & out_event, const char* in_szName )
161  {
162  // NOTE: AkWaitForEvent uses the SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT flag
163  // to get the same behavior as an auto-reset Win32 event
164  int ret = sceKernelCreateEventFlag(
165  &out_event,
166  in_szName,
167  SCE_KERNEL_EVF_ATTR_MULTI,
168  0 /* not signalled by default */,
169  NULL /* No optional params */ );
170 
171  if( ret == SCE_OK && AkIsValidEvent(out_event))
172  return AK_Success;
173 
174  AkClearEvent( out_event );
175  return AK_Fail;
176  }
177 
178  /// Platform Independent Helper
180  {
181  return AkCreateNamedEvent( out_event, "AkEvent" );
182  }
183 
184  /// Platform Independent Helper
185  AkForceInline void AkDestroyEvent( AkEvent & io_event )
186  {
187  sceKernelDeleteEventFlag(io_event);
188  AkClearEvent( io_event );
189  }
190 
191  /// Platform Independent Helper
192  AkForceInline void AkWaitForEvent( AkEvent & in_event )
193  {
194  AKVERIFY( sceKernelWaitEventFlag(
195  in_event,
196  1,
197  SCE_KERNEL_EVF_WAITMODE_OR | SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL,
198  SCE_NULL,
199  SCE_NULL) == 0 );
200  }
201 
202  /// Platform Independent Helper
203  AkForceInline void AkSignalEvent( const AkEvent & in_event )
204  {
205  AKVERIFY( sceKernelSetEventFlag( in_event, 1 ) == 0 );
206  }
207 
208  /// Platform Independent Helper
209  inline AKRESULT AkCreateSemaphore( AkSemaphore* out_semaphore, AkUInt32 in_initialCount )
210  {
211  int ret = sceKernelCreateSema(
212  out_semaphore,
213  "AkSemaphore",
214  0,
215  in_initialCount,
216  INT_MAX,
217  NULL );
218 
219  return ( ret == SCE_OK ) ? AK_Success : AK_Fail;
220  }
221 
222  /// Platform Independent Helper
223  inline void AkDestroySemaphore( AkSemaphore* io_semaphore )
224  {
225  AKVERIFY( sceKernelDeleteSema( *io_semaphore ) == SCE_OK);
226  }
227 
228  /// 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.
229  inline void AkWaitForSemaphore( AkSemaphore* in_semaphore )
230  {
231  AKVERIFY( sceKernelWaitSema( *in_semaphore, 1, NULL ) == SCE_OK );
232  }
233 
234  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore.
235  inline void AkReleaseSemaphore( AkSemaphore* in_semaphore )
236  {
237  AKVERIFY( sceKernelSignalSema( *in_semaphore, 1 ) == SCE_OK );
238  }
239 
240  // Virtual Memory
241  // ------------------------------------------------------------------
242 
243  AkForceInline void* AllocVM(size_t size, size_t* extra)
244  {
245  AKASSERT((size % AK_VM_PAGE_SIZE) == 0);
246  off_t directMemStart = 0;
247  void* ptr = NULL;
248 
249  int32_t err;
250  err = sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, size, AK_VM_PAGE_SIZE, SCE_KERNEL_WB_ONION, &directMemStart);
251  if (err == SCE_OK)
252  {
253  err = sceKernelMapDirectMemory(&ptr, size, SCE_KERNEL_PROT_CPU_RW, 0, directMemStart, AK_VM_PAGE_SIZE);
254  AKASSERT(ptr);
255  AKASSERT(err == SCE_OK);
256 
257  *extra = (size_t)directMemStart;
258  }
259  return (uint8_t*)ptr;
260  }
261 
262  AkForceInline void FreeVM(void* address, size_t size, size_t extra, size_t release)
263  {
264  if (release)
265  {
266  AKASSERT(extra);
267  off_t directMemStart = (off_t)extra;
268  int32_t err = sceKernelReleaseDirectMemory(directMemStart, release);
269  AKASSERT(err == SCE_OK);
270  }
271  }
272 
273  // Threads
274  // ------------------------------------------------------------------
275 
276  /// Platform Independent Helper
278  {
279  return ( *in_pThread != AK_NULL_THREAD );
280  }
281 
282  /// Platform Independent Helper
283  AkForceInline void AkClearThread( AkThread * in_pThread )
284  {
285  *in_pThread = AK_NULL_THREAD;
286  }
287 
288  /// Platform Independent Helper
289  AkForceInline void AkCloseThread( AkThread * in_pThread )
290  {
291  AKASSERT( in_pThread );
292  AKASSERT( *in_pThread );
293 
294  // #define KILL_THREAD(t) do { void *ret; scePthreadJoin(t,&ret); } while(false)
295  // AKVERIFY( SCE_OK == sceKernelDeleteThread( *in_pThread ) );
296  AkClearThread( in_pThread );
297  }
298 
299  #define AkExitThread( _result ) return _result;
300 
301  /// Platform Independent Helper
303  {
304  out_threadProperties.uStackSize = AK_DEFAULT_STACK_SIZE;
305  out_threadProperties.uSchedPolicy = AK_THREAD_DEFAULT_SCHED_POLICY;
306  out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL;
307  out_threadProperties.dwAffinityMask = AK_THREAD_AFFINITY_DEFAULT;
308  }
309 
310  /// Platform Independent Helper
311  inline void AkCreateThread(
312  AkThreadRoutine pStartRoutine, // Thread routine.
313  void * pParams, // Routine params.
314  const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
315  AkThread * out_pThread, // Returned thread handle.
316  const char * in_szThreadName ) // Opt thread name.
317  {
318  AKASSERT( out_pThread != NULL );
319 
320  ScePthreadAttr attr;
321 
322  // Create the attr
323  AKVERIFY(!scePthreadAttrInit(&attr));
324  // Set the stack size
325  AKVERIFY(!scePthreadAttrSetstacksize(&attr,in_threadProperties.uStackSize));
326  AKVERIFY(!scePthreadAttrSetdetachstate(&attr, SCE_PTHREAD_CREATE_JOINABLE));
327  AKVERIFY(!scePthreadAttrSetinheritsched(&attr, SCE_PTHREAD_EXPLICIT_SCHED));
328  AKVERIFY(!scePthreadAttrSetaffinity(&attr,in_threadProperties.dwAffinityMask));
329 
330  // Try to set the thread policy
331  int sched_policy = in_threadProperties.uSchedPolicy;
332  if( scePthreadAttrSetschedpolicy( &attr, sched_policy ) )
333  {
334  AKASSERT( !"AKCreateThread invalid sched policy, will automatically set it to FIFO scheduling" );
335  sched_policy = AK_THREAD_DEFAULT_SCHED_POLICY;
336  AKVERIFY( !scePthreadAttrSetschedpolicy( &attr, sched_policy ));
337  }
338 
339  int minPriority, maxPriority;
340  minPriority = SCE_KERNEL_PRIO_FIFO_HIGHEST;
341  maxPriority = SCE_KERNEL_PRIO_FIFO_LOWEST;
342 
343  // Set the thread priority if valid
344  AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );
345  if( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority )
346  {
347  SceKernelSchedParam schedParam;
348  AKVERIFY( scePthreadAttrGetschedparam(&attr, &schedParam) == 0 );
349  schedParam.sched_priority = in_threadProperties.nPriority;
350  AKVERIFY( scePthreadAttrSetschedparam(&attr, &schedParam) == 0 );
351  }
352 
353  // Create the tread
354  int threadError = scePthreadCreate(out_pThread, &attr, pStartRoutine, pParams, in_szThreadName);
355  AKASSERT( threadError == 0 );
356  AKVERIFY(!scePthreadAttrDestroy(&attr));
357 
358  if( threadError != 0 )
359  {
360  AkClearThread( out_pThread );
361  return;
362  }
363 
364  // ::CreateThread() return NULL if it fails.
365  if ( !*out_pThread )
366  {
367  AkClearThread( out_pThread );
368  return;
369  }
370  }
371 
372  /// Platform Independent Helper
374  {
375  AKASSERT( in_pThread );
376  AKASSERT( *in_pThread );
377  AKVERIFY(!scePthreadJoin( *in_pThread, NULL ));
378  }
379 
381  {
382  return scePthreadSelf();
383  }
384 
385  /// Platform Independent Helper
386  AkForceInline void AkSleep( AkUInt32 in_ulMilliseconds )
387  {
388  usleep( in_ulMilliseconds * 1000 );
389  }
390 
391  // Optimized memory functions
392  // --------------------------------------------------------------------
393 
394  /// Platform Independent Helper
395  AkForceInline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize )
396  {
397  memcpy( pDest, pSrc, uSize );
398  }
399 
400  /// Platform Independent Helper
401  AkForceInline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize )
402  {
403  memset( pDest, iVal, uSize );
404  }
405 
406  // Time functions
407  // ------------------------------------------------------------------
408 
409  /// Platform Independent Helper
410  AkForceInline void PerformanceCounter( AkInt64 * out_piLastTime )
411  {
412  uint64_t uTime = sceKernelGetProcessTimeCounter();
413  *out_piLastTime = (AkInt64)uTime;
414  }
415 
416  /// Frequency of the PerformanceCounter() (ticks per second)
417  AkForceInline void PerformanceFrequency( AkInt64 * out_piFreq )
418  {
419  *out_piFreq = (AkInt64)sceKernelGetProcessTimeCounterFrequency();
420  }
421 
422  /// Platform Independent Helper
424  {
425  AkInt64 iFreq;
426  PerformanceFrequency( &iFreq );
427  AK::g_fFreqRatio = (AkReal32)((AkReal64)iFreq / 1000);
428  }
429 
430  /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
431  AkForceInline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
432  {
433  return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
434  }
435 
436  /// String conversion helper
437  AkForceInline AkInt32 AkWideCharToChar( const wchar_t* in_pszUnicodeString,
438  AkUInt32 in_uiOutBufferSize,
439  char* io_pszAnsiString )
440  {
441  AKASSERT( io_pszAnsiString != NULL );
442 
443  mbstate_t state;
444  memset (&state, '\0', sizeof (state));
445 
446  return (AkInt32)wcsrtombs(io_pszAnsiString, // destination
447  &in_pszUnicodeString, // source
448  in_uiOutBufferSize, // destination length
449  &state); //
450 
451  }
452 
453  /// String conversion helper
454  AkForceInline AkInt32 AkCharToWideChar( const char* in_pszAnsiString,
455  AkUInt32 in_uiOutBufferSize,
456  void* io_pvUnicodeStringBuffer )
457  {
458  AKASSERT( io_pvUnicodeStringBuffer != NULL );
459 
460  mbstate_t state;
461  memset (&state, '\0', sizeof (state));
462 
463  return (AkInt32)mbsrtowcs((wchar_t*)io_pvUnicodeStringBuffer, // destination
464  &in_pszAnsiString, // source
465  in_uiOutBufferSize, // destination length
466  &state); //
467  }
468 
469  AkForceInline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String,
470  AkUInt32 in_uiOutBufferSize,
471  void* io_pvUnicodeStringBuffer )
472  {
473  return AkCharToWideChar( in_pszUtf8String, in_uiOutBufferSize, (wchar_t*)io_pvUnicodeStringBuffer );
474  }
475 
476  /// Safe unicode string copy.
477  AkForceInline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
478  {
479  size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
480  wcsncpy( in_pDest, in_pSrc, uSizeCopy );
481  in_pDest[uSizeCopy] = '\0';
482  }
483 
484  /// Safe ansi string copy.
485  AkForceInline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
486  {
487  size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
488  strncpy( in_pDest, in_pSrc, uSizeCopy );
489  in_pDest[uSizeCopy] = '\0';
490  }
491 
492  /// Safe unicode string concatenation.
493  AkForceInline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
494  {
495  size_t uAvailableSize = ( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
496  wcsncat( in_pDest, in_pSrc, AkMin( uAvailableSize, wcslen( in_pSrc ) ) );
497  }
498 
499  /// Safe ansi string concatenation.
500  AkForceInline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
501  {
502  size_t uAvailableSize = ( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
503  strncat( in_pDest, in_pSrc, AkMin( uAvailableSize, strlen( in_pSrc ) ) );
504  }
505 
506  /// Stack allocations.
507  #define AkAlloca( _size_ ) alloca( _size_ )
508 
509 
510 
511  /// Converts a wchar_t string to an AkOSChar string.
512  /// \remark On some platforms the AkOSChar string simply points to the same string,
513  /// on others a new buffer is allocated on the stack using AkAlloca. This means
514  /// you must make sure that:
515  /// - The source string stays valid and unmodified for as long as you need the
516  /// AkOSChar string (for cases where they point to the same string)
517  /// - The AkOSChar string is used within this scope only -- for example, do NOT
518  /// return that string from a function (for cases where it is allocated on the stack)
519  #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) \
520  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + wcslen( _wstring_ )) * sizeof(AkOSChar) ); \
521  AKPLATFORM::AkWideCharToChar( _wstring_ , (AkUInt32)(1 + wcslen( _wstring_ )), (AkOSChar*)( _oscharstring_ ) )
522 
523 
524  /// Converts a char string to an AkOSChar string.
525  /// \remark On some platforms the AkOSChar string simply points to the same string,
526  /// on others a new buffer is allocated on the stack using AkAlloca. This means
527  /// you must make sure that:
528  /// - The source string stays valid and unmodified for as long as you need the
529  /// AkOSChar string (for cases where they point to the same string)
530  /// - The AkOSChar string is used within this scope only -- for example, do NOT
531  /// return that string from a function (for cases where it is allocated on the stack)
532  #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _astring_ )
533 
534  /// Converts a AkOSChar string into wide char string.
535  /// \remark On some platforms the AkOSChar string simply points to the same string,
536  /// on others a new buffer is allocated on the stack using AkAlloca. This means
537  /// you must make sure that:
538  /// - The source string stays valid and unmodified for as long as you need the
539  /// AkOSChar string (for cases where they point to the same string)
540  /// - The AkOSChar string is used within this scope only -- for example, do NOT
541  /// return that string from a function (for cases where it is allocated on the stack)
542  #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) \
543  _wstring_ = (wchar_t*)AkAlloca((1+strlen(_osstring_)) * sizeof(wchar_t)); \
544  AKPLATFORM::AkCharToWideChar( _osstring_, (AkUInt32)(1 + strlen(_osstring_ )), _wstring_ )
545 
546  /// Converts a AkOSChar string into char string.
547  /// \remark On some platforms the AkOSChar string simply points to the same string,
548  /// on others a new buffer is allocated on the stack using AkAlloca. This means
549  /// you must make sure that:
550  /// - The source string stays valid and unmodified for as long as you need the
551  /// AkOSChar string (for cases where they point to the same string)
552  /// - The AkOSChar string is used within this scope only -- for example, do NOT
553  /// return that string from a function (for cases where it is allocated on the stack)
554  #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) _astring_ = (char*)_osstring_
555 
556  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
557  /// \return The length, in characters, of the specified string (excluding terminating NULL)
558  AkForceInline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
559  {
560  return ( wcslen( in_pStr ) );
561  }
562 
563  /// Get the length, in characters, of a NULL-terminated AkOSChar string
564  /// \return The length, in characters, of the specified string (excluding terminating NULL)
565  AkForceInline size_t OsStrLen( const AkOSChar* in_pszString )
566  {
567  return ( strlen( in_pszString ) );
568  }
569 
570  /// AkOSChar version of sprintf().
571  #define AK_OSPRINTF snprintf
572 
573  /// Compare two NULL-terminated AkOSChar strings
574  /// \return
575  /// - < 0 if in_pszString1 < in_pszString2
576  /// - 0 if the two strings are identical
577  /// - > 0 if in_pszString1 > in_pszString2
578  /// \remark The comparison is case-sensitive
579  AkForceInline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
580  {
581  return ( strcmp( in_pszString1, in_pszString2 ) );
582  }
583 
584  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
585  /// \return
586  /// - < 0 if in_pszString1 < in_pszString2
587  /// - 0 if the two strings are identical
588  /// - > 0 if in_pszString1 > in_pszString2
589  /// \remark The comparison is case-sensitive
590  inline int OsStrNCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize )
591  {
592  return ( strncmp(in_pszString1, in_pszString2, in_MaxCountSize) );
593  }
594 
595  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
596  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
597  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
598  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
599  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
600  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
601  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
602 
603  // Use with AkOSChar.
604  #define AK_PATH_SEPARATOR ("/")
605  #define AK_LIBRARY_PREFIX ("")
606  #define AK_DYNAMIC_LIBRARY_EXTENSION (".prx")
607 
608  /// Support to fetch the CPUID for the platform. Only valid for X86 targets
609  /// \remark Note that IAkProcessorFeatures should be preferred to fetch this data
610  /// as it will have already translated the feature bits into AK-relevant enums
611  inline void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
612  {
613  __get_cpuid_count( in_uLeafOpcode, in_uSubLeafOpcode,
614  &out_uCPUFeatures[0],
615  &out_uCPUFeatures[1],
616  &out_uCPUFeatures[2],
617  &out_uCPUFeatures[3]);
618  }
619 }
620 
621 #ifdef AK_ENABLE_INSTRUMENT
622 
623 #include <perf.h>
624 #include <sdk_version.h>
625 #if SCE_ORBIS_SDK_VERSION >= 0x04500000
626  #include <razorcpu.h>
627  #ifndef SCE_RAZOR_MARKER_DISABLE_HUD
628  #define SCE_RAZOR_MARKER_DISABLE_HUD 0
629  #endif
630 #endif
631 
632 class AkInstrumentScope
633 {
634 public:
635  inline AkInstrumentScope( const char *in_pszZoneName )
636  {
637  sceRazorCpuPushMarkerStatic( in_pszZoneName, 0, SCE_RAZOR_MARKER_DISABLE_HUD );
638  }
639 
640  inline ~AkInstrumentScope()
641  {
642  sceRazorCpuPopMarker();
643  }
644 };
645 
646 #define AK_INSTRUMENT_BEGIN( _zone_name_ ) sceRazorCpuPushMarkerStatic( text, 0, SCE_RAZOR_MARKER_DISABLE_HUD )
647 #define AK_INSTRUMENT_BEGIN_C( _color_, _zone_name_ ) sceRazorCpuPushMarkerStatic( text, _color_, SCE_RAZOR_MARKER_DISABLE_HUD )
648 #define AK_INSTRUMENT_END( _zone_name_ ) sceRazorCpuPopMarker()
649 #define AK_INSTRUMENT_SCOPE( _zone_name_ ) AkInstrumentScope akInstrumentScope_##__LINE__(_zone_name_)
650 
651 #define AK_INSTRUMENT_IDLE_BEGIN( _zone_name_ )
652 #define AK_INSTRUMENT_IDLE_END( _zone_name_ )
653 #define AK_INSTRUMENT_IDLE_SCOPE( _zone_name_ )
654 
655 #define AK_INSTRUMENT_STALL_BEGIN( _zone_name_ )
656 #define AK_INSTRUMENT_STALL_END( _zone_name_ )
657 #define AK_INSTRUMENT_STALL_SCOPE( _zone_name_ )
658 
659 #define AK_INSTRUMENT_THREAD_START( _thread_name_ )
660 
661 #endif // AK_ENABLE_INSTRUMENT
662 
663 #endif // _AK_PLATFORM_FUNCS_H_
#define AK_THREAD_DEFAULT_SCHED_POLICY
Definition: AkPlatformFuncs.h:77
#define AkMin(x1, x2)
Definition: AkPlatformFuncs.h:94
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Definition: AkPlatformFuncs.h:558
#define AkForceInline
Force inlining.
Definition: AkTypes.h:61
Audiokinetic namespace.
@ AK_Fail
The operation failed.
Definition: AkTypes.h:130
semaphore_t AkEvent
Definition: AkTypes.h:66
AkForceInline void FreeVM(void *address, size_t size, size_t extra, size_t release)
Definition: AkPlatformFuncs.h:262
int nPriority
Thread priority.
Definition: AkPlatformFuncs.h:49
void AkClearEvent(AkEvent &out_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:52
Platform-dependent helpers.
Definition: AkPlatformFuncs.h:157
ScePthread AkThreadID
Thread ID.
Definition: AkTypes.h:99
void AkWaitForEvent(AkEvent &in_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:80
AkForceInline void UpdatePerformanceFrequency()
Platform Independent Helper.
Definition: AkPlatformFuncs.h:423
#define AK_NULL_THREAD
Definition: AkPlatformFuncs.h:89
wchar_t AkUtf16
Definition: AkTypes.h:109
AKRESULT
Standard function call result.
Definition: AkTypes.h:127
void OutputDebugMsg(const char *in_pszMsg)
Output a debug message on the console (Ansi string)
Definition: AkPlatformFuncs.h:121
AkForceInline void * AllocVM(size_t size, size_t *extra)
Definition: AkPlatformFuncs.h:243
void AkDestroySemaphore(AkSemaphore *io_semaphore)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:105
void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
Definition: AkPlatformFuncs.h:293
char AkOSChar
Generic character string.
Definition: AkTypes.h:93
#define AK_VM_PAGE_SIZE
Definition: AkPlatformFuncs.h:76
#define NULL
Definition: AkTypes.h:47
#define AK_THREAD_PRIORITY_NORMAL
Definition: AkPlatformFuncs.h:78
AkThreadID CurrentThread()
Returns the calling thread's ID.
Definition: AkPlatformFuncs.h:380
@ AK_Success
The operation was successful.
Definition: AkTypes.h:129
void AkCreateThread(AkThreadRoutine pStartRoutine, void *pParams, const AkThreadProperties &in_threadProperties, AkThread *out_pThread, const char *)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:183
void OutputDebugMsgV(const char *in_pszFmt,...)
Output a debug message on the console (variadic function).
Definition: AkPlatformFuncs.h:130
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:143
double AkReal64
64-bit floating point
Definition: AkTypes.h:96
void AkDestroyEvent(AkEvent &io_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:70
nn::os::ThreadFunction AkThreadRoutine
Thread routine.
Definition: AkTypes.h:99
AkForceInline bool AkIsValidThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:277
int64_t AkInt64
Signed 64-bit integer.
Definition: AkTypes.h:91
AkForceInline bool AkIsValidEvent(const AkEvent &in_event)
Definition: AkPlatformFuncs.h:155
AkForceInline void AkMemCpy(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:395
#define AKASSERT(Condition)
Definition: AkAssert.h:76
#define AK_DEFAULT_STACK_SIZE
Definition: AkPlatformFuncs.h:75
#define AKVERIFY(x)
Definition: AkAssert.h:78
AkForceInline void AkSleep(AkUInt32 in_ulMilliseconds)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:386
int32_t AkInt32
Signed 32-bit integer.
Definition: AkTypes.h:90
AkForceInline void AkClearThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:283
AkForceInline void AkGetDefaultThreadProperties(AkThreadProperties &out_threadProperties)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:302
int OsStrNCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2, size_t in_MaxCountSize)
Definition: AkPlatformFuncs.h:590
AkForceInline void AkMemSet(void *pDest, AkInt32 iVal, AkUInt32 uSize)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:401
SceKernelCpumask dwAffinityMask
Affinity mask.
Definition: AkPlatformFuncs.h:50
AkReal32 g_fFreqRatio
Definition: AkPlatformFuncs.h:63
AKRESULT AkCreateEvent(AkEvent &out_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:58
AkForceInline void SafeStrCpy(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string copy.
Definition: AkPlatformFuncs.h:477
#define AK_THREAD_AFFINITY_DEFAULT
Definition: AkPlatformFuncs.h:83
size_t uStackSize
Thread stack size.
Definition: AkPlatformFuncs.h:51
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:46
int uSchedPolicy
Thread scheduling policy.
Definition: AkPlatformFuncs.h:52
float AkReal32
32-bit floating point
Definition: AkTypes.h:95
AkForceInline AkInt32 AkCharToWideChar(const char *in_pszAnsiString, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper.
Definition: AkPlatformFuncs.h:454
AKRESULT AkCreateSemaphore(AkSemaphore *out_semaphore, AkUInt32 in_initialCount)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:93
AkForceInline void SafeStrCat(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string concatenation.
Definition: AkPlatformFuncs.h:493
void AkWaitForSemaphore(AkSemaphore *in_semaphore)
Platform Independent Helper - Semaphore wait, aka Operation P. Decrements value of semaphore,...
Definition: AkPlatformFuncs.h:115
AkForceInline AKRESULT AkCreateNamedEvent(AkEvent &out_event, const char *in_szName)
Definition: AkPlatformFuncs.h:160
AkForceInline AkInt32 AkWideCharToChar(const wchar_t *in_pszUnicodeString, AkUInt32 in_uiOutBufferSize, char *io_pszAnsiString)
String conversion helper.
Definition: AkPlatformFuncs.h:437
AkForceInline void AkWaitForSingleThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:373
void AkSignalEvent(const AkEvent &in_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:87
Definition: AkTypes.h:104
AkForceInline AkInt32 AkUtf8ToWideChar(const char *in_pszUtf8String, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper.
Definition: AkPlatformFuncs.h:469
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:77
semaphore_t AkSemaphore
Definition: AkTypes.h:67
AkForceInline void AkCloseThread(AkThread *in_pThread)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:289
AkForceInline int OsStrCmp(const AkOSChar *in_pszString1, const AkOSChar *in_pszString2)
Definition: AkPlatformFuncs.h:579
void AkReleaseSemaphore(AkSemaphore *in_semaphore)
Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore.
Definition: AkPlatformFuncs.h:121
AkForceInline size_t OsStrLen(const AkOSChar *in_pszString)
Definition: AkPlatformFuncs.h:565
AkForceInline AkReal32 Elapsed(const AkInt64 &in_iNow, const AkInt64 &in_iStart)
Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
Definition: AkPlatformFuncs.h:431