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 #include <ajm.h>
44 
45 //-----------------------------------------------------------------------------
46 // Platform-specific thread properties definition.
47 //-----------------------------------------------------------------------------
48 struct AkThreadProperties
49 {
50  int nPriority; ///< Thread priority
51  SceKernelCpumask dwAffinityMask; ///< Affinity mask
52  size_t uStackSize; ///< Thread stack size
53  int uSchedPolicy; ///< Thread scheduling policy
54 };
55 
56 //-----------------------------------------------------------------------------
57 // External variables.
58 //-----------------------------------------------------------------------------
59 // These variables are declared and updated by the sound engine.
60 namespace AK
61 {
62  // used by time helpers to return time values in milliseconds.
64 }
65 
66 //-----------------------------------------------------------------------------
67 // Defines for PS5.
68 //-----------------------------------------------------------------------------
69 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) void* FuncName(void* lpParameter)
70 #define AK_THREAD_RETURN( _param_ ) return (_param_);
71 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
72 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
73 
74 #define AK_RETURN_THREAD_OK 0x00000000
75 #define AK_RETURN_THREAD_ERROR 0x00000001
76 #define AK_DEFAULT_STACK_SIZE (128*1024)
77 #define AK_VM_PAGE_SIZE (16*1024)
78 #define AK_VM_DEVICE_PAGE_SIZE (64*1024)
79 #define AK_THREAD_DEFAULT_SCHED_POLICY SCE_KERNEL_SCHED_FIFO
80 #define AK_THREAD_PRIORITY_NORMAL SCE_KERNEL_PRIO_FIFO_DEFAULT
81 #define AK_THREAD_PRIORITY_ABOVE_NORMAL SCE_KERNEL_PRIO_FIFO_HIGHEST
82 #define AK_THREAD_PRIORITY_BELOW_NORMAL SCE_KERNEL_PRIO_FIFO_LOWEST
83 
84 #define AK_THREAD_AFFINITY_ALL 4095 // from 0b1111'1111'1111 setting the 12 available core to true. (ex: 12 << 1 - 1)
85 #define AK_THREAD_AFFINITY_DEFAULT AK_THREAD_AFFINITY_ALL
86 
87 // NULL objects
88 #define AK_NULL_THREAD NULL
89 
90 #define AK_INFINITE (AK_UINT_MAX)
91 
92 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2))
93 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2))
94 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x)))
95 
96 namespace AKPLATFORM
97 {
98 #ifndef AK_OPTIMIZED
99  /// Output a debug message on the console (Ansi string)
100  AkForceInline void OutputDebugMsg( const char* in_pszMsg )
101  {
102  fputs( in_pszMsg, stderr );
103  }
104  /// Output a debug message on the console (Unicode string)
105  AkForceInline void OutputDebugMsg( const wchar_t* in_pszMsg )
106  {
107  fputws( in_pszMsg, stderr );
108  }
109 
110  /// Output a debug message on the console (Unicode string) (variadic function)
111  template <int MaxSize = 0> // Unused
112  AkForceInline void OutputDebugMsgV( const wchar_t* in_pszFmt, ... )
113  {
114  va_list args;
115  va_start(args, in_pszFmt);
116  vfwprintf(stderr, in_pszFmt, args);
117  va_end(args);
118  }
119 
120  /// Output a debug message on the console (Ansi string) (variadic function)
121  template <int MaxSize = 0> // Unused
122  AkForceInline void OutputDebugMsgV( const char* in_pszFmt, ... )
123  {
124  va_list args;
125  va_start(args, in_pszFmt);
126  vfprintf(stderr, in_pszFmt, args);
127  va_end(args);
128  }
129 #else
130  inline void OutputDebugMsg( const wchar_t* ){}
131  inline void OutputDebugMsg( const char* ){}
132 
133  template <int MaxSize = 0> // Unused
134  inline void OutputDebugMsgV( const wchar_t*, ... ){}
135 
136  template <int MaxSize = 0> // Unused
137  inline void OutputDebugMsgV( const char*, ... ){}
138 #endif
139 
140 
141  // Simple automatic event API
142  // ------------------------------------------------------------------
143 
144  /// Platform Independent Helper
145  AkForceInline void AkClearEvent( AkEvent & out_event )
146  {
147  out_event = NULL;
148  }
149 
150  AkForceInline bool AkIsValidEvent(const AkEvent & in_event)
151  {
152  return (in_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 && AkIsValidEvent(out_event))
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  inline AKRESULT AkCreateSemaphore( AkSemaphore* out_semaphore, AkUInt32 in_initialCount )
205  {
206  int ret = sceKernelCreateSema(
207  out_semaphore,
208  "AkSemaphore",
209  0,
210  in_initialCount,
211  INT_MAX,
212  NULL );
213 
214  return ( ret == SCE_OK ) ? AK_Success : AK_Fail;
215  }
216 
217  /// Platform Independent Helper
218  inline void AkDestroySemaphore( AkSemaphore* io_semaphore )
219  {
220  AKVERIFY( sceKernelDeleteSema( *io_semaphore ) == SCE_OK);
221  }
222 
223  /// 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.
224  inline void AkWaitForSemaphore( AkSemaphore* in_semaphore )
225  {
226  AKVERIFY( sceKernelWaitSema( *in_semaphore, 1, NULL ) == SCE_OK );
227  }
228 
229  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore.
230  inline void AkReleaseSemaphore( AkSemaphore* in_semaphore )
231  {
232  AKVERIFY( sceKernelSignalSema( *in_semaphore, 1 ) == SCE_OK );
233  }
234 
235  // Virtual Memory
236  // ------------------------------------------------------------------
237 
238  const int kMemoryFlags = SCE_KERNEL_PROT_CPU_RW | SCE_KERNEL_PROT_GPU_RW | SCE_KERNEL_PROT_AMPR_ALL;
239  const int kDeviceMemoryFlags = SCE_KERNEL_PROT_CPU_RW | SCE_KERNEL_PROT_GPU_RW | SCE_KERNEL_PROT_AMPR_ALL | SCE_KERNEL_PROT_ACP_RW;
240 
241  AkForceInline void* AllocVM(size_t size, size_t* extra)
242  {
243  AKASSERT((size % AK_VM_PAGE_SIZE) == 0);
244  off_t directMemStart = 0;
245  void* ptr = NULL;
246 
247  // In order to use ACM hardware accelerated functions, Wwise must have GPU-visible memory
248  int32_t err;
249  err = sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, size, AK_VM_PAGE_SIZE, SCE_KERNEL_MTYPE_C_SHARED, &directMemStart);
250  if (err == SCE_OK)
251  {
252  err = sceKernelMapDirectMemory(&ptr, size, kMemoryFlags, 0, directMemStart, AK_VM_PAGE_SIZE);
253  AKASSERT(ptr);
254  AKASSERT(err == SCE_OK);
255 
256  *extra = (size_t)directMemStart;
257  }
258  return (uint8_t*)ptr;
259  }
260 
261  AkForceInline void FreeVM(void* address, size_t size, size_t extra, size_t release)
262  {
263  if (release)
264  {
265  AKASSERT(extra);
266  off_t directMemStart = (off_t)extra;
267  int32_t err = sceKernelReleaseDirectMemory(directMemStart, release);
268  AKASSERT(err == SCE_OK);
269  }
270  }
271 
272  AkForceInline void* AllocDevice(size_t size, size_t* extra)
273  {
274  AKASSERT((size % AK_VM_DEVICE_PAGE_SIZE) == 0);
275  off_t directMemStart = 0;
276  void* ptr = NULL;
277 
278  // In order to use AJM zero-copy operations, Wwise must have ACP-visible memory
279  int32_t err;
280  err = sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, size, AK_VM_DEVICE_PAGE_SIZE, SCE_KERNEL_MTYPE_C_SHARED, &directMemStart);
281  if (err == SCE_OK)
282  {
283  err = sceKernelMapDirectMemory(&ptr, size, kDeviceMemoryFlags, 0, directMemStart, AK_VM_DEVICE_PAGE_SIZE);
284  AKASSERT(ptr);
285  AKASSERT(err == SCE_OK);
286 
287  *extra = (size_t)directMemStart;
288  }
289  return (uint8_t*)ptr;
290  }
291 
292  AkForceInline void FreeDevice(void* address, size_t size, size_t extra, size_t release)
293  {
294  if (release)
295  {
296  AKASSERT(extra);
297  off_t directMemStart = (off_t)extra;
298  int32_t err = sceKernelReleaseDirectMemory(directMemStart, release);
299  AKASSERT(err == SCE_OK);
300  }
301  }
302 
303  AkForceInline bool CheckMemoryProtection(void* address, size_t size, int expectedProt)
304  {
305  void* pStart, * pEnd;
306  int prot;
307 
308  AkUIntPtr addressEnd = (AkUIntPtr)address + size - 1;
309 
310  // Check protection flags apply to the whole range
311  while ((AkUIntPtr)address < addressEnd)
312  {
313  int err = sceKernelQueryMemoryProtection(address, &pStart, &pEnd, &prot);
314  if (err != SCE_OK)
315  return false;
316 
317  // Check protection flags
318  if ((prot & expectedProt) != expectedProt)
319  return false;
320 
321  if ((AkUIntPtr)pStart > (AkUIntPtr)address)
322  return false;
323 
324  address = pEnd;
325  }
326 
327  return true;
328  }
329 
330  // Threads
331  // ------------------------------------------------------------------
332 
333  /// Platform Independent Helper
334  AkForceInline bool AkIsValidThread( AkThread * in_pThread )
335  {
336  return ( *in_pThread != AK_NULL_THREAD );
337  }
338 
339  /// Platform Independent Helper
340  AkForceInline void AkClearThread( AkThread * in_pThread )
341  {
342  *in_pThread = AK_NULL_THREAD;
343  }
344 
345  /// Platform Independent Helper
346  AkForceInline void AkCloseThread( AkThread * in_pThread )
347  {
348  AKASSERT( in_pThread );
349  AKASSERT( *in_pThread );
350 
351  // #define KILL_THREAD(t) do { void *ret; scePthreadJoin(t,&ret); } while(false)
352  // AKVERIFY( SCE_OK == sceKernelDeleteThread( *in_pThread ) );
353  AkClearThread( in_pThread );
354  }
355 
356  #define AkExitThread( _result ) return _result; // ?????
357 
358  /// Platform Independent Helper
359  AkForceInline void AkGetDefaultThreadProperties( AkThreadProperties & out_threadProperties )
360  {
361  out_threadProperties.uStackSize = AK_DEFAULT_STACK_SIZE;
362  out_threadProperties.uSchedPolicy = AK_THREAD_DEFAULT_SCHED_POLICY;
363  out_threadProperties.nPriority = AK_THREAD_PRIORITY_NORMAL;
364  out_threadProperties.dwAffinityMask = AK_THREAD_AFFINITY_DEFAULT;
365  }
366 
367  /// Platform Independent Helper
368  inline void AkCreateThread(
369  AkThreadRoutine pStartRoutine, // Thread routine.
370  void * pParams, // Routine params.
371  const AkThreadProperties & in_threadProperties, // Properties. NULL for default.
372  AkThread * out_pThread, // Returned thread handle.
373  const char * in_szThreadName ) // Opt thread name.
374  {
375  AKASSERT( out_pThread != NULL );
376 
377  ScePthreadAttr attr;
378 
379  // Create the attr
380  AKVERIFY(!scePthreadAttrInit(&attr));
381  // Set the stack size
382  AKVERIFY(!scePthreadAttrSetstacksize(&attr,in_threadProperties.uStackSize));
383  AKVERIFY(!scePthreadAttrSetdetachstate(&attr, SCE_PTHREAD_CREATE_JOINABLE));
384  AKVERIFY(!scePthreadAttrSetinheritsched(&attr, SCE_PTHREAD_EXPLICIT_SCHED));
385  AKVERIFY(!scePthreadAttrSetaffinity(&attr,in_threadProperties.dwAffinityMask));
386 
387  // Try to set the thread policy
388  int sched_policy = in_threadProperties.uSchedPolicy;
389  if( scePthreadAttrSetschedpolicy( &attr, sched_policy ) )
390  {
391  AKASSERT( !"AKCreateThread invalid sched policy, will automatically set it to FIFO scheduling" );
392  sched_policy = AK_THREAD_DEFAULT_SCHED_POLICY;
393  AKVERIFY( !scePthreadAttrSetschedpolicy( &attr, sched_policy ));
394  }
395 
396  int minPriority, maxPriority;
397  minPriority = SCE_KERNEL_PRIO_FIFO_HIGHEST;
398  maxPriority = SCE_KERNEL_PRIO_FIFO_LOWEST;
399 
400  // Set the thread priority if valid
401  AKASSERT( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority );
402  if( in_threadProperties.nPriority >= minPriority && in_threadProperties.nPriority <= maxPriority )
403  {
404  SceKernelSchedParam schedParam;
405  AKVERIFY( scePthreadAttrGetschedparam(&attr, &schedParam) == 0 );
406  schedParam.sched_priority = in_threadProperties.nPriority;
407  AKVERIFY( scePthreadAttrSetschedparam(&attr, &schedParam) == 0 );
408  }
409 
410  // Create the tread
411  int threadError = scePthreadCreate(out_pThread, &attr, pStartRoutine, pParams, in_szThreadName);
412  AKASSERT( threadError == 0 );
413  AKVERIFY(!scePthreadAttrDestroy(&attr));
414 
415  if( threadError != 0 )
416  {
417  AkClearThread( out_pThread );
418  return;
419  }
420 
421  // ::CreateThread() return NULL if it fails.
422  if ( !*out_pThread )
423  {
424  AkClearThread( out_pThread );
425  return;
426  }
427  }
428 
429  /// Platform Independent Helper
430  AkForceInline void AkWaitForSingleThread( AkThread * in_pThread )
431  {
432  AKASSERT( in_pThread );
433  AKASSERT( *in_pThread );
434  AKVERIFY(!scePthreadJoin( *in_pThread, NULL ));
435  }
436 
437  inline AkThreadID CurrentThread()
438  {
439  return scePthreadSelf();
440  }
441 
442  /// Platform Independent Helper
443  AkForceInline void AkSleep( AkUInt32 in_ulMilliseconds )
444  {
445  usleep( in_ulMilliseconds * 1000 );
446  }
447 
448  // Optimized memory functions
449  // --------------------------------------------------------------------
450 
451  /// Platform Independent Helper
452  AkForceInline void AkMemCpy( void * pDest, const void * pSrc, AkUInt32 uSize )
453  {
454  memcpy( pDest, pSrc, uSize );
455  }
456 
457  /// Platform Independent Helper
458  AkForceInline void AkMemSet( void * pDest, AkInt32 iVal, AkUInt32 uSize )
459  {
460  memset( pDest, iVal, uSize );
461  }
462 
463  // Time functions
464  // ------------------------------------------------------------------
465 
466  /// Platform Independent Helper
467  AkForceInline void PerformanceCounter( AkInt64 * out_piLastTime )
468  {
469  uint64_t uTime = sceKernelGetProcessTimeCounter();
470  *out_piLastTime = (AkInt64)uTime;
471  }
472 
473  /// Frequency of the PerformanceCounter() (ticks per second)
474  AkForceInline void PerformanceFrequency( AkInt64 * out_piFreq )
475  {
476  *out_piFreq = (AkInt64)sceKernelGetProcessTimeCounterFrequency();
477  }
478 
479  /// Platform Independent Helper
481  {
482  AkInt64 iFreq;
483  PerformanceFrequency( &iFreq );
484  AK::g_fFreqRatio = (AkReal32)((AkReal64)iFreq / 1000);
485  }
486 
487  /// Returns a time range in milliseconds, using the sound engine's updated count->milliseconds ratio.
488  AkForceInline AkReal32 Elapsed( const AkInt64 & in_iNow, const AkInt64 & in_iStart )
489  {
490  return ( in_iNow - in_iStart ) / AK::g_fFreqRatio;
491  }
492 
493  /// String conversion helper
494  AkForceInline AkInt32 AkWideCharToChar( const wchar_t* in_pszUnicodeString,
495  AkUInt32 in_uiOutBufferSize,
496  char* io_pszAnsiString )
497  {
498  AKASSERT( io_pszAnsiString != NULL );
499 
500  mbstate_t state;
501  memset (&state, '\0', sizeof (state));
502 
503  return (AkInt32)wcsrtombs(io_pszAnsiString, // destination
504  &in_pszUnicodeString, // source
505  in_uiOutBufferSize, // destination length
506  &state); //
507 
508  }
509 
510  /// String conversion helper
511  AkForceInline AkInt32 AkCharToWideChar( const char* in_pszAnsiString,
512  AkUInt32 in_uiOutBufferSize,
513  void* io_pvUnicodeStringBuffer )
514  {
515  AKASSERT( io_pvUnicodeStringBuffer != NULL );
516 
517  mbstate_t state;
518  memset (&state, '\0', sizeof (state));
519 
520  return (AkInt32)mbsrtowcs((wchar_t*)io_pvUnicodeStringBuffer, // destination
521  &in_pszAnsiString, // source
522  in_uiOutBufferSize, // destination length
523  &state); //
524  }
525 
526  AkForceInline AkInt32 AkUtf8ToWideChar( const char* in_pszUtf8String,
527  AkUInt32 in_uiOutBufferSize,
528  void* io_pvUnicodeStringBuffer )
529  {
530  return AkCharToWideChar( in_pszUtf8String, in_uiOutBufferSize, (wchar_t*)io_pvUnicodeStringBuffer );
531  }
532 
533  /// Safe unicode string copy.
534  AkForceInline void SafeStrCpy( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
535  {
536  size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
537  wcsncpy( in_pDest, in_pSrc, uSizeCopy );
538  in_pDest[uSizeCopy] = '\0';
539  }
540 
541  /// Safe ansi string copy.
542  AkForceInline void SafeStrCpy( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
543  {
544  size_t uSizeCopy = AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
545  strncpy( in_pDest, in_pSrc, uSizeCopy );
546  in_pDest[uSizeCopy] = '\0';
547  }
548 
549  /// Safe unicode string concatenation.
550  AkForceInline void SafeStrCat( wchar_t * in_pDest, const wchar_t* in_pSrc, size_t in_uDestMaxNumChars )
551  {
552  size_t uAvailableSize = ( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
553  wcsncat( in_pDest, in_pSrc, AkMin( uAvailableSize, wcslen( in_pSrc ) ) );
554  }
555 
556  /// Safe ansi string concatenation.
557  AkForceInline void SafeStrCat( char * in_pDest, const char* in_pSrc, size_t in_uDestMaxNumChars )
558  {
559  size_t uAvailableSize = ( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
560  strncat( in_pDest, in_pSrc, AkMin( uAvailableSize, strlen( in_pSrc ) ) );
561  }
562 
563  inline int SafeStrFormat(wchar_t * in_pDest, size_t in_uDestMaxNumChars, const wchar_t* in_pszFmt, ...)
564  {
565  va_list args;
566  va_start(args, in_pszFmt);
567  int r = vswprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
568  va_end(args);
569  return r;
570  }
571 
572  inline int SafeStrFormat(char * in_pDest, size_t in_uDestMaxNumChars, const char* in_pszFmt, ...)
573  {
574  va_list args;
575  va_start(args, in_pszFmt);
576  int r = vsnprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
577  va_end(args);
578  return r;
579  }
580 
581  /// Stack allocations.
582  #define AkAlloca( _size_ ) alloca( _size_ )
583 
584 
585 
586  /// Converts a wchar_t string to an AkOSChar string.
587  /// \remark On some platforms the AkOSChar string simply points to the same string,
588  /// on others a new buffer is allocated on the stack using AkAlloca. This means
589  /// you must make sure that:
590  /// - The source string stays valid and unmodified for as long as you need the
591  /// AkOSChar string (for cases where they point to the same string)
592  /// - The AkOSChar string is used within this scope only -- for example, do NOT
593  /// return that string from a function (for cases where it is allocated on the stack)
594  #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) \
595  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + wcslen( _wstring_ )) * sizeof(AkOSChar) ); \
596  AKPLATFORM::AkWideCharToChar( _wstring_ , (AkUInt32)(1 + wcslen( _wstring_ )), (AkOSChar*)( _oscharstring_ ) )
597 
598 
599  /// Converts a char string to an AkOSChar string.
600  /// \remark On some platforms the AkOSChar string simply points to the same string,
601  /// on others a new buffer is allocated on the stack using AkAlloca. This means
602  /// you must make sure that:
603  /// - The source string stays valid and unmodified for as long as you need the
604  /// AkOSChar string (for cases where they point to the same string)
605  /// - The AkOSChar string is used within this scope only -- for example, do NOT
606  /// return that string from a function (for cases where it is allocated on the stack)
607  #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _astring_ )
608 
609  /// Converts a AkOSChar string into wide char string.
610  /// \remark On some platforms the AkOSChar string simply points to the same string,
611  /// on others a new buffer is allocated on the stack using AkAlloca. This means
612  /// you must make sure that:
613  /// - The source string stays valid and unmodified for as long as you need the
614  /// AkOSChar string (for cases where they point to the same string)
615  /// - The AkOSChar string is used within this scope only -- for example, do NOT
616  /// return that string from a function (for cases where it is allocated on the stack)
617  #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) \
618  _wstring_ = (wchar_t*)AkAlloca((1+strlen(_osstring_)) * sizeof(wchar_t)); \
619  AKPLATFORM::AkCharToWideChar( _osstring_, (AkUInt32)(1 + strlen(_osstring_ )), _wstring_ )
620 
621  /// Converts a AkOSChar string into char string.
622  /// \remark On some platforms the AkOSChar string simply points to the same string,
623  /// on others a new buffer is allocated on the stack using AkAlloca. This means
624  /// you must make sure that:
625  /// - The source string stays valid and unmodified for as long as you need the
626  /// AkOSChar string (for cases where they point to the same string)
627  /// - The AkOSChar string is used within this scope only -- for example, do NOT
628  /// return that string from a function (for cases where it is allocated on the stack)
629  #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) _astring_ = (char*)_osstring_
630 
631  /// Get the length, in characters, of a NULL-terminated AkUtf16 string
632  /// \return The length, in characters, of the specified string (excluding terminating NULL)
633  AkForceInline size_t AkUtf16StrLen( const AkUtf16* in_pStr )
634  {
635  return ( wcslen( in_pStr ) );
636  }
637 
638  /// Get the length, in characters, of a NULL-terminated AkOSChar string
639  /// \return The length, in characters, of the specified string (excluding terminating NULL)
640  AkForceInline size_t OsStrLen( const AkOSChar* in_pszString )
641  {
642  return ( strlen( in_pszString ) );
643  }
644 
645  /// AkOSChar version of sprintf().
646  #define AK_OSPRINTF snprintf
647 
648  /// Compare two NULL-terminated AkOSChar strings
649  /// \return
650  /// - < 0 if in_pszString1 < in_pszString2
651  /// - 0 if the two strings are identical
652  /// - > 0 if in_pszString1 > in_pszString2
653  /// \remark The comparison is case-sensitive
654  AkForceInline int OsStrCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2 )
655  {
656  return ( strcmp( in_pszString1, in_pszString2 ) );
657  }
658 
659  /// Compare two NULL-terminated AkOSChar strings up to the specified count of characters.
660  /// \return
661  /// - < 0 if in_pszString1 < in_pszString2
662  /// - 0 if the two strings are identical
663  /// - > 0 if in_pszString1 > in_pszString2
664  /// \remark The comparison is case-sensitive
665  inline int OsStrNCmp( const AkOSChar* in_pszString1, const AkOSChar* in_pszString2, size_t in_MaxCountSize )
666  {
667  return ( strncmp(in_pszString1, in_pszString2, in_MaxCountSize) );
668  }
669 
670  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
671  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
672  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
673  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
674  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
675  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
676  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
677 
678  // Use with AkOSChar.
679  #define AK_PATH_SEPARATOR ("/")
680  #define AK_LIBRARY_PREFIX ("")
681  #define AK_DYNAMIC_LIBRARY_EXTENSION (".prx")
682 
683  /// Support to fetch the CPUID for the platform. Only valid for X86 targets
684  /// \remark Note that IAkProcessorFeatures should be preferred to fetch this data
685  /// as it will have already translated the feature bits into AK-relevant enums
686  inline void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
687  {
688  __get_cpuid_count( in_uLeafOpcode, in_uSubLeafOpcode,
689  &out_uCPUFeatures[0],
690  &out_uCPUFeatures[1],
691  &out_uCPUFeatures[2],
692  &out_uCPUFeatures[3]);
693  }
694 }
695 
696 #ifdef AK_ENABLE_INSTRUMENT
697 
698 #include <perf.h>
699 #include <sdk_version.h>
700 #if SCE_ORBIS_SDK_VERSION >= 0x04500000
701  #include <razorcpu.h>
702  #ifndef SCE_RAZOR_MARKER_DISABLE_HUD
703  #define SCE_RAZOR_MARKER_DISABLE_HUD 0
704  #endif
705 #endif
706 
707 class AkInstrumentScope
708 {
709 public:
710  inline AkInstrumentScope( const char *in_pszZoneName )
711  {
712  sceRazorCpuPushMarkerStatic( in_pszZoneName, 0, SCE_RAZOR_MARKER_DISABLE_HUD );
713  }
714 
715  inline ~AkInstrumentScope()
716  {
717  sceRazorCpuPopMarker();
718  }
719 };
720 
721 #define AK_INSTRUMENT_BEGIN( _zone_name_ ) sceRazorCpuPushMarkerStatic( text, 0, SCE_RAZOR_MARKER_DISABLE_HUD )
722 #define AK_INSTRUMENT_BEGIN_C( _color_, _zone_name_ ) sceRazorCpuPushMarkerStatic( text, _color_, SCE_RAZOR_MARKER_DISABLE_HUD )
723 #define AK_INSTRUMENT_END( _zone_name_ ) sceRazorCpuPopMarker()
724 #define AK_INSTRUMENT_SCOPE( _zone_name_ ) AkInstrumentScope akInstrumentScope_##__LINE__(_zone_name_)
725 
726 #define AK_INSTRUMENT_IDLE_BEGIN( _zone_name_ )
727 #define AK_INSTRUMENT_IDLE_END( _zone_name_ )
728 #define AK_INSTRUMENT_IDLE_SCOPE( _zone_name_ )
729 
730 #define AK_INSTRUMENT_STALL_BEGIN( _zone_name_ )
731 #define AK_INSTRUMENT_STALL_END( _zone_name_ )
732 #define AK_INSTRUMENT_STALL_SCOPE( _zone_name_ )
733 
734 #define AK_INSTRUMENT_THREAD_START( _thread_name_ )
735 
736 #endif // AK_ENABLE_INSTRUMENT
737 
738 #endif // _AK_PLATFORM_FUNCS_H_
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
#define AK_THREAD_DEFAULT_SCHED_POLICY
Definition: AkPlatformFuncs.h:79
int nPriority
Thread priority.
Definition: AkPlatformFuncs.h:49
void AkClearEvent(AkEvent &out_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:52
AkForceInline void FreeDevice(void *address, size_t size, size_t extra, size_t release)
Definition: AkPlatformFuncs.h:292
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
AKRESULT
Standard function call result.
Definition: AkTypes.h:132
AkForceInline bool CheckMemoryProtection(void *address, size_t size, int expectedProt)
Definition: AkPlatformFuncs.h:303
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
uintptr_t AkUIntPtr
Definition: AkTypes.h:61
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
#define AK_NULL_THREAD
Definition: AkPlatformFuncs.h:88
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
AkForceInline void * AllocDevice(size_t size, size_t *extra)
Definition: AkPlatformFuncs.h:272
#define NULL
Definition: AkTypes.h:47
#define AK_THREAD_AFFINITY_DEFAULT
Definition: AkPlatformFuncs.h:85
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
const int kMemoryFlags
Definition: AkPlatformFuncs.h:238
AkUInt16 AkUtf16
Definition: AkTypes.h:82
#define AK_VM_PAGE_SIZE
Definition: AkPlatformFuncs.h:77
#define AK_THREAD_PRIORITY_NORMAL
Definition: AkPlatformFuncs.h:80
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
#define AkMin(x1, x2)
Definition: AkPlatformFuncs.h:93
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 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
const int kDeviceMemoryFlags
Definition: AkPlatformFuncs.h:239
size_t uStackSize
Thread stack size.
Definition: AkPlatformFuncs.h:51
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:46
#define AK_DEFAULT_STACK_SIZE
Definition: AkPlatformFuncs.h:76
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
#define AK_VM_DEVICE_PAGE_SIZE
Definition: AkPlatformFuncs.h:78
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