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