Version

menu_open
Wwise SDK 2024.1.4
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) 2025 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #pragma once
28 
31 
32 #include <mach/task.h>
33 #include <mach/semaphore.h>
34 #include <CoreFoundation/CFString.h>
35 #include <libkern/OSAtomic.h>
36 #include <mach/task.h>
37 #include <mach/mach_init.h>
38 #include <time.h>
39 #include <wchar.h>
40 
41 #define AK_SEC_TO_NANOSEC 1000000000ULL
42 
43 namespace AKPLATFORM
44 {
45  extern inline size_t AkUtf16StrLen( const AkUtf16* in_pStr );
46  // Simple automatic event API
47  // ------------------------------------------------------------------
48 
49  /// Platform Independent Helper
50  inline void AkClearEvent( AkEvent & out_event )
51  {
52  out_event = 0;
53  }
54 
55  /// Platform Independent Helper
56  inline AKRESULT AkCreateEvent( AkEvent & out_event )
57  {
58  kern_return_t ret = semaphore_create(
59  mach_task_self(),
60  &out_event,
61  SYNC_POLICY_FIFO,
62  0 );
63 
64  return ( ret == noErr ) ? AK_Success : AK_Fail;
65  }
66 
67  /// Platform Independent Helper
68  inline void AkDestroyEvent( AkEvent & io_event )
69  {
70  if( io_event != 0 )
71  {
72  AKVERIFY( semaphore_destroy( mach_task_self(), io_event ) == noErr);
73  }
74  io_event = 0;
75  }
76 
77  /// Platform Independent Helper
78  inline void AkWaitForEvent( AkEvent & in_event )
79  {
80  AKVERIFY( semaphore_wait( in_event ) == noErr );
81  }
82 
83 
84  /// Platform Independent Helper
85  inline void AkSignalEvent( const AkEvent & in_event )
86  {
87  AKVERIFY( semaphore_signal( in_event ) == noErr );
88  }
89 
90 
91  /// Platform Independent Helper
93  {
94  io_semaphore = 0;
95  }
96 
97  /// Platform Independent Helper
98  inline AKRESULT AkCreateSemaphore( AkSemaphore& out_semaphore, AkUInt32 in_initialCount )
99  {
100  kern_return_t ret = semaphore_create(
101  mach_task_self(),
102  &out_semaphore,
103  SYNC_POLICY_FIFO,
104  in_initialCount );
105 
106  return ( ret == noErr ) ? AK_Success : AK_Fail;
107  }
108 
109  /// Platform Independent Helper
110  inline void AkDestroySemaphore( AkSemaphore& io_semaphore )
111  {
112  AKVERIFY(semaphore_destroy(mach_task_self(), io_semaphore) == noErr);
113  }
114 
115  /// 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.
116  inline void AkWaitForSemaphore(AkSemaphore& in_semaphore)
117  {
118  AKVERIFY(semaphore_wait(in_semaphore) == noErr);
119  }
120 
121  /// Platform Independent Helper - Semaphore signal, aka Operation V. Increments value of semaphore by an arbitrary count.
122  inline void AkReleaseSemaphore(AkSemaphore& in_semaphore, AkUInt32 in_count)
123  {
124  for (int i=0; i < in_count; i++)
125  {
126  AKVERIFY(semaphore_signal(in_semaphore) == noErr);
127  }
128  }
129 
130  // Time functions
131  // ------------------------------------------------------------------
132 
133  /// Platform Independent Helper
134  inline void PerformanceCounter( AkInt64 * out_piLastTime )
135  {
136  struct timespec clockNow;
137  clock_gettime(CLOCK_MONOTONIC, &clockNow);
138  //This give the wallclock time in NS
139  *out_piLastTime = clockNow.tv_sec*AK_SEC_TO_NANOSEC + clockNow.tv_nsec;
140  }
141 
142  /// Platform Independent Helper
143  inline void PerformanceFrequency( AkInt64 * out_piFreq )
144  {
145  //Since Wall Clock is used, 1 NS is the frequency independent of the clock resolution
146  *out_piFreq = AK_SEC_TO_NANOSEC;
147  }
148 
149 
150  template<class destType, class srcType>
151  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 *) )
152  {
153  CFStringBuiltInEncodings dstEncoding;
154  CFStringBuiltInEncodings srcEncoding;
155  switch(sizeof(destType))
156  {
157  case 1:
158  dstEncoding = kCFStringEncodingUTF8;
159  break;
160  case 2:
161  dstEncoding = kCFStringEncodingUTF16LE;
162  break;
163  case 4:
164  dstEncoding = kCFStringEncodingUTF32LE;
165  break;
166  default:
167  AKASSERT(!"Invalid Char size");
168  }
169 
170  switch(sizeof(srcType))
171  {
172  case 1:
173  srcEncoding = kCFStringEncodingUTF8;
174  break;
175  case 2:
176  srcEncoding = kCFStringEncodingUTF16LE;
177  break;
178  case 4:
179  srcEncoding = kCFStringEncodingUTF32LE;
180  break;
181  default:
182  AKASSERT(!"Invalid Char size");
183  }
184 
185  CFStringRef strRef;
186  strRef = CFStringCreateWithBytes( nil,
187  (UInt8 *) in_pSrc,
188  (srcStrLen( in_pSrc ) + 1) * sizeof(srcType),
189  srcEncoding,
190  false );
191  CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(strRef));
192  CFIndex sizeConverted = CFStringGetBytes(strRef, rangeToProcess, dstEncoding, '?', false, (UInt8 *)in_pdDest , in_MaxSize * sizeof(destType), NULL);
193 
194  //WG-28497 Memory leak when converting strings on Mac & iOS
195  CFRelease(strRef);
196 
197  return sizeConverted;
198  }
199 
200  #define CONVERT_UTF16_TO_WCHAR( _astring_, _wcharstring_ ) \
201  _wcharstring_ = (wchar_t*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(wchar_t) ); \
202  AK_UTF16_TO_WCHAR( _wcharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
203 
204  #define CONVERT_WCHAR_TO_UTF16( _astring_, _utf16string_ ) \
205  _utf16string_ = (AkUtf16*)AkAlloca( (1 + wcslen(_astring_)) * sizeof(AkUtf16) ); \
206  AK_WCHAR_TO_UTF16( _utf16string_, (const wchar_t*)_astring_, wcslen(_astring_)+1 )
207 
208  #define CONVERT_OSCHAR_TO_UTF16( _astring_, _utf16string_ ) \
209  _utf16string_ = (AkUtf16*)AkAlloca( (1 + strlen(_astring_)) * sizeof(AkUtf16) ); \
210  AK_OSCHAR_TO_UTF16( _utf16string_, (const AkOSChar*)_astring_, strlen(_astring_)+1 )
211 
212  #define CONVERT_UTF16_TO_OSCHAR( _astring_, _oscharstring_ ) \
213  _oscharstring_ = (AkOSChar*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(AkOSChar) ); \
214  AK_UTF16_TO_OSCHAR( _oscharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
215 
216  #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkOSChar, char>( in_pdDest, in_pSrc, in_MaxSize, strlen, strlen )
217  #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)
218  #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 )
219  #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkOSChar, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
220  #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<char, AkUtf16>( in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
221  #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, char>( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
222  #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkMacConvertString<AkUtf16, AkOSChar>( in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)
223 
224  /// Stack allocations.
225  #define AkAlloca( _size_ ) alloca( _size_ )
226 
227 #if __BIGGEST_ALIGNMENT__ < AK_SIMD_ALIGNMENT
228  #define AkAllocaSIMD( _size_ ) __builtin_alloca_with_align( _size_, AK_SIMD_ALIGNMENT*8 )
229 #endif
230 
231  #define AK_LIBRARY_PREFIX ("")
232  #define AK_DYNAMIC_LIBRARY_EXTENSION (".dylib")
233 
234  #define AK_FILEHANDLE_TO_UINTPTR(_h) ((AkUIntPtr)_h)
235  #define AK_SET_FILEHANDLE_TO_UINTPTR(_h,_u) _h = (AkFileHandle)_u
236 
237 }
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:137
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.
void AkWaitForEvent(AkEvent &in_event)
Platform Independent Helper.
AKRESULT
Standard function call result.
Definition: AkTypes.h:134
#define NULL
Definition: AkTypes.h:46
@ AK_Success
The operation was successful.
Definition: AkTypes.h:136
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