Table of Contents

include/AK/Tools/Common/AkBankReadHelpers.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 #ifndef _AK_BANKREADHELPERS_H_
00029 #define _AK_BANKREADHELPERS_H_
00030 
00031 /// Read data from bank and advance pointer.
00032 template< typename T > 
00033 inline T ReadBankData( 
00034                         AkUInt8*& in_rptr 
00035 #ifdef _DEBUG
00036                         ,AkUInt32& in_rSize
00037 #endif
00038                         )
00039 {
00040     T l_Value;
00041 #if defined(AK_IOS) || defined(AK_ANDROID) || defined(AK_LINUX) || defined(__EMSCRIPTEN__) || defined (AK_NX)
00042     typedef struct {T t;} __attribute__((__packed__)) packedStruct;
00043     l_Value = ((packedStruct *)in_rptr)->t;
00044 #else
00045     l_Value = *( ( T* )in_rptr );
00046 #endif
00047 
00048     in_rptr += sizeof( T );
00049 #ifdef _DEBUG
00050     in_rSize -= sizeof( T );
00051 #endif
00052     return l_Value;
00053 }
00054 
00055 template< typename T >
00056 inline T ReadVariableSizeBankData(
00057     AkUInt8*& in_rptr
00058 #ifdef _DEBUG
00059     , AkUInt32& in_rSize
00060 #endif
00061     )
00062 {
00063     AkUInt32 l_Value = 0;
00064 
00065     AkUInt8 currentByte = *in_rptr;
00066     ++in_rptr;
00067 #ifdef _DEBUG
00068     --in_rSize;
00069 #endif
00070     l_Value = (currentByte & 0x7F);
00071     while (0x80 & currentByte)
00072     {
00073         currentByte = *in_rptr;
00074         ++in_rptr;
00075 #ifdef _DEBUG
00076         --in_rSize;
00077 #endif
00078         l_Value = l_Value << 7;
00079         l_Value |= (currentByte & 0x7F);
00080     }
00081 
00082     return (T)l_Value;
00083 }
00084 
00085 inline char * ReadBankStringUtf8( 
00086                         AkUInt8*& in_rptr 
00087 #ifdef _DEBUG
00088                         ,AkUInt32& in_rSize
00089 #endif
00090                         ,AkUInt32& out_uStringSize )
00091 {
00092     out_uStringSize = ReadBankData<AkUInt32>( in_rptr 
00093 #ifdef _DEBUG
00094                         ,in_rSize
00095 #endif
00096                         );
00097 
00098     char * pString = 0;
00099     if ( out_uStringSize > 0 )
00100     {
00101         pString = reinterpret_cast<char*>( in_rptr );
00102         in_rptr += out_uStringSize;
00103 #ifdef _DEBUG
00104         in_rSize -= out_uStringSize;
00105 #endif
00106     }
00107     return pString;
00108 }
00109 
00110 /// Read unaligned memory, const version
00111 template< typename T >
00112 inline T ReadUnaligned( const AkUInt8* in_rptr, AkUInt32 in_bytesToSkip = 0 )
00113 {
00114 #ifdef _DEBUG
00115     AkUInt32 size = sizeof(T);
00116 #endif
00117     AkUInt8* ptr = const_cast<AkUInt8*>(in_rptr) + in_bytesToSkip;
00118     return ReadBankData<T>(ptr
00119 #ifdef _DEBUG
00120     , size
00121 #endif
00122     );
00123 }
00124 
00125 #ifdef __EMSCRIPTEN__
00126 
00127 /// Handle reading float not aligned on proper memory boundaries (banks are byte packed).
00128 inline AkReal64 AlignFloat(AkReal64* ptr)
00129 {
00130     AkReal64 LocalValue;
00131 
00132     // Forcing the char copy instead of the memcpy, as memcpy was optimized....
00133     char* pSource = (char*)ptr;
00134     char* pDest = (char*)&LocalValue;
00135     for( int i = 0; i < 8; ++i)
00136     {
00137         pDest[i] = pSource[i];
00138     }
00139 
00140     //memcpy( &LocalValue, ptr, sizeof( AkReal64 ) );
00141     return LocalValue;
00142 }
00143 
00144 /// Read data from bank and advance pointer.
00145 template<> 
00146 inline AkReal64 ReadBankData<AkReal64>( 
00147     AkUInt8*& in_rptr
00148 #ifdef _DEBUG
00149     ,AkUInt32& in_rSize
00150 #endif
00151     )
00152 {
00153     AkReal64 l_Value = AlignFloat( (AkReal64*)in_rptr );
00154     in_rptr += sizeof( AkReal64 );
00155 #ifdef _DEBUG
00156     in_rSize -= sizeof( AkReal64 );
00157 #endif
00158     return l_Value;
00159 }
00160 #endif
00161 
00162 #if (defined(AK_IOS) && defined(_DEBUG)) // bug with iOS SDK 4.3 in Debug only
00163 
00164 /// Type conversion helper on some platforms.
00165 template < typename TO, typename FROM >
00166 inline TO union_cast( FROM value )
00167 {
00168     union { FROM from; TO to; } convert;
00169     convert.from = value;
00170     return convert.to;
00171 }
00172 
00173 /// Handle reading float not aligned on proper memory boundaries (banks are byte packed).
00174 inline AkReal32 AlignFloat( AkReal32* ptr )
00175 {
00176     AkUInt32 *puint = reinterpret_cast<AkUInt32 *>( ptr );
00177     volatile AkUInt32 uint = *puint;
00178     return union_cast<AkReal32>( uint );
00179 }
00180 
00181 /// Read data from bank and advance pointer.
00182 template<> 
00183 inline AkReal32 ReadBankData<AkReal32>( 
00184                                        AkUInt8*& in_rptr
00185 #ifdef _DEBUG
00186                                        ,AkUInt32& in_rSize
00187 #endif
00188                                        )
00189 {
00190     AkReal32 l_Value = AlignFloat( ( AkReal32* )in_rptr );
00191     in_rptr += sizeof( AkReal32 );
00192 #ifdef _DEBUG
00193     in_rSize -= sizeof( AkReal32 );
00194 #endif
00195     return l_Value;
00196 }
00197 
00198 /// Handle reading float not aligned on proper memory boundaries (banks are byte packed).
00199 inline AkReal64 AlignFloat( AkReal64* ptr )
00200 {
00201     AkUInt64 *puint = reinterpret_cast<AkUInt64 *>( ptr );
00202     volatile AkUInt64 uint = *puint;
00203     return union_cast<AkReal64>( uint );
00204 }
00205 
00206 /// Read data from bank and advance pointer.
00207 template<> 
00208 inline AkReal64 ReadBankData<AkReal64>( 
00209                                        AkUInt8*& in_rptr
00210 #ifdef _DEBUG
00211                                        ,AkUInt32& in_rSize
00212 #endif
00213                                        )
00214 {
00215     AkReal64 l_Value = AlignFloat( ( AkReal64* )in_rptr );
00216     in_rptr += sizeof( AkReal64 );
00217 #ifdef _DEBUG
00218     in_rSize -= sizeof( AkReal64 );
00219 #endif
00220     return l_Value;
00221 }
00222 #endif
00223 
00224 #ifdef _DEBUG
00225 
00226 /// Read and return bank data of a given type, incrementing running pointer and decrementing block size for debug tracking purposes
00227 #define READBANKDATA( _Type, _Ptr, _Size )      \
00228         ReadBankData<_Type>( _Ptr, _Size )
00229 
00230 #define READVARIABLESIZEBANKDATA( _Type, _Ptr, _Size )      \
00231         ReadVariableSizeBankData<_Type>( _Ptr, _Size )
00232 
00233 /// Read and return non-null-terminatd UTF-8 string stored in bank, and its size.
00234 #define READBANKSTRING_UTF8( _Ptr, _Size, _out_StringSize )     \
00235         ReadBankStringUtf8( _Ptr, _Size, _out_StringSize )
00236 
00237 /// Read and return non-null-terminatd string stored in bank, and its size.
00238 #define READBANKSTRING( _Ptr, _Size, _out_StringSize )      \
00239         ReadBankStringUtf8( _Ptr, _Size, _out_StringSize ) //same as UTF-8 for now.
00240 
00241 /// Skip over some bank data  of a given type, incrementing running pointer and decrementing block size for debug tracking purposes
00242 #define SKIPBANKDATA( _Type, _Ptr, _Size )      \
00243         ( _Ptr ) += sizeof( _Type );    \
00244         ( _Size ) -= sizeof( _Type )
00245 
00246 /// Skip over some bank data by a given size in bytes, incrementing running pointer and decrementing block size for debug tracking purposes
00247 #define SKIPBANKBYTES( _NumBytes, _Ptr, _Size ) \
00248         ( _Ptr ) += _NumBytes;      \
00249         ( _Size ) -= _NumBytes
00250 
00251 #else
00252 
00253 /// Read and return bank data of a given type, incrementing running pointer and decrementing block size for debug tracking purposes
00254 #define READBANKDATA( _Type, _Ptr, _Size )      \
00255         ReadBankData<_Type>( _Ptr )
00256 
00257 #define READVARIABLESIZEBANKDATA( _Type, _Ptr, _Size )      \
00258         ReadVariableSizeBankData<_Type>( _Ptr )
00259 
00260 #define READBANKSTRING_UTF8( _Ptr, _Size, _out_StringSize )     \
00261         ReadBankStringUtf8( _Ptr, _out_StringSize )
00262 
00263 #define READBANKSTRING( _Ptr, _Size, _out_StringSize )      \
00264         ReadBankStringUtf8( _Ptr, _out_StringSize )
00265 
00266 /// Skip over some bank data  of a given type, incrementing running pointer and decrementing block size for debug tracking purposes
00267 #define SKIPBANKDATA( _Type, _Ptr, _Size )      \
00268         ( _Ptr ) += sizeof( _Type )
00269 
00270 /// Skip over some bank data by a given size in bytes, incrementing running pointer and decrementing block size for debug tracking purposes
00271 #define SKIPBANKBYTES( _NumBytes, _Ptr, _Size ) \
00272         ( _Ptr ) += _NumBytes;
00273 
00274 #endif
00275 
00276 #define GETBANKDATABIT( _Data, _Shift ) \
00277     (((_Data) >> (_Shift)) & 0x1)
00278 
00279 /// Helper macro to determine whether the full content of a block of memory was properly parsed
00280 #ifdef _DEBUG
00281     #define CHECKBANKDATASIZE( _DATASIZE_, _ERESULT_ ) AKASSERT( _DATASIZE_ == 0 || _ERESULT_ != AK_Success );
00282 #else
00283     #define CHECKBANKDATASIZE(_DATASIZE_, _ERESULT_ )
00284 #endif
00285 
00286 #endif //_AK_BANKREADHELPERS_H_