Version Wwise

include/AK/SoundEngine/Common/AkFPUtilities.h

Go to the documentation of this file.
00001 
00002 //
00003 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
00004 //
00006 
00009 
00010 #ifndef _AK_FP_UTILS_H_
00011 #define _AK_FP_UTILS_H_
00012 
00013 #include <AK/SoundEngine/Common/AkTypes.h>
00014 
00015 // Note: In many case you can use AK_FPSetValXX instead of FSEL. This saves a subtraction on platforms that do not have FSEL instructions.
00016 #if defined(__PPU__)
00017 #include <ppu_intrinsics.h>
00018 #define AK_FSEL( __a__, __b__, __c__ ) ( __fsels((__a__),(__b__),(__c__) ) )
00019 #elif defined(AK_XBOX360)
00020 #include "ppcintrinsics.h"
00021 #define AK_FSEL( __a__, __b__, __c__ ) ( (AkReal32)__fsel((__a__),(__b__),(__c__) ) )
00022 #else
00023 #define AK_FSEL( __a__, __b__, __c__) (((__a__) >= 0) ? (__b__) : (__c__))
00024 #endif
00025 
00026 #if defined(AK_XBOX360) || defined (__PPU__) || defined(AK_WIIU_SOFTWARE)
00027 
00029 static AkForceInline AkReal32 AK_FPMin( AkReal32 fA, AkReal32 fB )
00030 {   
00031     return AK_FSEL(fA-fB,fB,fA);
00032 } 
00033 
00035 static AkForceInline AkReal32 AK_FPMax( AkReal32 fA, AkReal32 fB )
00036 {   
00037     return AK_FSEL(fA-fB,fA,fB);
00038 }
00039 
00041 static AkForceInline void AK_FPSetValGT( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00042 {   
00043     io_fVariableToSet = AK_FSEL( (in_fComparandB-in_fComparandA), io_fVariableToSet, in_fValueIfTrue );
00044 }
00045 
00047 static AkForceInline void AK_FPSetValGTE( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00048 {   
00049     io_fVariableToSet = AK_FSEL( (in_fComparandA-in_fComparandB), in_fValueIfTrue, io_fVariableToSet );
00050 }
00051 
00053 static AkForceInline void AK_FPSetValLT( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00054 {   
00055     io_fVariableToSet = AK_FSEL( (in_fComparandA-in_fComparandB), io_fVariableToSet, in_fValueIfTrue );
00056 }
00057 
00059 static AkForceInline void AK_FPSetValLTE( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00060 {   
00061     io_fVariableToSet = AK_FSEL( (in_fComparandB-in_fComparandA), in_fValueIfTrue, io_fVariableToSet );
00062 }
00063 
00064 #elif defined(__SPU__)
00065 
00066 // Note: spu_insert() and spu_promote should not compile to actual instructions on the SPU where everything is vector types
00067 
00069 static AkForceInline AkReal32 AK_FPMin( AkReal32 fA, AkReal32 fB )
00070 {   
00071     vec_float4 vA = spu_promote( fA, 0 );
00072     vec_float4 vB = spu_promote( fB, 0 );
00073     vec_float4 vSel = spu_sel(vA, vB, spu_cmpgt(vA, vB));
00074     return spu_extract( vSel, 0 );
00075 } 
00076 
00078 static AkForceInline AkReal32 AK_FPMax( AkReal32 fA, AkReal32 fB )
00079 {   
00080     vec_float4 vA = spu_promote( fA, 0 );
00081     vec_float4 vB = spu_promote( fB, 0 );
00082     vec_float4 vSel = spu_sel(vB, vA, spu_cmpgt(vA, vB));
00083     return spu_extract( vSel, 0 );
00084 }
00085 
00087 static AkForceInline void AK_FPSetValGT( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00088 {   
00089     vec_float4 vA = spu_promote( in_fComparandA, 0 );
00090     vec_float4 vB = spu_promote( in_fComparandB, 0 );
00091     vec_float4 vVTS = spu_promote( io_fVariableToSet, 0 );
00092     vec_float4 vVIT = spu_promote( in_fValueIfTrue, 0 );
00093     vVTS = spu_sel(vVTS, vVIT, spu_cmpgt(vA, vB));
00094     io_fVariableToSet = spu_extract( vVTS, 0 );
00095 }
00096 
00099 static AkForceInline void AK_FPSetValGTE( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00100 {   
00101     vec_float4 vA = spu_promote( in_fComparandA, 0 );
00102     vec_float4 vB = spu_promote( in_fComparandB, 0 );
00103     vec_float4 vVTS = spu_promote( io_fVariableToSet, 0 );
00104     vec_float4 vVIT = spu_promote( in_fValueIfTrue, 0 );
00105     vec_uint4 vCmp = spu_cmpgt(vA, vB);
00106     vCmp = spu_or( vCmp, spu_cmpeq( vA, vB ) );
00107     vVTS = spu_sel(vVTS, vVIT, vCmp);
00108     io_fVariableToSet = spu_extract( vVTS, 0 );
00109 }
00110 
00113 static AkForceInline void AK_FPSetValLT( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00114 {   
00115     vec_float4 vA = spu_promote( in_fComparandA, 0 );
00116     vec_float4 vB = spu_promote( in_fComparandB, 0 );
00117     vec_float4 vVTS = spu_promote( io_fVariableToSet, 0 );
00118     vec_float4 vVIT = spu_promote( in_fValueIfTrue, 0 );
00119     vec_uint4 vCmp = spu_cmpgt(vA, vB);
00120     vCmp = spu_nor( vCmp, spu_cmpeq( vA, vB ) );
00121     vVTS = spu_sel(vVTS, vVIT, vCmp);
00122     io_fVariableToSet = spu_extract( vVTS, 0 );
00123 }
00124 
00126 static AkForceInline void AK_FPSetValLTE( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00127 {   
00128     vec_float4 vA = spu_promote( in_fComparandA, 0 );
00129     vec_float4 vB = spu_promote( in_fComparandB, 0 );
00130     vec_float4 vVTS = spu_promote( io_fVariableToSet, 0 );
00131     vec_float4 vVIT = spu_promote( in_fValueIfTrue, 0 );
00132     vec_uint4 vCtl = spu_cmpgt(vA, vB);
00133     vCtl = spu_nand(vCtl,vCtl);
00134     vVTS = spu_sel(vVTS, vVIT, vCtl);
00135     io_fVariableToSet = spu_extract( vVTS, 0 );
00136 }
00137 
00138 #else
00139 
00141 static AkForceInline AkReal32 AK_FPMin( AkReal32 fA, AkReal32 fB )
00142 {   
00143     return (fA < fB ? fA : fB);
00144 } 
00145 
00147 static AkForceInline AkReal32 AK_FPMax( AkReal32 fA, AkReal32 fB )
00148 {   
00149     return (fA > fB ? fA : fB);
00150 }
00151 
00153 static AkForceInline void AK_FPSetValGT( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00154 {   
00155     if ( in_fComparandA > in_fComparandB )
00156         io_fVariableToSet = in_fValueIfTrue;
00157 }
00158 
00160 static AkForceInline void AK_FPSetValGTE( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00161 {   
00162     if ( in_fComparandA >= in_fComparandB )
00163         io_fVariableToSet = in_fValueIfTrue;
00164 }
00165 
00167 static AkForceInline void AK_FPSetValLT( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00168 {   
00169     if ( in_fComparandA < in_fComparandB )
00170         io_fVariableToSet = in_fValueIfTrue;
00171 }
00172 
00174 static AkForceInline void AK_FPSetValLTE( AkReal32 in_fComparandA, AkReal32 in_fComparandB, AkReal32 & io_fVariableToSet, AkReal32 in_fValueIfTrue )
00175 {   
00176     if ( in_fComparandA <= in_fComparandB )
00177         io_fVariableToSet = in_fValueIfTrue;
00178 }
00179 
00180 #endif
00181 
00182 #endif //_AK_FP_UTILS_H_
00183