Version
menu_open
link
Wwise SDK 2021.1.14
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.14 Build: 6590
25  Copyright (c) 2006-2023 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  inline int SafeStrFormat(wchar_t * in_pDest, size_t in_uDestMaxNumChars, const wchar_t* in_pszFmt, ...)
507  {
508  va_list args;
509  va_start(args, in_pszFmt);
510  int r = vswprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
511  va_end(args);
512  return r;
513  }
514 
515  inline int SafeStrFormat(char * in_pDest, size_t in_uDestMaxNumChars, const char* in_pszFmt, ...)
516  {
517  va_list args;
518  va_start(args, in_pszFmt);
519  int r = vsnprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
520  va_end(args);
521  return r;
522  }
523 
524  /// Stack allocations.
525  #define AkAlloca( _size_ ) alloca( _size_ )
526 
527 
528 
529  /// Converts a wchar_t string to an AkOSChar string.
530  /// \remark On some platforms the AkOSChar string simply points to the same string,
531  /// on others a new buffer is allocated on the stack using AkAlloca. This means
532  /// you must make sure that:
533  /// - The source string stays valid and unmodified for as long as you need the
534  /// AkOSChar string (for cases where they point to the same string)
535  /// - The AkOSChar string is used within this scope only -- for example, do NOT
536  /// return that string from a function (for cases where it is allocated on the stack)
537  #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) \
538  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + wcslen( _wstring_ )) * sizeof(AkOSChar) ); \
539  AKPLATFORM::AkWideCharToChar( _wstring_ , (AkUInt32)(1 + wcslen( _wstring_ )), (AkOSChar*)( _oscharstring_ ) )
540 
541 
542  /// Converts a char string to an AkOSChar string.
543  /// \remark On some platforms the AkOSChar string simply points to the same string,
544  /// on others a new buffer is allocated on the stack using AkAlloca. This means
545  /// you must make sure that:
546  /// - The source string stays valid and unmodified for as long as you need the
547  /// AkOSChar string (for cases where they point to the same string)
548  /// - The AkOSChar string is used within this scope only -- for example, do NOT
549  /// return that string from a function (for cases where it is allocated on the stack)
550  #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _astring_ )
551 
552  /// Converts a AkOSChar string into wide char string.
553  /// \remark On some platforms the AkOSChar string simply points to the same string,
554  /// on others a new buffer is allocated on the stack using AkAlloca. This means
555  /// you must make sure that:
556  /// - The source string stays valid and unmodified for as long as you need the
557  /// AkOSChar string (for cases where they point to the same string)
558  /// - The AkOSChar string is used within this scope only -- for example, do NOT
559  /// return that string from a function (for cases where it is allocated on the stack)
560  #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) \
561  _wstring_ = (wchar_t*)AkAlloca((1+strlen(_osstring_)) * sizeof(wchar_t)); \
562  AKPLATFORM::AkCharToWideChar( _osstring_, (AkUInt32)(1 + strlen(_osstring_ )), _wstring_ )
563 
564  /// Converts a AkOSChar string into char string.
565  /// \remark On some platforms the AkOSChar string simply points to the same string,
566  /// on others a new buffer is allocated on the stack using AkAlloca. This means
567  /// you must make sure that:
568  /// - The source string stays valid and unmodified for as long as you need the
569  /// AkOSChar string (for cases where they point to the same string)
570  /// - The AkOSChar string is used within this scope only -- for example, do NOT
571  /// return that string from a function (for cases where it is allocated on the stack)
572  #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) _astring_ = (char*)_osstring_
573 
574  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
575  /// \return The length, in characters, of the specified string (excluding terminating NULL)
576  AkForceInline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
577  {
578  return ( wcslen( in_pStr ) );
579  }
580 
581  /// Get the length, in characters, of a NULL-terminated AkOSChar string
582  /// \return The length, in characters, of the specified string (excluding terminating NULL)
583  AkForceInline size_t OsStrLen( const AkOSChar* in_pszString )
584  {
585  return ( strlen( in_pszString ) );
586  }
587 
588  /// AkOSChar version of sprintf().
589  #define AK_OSPRINTF snprintf
590 
591  /// Compare two NULL-terminated AkOSChar strings
592  /// \return
593  /// - < 0 if in_pszString1 < in_pszString2
594  /// - 0 if the two strings are identical
595  /// - > 0 if in_pszString1 > in_pszString2
596  /// \remark The comparison is case-sensitive
597  AkForceInline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
598  {
599  return ( strcmp( in_pszString1, in_pszString2 ) );
600  }
601 
602  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
603  /// \return
604  /// - < 0 if in_pszString1 < in_pszString2
605  /// - 0 if the two strings are identical
606  /// - > 0 if in_pszString1 > in_pszString2
607  /// \remark The comparison is case-sensitive
608  inline int OsStrNCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize )
609  {
610  return ( strncmp(in_pszString1, in_pszString2, in_MaxCountSize) );
611  }
612 
613  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
614  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
615  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
616  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
617  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
618  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
619  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
620 
621  // Use with AkOSChar.
622  #define AK_PATH_SEPARATOR ("/")
623  #define AK_LIBRARY_PREFIX ("")
624  #define AK_DYNAMIC_LIBRARY_EXTENSION (".prx")
625 
626  /// Support to fetch the CPUID for the platform. Only valid for X86 targets
627  /// \remark Note that IAkProcessorFeatures should be preferred to fetch this data
628  /// as it will have already translated the feature bits into AK-relevant enums
629  inline void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
630  {
631  __get_cpuid_count( in_uLeafOpcode, in_uSubLeafOpcode,
632  &out_uCPUFeatures[0],
633  &out_uCPUFeatures[1],
634  &out_uCPUFeatures[2],
635  &out_uCPUFeatures[3]);
636  }
637 }
638 
639 #ifdef AK_ENABLE_INSTRUMENT
640 
641 #include <perf.h>
642 #include <sdk_version.h>
643 #if SCE_ORBIS_SDK_VERSION >= 0x04500000
644  #include <razorcpu.h>
645  #ifndef SCE_RAZOR_MARKER_DISABLE_HUD
646  #define SCE_RAZOR_MARKER_DISABLE_HUD 0
647  #endif
648 #endif
649 
650 class AkInstrumentScope
651 {
652 public:
653  inline AkInstrumentScope( const char *in_pszZoneName )
654  {
655  sceRazorCpuPushMarkerStatic( in_pszZoneName, 0, SCE_RAZOR_MARKER_DISABLE_HUD );
656  }
657 
658  inline ~AkInstrumentScope()
659  {
660  sceRazorCpuPopMarker();
661  }
662 };
663 
664 #define AK_INSTRUMENT_BEGIN( _zone_name_ ) sceRazorCpuPushMarkerStatic( text, 0, SCE_RAZOR_MARKER_DISABLE_HUD )
665 #define AK_INSTRUMENT_BEGIN_C( _color_, _zone_name_ ) sceRazorCpuPushMarkerStatic( text, _color_, SCE_RAZOR_MARKER_DISABLE_HUD )
666 #define AK_INSTRUMENT_END( _zone_name_ ) sceRazorCpuPopMarker()
667 #define AK_INSTRUMENT_SCOPE( _zone_name_ ) AkInstrumentScope akInstrumentScope_##__LINE__(_zone_name_)
668 
669 #define AK_INSTRUMENT_IDLE_BEGIN( _zone_name_ )
670 #define AK_INSTRUMENT_IDLE_END( _zone_name_ )
671 #define AK_INSTRUMENT_IDLE_SCOPE( _zone_name_ )
672 
673 #define AK_INSTRUMENT_STALL_BEGIN( _zone_name_ )
674 #define AK_INSTRUMENT_STALL_END( _zone_name_ )
675 #define AK_INSTRUMENT_STALL_SCOPE( _zone_name_ )
676 
677 #define AK_INSTRUMENT_THREAD_START( _thread_name_ )
678 
679 #endif // AK_ENABLE_INSTRUMENT
680 
681 #endif // _AK_PLATFORM_FUNCS_H_
#define AK_THREAD_DEFAULT_SCHED_POLICY
Definition: AkPlatformFuncs.h:77
#define AkMin(x1, x2)
Definition: AkPlatformFuncs.h:94
float AkReal32
32-bit floating point
Definition: AkTypes.h:70
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Definition: AkPlatformFuncs.h:576
Audiokinetic namespace.
@ AK_Fail
The operation failed.
Definition: AkTypes.h:135
semaphore_t AkEvent
Definition: AkTypes.h:73
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
void AkWaitForEvent(AkEvent &in_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:80
pthread_t AkThreadID
Thread ID.
Definition: AkTypes.h:74
AkForceInline void UpdatePerformanceFrequency()
Platform Independent Helper.
Definition: AkPlatformFuncs.h:423
#define AK_NULL_THREAD
Definition: AkPlatformFuncs.h:89
AKRESULT
Standard function call result.
Definition: AkTypes.h:132
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
double AkReal64
64-bit floating point
Definition: AkTypes.h:71
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:68
int SafeStrFormat(wchar_t *in_pDest, size_t in_uDestMaxNumChars, const wchar_t *in_pszFmt,...)
Definition: AkPlatformFuncs.h:506
#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:134
void AkCreateThread(AkThreadRoutine pStartRoutine, void *pParams, const AkThreadProperties &in_threadProperties, AkThread *out_pThread, const char *)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:183
AkUInt16 AkUtf16
Definition: AkTypes.h:82
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
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
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
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:608
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
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
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:59
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
int32_t AkInt32
Signed 32-bit integer.
Definition: AkTypes.h:64
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
semaphore_t AkSemaphore
Definition: AkTypes.h:74
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:597
#define AkForceInline
Definition: AkTypes.h:60
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:583
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
int64_t AkInt64
Signed 64-bit integer.
Definition: AkTypes.h:65

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