devsound/devsoundrefplugin/src/plugin/audio/mmfpcm16ToImaAdpcm.cpp
changeset 0 79dd3e2336a0
equal deleted inserted replaced
-1:000000000000 0:79dd3e2336a0
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "mmfpcm16ToImaAdpcm.h"
       
    17 
       
    18 /**
       
    19 *
       
    20 * NewL
       
    21 *
       
    22 */
       
    23 CMMFPcm16ToImaAdpcmHwDevice* CMMFPcm16ToImaAdpcmHwDevice::NewL()
       
    24 	{
       
    25 	CMMFPcm16ToImaAdpcmHwDevice* self=new(ELeave) CMMFPcm16ToImaAdpcmHwDevice();
       
    26 	CleanupStack::PushL(self);
       
    27 	self->ConstructL();
       
    28 	CleanupStack::Pop(self);
       
    29 	return self;
       
    30 	}
       
    31 
       
    32 /**
       
    33 *
       
    34 * ~CMMFPcm16ToAlawHwDevice
       
    35 *
       
    36 */
       
    37 CMMFPcm16ToImaAdpcmHwDevice::~CMMFPcm16ToImaAdpcmHwDevice()
       
    38 	{
       
    39 	}
       
    40 
       
    41 /**
       
    42 *
       
    43 * ConstructL
       
    44 *
       
    45 */
       
    46 void CMMFPcm16ToImaAdpcmHwDevice::ConstructL()
       
    47 	{
       
    48 	iCodec = new (ELeave) CMMFPcm16ToImaAdpcmCodec();
       
    49 	}
       
    50 
       
    51 /**
       
    52 *
       
    53 * Codec
       
    54 *
       
    55 */
       
    56 CMMFSwCodec &CMMFPcm16ToImaAdpcmHwDevice::Codec()
       
    57 	{
       
    58 	return *iCodec;
       
    59 	}
       
    60 
       
    61 /**
       
    62 *
       
    63 * ResetL
       
    64 *
       
    65 */
       
    66 void CMMFPcm16ToImaAdpcmCodec::ResetL()
       
    67 	{
       
    68 	//Reset the actual codec
       
    69 	TMMFImaAdpcmCodecState state;
       
    70 	state.iIndex = 0;
       
    71 	state.iPredicted = 0;
       
    72 	iPcm16ToImaAdpcm.SetState(state);
       
    73 	}
       
    74 	
       
    75 /**
       
    76 *
       
    77 * ProcessL
       
    78 * @param aSrc src buffer
       
    79 * @param aDst destination buffer
       
    80 * @return CMMFSwCodec::TCodecProcessResult
       
    81 *  This function converts PCM samples to IMA ADPCM samples in
       
    82 *  blocks of KImaAdpcmBlockAlign (256) bytes. 1010 source 
       
    83 *  bytes are required to fill a 256 byte block.
       
    84 * @pre if last buffer and src contains < 1010 bytes discard input
       
    85 * This function throws away the last buffer if it contains < 1010 bytes
       
    86 * (ie we must have sufficient data to process an entire frame )
       
    87 * All other src buffers must contain
       
    88 * All destination buffer must contain
       
    89 *
       
    90 **/
       
    91 CMMFSwCodec::TCodecProcessResult CMMFPcm16ToImaAdpcmCodec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
       
    92 	{
       
    93 	CMMFSwCodec::TCodecProcessResult result;
       
    94 	result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete;
       
    95 	
       
    96 	//convert from generic CMMFBuffer to CMMFDataBuffer
       
    97 	const CMMFDataBuffer* source = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
       
    98 	CMMFDataBuffer* destination  = STATIC_CAST(CMMFDataBuffer*, &aDst);
       
    99 	
       
   100 	//[ source and destination must not be null ]
       
   101 	if( !source || !destination )
       
   102 		User::Leave( KErrArgument );
       
   103 	
       
   104 	//[ check preconditions ]
       
   105 	if( !BuffersStatus( source, destination ))
       
   106 		{
       
   107 		User::Leave( KErrArgument );
       
   108 		}
       
   109 	
       
   110 	//[ code the buffers ]
       
   111 	ProcessBuffers( *source, *destination, result );
       
   112 	
       
   113 	return result;	
       
   114 	}
       
   115 
       
   116 /**
       
   117 *
       
   118 * ProcessBuffers
       
   119 * @param aSource
       
   120 * @param aDestination
       
   121 * @param aResult 
       
   122 * all we have to do is find out how many source frames there 
       
   123 * are to process and process them
       
   124 * finally returning process complete and fillin the status of the result
       
   125 *
       
   126 **/
       
   127 void CMMFPcm16ToImaAdpcmCodec::ProcessBuffers(const CMMFDataBuffer& aSource, CMMFDataBuffer& aDestination, CMMFSwCodec::TCodecProcessResult& aResult )
       
   128 	{
       
   129 	//[ calculate how many full buffers are to be processed ]
       
   130     const TUint srcLen    = aSource.Data().Length();
       
   131     TInt numFullSrcFrames = srcLen/KSourceFrameSize;
       
   132     
       
   133 	TUint8* pSrc = const_cast<TUint8*>(aSource.Data().Ptr());
       
   134 	TUint8* pDst = const_cast<TUint8*>(aDestination.Data().Ptr());
       
   135     TInt dstBytesAdded = 0;
       
   136 	// calculate number of pcm samples per source frame
       
   137 	const TInt KSamplesPerFrame = KSourceFrameSize/(sizeof(TInt16)); 
       
   138 	
       
   139 	//[ convert all the buffers ]
       
   140 	for( TInt count = 0; count < numFullSrcFrames; count++ )
       
   141 		{
       
   142 		i16PcmToImaAdpcm.Convert(pSrc, pDst, KSamplesPerFrame );				
       
   143 		pSrc          += KSourceFrameSize;
       
   144 		pDst          += KCodedFrameSize;
       
   145 		dstBytesAdded += KCodedFrameSize;
       
   146 		}
       
   147 	aResult.iSrcBytesProcessed = numFullSrcFrames*KSourceFrameSize;
       
   148 	aResult.iDstBytesAdded = dstBytesAdded;		
       
   149 	aDestination.Data().SetLength( aResult.iDstBytesAdded);
       
   150 	}
       
   151 
       
   152 /**
       
   153 *
       
   154 * BuffersStatus
       
   155 * @param source buffer containing the data to be coded
       
   156 * @param destination buffer containing the coded data
       
   157 * @return TBool EFalse indicates bad buffers
       
   158 *
       
   159 **/
       
   160 TBool CMMFPcm16ToImaAdpcmCodec::BuffersStatus( const CMMFDataBuffer* source, const CMMFDataBuffer* destination )
       
   161 	{
       
   162 	TBool status = EFalse;
       
   163 	
       
   164 	//[ demand source and destination positions are zero ]
       
   165     CMMFDataBuffer* pDst = const_cast<CMMFDataBuffer*>( destination );
       
   166 	if( source->Position() || destination->Position() )
       
   167 		{
       
   168 		return status;
       
   169 		}
       
   170 	
       
   171 	//[ Have we got full buffers ]
       
   172 	TInt sourceBuffers = source->Data().Length()/KSourceFrameSize;
       
   173 	TInt destBuffers   = (pDst->Data().MaxLength())/KCodedFrameSize;
       
   174 	
       
   175 	if( sourceBuffers <= destBuffers )  // the sink can process the source
       
   176 		{
       
   177 		return ETrue;                       // note this precondition has been weakened in line with other codecs
       
   178 		}                                   // such that it can process partially full buffers
       
   179 	                                        // ie you can if you wish use larger buffers than needed and only partially
       
   180 	                                        // fill them. We do however expect all the input to be processed.
       
   181 	return status;
       
   182 	}