Version
menu_open
link

include/AK/Tools/Mac/AkPlatformFuncs.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
00003 released in source code form as part of the SDK installer package.
00004 
00005 Commercial License Usage
00006 
00007 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
00008 may use this file in accordance with the end user license agreement provided 
00009 with the software or, alternatively, in accordance with the terms contained in a
00010 written agreement between you and Audiokinetic Inc.
00011 
00012 Apache License Usage
00013 
00014 Alternatively, this file may be used under the Apache License, Version 2.0 (the 
00015 "Apache License"); you may not use this file except in compliance with the 
00016 Apache License. You may obtain a copy of the Apache License at 
00017 http://www.apache.org/licenses/LICENSE-2.0.
00018 
00019 Unless required by applicable law or agreed to in writing, software distributed
00020 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
00021 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
00022 the specific language governing permissions and limitations under the License.
00023 
00024   Version: <VERSION>  Build: <BUILDNUMBER>
00025   Copyright (c) <COPYRIGHTYEAR> Audiokinetic Inc.
00026 *******************************************************************************/
00027 
00028 #pragma once
00029 
00030 #include <AK/Tools/Common/AkAssert.h>
00031 #include <AK/SoundEngine/Common/AkTypes.h>
00032 
00033 #include <mach/task.h>
00034 #include <mach/semaphore.h>
00035 #include <CoreFoundation/CFString.h>
00036 #include <libkern/OSAtomic.h>
00037 #include <mach/task.h>
00038 #include <mach/mach_init.h>
00039 #include <mach/mach_time.h>
00040 #include <wchar.h>
00041 
00042 namespace AKPLATFORM
00043 {
00044     extern inline size_t AkUtf16StrLen( const AkUtf16* in_pStr );
00045     // Simple automatic event API
00046     // ------------------------------------------------------------------
00047     
00049     inline void AkClearEvent( AkEvent & out_event )
00050     {
00051         out_event = 0;
00052     }
00053     
00055     inline AKRESULT AkCreateEvent( AkEvent & out_event )
00056     {
00057         kern_return_t ret = semaphore_create(   
00058                             mach_task_self(),
00059                             &out_event,
00060                             SYNC_POLICY_FIFO,
00061                             0 );
00062         
00063         return ( ret == noErr  ) ? AK_Success : AK_Fail;
00064     }
00065 
00066     inline AKRESULT AkCreateSemaphore( AkSemaphore & out_semaphore, AkUInt32 in_initialCount )
00067     {
00068         kern_return_t ret = semaphore_create(   
00069                             mach_task_self(),
00070                             &out_semaphore,
00071                             SYNC_POLICY_FIFO,
00072                             in_initialCount );
00073         
00074         return ( ret == noErr  ) ? AK_Success : AK_Fail;    
00075     }
00076     
00078     inline void AkDestroyEvent( AkEvent & io_event )
00079     {
00080         if( io_event != 0 )
00081         {
00082             AKVERIFY( semaphore_destroy( mach_task_self(), io_event ) == noErr);
00083         }
00084         io_event = 0;
00085     }
00086 
00088     inline void AkDestroySemaphore( AkSemaphore & io_semaphore )
00089     {
00090         if( io_semaphore != 0 )
00091         {
00092             AKVERIFY( semaphore_destroy( mach_task_self(), io_semaphore ) == noErr);
00093         }
00094         io_semaphore = 0;
00095     }   
00096     
00098     inline void AkWaitForEvent( AkEvent & in_event )
00099     {
00100         AKVERIFY( semaphore_wait( in_event ) == noErr );
00101     }
00102     
00103     inline void AkWaitForSemaphore( AkSemaphore & in_semaphore )
00104     {
00105         AKVERIFY( semaphore_wait( in_semaphore ) == noErr );
00106     }
00107 
00109     inline void AkSignalEvent( const AkEvent & in_event )
00110     {
00111         AKVERIFY( semaphore_signal( in_event ) == noErr );
00112     }
00113     
00114     inline void AkReleaseSemaphore( const AkSemaphore & in_event )
00115     {
00116         AKVERIFY( semaphore_signal( in_event ) == noErr );
00117     }
00118     
00119     // Atomic Operations
00120     // ------------------------------------------------------------------
00121 
00123     inline AkInt32 AkInterlockedIncrement( AkAtomic32 * pValue )
00124     {
00125 #ifdef AK_USE_STD_ATOMIC
00126         return __c11_atomic_fetch_add( pValue,1,__ATOMIC_SEQ_CST );
00127 #else
00128         return OSAtomicIncrement32( pValue );
00129 #endif
00130     }
00131 
00133     inline AkInt32 AkInterlockedDecrement( AkAtomic32 * pValue )
00134     {
00135 #ifdef AK_USE_STD_ATOMIC
00136         return __c11_atomic_fetch_sub( pValue,1,__ATOMIC_SEQ_CST );
00137 #else
00138         return OSAtomicDecrement32( pValue );
00139 #endif
00140     }
00141 
00142     inline bool AkInterlockedCompareExchange( volatile AkAtomic32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal )
00143     {
00144 #ifdef AK_USE_STD_ATOMIC
00145         return __c11_atomic_compare_exchange_strong( io_pDest, &in_expectedOldVal, in_newValue, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
00146 #else
00147         return OSAtomicCompareAndSwapInt(in_expectedOldVal, in_newValue, io_pDest);
00148 #endif
00149     }
00150 
00151     inline bool AkInterlockedCompareExchange( volatile AkAtomic64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal )
00152     {
00153 #ifdef AK_USE_STD_ATOMIC
00154         return __c11_atomic_compare_exchange_strong( io_pDest, &in_expectedOldVal, in_newValue, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
00155 #else
00156         return OSAtomicCompareAndSwap64(in_expectedOldVal, in_newValue, io_pDest);
00157 #endif
00158     }
00159 
00160     inline bool AkInterlockedCompareExchange( volatile AkAtomicPtr* io_pDest, AkIntPtr in_newValue, AkIntPtr in_expectedOldVal )
00161     {
00162 #ifdef AK_USE_STD_ATOMIC
00163     #ifndef AK_IOS
00164         if (sizeof(io_pDest) == 8)
00165             return AkInterlockedCompareExchange( (volatile AkAtomic64*)io_pDest, (AkInt64)in_newValue, (AkInt64)in_expectedOldVal );
00166     #endif // #ifndef AK_IOS
00167         return AkInterlockedCompareExchange( (volatile AkAtomic32*)io_pDest, (AkInt32)in_newValue, (AkInt32)in_expectedOldVal );
00168 #else
00169     #ifndef AK_IOS
00170         if (sizeof(io_pDest) == 8)
00171             return OSAtomicCompareAndSwap64(( AkInt64)in_expectedOldVal, (AkInt64)in_newValue, (volatile AkInt64*)io_pDest);
00172     #endif // #ifndef AK_IOS
00173         return OSAtomicCompareAndSwapInt((AkInt32)in_expectedOldVal, (AkInt32)in_newValue, (AkInt32*)io_pDest);
00174 #endif
00175     }
00176 
00177     inline void AkMemoryBarrier()
00178     {
00179 #ifdef AK_USE_STD_ATOMIC
00180         atomic_thread_fence( __ATOMIC_SEQ_CST );
00181 #else
00182         OSMemoryBarrier();
00183 #endif
00184     }
00185     
00186     // Time functions
00187     // ------------------------------------------------------------------
00188 
00190     inline void PerformanceCounter( AkInt64 * out_piLastTime )
00191     {
00192         *out_piLastTime = mach_absolute_time();
00193     }
00194 
00196     inline void PerformanceFrequency( AkInt64 * out_piFreq )
00197     {
00198         static mach_timebase_info_data_t    sTimebaseInfo;
00199         mach_timebase_info(&sTimebaseInfo);
00200         if ( sTimebaseInfo.numer !=0 )
00201         {
00202             *out_piFreq = AkInt64((1E9 * sTimebaseInfo.denom) / sTimebaseInfo.numer );
00203         }
00204         else
00205         {
00206             *out_piFreq = 0;
00207         }
00208     }
00209 
00210 
00211     template<class destType, class srcType>
00212     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 *) )
00213     { 
00214         CFStringBuiltInEncodings dstEncoding;       
00215         CFStringBuiltInEncodings srcEncoding;
00216         switch(sizeof(destType))
00217         {
00218             case 1:
00219                 dstEncoding = kCFStringEncodingUTF8;
00220                 break;
00221             case 2:
00222                 dstEncoding = kCFStringEncodingUTF16LE;
00223                 break;
00224             case 4:
00225                 dstEncoding = kCFStringEncodingUTF32LE;
00226                 break;
00227             default:
00228                 AKASSERT(!"Invalid Char size");
00229         }
00230         
00231         switch(sizeof(srcType))
00232         {
00233             case 1:
00234                 srcEncoding = kCFStringEncodingUTF8;
00235                 break;
00236             case 2:
00237                 srcEncoding = kCFStringEncodingUTF16LE;
00238                 break;
00239             case 4:
00240                 srcEncoding = kCFStringEncodingUTF32LE;
00241                 break;
00242             default:
00243                 AKASSERT(!"Invalid Char size");
00244         }
00245         
00246         CFStringRef strRef;
00247         strRef = CFStringCreateWithBytes(   nil, 
00248                                          (UInt8 *) in_pSrc,
00249                                          (srcStrLen( in_pSrc ) + 1) * sizeof(srcType),
00250                                          srcEncoding,
00251                                          false );
00252         CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(strRef));
00253         CFIndex sizeConverted = CFStringGetBytes(strRef, rangeToProcess, dstEncoding, '?', false, (UInt8 *)in_pdDest , in_MaxSize * sizeof(destType), NULL);
00254         
00255         //WG-28497 Memory leak when converting strings on Mac & iOS
00256         CFRelease(strRef);
00257         
00258         return sizeConverted;
00259     }
00260 
00261     #define CONVERT_UTF16_TO_WCHAR( _astring_, _wcharstring_ ) \
00262         _wcharstring_ = (wchar_t*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(wchar_t) ); \
00263         AK_UTF16_TO_WCHAR(  _wcharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
00264     
00265     #define CONVERT_WCHAR_TO_UTF16( _astring_, _utf16string_ ) \
00266         _utf16string_ = (AkUtf16*)AkAlloca( (1 + wcslen(_astring_)) * sizeof(AkUtf16) ); \
00267         AK_WCHAR_TO_UTF16(  _utf16string_, (const wchar_t*)_astring_, wcslen(_astring_)+1 )
00268 
00269     #define CONVERT_OSCHAR_TO_UTF16( _astring_, _utf16string_ ) \
00270         _utf16string_ = (AkUtf16*)AkAlloca( (1 + strlen(_astring_)) * sizeof(AkUtf16) ); \
00271         AK_OSCHAR_TO_UTF16( _utf16string_, (const AkOSChar*)_astring_, strlen(_astring_)+1 )
00272 
00273     #define CONVERT_UTF16_TO_OSCHAR( _astring_, _oscharstring_ ) \
00274         _oscharstring_ = (AkOSChar*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(AkOSChar) ); \
00275         AK_UTF16_TO_OSCHAR( _oscharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 ) 
00276 
00277     #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)
00278     #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 )
00279     #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkOSChar, AkUtf16>(  in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00280     #define AK_UTF16_TO_CHAR(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<char, AkUtf16>(  in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00281     #define AK_CHAR_TO_UTF16(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, char>(  in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)  
00282     #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, AkOSChar>(  in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)  
00283     
00285     #define AkAlloca( _size_ ) alloca( _size_ )
00286 }

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