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

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