目次

include/AK/SoundEngine/Common/AkSpeakerVolumes.h

説明を見る。
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 // AkSpeakerVolumes.h
00029 
00030 /// \file 
00031 /// Multi-channel volume definitions and services.
00032 /// Always associated with an AkChannelConfig. In the case of standard configurations, the volume items ordering
00033 /// match the bit ordering in the channel mask, except for the LFE which is skipped and placed at the end of the
00034 /// volume array.
00035 /// Refer to \ref goingfurther_speakermatrixcallback for an example of how to manipulate speaker volume vectors/matrices.
00036 
00037 #ifndef _AK_SPEAKER_VOLUMES_H_
00038 #define _AK_SPEAKER_VOLUMES_H_
00039 
00040 #include <AK/SoundEngine/Common/AkTypes.h>
00041 #include <AK/Tools/Common/AkPlatformFuncs.h>
00042 #include <AK/SoundEngine/Platforms/Generic/AkSpeakerVolumes.h>
00043 
00044 namespace AK
00045 {
00046 /// Multi-channel volume definitions and services.
00047 namespace SpeakerVolumes
00048 {
00049     typedef AkReal32 * VectorPtr;               ///< Volume vector. Access each element with the standard bracket [] operator.
00050     typedef AkReal32 * MatrixPtr;               ///< Volume matrix. Access each input channel vector with AK::SpeakerVolumes::Matrix::GetChannel().
00051     typedef const AkReal32 * ConstVectorPtr;    ///< Constant volume vector. Access each element with the standard bracket [] operator.
00052     typedef const AkReal32 * ConstMatrixPtr;    ///< Constant volume matrix. Access each input channel vector with AK::SpeakerVolumes::Matrix::GetChannel().
00053 
00054     /// Volume vector services.
00055     namespace Vector
00056     {
00057         /// Copy volumes.
00058         AkForceInline void Copy( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels )
00059         {
00060             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
00061             if ( in_uNumChannels )
00062                 memcpy( in_pVolumesDst, in_pVolumesSrc, in_uNumChannels * sizeof( AkReal32 ) );
00063         }
00064 
00065         /// Copy volumes with gain.
00066         AkForceInline void Copy( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels, AkReal32 in_fGain )
00067         {
00068             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
00069             for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
00070             {
00071                 in_pVolumesDst[uChan] = in_pVolumesSrc[uChan] * in_fGain;
00072             }
00073         }
00074 
00075         /// Clear volumes.
00076         AkForceInline void Zero( VectorPtr in_pVolumes, AkUInt32 in_uNumChannels )
00077         {
00078             AKASSERT( in_pVolumes || in_uNumChannels == 0 );
00079             if ( in_uNumChannels )
00080                 memset( in_pVolumes, 0, in_uNumChannels * sizeof( AkReal32 ) );
00081         }
00082 
00083         /// Accumulate two volume vectors.
00084         AkForceInline void Add( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels )
00085         {
00086             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
00087             for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
00088             {
00089                 in_pVolumesDst[uChan] += in_pVolumesSrc[uChan];
00090             }
00091         }
00092 
00093         /// Compute the sum of all components of a volume vector.
00094         AkForceInline AkReal32 L1Norm(ConstVectorPtr io_pVolumes, AkUInt32 in_uNumChannels)
00095         {
00096             AkReal32 total = 0;
00097             AKASSERT((io_pVolumes) || in_uNumChannels == 0);
00098             for (AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++)
00099             {
00100                 total += io_pVolumes[uChan];
00101             }
00102 
00103             return total;
00104         }
00105 
00106         /// Multiply volume vector with a scalar.
00107         AkForceInline void Mul( VectorPtr in_pVolumesDst, const AkReal32 in_fVol, AkUInt32 in_uNumChannels )
00108         {
00109             AKASSERT( in_pVolumesDst || in_uNumChannels == 0 );
00110             for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
00111             {
00112                 in_pVolumesDst[uChan] *= in_fVol;
00113             }
00114         }
00115 
00116         /// Multiply two volume vectors.
00117         AkForceInline void Mul( VectorPtr in_pVolumesDst, ConstVectorPtr in_pVolumesSrc, AkUInt32 in_uNumChannels )
00118         {
00119             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
00120             for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
00121             {
00122                 in_pVolumesDst[uChan] *= in_pVolumesSrc[uChan];
00123             }
00124         }
00125 
00126         /// Get max for all elements of two volume vectors, independently.
00127         AkForceInline void Max( AkReal32 * in_pVolumesDst, const AkReal32 * in_pVolumesSrc, AkUInt32 in_uNumChannels )
00128         {
00129             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
00130             for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
00131             {
00132                 in_pVolumesDst[uChan] = AkMax( in_pVolumesDst[uChan], in_pVolumesSrc[uChan] );
00133             }
00134         }
00135         
00136         /// Get min for all elements of two volume vectors, independently.
00137         AkForceInline void Min( AkReal32 * in_pVolumesDst, const AkReal32 * in_pVolumesSrc, AkUInt32 in_uNumChannels )
00138         {
00139             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || in_uNumChannels == 0 );
00140             for ( AkUInt32 uChan = 0; uChan < in_uNumChannels; uChan++ )
00141             {
00142                 in_pVolumesDst[uChan] = AkMin( in_pVolumesDst[uChan], in_pVolumesSrc[uChan] );
00143             }
00144         }
00145     }
00146 
00147     /// Volume matrix (multi-in/multi-out channel configurations) services.
00148     namespace Matrix
00149     {
00150         /// Compute size (in bytes) required for given channel configurations.
00151         AkForceInline AkUInt32 GetRequiredSize( AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut ) 
00152         {
00153             return in_uNumChannelsIn * Vector::GetRequiredSize( in_uNumChannelsOut );
00154         }
00155 
00156         /// Compute size (in number of elements) required for given channel configurations.
00157         AkForceInline AkUInt32 GetNumElements( AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut ) 
00158         {
00159             return in_uNumChannelsIn * Vector::GetNumElements( in_uNumChannelsOut );
00160         }
00161         
00162         /// Get pointer to volume distribution for input channel in_uIdxChannelIn.
00163         AkForceInline VectorPtr GetChannel( MatrixPtr in_pVolumeMx, AkUInt32 in_uIdxChannelIn, AkUInt32 in_uNumChannelsOut ) 
00164         {
00165             AKASSERT( in_pVolumeMx );
00166             return in_pVolumeMx + in_uIdxChannelIn * Vector::GetNumElements( in_uNumChannelsOut );
00167         }
00168 
00169         /// Get pointer to volume distribution for input channel in_uIdxChannelIn.
00170         AkForceInline ConstVectorPtr GetChannel( ConstMatrixPtr in_pVolumeMx, AkUInt32 in_uIdxChannelIn, AkUInt32 in_uNumChannelsOut ) 
00171         {
00172             AKASSERT( in_pVolumeMx );
00173             return in_pVolumeMx + in_uIdxChannelIn * Vector::GetNumElements( in_uNumChannelsOut );
00174         }
00175 
00176         /// Copy matrix.
00177         AkForceInline void Copy( MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
00178         {
00179             AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
00180             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || uNumElements == 0 );
00181             if ( uNumElements )
00182                 memcpy( in_pVolumesDst, in_pVolumesSrc, uNumElements * sizeof( AkReal32 ) );
00183         }
00184 
00185         /// Copy matrix with gain.
00186         AkForceInline void Copy( MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut, AkReal32 in_fGain )
00187         {
00188             AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
00189             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || uNumElements == 0 );
00190             for ( AkUInt32 uChan = 0; uChan < uNumElements; uChan++ )
00191             {
00192                 in_pVolumesDst[uChan] = in_pVolumesSrc[uChan] * in_fGain;
00193             }
00194         }
00195 
00196         /// Clear matrix.
00197         AkForceInline void Zero( MatrixPtr in_pVolumes, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
00198         {
00199             AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
00200             AKASSERT( in_pVolumes || uNumElements == 0 );
00201             if ( uNumElements )
00202                 memset( in_pVolumes, 0, uNumElements * sizeof( AkReal32 ) );
00203         }
00204 
00205         /// Multiply a matrix with a scalar.
00206         AkForceInline void Mul( MatrixPtr in_pVolumesDst, const AkReal32 in_fVol, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut )
00207         {
00208             AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
00209             AKASSERT( in_pVolumesDst || uNumElements == 0 );
00210             for ( AkUInt32 uChan = 0; uChan < uNumElements; uChan++ )
00211             {
00212                 in_pVolumesDst[uChan] *= in_fVol;
00213             }
00214         }
00215 
00216         /// Add all elements of two volume matrices, independently.
00217         AkForceInline void Add(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
00218         {
00219             AkUInt32 uNumElements = Matrix::GetNumElements(in_uNumChannelsIn, in_uNumChannelsOut);
00220             AKASSERT((in_pVolumesDst && in_pVolumesSrc) || uNumElements == 0);
00221             for (AkUInt32 uChan = 0; uChan < uNumElements; uChan++)
00222             {
00223                 in_pVolumesDst[uChan] += in_pVolumesSrc[uChan];
00224             }
00225         }
00226 
00227         /// Pointwise Multiply-Add of all elements of two volume matrices.
00228         AkForceInline void MAdd(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut, AkReal32 in_fGain)
00229         {
00230             AkUInt32 uNumElements = Matrix::GetNumElements(in_uNumChannelsIn, in_uNumChannelsOut);
00231             AKASSERT((in_pVolumesDst && in_pVolumesSrc) || uNumElements == 0);
00232             for (AkUInt32 uChan = 0; uChan < uNumElements; uChan++)
00233             {
00234                 in_pVolumesDst[uChan] += in_pVolumesSrc[uChan] * in_fGain;
00235             }
00236         }
00237         
00238         /// Get absolute max for all elements of two volume matrices, independently.
00239         AkForceInline void AbsMax(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
00240         {
00241             AkUInt32 uNumElements = Matrix::GetNumElements( in_uNumChannelsIn, in_uNumChannelsOut );
00242             AKASSERT( ( in_pVolumesDst && in_pVolumesSrc ) || uNumElements == 0 );
00243             for ( AkUInt32 uChan = 0; uChan < uNumElements; uChan++ )
00244             {
00245                 in_pVolumesDst[uChan] = ((in_pVolumesDst[uChan] * in_pVolumesDst[uChan]) > (in_pVolumesSrc[uChan] * in_pVolumesSrc[uChan])) ? in_pVolumesDst[uChan] : in_pVolumesSrc[uChan];
00246             }
00247         }
00248 
00249         /// Get max for all elements of two volume matrices, independently.
00250         AkForceInline void Max(MatrixPtr in_pVolumesDst, ConstMatrixPtr in_pVolumesSrc, AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
00251         {
00252             AkUInt32 uNumElements = Matrix::GetNumElements(in_uNumChannelsIn, in_uNumChannelsOut);
00253             AKASSERT((in_pVolumesDst && in_pVolumesSrc) || uNumElements == 0);
00254             for (AkUInt32 uChan = 0; uChan < uNumElements; uChan++)
00255             {
00256                 in_pVolumesDst[uChan] = (in_pVolumesDst[uChan] > in_pVolumesSrc[uChan]) ? in_pVolumesDst[uChan] : in_pVolumesSrc[uChan];
00257             }
00258         }
00259     }
00260 }
00261 }
00262 
00263 #endif  //_AK_SPEAKER_VOLUMES_H_