sl@0: /* sl@0: * Copyright (c) 1997-2002 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: sl@0: #include "MMFPcm16ToImaAdPcmCodec.h" sl@0: sl@0: // __________________________________________________________________________ sl@0: // Implementation sl@0: sl@0: CMMFCodec* CMMFPcm16ImaAdPcmCodec::NewL(TAny* aInitParams) sl@0: { sl@0: CMMFPcm16ImaAdPcmCodec* self=new(ELeave) CMMFPcm16ImaAdPcmCodec(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aInitParams); sl@0: CleanupStack::Pop(self); sl@0: return STATIC_CAST( CMMFCodec*, self ); sl@0: } sl@0: sl@0: CMMFPcm16ImaAdPcmCodec::~CMMFPcm16ImaAdPcmCodec() sl@0: { sl@0: } sl@0: sl@0: CMMFPcm16ImaAdPcmCodec::CMMFPcm16ImaAdPcmCodec() : i16PcmToImaAdpcm(1) sl@0: { sl@0: } sl@0: sl@0: void CMMFPcm16ImaAdPcmCodec::ConstructL(TAny* /*aInitParams*/) sl@0: { sl@0: iTempSrcBufferPtr = iTempSrcBuffer; sl@0: iTempSrcBufferCount = 0; sl@0: } sl@0: sl@0: void CMMFPcm16ImaAdPcmCodec::ResetL() sl@0: { sl@0: //Reset the actual codec sl@0: TMMFImaAdpcmCodecStateOld state; sl@0: state.iIndex = 0; sl@0: state.iPredicted = 0; sl@0: i16PcmToImaAdpcm.SetState(state); sl@0: iTempSrcBufferPtr = iTempSrcBuffer; sl@0: iTempSrcBufferCount = 0; sl@0: } sl@0: sl@0: /************************************************************* sl@0: CMMFPcm16ImaAdPcmCodec::ProcessL sl@0: sl@0: This function converts PCM samples to IMA ADPCM samples in sl@0: blocks of KImaAdpcmBlockAlign (256) bytes. 1010 source sl@0: bytes are required to fill a 256 byte block. sl@0: **************************************************************/ sl@0: TCodecProcessResult CMMFPcm16ImaAdPcmCodec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst) sl@0: { sl@0: TCodecProcessResult result; sl@0: result.iStatus = TCodecProcessResult::EProcessIncomplete; sl@0: sl@0: //convert from generic CMMFBuffer to CMMFDataBuffer sl@0: iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc); sl@0: iDst = STATIC_CAST(CMMFDataBuffer*, &aDst); sl@0: sl@0: // If the Destination is set to zero, ensure the Codec is fully reset, sl@0: // as this may be a reposition sl@0: if ((iSrc->FrameNumber() == 0) && (iDst->Position() == 0)) sl@0: { sl@0: ResetL(); sl@0: } sl@0: sl@0: sl@0: const TUint srcLen = iSrc->Data().Length(); sl@0: const TUint dstMaxLen = iDst->Data().MaxLength(); sl@0: const TUint sourceRemain = srcLen - iSrc->Position(); sl@0: sl@0: if (dstMaxLen < KImaAdpcmBlockAlign) sl@0: User::Leave(KErrArgument); sl@0: sl@0: //reset data if not a consecutive frame number sl@0: if ((iSrc->FrameNumber() != iLastFrameNumber) && (iSrc->FrameNumber() != (iLastFrameNumber+1))) sl@0: { sl@0: iTempSrcBufferPtr = iTempSrcBuffer; sl@0: iTempSrcBufferCount = 0; sl@0: } sl@0: iLastFrameNumber = iSrc->FrameNumber(); sl@0: sl@0: TUint dstRemain = (dstMaxLen - iDst->Position()); sl@0: TUint srcToFillTempBuffer = 0; sl@0: sl@0: //take account of src to be added to temporary buffer sl@0: if (iTempSrcBufferCount > 0) sl@0: { sl@0: srcToFillTempBuffer = KImaAdpcmTempBufferSize - iTempSrcBufferCount; sl@0: if (srcToFillTempBufferData().Ptr()); sl@0: pSrc += iSrc->Position(); sl@0: TUint8* pDst = CONST_CAST(TUint8*,iDst->Data().Ptr()); sl@0: pDst += iDst->Position(); sl@0: sl@0: TUint dstBytesAdded = 0; sl@0: TUint srcLeft = srcToUse; sl@0: sl@0: //convert remaining source from previous call to ProcessL sl@0: if (iTempSrcBufferCount > 0) sl@0: { sl@0: //Fill temp buffer from source buffer sl@0: while((iTempSrcBufferCount < KImaAdpcmTempBufferSize) && (srcLeft)) sl@0: { sl@0: *iTempSrcBufferPtr++ = *pSrc++; sl@0: iTempSrcBufferCount++; sl@0: srcLeft--; sl@0: } sl@0: sl@0: if (iTempSrcBufferCount == KImaAdpcmTempBufferSize) sl@0: { sl@0: //reset sl@0: iTempSrcBufferCount = 0; sl@0: iTempSrcBufferPtr = iTempSrcBuffer; sl@0: sl@0: i16PcmToImaAdpcm.Convert(iTempSrcBufferPtr, pDst, KImaAdpcmSamplesPerBlock); sl@0: sl@0: pDst += KImaAdpcmBlockAlign; sl@0: dstBytesAdded += KImaAdpcmBlockAlign; sl@0: } sl@0: } sl@0: sl@0: //convert full blocks sl@0: while (srcLeft >= (KImaAdpcmSamplesPerBlock*2)) sl@0: { sl@0: i16PcmToImaAdpcm.Convert(pSrc, pDst, KImaAdpcmSamplesPerBlock); sl@0: sl@0: pSrc += KImaAdpcmSamplesPerBlock*2; sl@0: pDst += KImaAdpcmBlockAlign; sl@0: sl@0: dstBytesAdded += KImaAdpcmBlockAlign; sl@0: srcLeft -= KImaAdpcmSamplesPerBlock*2; sl@0: } sl@0: sl@0: //save remaining source in iTempSrcBuffer sl@0: while (srcLeft) sl@0: { sl@0: *iTempSrcBufferPtr++ = *pSrc++; sl@0: iTempSrcBufferCount++; sl@0: srcLeft--; sl@0: } sl@0: sl@0: //if the source buffer is consumed sl@0: if ((srcLen == srcToUse + iSrc->Position())) sl@0: { sl@0: if (dstBytesAdded < maxUsableDst) sl@0: result.iStatus = TCodecProcessResult::EDstNotFilled; sl@0: else sl@0: result.iStatus = TCodecProcessResult::EProcessComplete; sl@0: } sl@0: sl@0: result.iSrcBytesProcessed = srcToUse; sl@0: result.iDstBytesAdded = dstBytesAdded; sl@0: sl@0: iDst->Data().SetLength(iDst->Position() + result.iDstBytesAdded); sl@0: sl@0: return result; sl@0: }