Version
menu_open
Wwise SDK 2023.1.5
AkPlatformFuncs.h
Go to the documentation of this file.
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Copyright (c) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #pragma once
28 
31 
32 #if (defined(AK_CPU_X86_64) || defined(AK_CPU_X86))
33 #include <cpuid.h>
34 #endif
35 #include <mach/task.h>
36 #include <mach/semaphore.h>
37 #include <CoreFoundation/CFString.h>
38 #include <libkern/OSAtomic.h>
39 #include <mach/task.h>
40 #include <mach/mach_init.h>
41 #include <time.h>
42 #include <wchar.h>
43 
44 #define AK_SEC_TO_NANOSEC 1000000000ULL
45 
46 namespace AKPLATFORM
47 {
48  extern inline size_t AkUtf16StrLen( const AkUtf16* in_pStr );
49  // Simple automatic event API
50  // ------------------------------------------------------------------
51 
52  /// Platform Independent Helper
53  inline void AkClearEvent( AkEvent & out_event )
54  {
55  out_event = 0;
56  }
57 
58  /// Platform Independent Helper
59  inline AKRESULT AkCreateEvent( AkEvent & out_event )
60  {
61  kern_return_t ret = semaphore_create(
62  mach_task_self(),
63  &out_event,
64  SYNC_POLICY_FIFO,
65  0 );
66 
67  return ( ret == noErr ) ? AK_Success : AK_Fail;
68  }
69 
70  /// Platform Independent Helper
71  inline void AkDestroyEvent( AkEvent & io_event )
72  {
73  if( io_event != 0 )
74  {
75  AKVERIFY( semaphore_destroy( mach_task_self(), io_event ) == noErr);
76  }
77  io_event = 0;
78  }
79 
80  /// Platform Independent Helper
81  inline void AkWaitForEvent( AkEvent & in_event )
82  {
83  AKVERIFY( semaphore_wait( in_event ) == noErr );
84  }
85 
86 
87  /// Platform Independent Helper
88  inline void AkSignalEvent( const AkEvent & in_event )
89  {
90  AKVERIFY( semaphore_signal( in_event ) == noErr );
91  }
92 
93 
94  /// Platform Independent Helper
96  {
97  io_semaphore = 0;
98  }
99 
100  /// Platform Independent Helper
101  inline AKRESULT AkCreateSemaphore( AkSemaphore& out_semaphore, AkUInt32 in_initialCount )
102  {
103  kern_return_t ret = semaphore_create(
104  mach_task_self(),
105  &out_semaphore,
106  SYNC_POLICY_FIFO,
107  in_initialCount );
108 
109  return ( ret == noErr ) ? AK_Success : AK_Fail;
110  }
111 
112  /// Platform Independent Helper
113  inline void AkDestroySemaphore( AkSemaphore& io_semaphore )
114  {
115  AKVERIFY(semaphore_destroy(mach_task_self(), io_semaphore) == noErr);
116  }
117 
118  /// 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.
119  inline void AkWaitForSemaphore(AkSemaphore& in_semaphore)
120  {
121  AKVERIFY(semaphore_wait(in_semaphore) == noErr);
122  }
123 
124  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an arbitrary count.
125  inline void AkReleaseSemaphore(AkSemaphore& in_semaphore, AkUInt32 in_count)
126  {
127  for (int i=0; i < in_count; i++)
128  {
129  AKVERIFY(semaphore_signal(in_semaphore) == noErr);
130  }
131  }
132 
133  // Time functions
134  // ------------------------------------------------------------------
135 
136  /// Platform Independent Helper
137  inline void PerformanceCounter( AkInt64 * out_piLastTime )
138  {
139  struct timespec clockNow;
140  clock_gettime(CLOCK_MONOTONIC, &clockNow);
141  //This give the wallclock time in NS
142  *out_piLastTime = clockNow.tv_sec*AK_SEC_TO_NANOSEC + clockNow.tv_nsec;
143  }
144 
145  /// Platform Independent Helper
146  inline void PerformanceFrequency( AkInt64 * out_piFreq )
147  {
148  //Since Wall Clock is used, 1 NS is the frequency independent of the clock resolution
149  *out_piFreq = AK_SEC_TO_NANOSEC;
150  }
151 
152 
153  template<class destType, class srcType>
154  inline size_t AkMacConvertString( destType* in_pdDest, const srcType* in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *) )
155  {
156  CFStringBuiltInEncodings dstEncoding;
157  CFStringBuiltInEncodings srcEncoding;
158  switch(sizeof(destType))
159  {
160  case 1:
161  dstEncoding = kCFStringEncodingUTF8;
162  break;
163  case 2:
164  dstEncoding = kCFStringEncodingUTF16LE;
165  break;
166  case 4:
167  dstEncoding = kCFStringEncodingUTF32LE;
168  break;
169  default:
170  AKASSERT(!"Invalid Char size");
171  }
172 
173  switch(sizeof(srcType))
174  {
175  case 1:
176  srcEncoding = kCFStringEncodingUTF8;
177  break;
178  case 2:
179  srcEncoding = kCFStringEncodingUTF16LE;
180  break;
181  case 4:
182  srcEncoding = kCFStringEncodingUTF32LE;
183  break;
184  default:
185  AKASSERT(!"Invalid Char size");
186  }
187 
188  CFStringRef strRef;
189  strRef = CFStringCreateWithBytes( nil,
190  (UInt8 *) in_pSrc,
191  (srcStrLen( in_pSrc ) + 1) * sizeof(srcType),
192  srcEncoding,
193  false );
194  CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(strRef));
195  CFIndex sizeConverted = CFStringGetBytes(strRef, rangeToProcess, dstEncoding, '?', false, (UInt8 *)in_pdDest , in_MaxSize * sizeof(destType), NULL);
196 
197  //WG-28497 Memory leak when converting strings on Mac & iOS
198  CFRelease(strRef);
199 
200  return sizeConverted;
201  }
202 
203  #define CONVERT_UTF16_TO_WCHAR( _astring_, _wcharstring_ ) \
204  _wcharstring_ = (wchar_t*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(wchar_t) ); \
205  AK_UTF16_TO_WCHAR( _wcharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
206 
207  #define CONVERT_WCHAR_TO_UTF16( _astring_, _utf16string_ ) \
208  _utf16string_ = (AkUtf16*)AkAlloca( (1 + wcslen(_astring_)) * sizeof(AkUtf16) ); \
209  AK_WCHAR_TO_UTF16( _utf16string_, (const wchar_t*)_astring_, wcslen(_astring_)+1 )
210 
211  #define CONVERT_OSCHAR_TO_UTF16( _astring_, _utf16string_ ) \
212  _utf16string_ = (AkUtf16*)AkAlloca( (1 + strlen(_astring_)) * sizeof(AkUtf16) ); \
213  AK_OSCHAR_TO_UTF16( _utf16string_, (const AkOSChar*)_astring_, strlen(_astring_)+1 )
214 
215  #define CONVERT_UTF16_TO_OSCHAR( _astring_, _oscharstring_ ) \
216  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(AkOSChar) ); \
217  AK_UTF16_TO_OSCHAR( _oscharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
218 
219  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkOSChar, char>( in_pdDest, in_pSrc, in_MaxSize, strlen, strlen )
220  #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<wchar_t, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, &wcslen , &AKPLATFORM::AkUtf16StrLen)
221  #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, wchar_t>( in_pdDest, in_pSrc, in_MaxSize, &AKPLATFORM::AkUtf16StrLen, &wcslen )
222  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkOSChar, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
223  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<char, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
224  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, char>( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
225  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, AkOSChar>( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
226 
227  /// Stack allocations.
228  #define AkAlloca( _size_ ) alloca( _size_ )
229 
230 #if __BIGGEST_ALIGNMENT__ < AK_SIMD_ALIGNMENT
231  #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, AK_SIMD_ALIGNMENT*8 )
232 #endif
233 
234  #define AK_LIBRARY_PREFIX ("")
235  #define AK_DYNAMIC_LIBRARY_EXTENSION (".dylib")
236 
237  #define AK_FILEHANDLE_TO_UINTPTR(_h) ((AkUIntPtr)_h)
238  #define AK_SET_FILEHANDLE_TO_UINTPTR(_h,_u) _h = (AkFileHandle)_u
239 
240 #if (defined(AK_CPU_X86_64) || defined(AK_CPU_X86))
241  /// Support to fetch the CPUID for the platform. Only valid for X86 targets
242  /// \remark Note that IAkProcessorFeatures should be preferred to fetch this data
243  /// as it will have already translated the feature bits into AK-relevant enums
244  inline void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
245  {
246  __get_cpuid_count( in_uLeafOpcode, in_uSubLeafOpcode,
247  &out_uCPUFeatures[0],
248  &out_uCPUFeatures[1],
249  &out_uCPUFeatures[2],
250  &out_uCPUFeatures[3]);
251  }
252 #endif
253 }
AKRESULT AkCreateSemaphore(AkSemaphore &out_semaphore, AkUInt32 in_initialCount)
Platform Independent Helper.
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
@ AK_Fail
The operation failed.
Definition: AkTypes.h:134
semaphore_t AkEvent
Definition: AkTypes.h:84
void AkClearEvent(AkEvent &out_event)
Platform Independent Helper.
AkForceInline void AkClearSemaphore(AkSemaphore &io_semaphore)
Platform Independent Helper.
Platform-dependent helpers.
Definition: AkBitFuncs.h:43
void AkWaitForEvent(AkEvent &in_event)
Platform Independent Helper.
AKRESULT
Standard function call result.
Definition: AkTypes.h:131
void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
#define NULL
Definition: AkTypes.h:46
@ AK_Success
The operation was successful.
Definition: AkTypes.h:133
AkUInt16 AkUtf16
Definition: AkTypes.h:61
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
size_t AkMacConvertString(destType *in_pdDest, const srcType *in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *))
void AkDestroySemaphore(AkSemaphore &io_semaphore)
Platform Independent Helper.
void AkDestroyEvent(AkEvent &io_event)
Platform Independent Helper.
#define AKASSERT(Condition)
Definition: AkAssert.h:67
#define AKVERIFY(x)
Definition: AkAssert.h:69
#define AK_SEC_TO_NANOSEC
AKRESULT AkCreateEvent(AkEvent &out_event)
Platform Independent Helper.
int64_t AkInt64
Signed 64-bit integer.
void AkWaitForSemaphore(AkSemaphore &in_semaphore)
Platform Independent Helper - Semaphore wait, aka Operation P. Decrements value of semaphore,...
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
uint32_t AkUInt32
Unsigned 32-bit integer.
void AkReleaseSemaphore(AkSemaphore &in_semaphore, AkUInt32 in_count)
Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an ...
void AkSignalEvent(const AkEvent &in_event)
Platform Independent Helper.
semaphore_t AkSemaphore
Definition: AkTypes.h:85
#define AkForceInline
Definition: AkTypes.h:63

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