Wwise Version
Wwise SDK 2021.1.2
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.2 Build: 7629
25  Copyright (c) 2006-2021 Audiokinetic Inc.
26 *******************************************************************************/
27 
28 #pragma once
29 
32 
33 #if (defined(AK_CPU_X86_64) || defined(AK_CPU_X86))
34 #include <cpuid.h>
35 #endif
36 #include <mach/task.h>
37 #include <mach/semaphore.h>
38 #include <CoreFoundation/CFString.h>
39 #include <libkern/OSAtomic.h>
40 #include <mach/task.h>
41 #include <mach/mach_init.h>
42 #include <mach/mach_time.h>
43 #include <wchar.h>
44 
45 namespace AKPLATFORM
46 {
47  extern inline size_t AkUtf16StrLen( const AkUtf16* in_pStr );
48  // Simple automatic event API
49  // ------------------------------------------------------------------
50 
51  /// Platform Independent Helper
52  inline void AkClearEvent( AkEvent & out_event )
53  {
54  out_event = 0;
55  }
56 
57  /// Platform Independent Helper
58  inline AKRESULT AkCreateEvent( AkEvent & out_event )
59  {
60  kern_return_t ret = semaphore_create(
61  mach_task_self(),
62  &out_event,
63  SYNC_POLICY_FIFO,
64  0 );
65 
66  return ( ret == noErr ) ? AK_Success : AK_Fail;
67  }
68 
69  /// Platform Independent Helper
70  inline void AkDestroyEvent( AkEvent & io_event )
71  {
72  if( io_event != 0 )
73  {
74  AKVERIFY( semaphore_destroy( mach_task_self(), io_event ) == noErr);
75  }
76  io_event = 0;
77  }
78 
79  /// Platform Independent Helper
80  inline void AkWaitForEvent( AkEvent & in_event )
81  {
82  AKVERIFY( semaphore_wait( in_event ) == noErr );
83  }
84 
85 
86  /// Platform Independent Helper
87  inline void AkSignalEvent( const AkEvent & in_event )
88  {
89  AKVERIFY( semaphore_signal( in_event ) == noErr );
90  }
91 
92  /// Platform Independent Helper
93  inline AKRESULT AkCreateSemaphore( AkSemaphore* out_semaphore, AkUInt32 in_initialCount )
94  {
95  kern_return_t ret = semaphore_create(
96  mach_task_self(),
97  out_semaphore,
98  SYNC_POLICY_FIFO,
99  in_initialCount );
100 
101  return ( ret == noErr ) ? AK_Success : AK_Fail;
102  }
103 
104  /// Platform Independent Helper
105  inline void AkDestroySemaphore( AkSemaphore* io_semaphore )
106  {
107  if( io_semaphore != 0 )
108  {
109  AKVERIFY( semaphore_destroy( mach_task_self(), *io_semaphore ) == noErr);
110  }
111  io_semaphore = 0;
112  }
113 
114  /// 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.
115  inline void AkWaitForSemaphore( AkSemaphore* in_semaphore )
116  {
117  AKVERIFY( semaphore_wait( *in_semaphore ) == noErr );
118  }
119 
120  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore.
121  inline void AkReleaseSemaphore( AkSemaphore* in_semaphore )
122  {
123  AKVERIFY( semaphore_signal( *in_semaphore ) == noErr );
124  }
125 
126  // Time functions
127  // ------------------------------------------------------------------
128 
129  /// Platform Independent Helper
130  inline void PerformanceCounter( AkInt64 * out_piLastTime )
131  {
132  *out_piLastTime = mach_absolute_time();
133  }
134 
135  /// Platform Independent Helper
136  inline void PerformanceFrequency( AkInt64 * out_piFreq )
137  {
138  static mach_timebase_info_data_t sTimebaseInfo;
139  mach_timebase_info(&sTimebaseInfo);
140  if ( sTimebaseInfo.numer !=0 )
141  {
142  *out_piFreq = AkInt64((1E9 * sTimebaseInfo.denom) / sTimebaseInfo.numer );
143  }
144  else
145  {
146  *out_piFreq = 0;
147  }
148  }
149 
150 
151  template<class destType, class srcType>
152  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 *) )
153  {
154  CFStringBuiltInEncodings dstEncoding;
155  CFStringBuiltInEncodings srcEncoding;
156  switch(sizeof(destType))
157  {
158  case 1:
159  dstEncoding = kCFStringEncodingUTF8;
160  break;
161  case 2:
162  dstEncoding = kCFStringEncodingUTF16LE;
163  break;
164  case 4:
165  dstEncoding = kCFStringEncodingUTF32LE;
166  break;
167  default:
168  AKASSERT(!"Invalid Char size");
169  }
170 
171  switch(sizeof(srcType))
172  {
173  case 1:
174  srcEncoding = kCFStringEncodingUTF8;
175  break;
176  case 2:
177  srcEncoding = kCFStringEncodingUTF16LE;
178  break;
179  case 4:
180  srcEncoding = kCFStringEncodingUTF32LE;
181  break;
182  default:
183  AKASSERT(!"Invalid Char size");
184  }
185 
186  CFStringRef strRef;
187  strRef = CFStringCreateWithBytes( nil,
188  (UInt8 *) in_pSrc,
189  (srcStrLen( in_pSrc ) + 1) * sizeof(srcType),
190  srcEncoding,
191  false );
192  CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(strRef));
193  CFIndex sizeConverted = CFStringGetBytes(strRef, rangeToProcess, dstEncoding, '?', false, (UInt8 *)in_pdDest , in_MaxSize * sizeof(destType), NULL);
194 
195  //WG-28497 Memory leak when converting strings on Mac & iOS
196  CFRelease(strRef);
197 
198  return sizeConverted;
199  }
200 
201  #define CONVERT_UTF16_TO_WCHAR( _astring_, _wcharstring_ ) \
202  _wcharstring_ = (wchar_t*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(wchar_t) ); \
203  AK_UTF16_TO_WCHAR( _wcharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
204 
205  #define CONVERT_WCHAR_TO_UTF16( _astring_, _utf16string_ ) \
206  _utf16string_ = (AkUtf16*)AkAlloca( (1 + wcslen(_astring_)) * sizeof(AkUtf16) ); \
207  AK_WCHAR_TO_UTF16( _utf16string_, (const wchar_t*)_astring_, wcslen(_astring_)+1 )
208 
209  #define CONVERT_OSCHAR_TO_UTF16( _astring_, _utf16string_ ) \
210  _utf16string_ = (AkUtf16*)AkAlloca( (1 + strlen(_astring_)) * sizeof(AkUtf16) ); \
211  AK_OSCHAR_TO_UTF16( _utf16string_, (const AkOSChar*)_astring_, strlen(_astring_)+1 )
212 
213  #define CONVERT_UTF16_TO_OSCHAR( _astring_, _oscharstring_ ) \
214  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(AkOSChar) ); \
215  AK_UTF16_TO_OSCHAR( _oscharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
216 
217  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkOSChar, char>( in_pdDest, in_pSrc, in_MaxSize, strlen, strlen )
218  #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)
219  #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 )
220  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkOSChar, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
221  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<char, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
222  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, char>( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
223  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, AkOSChar>( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
224 
225  /// Stack allocations.
226  #define AkAlloca( _size_ ) alloca( _size_ )
227 
228 #if __BIGGEST_ALIGNMENT__ < AK_SIMD_ALIGNMENT
229  #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, AK_SIMD_ALIGNMENT*8 )
230 #endif
231 
232  #define AK_LIBRARY_PREFIX ("")
233  #define AK_DYNAMIC_LIBRARY_EXTENSION (".dylib")
234 
235 #if (defined(AK_CPU_X86_64) || defined(AK_CPU_X86))
236  /// Support to fetch the CPUID for the platform. Only valid for X86 targets
237  /// \remark Note that IAkProcessorFeatures should be preferred to fetch this data
238  /// as it will have already translated the feature bits into AK-relevant enums
239  inline void CPUID(AkUInt32 in_uLeafOpcode, AkUInt32 in_uSubLeafOpcode, unsigned int out_uCPUFeatures[4])
240  {
241  __get_cpuid_count( in_uLeafOpcode, in_uSubLeafOpcode,
242  &out_uCPUFeatures[0],
243  &out_uCPUFeatures[1],
244  &out_uCPUFeatures[2],
245  &out_uCPUFeatures[3]);
246  }
247 #endif
248 }
size_t AkUtf16StrLen(const AkUtf16 *in_pStr)
Definition: AkPlatformFuncs.h:558
@ AK_Fail
The operation failed.
Definition: AkTypes.h:130
semaphore_t AkEvent
Definition: AkTypes.h:73
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
wchar_t AkUtf16
Definition: AkTypes.h:109
AKRESULT
Standard function call result.
Definition: AkTypes.h:127
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 NULL
Definition: AkTypes.h:47
@ AK_Success
The operation was successful.
Definition: AkTypes.h:129
void PerformanceCounter(AkInt64 *out_piLastTime)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:143
size_t AkMacConvertString(destType *in_pdDest, const srcType *in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *), size_t srcStrLen(const srcType *))
Definition: AkPlatformFuncs.h:152
void AkDestroyEvent(AkEvent &io_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:70
int64_t AkInt64
Signed 64-bit integer.
Definition: AkTypes.h:91
#define AKASSERT(Condition)
Definition: AkAssert.h:76
#define AKVERIFY(x)
Definition: AkAssert.h:78
AKRESULT AkCreateEvent(AkEvent &out_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:58
void PerformanceFrequency(AkInt64 *out_piFreq)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:46
AKRESULT AkCreateSemaphore(AkSemaphore *out_semaphore, AkUInt32 in_initialCount)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:93
void AkWaitForSemaphore(AkSemaphore *in_semaphore)
Platform Independent Helper - Semaphore wait, aka Operation P. Decrements value of semaphore,...
Definition: AkPlatformFuncs.h:115
void AkSignalEvent(const AkEvent &in_event)
Platform Independent Helper.
Definition: AkPlatformFuncs.h:87
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:77
semaphore_t AkSemaphore
Definition: AkTypes.h:74
void AkReleaseSemaphore(AkSemaphore *in_semaphore)
Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore.
Definition: AkPlatformFuncs.h:121