Table des matières

include/AK/Plugin/PluginServices/AkFXTailHandler.h

Go to the documentation of this file.
00001 
00002 //
00003 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
00004 //
00006  
00007 #ifndef _AKFXTAILHANDLER_H_
00008 #define _AKFXTAILHANDLER_H_
00009 
00010 #include <AK/SoundEngine/Common/AkTypes.h>
00011 #include <AK/SoundEngine/Common/AkCommonDefs.h>
00012 #include <AK/Tools/Common/AkPlatformFuncs.h>
00013 
00015 #define AKFXTAILHANDLER_NOTINTAIL 0xFFFFFFFF
00016 
00020 class AkFXTailHandler
00021 {
00022 public:
00024     inline AkFXTailHandler() 
00025         : uTailFramesRemaining( AKFXTAILHANDLER_NOTINTAIL )
00026         , uTotalTailFrames(0) {}
00027 
00029     inline void HandleTail( 
00030         AkAudioBuffer * io_pBuffer, 
00031         AkUInt32 in_uTotalTailFrames )
00032     {
00033         bool bPreStop = io_pBuffer->eState == AK_NoMoreData;
00034         if ( bPreStop )
00035         {   
00036             // Tail not yet finished processing
00037             if ( uTailFramesRemaining > 0  
00038                 || io_pBuffer->uValidFrames > 0 // <-- there are valid frames, so last (maybe partially filled) buffer.
00039                 )
00040             {
00041                 // Not previously in tail, compute tail time
00042                 if (uTailFramesRemaining == AKFXTAILHANDLER_NOTINTAIL  
00043                     || io_pBuffer->uValidFrames > 0 // <- ANY valid frames in the buffer should reset the tail.
00044                     )
00045                 {
00046                     uTailFramesRemaining = in_uTotalTailFrames;
00047                     uTotalTailFrames     = in_uTotalTailFrames;
00048                 }
00049                 // Tail time changed, augment if necessary but preserve where we are so that effect will 
00050                 // still finish when constantly changing this based on RTPC parameters
00051                 else if ( in_uTotalTailFrames > uTotalTailFrames )
00052                 {
00053                     AkUInt32 uFramesElapsed = uTotalTailFrames - uTailFramesRemaining;
00054                     uTailFramesRemaining = in_uTotalTailFrames - uFramesElapsed;
00055                     uTotalTailFrames     = in_uTotalTailFrames;
00056                 }
00057                 // Always full buffers while in tail
00058                 AkUInt32 uNumTailFrames = (AkUInt32)(io_pBuffer->MaxFrames()-io_pBuffer->uValidFrames); 
00059                 uTailFramesRemaining -= AkMin( uTailFramesRemaining, uNumTailFrames ); 
00060                 io_pBuffer->ZeroPadToMaxFrames();
00061                 if ( uTailFramesRemaining > 0 )
00062                     io_pBuffer->eState = AK_DataReady;
00063             }
00064         }
00065         else
00066         {
00067             // Reset tail mode for next time if exits tail mode (on bus only)
00068             uTailFramesRemaining = AKFXTAILHANDLER_NOTINTAIL;
00069         }
00070     }
00071 
00072 #ifdef __SPU__
00073 
00074 
00076     AkForceInline void HandleTailChannelPre( AKRESULT in_eAudioBufferState, AkUInt32 in_uTotalTailFrames )
00077     {
00078         bool bPreStop = in_eAudioBufferState == AK_NoMoreData;
00079         if ( bPreStop )
00080         {   
00081             // Tail not yet finished processing
00082             if ( uTailFramesRemaining > 0 )
00083             {
00084                 // Not previously in tail, compute tail time
00085                 if ( uTailFramesRemaining == AKFXTAILHANDLER_NOTINTAIL )
00086                 {
00087                     uTailFramesRemaining = in_uTotalTailFrames;
00088                     uTotalTailFrames     = in_uTotalTailFrames;
00089                 }
00090                 // Tail time changed, augment if necessary but preserve where we are so that effect will 
00091                 // still finish when constanly changing this based on RTPC parameters
00092                 else if ( in_uTotalTailFrames > uTotalTailFrames )
00093                 {
00094                     AkUInt32 uFramesElapsed = uTotalTailFrames - uTailFramesRemaining;
00095                     uTailFramesRemaining = in_uTotalTailFrames - uFramesElapsed;
00096                     uTotalTailFrames     = in_uTotalTailFrames;
00097                 }
00098             }
00099         }
00100         else
00101         {
00102             // Reset tail mode for next time if exits tail mode (on bus only)
00103             uTailFramesRemaining = AKFXTAILHANDLER_NOTINTAIL;
00104         }
00105     }
00106     
00108     AkForceInline void HandleTailChannel( AkAudioBuffer * in_pAudioBuffer, AkReal32 * io_pfChannelData )
00109     {
00110         bool bPreStop = in_pAudioBuffer->eState == AK_NoMoreData;
00111         if ( bPreStop && (uTailFramesRemaining > 0) )
00112         {   
00113             // Always full buffers while in tail
00114             AkUInt32 uNumTailFrames = (AkUInt32)(in_pAudioBuffer->MaxFrames()-in_pAudioBuffer->uValidFrames); 
00115             AkZeroMemLarge( io_pfChannelData + in_pAudioBuffer->uValidFrames, uNumTailFrames * sizeof(AkReal32) );
00116             in_pAudioBuffer->uValidFrames = in_pAudioBuffer->MaxFrames();
00117         }
00118     }
00119 
00121     AkForceInline void HandleTailChannelPost( AkAudioBuffer * io_pBuffer )
00122     {
00123         bool bPreStop = io_pBuffer->eState == AK_NoMoreData;
00124         if ( bPreStop && (uTailFramesRemaining > 0) )
00125         {       
00126             uTailFramesRemaining -= AkMin( uTailFramesRemaining, (AkUInt32)(io_pBuffer->MaxFrames()-io_pBuffer->uValidFrames) ); 
00127             if ( uTailFramesRemaining > 0 )
00128                 io_pBuffer->eState = AK_DataReady;  
00129         }
00130     }
00131 #endif
00132 
00133 protected:
00134 
00135     AkUInt32    uTailFramesRemaining; // AKFXTAILHANDLER_NOTINTAIL, otherwise value represents number of frames remaining in tail
00136     AkUInt32    uTotalTailFrames;
00137     
00138 } AK_ALIGN_DMA;
00139 
00140 
00141 
00142 
00143 
00144 #endif // _AKFXTAILHANDLER_H_