목차

include/AK/SoundEngine/Common/AkCommonDefs.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 // AkCommonDefs.h
00029 
00030 /// \file 
00031 /// AudioLib common defines, enums, and structs.
00032 
00033 
00034 #ifndef _AK_COMMON_DEFS_H_
00035 #define _AK_COMMON_DEFS_H_
00036 
00037 #include <AK/SoundEngine/Common/AkSpeakerConfig.h>
00038 #include <AK/SoundEngine/Common/AkSpeakerVolumes.h>
00039 
00040 //-----------------------------------------------------------------------------
00041 // AUDIO DATA FORMAT
00042 //-----------------------------------------------------------------------------
00043 
00044 // Audio data format.
00045 // ------------------------------------------------
00046 
00047 const AkDataTypeID      AK_INT              = 0;        ///< Integer data type (uchar, short, and so on)
00048 const AkDataTypeID      AK_FLOAT            = 1;        ///< Float data type
00049 
00050 const AkDataInterleaveID AK_INTERLEAVED     = 0;        ///< Interleaved data
00051 const AkDataInterleaveID AK_NONINTERLEAVED  = 1;        ///< Non-interleaved data
00052 
00053 // Native format currently the same on all supported platforms, may become platform specific in the future
00054 const AkUInt32 AK_LE_NATIVE_BITSPERSAMPLE  = 32;                    ///< Native number of bits per sample.
00055 const AkUInt32 AK_LE_NATIVE_SAMPLETYPE = AK_FLOAT;                  ///< Native data type.
00056 const AkUInt32 AK_LE_NATIVE_INTERLEAVE = AK_NONINTERLEAVED;         ///< Native interleaved setting.
00057 
00058 /// Defines the parameters of an audio buffer format.
00059 struct AkAudioFormat
00060 {
00061     AkUInt32    uSampleRate;        ///< Number of samples per second
00062 
00063     AkChannelConfig channelConfig;  ///< Channel configuration.
00064 
00065     AkUInt32    uBitsPerSample  :6; ///< Number of bits per sample.
00066     AkUInt32    uBlockAlign     :10;///< Number of bytes per sample frame. (For example a 5.1 PCM 16bit should have a uBlockAlign equal to 6(5.1 channels)*2(16 bits per sample) = 12.
00067     AkUInt32    uTypeID         :2; ///< Data type ID (AkDataTypeID). 
00068     AkUInt32    uInterleaveID   :1; ///< Interleave ID (AkDataInterleaveID). 
00069     
00070     /// Get the number of channels.
00071     /// \return The number of channels
00072     AkForceInline AkUInt32 GetNumChannels() const
00073     {
00074         return channelConfig.uNumChannels;
00075     }
00076 
00077     /// Query if LFE channel is present.
00078     /// \return True when LFE channel is present
00079     AkForceInline bool HasLFE() const
00080     { 
00081         return channelConfig.HasLFE(); 
00082     }
00083 
00084     /// Query if center channel is present.
00085     /// Note that mono configurations have one channel which is arbitrary set to AK_SPEAKER_FRONT_CENTER,
00086     /// so HasCenter() returns true for mono signals.
00087     /// \return True when center channel is present and configuration has more than 2 channels.
00088     AkForceInline bool HasCenter() const
00089     { 
00090         return channelConfig.HasCenter(); 
00091     }
00092 
00093     /// Get the number of bits per sample.
00094     /// \return The number of bits per sample
00095     AkForceInline AkUInt32 GetBitsPerSample()   const                       
00096     { 
00097         return uBitsPerSample;
00098     }
00099 
00100     /// Get the block alignment.
00101     /// \return The block alignment
00102     AkForceInline AkUInt32 GetBlockAlign() const
00103     {
00104         return uBlockAlign;
00105     }
00106 
00107     /// Get the data sample format (Float or Integer).
00108     /// \return The data sample format
00109     AkForceInline AkUInt32 GetTypeID() const
00110     {
00111         return uTypeID;
00112     }
00113 
00114     /// Get the interleaved type.
00115     /// \return The interleaved type
00116     AkForceInline AkUInt32 GetInterleaveID() const
00117     {
00118         return uInterleaveID;
00119     }
00120 
00121     /// Set all parameters of the audio format structure.
00122     /// Channels are specified by channel mask (standard configs).
00123     void SetAll(
00124         AkUInt32    in_uSampleRate,     ///< Number of samples per second
00125         AkChannelConfig in_channelConfig,   ///< Channel configuration
00126         AkUInt32    in_uBitsPerSample,  ///< Number of bits per sample
00127         AkUInt32    in_uBlockAlign,     ///< Block alignment
00128         AkUInt32    in_uTypeID,         ///< Data sample format (Float or Integer)
00129         AkUInt32    in_uInterleaveID    ///< Interleaved type
00130         )
00131     {
00132         uSampleRate     = in_uSampleRate;
00133         channelConfig   = in_channelConfig;
00134         uBitsPerSample  = in_uBitsPerSample;
00135         uBlockAlign     = in_uBlockAlign;
00136         uTypeID         = in_uTypeID;
00137         uInterleaveID   = in_uInterleaveID;
00138     }
00139 
00140     /// Checks if the channel configuration is supported by the source pipeline.
00141     /// \return The interleaved type
00142     AkForceInline bool IsChannelConfigSupported() const
00143     {
00144         return channelConfig.IsChannelConfigSupported();
00145     }
00146 
00147     AkForceInline bool operator==(const AkAudioFormat & in_other) const
00148     {
00149         return uSampleRate == in_other.uSampleRate 
00150             && channelConfig == in_other.channelConfig
00151             && uBitsPerSample == in_other.uBitsPerSample
00152             && uBlockAlign == in_other.uBlockAlign
00153             && uTypeID == in_other.uTypeID
00154             && uInterleaveID == in_other.uInterleaveID;
00155     }
00156 
00157     AkForceInline bool operator!=(const AkAudioFormat & in_other) const
00158     {
00159         return uSampleRate != in_other.uSampleRate
00160             || channelConfig != in_other.channelConfig
00161             || uBitsPerSample != in_other.uBitsPerSample
00162             || uBlockAlign != in_other.uBlockAlign
00163             || uTypeID != in_other.uTypeID
00164             || uInterleaveID != in_other.uInterleaveID;
00165     }
00166 };
00167 
00168 enum AkSourceChannelOrdering
00169 {
00170     SourceChannelOrdering_Standard = 0, // SMPTE L-R-C-LFE-RL-RR-RC-SL-SR-HL-HR-HC-HRL-HRR-HRC-T
00171     // or ACN ordering + SN3D norm
00172 
00173     SourceChannelOrdering_Film, // L/C/R/Ls/Rs/Lfe
00174     SourceChannelOrdering_FuMa
00175 };
00176 
00177 #define AK_MAKE_CHANNELCONFIGOVERRIDE(_config,_order)   ((AkInt64)_config.Serialize()|((AkInt64)_order<<32))
00178 #define AK_GET_CHANNELCONFIGOVERRIDE_CONFIG(_over)      (_over&UINT_MAX)
00179 #define AK_GET_CHANNELCONFIGOVERRIDE_ORDERING(_over)    ((AkSourceChannelOrdering)(_over>>32))
00180 
00181 // Build a 32 bit class identifier based on the Plug-in type,
00182 // CompanyID and PluginID.
00183 //
00184 // Parameters:
00185 //   - in_pluginType: A value from enum AkPluginType (4 bits)
00186 //   - in_companyID: CompanyID as defined in the Plug-in's XML file (12 bits)
00187 //          * 0-63: Reserved for Audiokinetic
00188 //          * 64-255: Reserved for clients' in-house Plug-ins
00189 //          * 256-4095: Assigned by Audiokinetic to third-party plug-in developers
00190 //   - in_pluginID: PluginID as defined in the Plug-in's XML file (16 bits)
00191 //          * 0-32767: Set freely by the Plug-in developer
00192 #define AKMAKECLASSID( in_pluginType, in_companyID, in_pluginID ) \
00193     ( (in_pluginType) + ( (in_companyID) << 4 ) + ( (in_pluginID) << ( 4 + 12 ) ) )
00194 
00195 #define AKGETPLUGINTYPEFROMCLASSID( in_classID ) ( (in_classID) & AkPluginTypeMask )
00196 #define AKGETCOMPANYIDFROMCLASSID( in_classID ) ( ( (in_classID) & 0x0000FFF0 ) >> 4 )
00197 #define AKGETPLUGINIDFROMCLASSID( in_classID ) ( ( (in_classID) & 0xFFFF0000 ) >> ( 4 + 12 ) )
00198 
00199 #define CODECID_FROM_PLUGINID AKGETPLUGINIDFROMCLASSID
00200 
00201 
00202 namespace AK
00203 {
00204     /// Interface to retrieve metering information about a buffer.
00205     class IAkMetering
00206     {
00207     protected:
00208         /// Virtual destructor on interface to avoid warnings.
00209         virtual ~IAkMetering(){}
00210 
00211     public:
00212 
00213         /// Get peak of each channel in this frame.
00214         /// Depending on when this function is called, you may get metering data computed in the previous frame only. In order to force recomputing of
00215         /// meter values, pass in_bForceCompute=true.
00216         /// \return Vector of linear peak levels, corresponding to each channel. NULL if AK_EnableBusMeter_Peak is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
00217         virtual AK::SpeakerVolumes::ConstVectorPtr GetPeak() = 0;
00218 
00219         /// Get true peak of each channel (as defined by ITU-R BS.1770) in this frame.
00220         /// Depending on when this function is called, you may get metering data computed in the previous frame only. 
00221         /// \return Vector of linear true peak levels, corresponding to each channel. NULL if AK_EnableBusMeter_TruePeak is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
00222         virtual AK::SpeakerVolumes::ConstVectorPtr GetTruePeak() = 0;
00223 
00224         /// Get the RMS value of each channel in this frame.
00225         /// Depending on when this function is called, you may get metering data computed in the previous frame only. In order to force recomputing of
00226         /// meter values, pass in_bForceCompute=true.
00227         /// \return Vector of linear rms levels, corresponding to each channel. NULL if AK_EnableBusMeter_RMS is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
00228         virtual AK::SpeakerVolumes::ConstVectorPtr GetRMS() = 0;
00229         
00230         /// Get the mean k-weighted power value in this frame, used to compute loudness (as defined by ITU-R BS.1770).
00231         /// Depending on when this function is called, you may get metering data computed in the previous frame only.
00232         /// \return Total linear k-weighted power of all channels. 0 if AK_EnableBusMeter_KPower is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
00233         virtual AkReal32 GetKWeightedPower() = 0;
00234     };
00235 }
00236 
00237 // Audio buffer.
00238 // ------------------------------------------------
00239 
00240 /// Native sample type. 
00241 /// \remarks Sample values produced by insert effects must use this type.
00242 /// \remarks Source plug-ins can produce samples of other types (specified through 
00243 /// according fields of AkAudioFormat, at initial handshaking), but these will be 
00244 /// format converted internally into the native format.
00245 /// \sa
00246 /// - \ref iaksourceeffect_init
00247 /// - \ref iakmonadiceffect_init
00248 typedef AkReal32 AkSampleType;  ///< Audio sample data type (32 bit floating point)
00249 
00250 /// Audio buffer structure including the address of an audio buffer, the number of valid frames inside, 
00251 /// and the maximum number of frames the audio buffer can hold.
00252 /// \sa
00253 /// - \ref fx_audiobuffer_struct
00254 class AkAudioBuffer
00255 {
00256 public:
00257 
00258     /// Constructor.
00259     AkAudioBuffer() 
00260     { 
00261         Clear(); 
00262     }
00263 
00264     /// Clear data pointer.
00265     AkForceInline void ClearData()
00266     {
00267         pData = NULL;
00268     }
00269 
00270     /// Clear members.
00271     AkForceInline void Clear()
00272     {
00273         ClearData();
00274         uValidFrames        = 0;
00275         uMaxFrames          = 0;
00276         eState              = AK_DataNeeded;
00277     }
00278     
00279     /// \name Channel queries.
00280     //@{
00281     /// Get the number of channels.
00282     AkForceInline AkUInt32 NumChannels() const
00283     {
00284         return channelConfig.uNumChannels;
00285     }
00286 
00287     /// Returns true if there is an LFE channel present.
00288     AkForceInline bool HasLFE() const
00289     { 
00290         return channelConfig.HasLFE(); 
00291     }
00292 
00293     AkForceInline AkChannelConfig GetChannelConfig() const { return channelConfig; }
00294 
00295     //@}
00296 
00297     /// \name Interleaved interface
00298     //@{
00299     /// Get address of data: to be used with interleaved buffers only.
00300     /// \remarks Only source plugins can output interleaved data. This is determined at 
00301     /// initial handshaking.
00302     /// \sa 
00303     /// - \ref fx_audiobuffer_struct
00304     AkForceInline void * GetInterleavedData()
00305     { 
00306         return pData; 
00307     }
00308 
00309     /// Attach interleaved data. Allocation is performed outside.
00310     inline void AttachInterleavedData( void * in_pData, AkUInt16 in_uMaxFrames, AkUInt16 in_uValidFrames, AkChannelConfig in_channelConfig )
00311     { 
00312         pData = in_pData; 
00313         uMaxFrames = in_uMaxFrames; 
00314         uValidFrames = in_uValidFrames; 
00315         channelConfig = in_channelConfig; 
00316     }
00317     //@}
00318 
00319     /// \name Deinterleaved interface
00320     //@{
00321 
00322     /// Check if buffer has samples attached to it.
00323     AkForceInline bool HasData() const
00324     {
00325         return ( NULL != pData ); 
00326     }
00327 
00328     /// Convert a channel, identified by a single channel bit, to a buffer index used in GetChannel() below, for a given channel config.
00329     /// Standard indexing follows channel bit order (see AkSpeakerConfig.h). Pipeline/buffer indexing is the same but the LFE is moved to the end.
00330     static inline AkUInt32 StandardToPipelineIndex( 
00331         AkChannelConfig 
00332 #ifdef AK_LFECENTER
00333                         in_channelConfig        ///< Channel configuration.
00334 #endif
00335         , AkUInt32      in_uChannelIdx          ///< Channel index in standard ordering to be converted to pipeline ordering.
00336         )
00337     {
00338 #ifdef AK_LFECENTER
00339         if ( in_channelConfig.HasLFE() )
00340         {
00341             AKASSERT( in_channelConfig.eConfigType == AK_ChannelConfigType_Standard );  // in_channelConfig.HasLFE() would not have returned true otherwise.
00342             AKASSERT( AK::GetNumNonZeroBits( in_channelConfig.uChannelMask ) );
00343             AkUInt32 uIdxLFE = AK::GetNumNonZeroBits( ( AK_SPEAKER_LOW_FREQUENCY - 1 ) & in_channelConfig.uChannelMask );
00344             if ( in_uChannelIdx == uIdxLFE )
00345                 return in_channelConfig.uNumChannels - 1;
00346             else if ( in_uChannelIdx > uIdxLFE )
00347                 return in_uChannelIdx - 1;
00348         }
00349 #endif
00350         return in_uChannelIdx;
00351     }
00352 
00353     /// Get the buffer of the ith channel. 
00354     /// Access to channel data is most optimal through this method. Use whenever the
00355     /// speaker configuration is known, or when an operation must be made independently
00356     /// for each channel.
00357     /// \remarks When using a standard configuration, use ChannelMaskToBufferIndex() to convert channel bits to buffer indices.
00358     /// \return Address of the buffer of the ith channel.
00359     /// \sa
00360     /// - \ref fx_audiobuffer_struct
00361     /// - \ref fx_audiobuffer_struct_channels
00362     inline AkSampleType * GetChannel(
00363         AkUInt32 in_uIndex      ///< Channel index [0,NumChannels()-1]
00364         )
00365     {
00366         AKASSERT( in_uIndex < NumChannels() );
00367         return (AkSampleType*)((AkUInt8*)(pData) + ( in_uIndex * sizeof(AkSampleType) * MaxFrames() ));
00368     }
00369 
00370     /// Get the buffer of the LFE.
00371     /// \return Address of the buffer of the LFE. Null if there is no LFE channel.
00372     /// \sa
00373     /// - \ref fx_audiobuffer_struct_channels
00374     inline AkSampleType * GetLFE()
00375     {
00376         if ( channelConfig.uChannelMask & AK_SPEAKER_LOW_FREQUENCY )
00377             return GetChannel( NumChannels()-1 );
00378         
00379         return (AkSampleType*)0;
00380     }
00381 
00382     /// Can be used to transform an incomplete into a complete buffer with valid data.
00383     /// The invalid frames are made valid (zeroed out) for all channels and the validFrames count will be made equal to uMaxFrames.
00384     void ZeroPadToMaxFrames()
00385     {
00386         // Zero out all channels.
00387         const AkUInt32 uNumChannels = NumChannels();
00388         const AkUInt32 uNumZeroFrames = MaxFrames()-uValidFrames;
00389         if ( uNumZeroFrames )
00390         {
00391             for ( AkUInt32 i = 0; i < uNumChannels; ++i )
00392             {
00393                 AKPLATFORM::AkMemSet( GetChannel(i) + uValidFrames, 0, uNumZeroFrames * sizeof(AkSampleType) );
00394             }
00395             uValidFrames = MaxFrames();
00396         }
00397     }
00398 
00399     /// Attach deinterleaved data where channels are contiguous in memory. Allocation is performed outside.
00400     AkForceInline void AttachContiguousDeinterleavedData( void * in_pData, AkUInt16 in_uMaxFrames, AkUInt16 in_uValidFrames, AkChannelConfig in_channelConfig )
00401     { 
00402         AttachInterleavedData( in_pData, in_uMaxFrames, in_uValidFrames, in_channelConfig );
00403     }
00404     /// Detach deinterleaved data where channels are contiguous in memory. The address of the buffer is returned and fields are cleared.
00405     AkForceInline void * DetachContiguousDeinterleavedData()
00406     {
00407         uMaxFrames = 0; 
00408         uValidFrames = 0; 
00409         channelConfig.Clear();
00410         void * pDataOld = pData;
00411         pData = NULL;
00412         return pDataOld;
00413     }
00414 
00415 #if defined(AK_CHECK_AUDIO_BUFFER_VALID)
00416     bool CheckValidSamples()
00417     {
00418         // Zero out all channels.
00419         const AkUInt32 uNumChannels = NumChannels();
00420         for ( AkUInt32 i = 0; i < uNumChannels; ++i )
00421         {
00422             AkSampleType * AK_RESTRICT pfChan = GetChannel(i);
00423             if ( pfChan )
00424             {
00425                 for ( AkUInt32 j = 0; j < uValidFrames; j++ )
00426                 {
00427                     AkSampleType fSample = *pfChan++;
00428                     if ( fSample > 4.f )
00429                         return false;
00430                     else if ( fSample < -4.f )
00431                         return false;
00432                 }
00433             }
00434         }
00435 
00436         return true;
00437     }
00438 #endif
00439 
00440     //@}
00441 
00442     void RelocateMedia( AkUInt8* in_pNewMedia,  AkUInt8* in_pOldMedia )
00443     {
00444         AkUIntPtr uMemoryOffset = (AkUIntPtr)in_pNewMedia - (AkUIntPtr)in_pOldMedia;
00445         pData = (void*) (((AkUIntPtr)pData) + uMemoryOffset);
00446     }
00447 
00448 protected:
00449 
00450     void *          pData;              ///< Start of the audio buffer.
00451 
00452     AkChannelConfig channelConfig;      ///< Channel config.
00453 public: 
00454     AKRESULT        eState;             ///< Execution status   
00455 protected:  
00456     AkUInt16        uMaxFrames;         ///< Number of sample frames the buffer can hold. Access through AkAudioBuffer::MaxFrames().
00457 
00458 public:
00459     /// Access to the number of sample frames the buffer can hold.
00460     /// \return Number of sample frames the buffer can hold.
00461     AkForceInline AkUInt16 MaxFrames() const { return uMaxFrames; }
00462     
00463     AkUInt16        uValidFrames;       ///< Number of valid sample frames in the audio buffer
00464 } AK_ALIGN_DMA;
00465 
00466 #endif // _AK_COMMON_DEFS_H_
00467