os/mm/devsound/devsoundrefplugin/src/plugin/audio/mmfpcm16ToImaAdpcm.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/devsound/devsoundrefplugin/src/plugin/audio/mmfpcm16ToImaAdpcm.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,182 @@
     1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "mmfpcm16ToImaAdpcm.h"
    1.20 +
    1.21 +/**
    1.22 +*
    1.23 +* NewL
    1.24 +*
    1.25 +*/
    1.26 +CMMFPcm16ToImaAdpcmHwDevice* CMMFPcm16ToImaAdpcmHwDevice::NewL()
    1.27 +	{
    1.28 +	CMMFPcm16ToImaAdpcmHwDevice* self=new(ELeave) CMMFPcm16ToImaAdpcmHwDevice();
    1.29 +	CleanupStack::PushL(self);
    1.30 +	self->ConstructL();
    1.31 +	CleanupStack::Pop(self);
    1.32 +	return self;
    1.33 +	}
    1.34 +
    1.35 +/**
    1.36 +*
    1.37 +* ~CMMFPcm16ToAlawHwDevice
    1.38 +*
    1.39 +*/
    1.40 +CMMFPcm16ToImaAdpcmHwDevice::~CMMFPcm16ToImaAdpcmHwDevice()
    1.41 +	{
    1.42 +	}
    1.43 +
    1.44 +/**
    1.45 +*
    1.46 +* ConstructL
    1.47 +*
    1.48 +*/
    1.49 +void CMMFPcm16ToImaAdpcmHwDevice::ConstructL()
    1.50 +	{
    1.51 +	iCodec = new (ELeave) CMMFPcm16ToImaAdpcmCodec();
    1.52 +	}
    1.53 +
    1.54 +/**
    1.55 +*
    1.56 +* Codec
    1.57 +*
    1.58 +*/
    1.59 +CMMFSwCodec &CMMFPcm16ToImaAdpcmHwDevice::Codec()
    1.60 +	{
    1.61 +	return *iCodec;
    1.62 +	}
    1.63 +
    1.64 +/**
    1.65 +*
    1.66 +* ResetL
    1.67 +*
    1.68 +*/
    1.69 +void CMMFPcm16ToImaAdpcmCodec::ResetL()
    1.70 +	{
    1.71 +	//Reset the actual codec
    1.72 +	TMMFImaAdpcmCodecState state;
    1.73 +	state.iIndex = 0;
    1.74 +	state.iPredicted = 0;
    1.75 +	iPcm16ToImaAdpcm.SetState(state);
    1.76 +	}
    1.77 +	
    1.78 +/**
    1.79 +*
    1.80 +* ProcessL
    1.81 +* @param aSrc src buffer
    1.82 +* @param aDst destination buffer
    1.83 +* @return CMMFSwCodec::TCodecProcessResult
    1.84 +*  This function converts PCM samples to IMA ADPCM samples in
    1.85 +*  blocks of KImaAdpcmBlockAlign (256) bytes. 1010 source 
    1.86 +*  bytes are required to fill a 256 byte block.
    1.87 +* @pre if last buffer and src contains < 1010 bytes discard input
    1.88 +* This function throws away the last buffer if it contains < 1010 bytes
    1.89 +* (ie we must have sufficient data to process an entire frame )
    1.90 +* All other src buffers must contain
    1.91 +* All destination buffer must contain
    1.92 +*
    1.93 +**/
    1.94 +CMMFSwCodec::TCodecProcessResult CMMFPcm16ToImaAdpcmCodec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
    1.95 +	{
    1.96 +	CMMFSwCodec::TCodecProcessResult result;
    1.97 +	result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete;
    1.98 +	
    1.99 +	//convert from generic CMMFBuffer to CMMFDataBuffer
   1.100 +	const CMMFDataBuffer* source = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
   1.101 +	CMMFDataBuffer* destination  = STATIC_CAST(CMMFDataBuffer*, &aDst);
   1.102 +	
   1.103 +	//[ source and destination must not be null ]
   1.104 +	if( !source || !destination )
   1.105 +		User::Leave( KErrArgument );
   1.106 +	
   1.107 +	//[ check preconditions ]
   1.108 +	if( !BuffersStatus( source, destination ))
   1.109 +		{
   1.110 +		User::Leave( KErrArgument );
   1.111 +		}
   1.112 +	
   1.113 +	//[ code the buffers ]
   1.114 +	ProcessBuffers( *source, *destination, result );
   1.115 +	
   1.116 +	return result;	
   1.117 +	}
   1.118 +
   1.119 +/**
   1.120 +*
   1.121 +* ProcessBuffers
   1.122 +* @param aSource
   1.123 +* @param aDestination
   1.124 +* @param aResult 
   1.125 +* all we have to do is find out how many source frames there 
   1.126 +* are to process and process them
   1.127 +* finally returning process complete and fillin the status of the result
   1.128 +*
   1.129 +**/
   1.130 +void CMMFPcm16ToImaAdpcmCodec::ProcessBuffers(const CMMFDataBuffer& aSource, CMMFDataBuffer& aDestination, CMMFSwCodec::TCodecProcessResult& aResult )
   1.131 +	{
   1.132 +	//[ calculate how many full buffers are to be processed ]
   1.133 +    const TUint srcLen    = aSource.Data().Length();
   1.134 +    TInt numFullSrcFrames = srcLen/KSourceFrameSize;
   1.135 +    
   1.136 +	TUint8* pSrc = const_cast<TUint8*>(aSource.Data().Ptr());
   1.137 +	TUint8* pDst = const_cast<TUint8*>(aDestination.Data().Ptr());
   1.138 +    TInt dstBytesAdded = 0;
   1.139 +	// calculate number of pcm samples per source frame
   1.140 +	const TInt KSamplesPerFrame = KSourceFrameSize/(sizeof(TInt16)); 
   1.141 +	
   1.142 +	//[ convert all the buffers ]
   1.143 +	for( TInt count = 0; count < numFullSrcFrames; count++ )
   1.144 +		{
   1.145 +		i16PcmToImaAdpcm.Convert(pSrc, pDst, KSamplesPerFrame );				
   1.146 +		pSrc          += KSourceFrameSize;
   1.147 +		pDst          += KCodedFrameSize;
   1.148 +		dstBytesAdded += KCodedFrameSize;
   1.149 +		}
   1.150 +	aResult.iSrcBytesProcessed = numFullSrcFrames*KSourceFrameSize;
   1.151 +	aResult.iDstBytesAdded = dstBytesAdded;		
   1.152 +	aDestination.Data().SetLength( aResult.iDstBytesAdded);
   1.153 +	}
   1.154 +
   1.155 +/**
   1.156 +*
   1.157 +* BuffersStatus
   1.158 +* @param source buffer containing the data to be coded
   1.159 +* @param destination buffer containing the coded data
   1.160 +* @return TBool EFalse indicates bad buffers
   1.161 +*
   1.162 +**/
   1.163 +TBool CMMFPcm16ToImaAdpcmCodec::BuffersStatus( const CMMFDataBuffer* source, const CMMFDataBuffer* destination )
   1.164 +	{
   1.165 +	TBool status = EFalse;
   1.166 +	
   1.167 +	//[ demand source and destination positions are zero ]
   1.168 +    CMMFDataBuffer* pDst = const_cast<CMMFDataBuffer*>( destination );
   1.169 +	if( source->Position() || destination->Position() )
   1.170 +		{
   1.171 +		return status;
   1.172 +		}
   1.173 +	
   1.174 +	//[ Have we got full buffers ]
   1.175 +	TInt sourceBuffers = source->Data().Length()/KSourceFrameSize;
   1.176 +	TInt destBuffers   = (pDst->Data().MaxLength())/KCodedFrameSize;
   1.177 +	
   1.178 +	if( sourceBuffers <= destBuffers )  // the sink can process the source
   1.179 +		{
   1.180 +		return ETrue;                       // note this precondition has been weakened in line with other codecs
   1.181 +		}                                   // such that it can process partially full buffers
   1.182 +	                                        // ie you can if you wish use larger buffers than needed and only partially
   1.183 +	                                        // fill them. We do however expect all the input to be processed.
   1.184 +	return status;
   1.185 +	}