Version
menu_open
link

include/AK/Tools/Mac/AkPlatformFuncs.h

Go to the documentation of this file.
00001 
00002 //
00003 // AkPlatformFuncs.h 
00004 //
00005 // Audiokinetic platform-dependent functions definition.
00006 //
00007 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
00008 //
00010 
00011 #pragma once
00012 
00013 #include <AK/Tools/Common/AkAssert.h>
00014 #include <AK/SoundEngine/Common/AkTypes.h>
00015 
00016 #include <mach/task.h>
00017 #include <mach/semaphore.h>
00018 #include <CoreFoundation/CFString.h>
00019 #include <libkern/OSAtomic.h>
00020 #include <mach/task.h>
00021 #include <mach/mach_init.h>
00022 #include <mach/mach_time.h>
00023 #include <wchar.h>
00024 
00025 namespace AKPLATFORM
00026 {
00027     extern inline size_t AkUtf16StrLen( const AkUtf16* in_pStr );
00028     // Simple automatic event API
00029     // ------------------------------------------------------------------
00030     
00032     inline void AkClearEvent( AkEvent & out_event )
00033     {
00034         out_event = 0;
00035     }
00036     
00038     inline AKRESULT AkCreateEvent( AkEvent & out_event )
00039     {
00040         kern_return_t ret = semaphore_create(   
00041                             mach_task_self(),
00042                             &out_event,
00043                             SYNC_POLICY_FIFO,
00044                             0 );
00045         
00046         return ( ret == noErr  ) ? AK_Success : AK_Fail;
00047     }
00048 
00049     inline AKRESULT AkCreateSemaphore( AkSemaphore & out_semaphore, AkUInt32 in_initialCount )
00050     {
00051         kern_return_t ret = semaphore_create(   
00052                             mach_task_self(),
00053                             &out_semaphore,
00054                             SYNC_POLICY_FIFO,
00055                             in_initialCount );
00056         
00057         return ( ret == noErr  ) ? AK_Success : AK_Fail;    
00058     }
00059     
00061     inline void AkDestroyEvent( AkEvent & io_event )
00062     {
00063         if( io_event != 0 )
00064         {
00065             AKVERIFY( semaphore_destroy( mach_task_self(), io_event ) == noErr);
00066         }
00067         io_event = 0;
00068     }
00069 
00071     inline void AkDestroySemaphore( AkSemaphore & io_semaphore )
00072     {
00073         if( io_semaphore != 0 )
00074         {
00075             AKVERIFY( semaphore_destroy( mach_task_self(), io_semaphore ) == noErr);
00076         }
00077         io_semaphore = 0;
00078     }   
00079     
00081     inline void AkWaitForEvent( AkEvent & in_event )
00082     {
00083         AKVERIFY( semaphore_wait( in_event ) == noErr );
00084     }
00085     
00086     inline void AkWaitForSemaphore( AkSemaphore & in_semaphore )
00087     {
00088         AKVERIFY( semaphore_wait( in_semaphore ) == noErr );
00089     }
00090 
00092     inline void AkSignalEvent( const AkEvent & in_event )
00093     {
00094         AKVERIFY( semaphore_signal( in_event ) == noErr );
00095     }
00096     
00097     inline void AkReleaseSemaphore( const AkSemaphore & in_event )
00098     {
00099         AKVERIFY( semaphore_signal( in_event ) == noErr );
00100     }
00101     
00102     // Atomic Operations
00103     // ------------------------------------------------------------------
00104 
00106     inline AkInt32 AkInterlockedIncrement( AkInt32 * pValue )
00107     {
00108         return OSAtomicIncrement32( pValue );
00109     }
00110 
00112     inline AkInt32 AkInterlockedDecrement( AkInt32 * pValue )
00113     {
00114         return OSAtomicDecrement32( pValue );
00115     }
00116 
00117     inline bool AkInterlockedCompareExchange( volatile AkInt32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal )
00118     {
00119         return OSAtomicCompareAndSwapInt(in_expectedOldVal, in_newValue, io_pDest);
00120     }
00121 
00122     inline bool AkInterlockedCompareExchange( volatile AkInt64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal )
00123     {
00124         return OSAtomicCompareAndSwap64(in_expectedOldVal, in_newValue, io_pDest);
00125     }
00126 
00127     inline bool AkInterlockedCompareExchange( volatile AkIntPtr* io_pDest, AkIntPtr in_newValue, AkIntPtr in_expectedOldVal )
00128     {
00129 #ifndef AK_IOS
00130         if (sizeof(io_pDest) == 8)
00131             return OSAtomicCompareAndSwap64(( AkInt64)in_expectedOldVal, (AkInt64)in_newValue, (volatile AkInt64*)io_pDest);
00132 #endif // #ifndef AK_IOS
00133         return OSAtomicCompareAndSwapInt((AkInt32)in_expectedOldVal, (AkInt32)in_newValue, (AkInt32*)io_pDest);
00134     }
00135 
00136     inline void AkMemoryBarrier()
00137     {
00138         OSMemoryBarrier();
00139     }
00140     
00141     // Time functions
00142     // ------------------------------------------------------------------
00143 
00145     inline void PerformanceCounter( AkInt64 * out_piLastTime )
00146     {
00147         *out_piLastTime = mach_absolute_time();
00148     }
00149 
00151     inline void PerformanceFrequency( AkInt64 * out_piFreq )
00152     {
00153         static mach_timebase_info_data_t    sTimebaseInfo;
00154         mach_timebase_info(&sTimebaseInfo);
00155         if ( sTimebaseInfo.numer !=0 )
00156         {
00157             *out_piFreq = AkInt64((1E9 * sTimebaseInfo.denom) / sTimebaseInfo.numer );
00158         }
00159         else
00160         {
00161             *out_piFreq = 0;
00162         }
00163     }
00164 
00165 
00166     template<class destType, class srcType>
00167     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 *) )
00168     { 
00169         CFStringBuiltInEncodings dstEncoding;       
00170         CFStringBuiltInEncodings srcEncoding;
00171         switch(sizeof(destType))
00172         {
00173             case 1:
00174                 dstEncoding = kCFStringEncodingUTF8;
00175                 break;
00176             case 2:
00177                 dstEncoding = kCFStringEncodingUTF16LE;
00178                 break;
00179             case 4:
00180                 dstEncoding = kCFStringEncodingUTF32LE;
00181                 break;
00182             default:
00183                 AKASSERT(!"Invalid Char size");
00184         }
00185         
00186         switch(sizeof(srcType))
00187         {
00188             case 1:
00189                 srcEncoding = kCFStringEncodingUTF8;
00190                 break;
00191             case 2:
00192                 srcEncoding = kCFStringEncodingUTF16LE;
00193                 break;
00194             case 4:
00195                 srcEncoding = kCFStringEncodingUTF32LE;
00196                 break;
00197             default:
00198                 AKASSERT(!"Invalid Char size");
00199         }
00200         
00201         CFStringRef strRef;
00202         strRef = CFStringCreateWithBytes(   nil, 
00203                                          (UInt8 *) in_pSrc,
00204                                          (srcStrLen( in_pSrc ) + 1) * sizeof(srcType),
00205                                          srcEncoding,
00206                                          false );
00207         CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(strRef));
00208         CFIndex sizeConverted = CFStringGetBytes(strRef, rangeToProcess, dstEncoding, '?', false, (UInt8 *)in_pdDest , in_MaxSize * sizeof(destType), NULL);
00209         
00210         //WG-28497 Memory leak when converting strings on Mac & iOS
00211         CFRelease(strRef);
00212         
00213         return sizeConverted;
00214     }
00215 
00216     #define CONVERT_UTF16_TO_WCHAR( _astring_, _wcharstring_ ) \
00217         _wcharstring_ = (wchar_t*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(wchar_t) ); \
00218         AK_UTF16_TO_WCHAR(  _wcharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
00219     
00220     #define CONVERT_WCHAR_TO_UTF16( _astring_, _utf16string_ ) \
00221         _utf16string_ = (AkUtf16*)AkAlloca( (1 + wcslen(_astring_)) * sizeof(AkUtf16) ); \
00222         AK_WCHAR_TO_UTF16(  _utf16string_, (const wchar_t*)_astring_, wcslen(_astring_)+1 )
00223 
00224     #define CONVERT_OSCHAR_TO_UTF16( _astring_, _utf16string_ ) \
00225         _utf16string_ = (AkUtf16*)AkAlloca( (1 + strlen(_astring_)) * sizeof(AkUtf16) ); \
00226         AK_OSCHAR_TO_UTF16( _utf16string_, (const AkOSChar*)_astring_, strlen(_astring_)+1 )
00227 
00228     #define CONVERT_UTF16_TO_OSCHAR( _astring_, _oscharstring_ ) \
00229         _oscharstring_ = (AkOSChar*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(AkOSChar) ); \
00230         AK_UTF16_TO_OSCHAR( _oscharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 ) 
00231 
00232     #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)
00233     #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 )
00234     #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkOSChar, AkUtf16>(  in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00235     #define AK_UTF16_TO_CHAR(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<char, AkUtf16>(  in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00236     #define AK_CHAR_TO_UTF16(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, char>(  in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)  
00237     #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, AkOSChar>(  in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)  
00238     
00240     #define AkAlloca( _size_ ) alloca( _size_ )
00241 }

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