1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/src/Plugin/Codec/audio/MMFImaAdStereoPcmToPcm16Codec.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,169 @@
1.4 +/*
1.5 +* Copyright (c) 1997-2002 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +
1.23 +#include "MMFImaAdStereoPcmToPcm16Codec.h"
1.24 +
1.25 +
1.26 +// __________________________________________________________________________
1.27 +// Implementation
1.28 +
1.29 +CMMFCodec* CMMFImaAdStereoPcmPcm16Codec::NewL(TAny* aInitParams)
1.30 + {
1.31 + CMMFImaAdStereoPcmPcm16Codec* self=new(ELeave) CMMFImaAdStereoPcmPcm16Codec();
1.32 + CleanupStack::PushL(self);
1.33 + self->ConstructL(aInitParams);
1.34 + CleanupStack::Pop(self);
1.35 + return STATIC_CAST( CMMFCodec*, self );
1.36 + }
1.37 +
1.38 +CMMFImaAdStereoPcmPcm16Codec::~CMMFImaAdStereoPcmPcm16Codec()
1.39 + {
1.40 + }
1.41 +
1.42 +CMMFImaAdStereoPcmPcm16Codec::CMMFImaAdStereoPcmPcm16Codec() : iImaAdpcmTo16Pcm(2)
1.43 + {
1.44 + }
1.45 +
1.46 +void CMMFImaAdStereoPcmPcm16Codec::ConstructL(TAny* /*aInitParams*/)
1.47 + {
1.48 + iTempSrcBufferPtr = iTempSrcBuffer;
1.49 + iTempSrcBufferCount = 0;
1.50 + }
1.51 +
1.52 +/*************************************************************
1.53 +CMMFImaAdStereoPcmPcm16Codec::ProcessL
1.54 +
1.55 +This function converts IMA ADPCM stereo samples to PCM samples
1.56 +in blocks of KImaAdpcmBlockAlign (256) bytes. 256
1.57 +source bytes are required to fill a 996 byte block.
1.58 +**************************************************************/
1.59 +TCodecProcessResult CMMFImaAdStereoPcmPcm16Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
1.60 + {
1.61 + TCodecProcessResult result;
1.62 + result.iStatus = TCodecProcessResult::EProcessIncomplete;
1.63 +
1.64 + //convert from generic CMMFBuffer to CMMFDataBuffer
1.65 + iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
1.66 + iDst = STATIC_CAST(CMMFDataBuffer*, &aDst);
1.67 +
1.68 + const TUint srcLen = iSrc->Data().Length();
1.69 + const TUint dstMaxLen = iDst->Data().MaxLength();
1.70 + const TUint sourceRemain = srcLen - iSrc->Position();
1.71 +
1.72 + if (dstMaxLen < (KImaAdpcmStereoSamplesPerBlock*4))
1.73 + User::Leave(KErrArgument);
1.74 +
1.75 + //reset data if not a consecutive frame number
1.76 + if ((iSrc->FrameNumber() != iLastFrameNumber) && (iSrc->FrameNumber() != (iLastFrameNumber+1)))
1.77 + {
1.78 + iTempSrcBufferPtr = iTempSrcBuffer;
1.79 + iTempSrcBufferCount = 0;
1.80 + }
1.81 + iLastFrameNumber = iSrc->FrameNumber();
1.82 +
1.83 + TUint dstRemain = (dstMaxLen - iDst->Position());
1.84 + TUint srcToFillTempBuffer = 0;
1.85 +
1.86 + //take account of src to be added to temporary buffer
1.87 + if (iTempSrcBufferCount > 0)
1.88 + {
1.89 + srcToFillTempBuffer = KImaAdpcmBlockAlign - iTempSrcBufferCount;
1.90 +
1.91 + if (srcToFillTempBuffer<sourceRemain) //enough source to fill temporary buffer
1.92 + dstRemain -= (KImaAdpcmStereoSamplesPerBlock*4);
1.93 + else //not enough source to fill the temporary buffer
1.94 + srcToFillTempBuffer = sourceRemain;
1.95 + }
1.96 +
1.97 + //calculate how much source is required to fill the destination buffer
1.98 + TUint blocksRemaining = dstRemain/(KImaAdpcmStereoSamplesPerBlock*4);
1.99 + TUint maxUsableDst = blocksRemaining * KImaAdpcmSamplesPerBlock * 4;
1.100 + TUint srcToUse = blocksRemaining * KImaAdpcmBlockAlign;
1.101 +
1.102 + srcToUse += srcToFillTempBuffer;
1.103 + srcToUse = (srcToUse<sourceRemain ? srcToUse : sourceRemain);
1.104 +
1.105 + //we need to cast away CONST even on the source, as the TClass needs a TUint8*
1.106 + TUint8* pSrc = CONST_CAST(TUint8*,iSrc->Data().Ptr());
1.107 + pSrc += iSrc->Position();
1.108 + TUint8* pDst = CONST_CAST(TUint8*,iDst->Data().Ptr());
1.109 + pDst += iDst->Position();
1.110 +
1.111 + TUint dstBytesAdded = 0;
1.112 + TUint srcLeft = srcToUse;
1.113 +
1.114 + //convert remaining source from previous call to ProcessL
1.115 + if (iTempSrcBufferCount > 0)
1.116 + {
1.117 + //Fill temp buffer from source buffer
1.118 + while((iTempSrcBufferCount < KImaAdpcmBlockAlign) && (srcLeft))
1.119 + {
1.120 + *iTempSrcBufferPtr++ = *pSrc++;
1.121 + iTempSrcBufferCount++;
1.122 + srcLeft--;
1.123 + }
1.124 +
1.125 + if(iTempSrcBufferCount == KImaAdpcmBlockAlign)
1.126 + {
1.127 + //reset
1.128 + iTempSrcBufferCount = 0;
1.129 + iTempSrcBufferPtr = iTempSrcBuffer;
1.130 +
1.131 + iImaAdpcmTo16Pcm.Convert(iTempSrcBufferPtr, pDst, KImaAdpcmStereoSamplesPerBlock);
1.132 +
1.133 + pDst += (KImaAdpcmStereoSamplesPerBlock*4);
1.134 + dstBytesAdded += (KImaAdpcmStereoSamplesPerBlock*4);
1.135 + }
1.136 + }
1.137 +
1.138 + //convert full blocks
1.139 + while (srcLeft >= KImaAdpcmBlockAlign)
1.140 + {
1.141 + iImaAdpcmTo16Pcm.Convert(pSrc, pDst, KImaAdpcmStereoSamplesPerBlock);
1.142 +
1.143 + pSrc += KImaAdpcmBlockAlign;
1.144 + pDst += (KImaAdpcmStereoSamplesPerBlock*4);
1.145 +
1.146 + dstBytesAdded += (KImaAdpcmStereoSamplesPerBlock*4);
1.147 + srcLeft -= KImaAdpcmBlockAlign;
1.148 + }
1.149 +
1.150 + while (srcLeft)
1.151 + {
1.152 + *iTempSrcBufferPtr++ = *pSrc++;
1.153 + iTempSrcBufferCount++;
1.154 + srcLeft--;
1.155 + }
1.156 +
1.157 + //if the source buffer is consumed
1.158 + if ((srcLen == srcToUse + iSrc->Position()))
1.159 + {
1.160 + if (dstBytesAdded < maxUsableDst)
1.161 + result.iStatus = TCodecProcessResult::EDstNotFilled;
1.162 + else
1.163 + result.iStatus = TCodecProcessResult::EProcessComplete;
1.164 + }
1.165 +
1.166 + result.iSrcBytesProcessed = srcToUse;
1.167 + result.iDstBytesAdded = dstBytesAdded;
1.168 +
1.169 + iDst->Data().SetLength( iDst->Position() + result.iDstBytesAdded);
1.170 +
1.171 + return result;
1.172 + }