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