devsound/devsoundrefplugin/src/plugin/audio/Mmfimaadpcmtopcm16hwdevice.cpp
author hgs
Fri, 08 Oct 2010 19:43:41 +0100
changeset 1 a9d1c8e49653
parent 0 79dd3e2336a0
permissions -rw-r--r--
2010wk40
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 "MMFAudioCodec.h"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    17
#include <mmf/common/mmfpaniccodes.h>
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    18
#include "MmfImaAdpcmtopcm16hwdevice.h"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    19
#include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh>
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    20
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    21
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    22
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    23
* NewL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    24
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    25
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    26
CMMFImaAdpcmToPcm16CodecHwDevice* CMMFImaAdpcmToPcm16CodecHwDevice::NewL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    27
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    28
	CMMFImaAdpcmToPcm16CodecHwDevice* self=new(ELeave)CMMFImaAdpcmToPcm16CodecHwDevice();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    29
	CleanupStack::PushL(self);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    30
	self->ConstructL();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    31
	CleanupStack::Pop(self);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    32
	return self;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    33
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    34
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    35
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    36
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    37
* ConstructL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    38
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    39
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    40
void CMMFImaAdpcmToPcm16CodecHwDevice::ConstructL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    41
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    42
	iCodec = new (ELeave) CMMFImaAdpcmToPcm16Codec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    43
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    44
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    45
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    46
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    47
* ~CMMFMulawPcm16HwDevice
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    48
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    49
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    50
CMMFImaAdpcmToPcm16CodecHwDevice::~CMMFImaAdpcmToPcm16CodecHwDevice()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    51
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    52
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    53
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    54
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    55
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    56
* Codec
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    57
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    58
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    59
CMMFSwCodec &CMMFImaAdpcmToPcm16CodecHwDevice::Codec()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    60
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    61
	return *iCodec;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    62
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    63
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    64
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    65
Retrieves a custom interface to the device.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    66
The reference CMMFImaAdpcmToPcm16CodecHwDevice supports one FileBlockLength custom interface,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    67
or else calls two standard (CMMFSwCodecWrapper) custom interfaces,TPlayCustomInterface and TRecordCustomInterface.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    68
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    69
@param	aInterface
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    70
		Interface UID, defined with the custom interface.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    71
		aInterface = KUidCustomInterfaceDevSoundFileBlockLength,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    72
		aInterface = KMmfPlayCustomInterface for TPlayCustomInterface,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    73
		aInterface = KMmfRecordCustomInterface for TRecordCustomInterface.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    74
@return A pointer to the interface implementation, The return value must be cast to the
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    75
		correct type by the user.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    76
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    77
TAny* CMMFImaAdpcmToPcm16CodecHwDevice::CustomInterface(TUid aInterfaceId)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    78
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    79
	if(aInterfaceId == KUidCustomInterfaceDevSoundFileBlockLength)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    80
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    81
		return static_cast<MMMFDevSoundCustomInterfaceFileBlockLength*>(this);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    82
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    83
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    84
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    85
		return CMMFSwCodecWrapper::CustomInterface(aInterfaceId);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    86
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    87
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    88
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    89
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    90
@see CMMFSwCodecWrapper::Start
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    91
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    92
this function sets SampleRate and Channels for CMMFImaAdpcmToPcm16Codec
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    93
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    94
TInt CMMFImaAdpcmToPcm16CodecHwDevice::Start(TDeviceFunc aFuncCmd, TDeviceFlow aFlowCmd)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    95
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    96
	TInt err = static_cast<CMMFImaAdpcmToPcm16Codec*>(iCodec)->Configure(iChannels, iSampleRate, iBlockAlign);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    97
	if (err == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    98
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    99
		err = CMMFSwCodecWrapper::Start(aFuncCmd, aFlowCmd);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   100
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   101
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   102
	return err;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   103
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   104
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   105
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   106
SetFileBlockLength
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   107
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   108
This function sets file's block length for CMMFImaAdpcmToPcm16CodecHwDevice
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   109
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   110
@param aBlockAlign
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   111
       The file's block length 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   112
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   113
void CMMFImaAdpcmToPcm16CodecHwDevice::SetFileBlockLength(TUint aBlockAlign)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   114
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   115
	iBlockAlign = aBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   116
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   117
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   118
CMMFImaAdpcmToPcm16Codec::CMMFImaAdpcmToPcm16Codec()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   119
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   120
	iChannels = 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   121
	iSampleRate = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   122
	iBlockAlign = KImaAdpcmBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   123
	iSamplesPerBlock = KImaAdpcmSamplesPerBlock;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   124
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   125
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   126
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   127
* ProcessL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   128
* @param aSrc
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   129
* @param aDst
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   130
* @pre position of buffer aSrc is 0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   131
* @pre position of buffer aDst is 0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   132
* @pre sufficient bytes in output to consume input
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   133
* @return TCodecProcessResult
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   134
* This function converts IMA ADPCM samples to PCM samples.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   135
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   136
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   137
CMMFSwCodec::TCodecProcessResult CMMFImaAdpcmToPcm16Codec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   138
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   139
	CMMFSwCodec::TCodecProcessResult result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   140
	result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   141
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   142
	//convert from generic CMMFBuffer to CMMFDataBuffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   143
	const CMMFDataBuffer* src = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   144
	CMMFDataBuffer* dst = STATIC_CAST(CMMFDataBuffer*, &aDst);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   145
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   146
	if( !CheckPreconditions( src, dst ) )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   147
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   148
		//[ precondition(s) violation ]
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   149
		User::Leave(KErrArgument);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   150
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   151
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   152
	//calculate how much source is required to fill the destination buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   153
	TUint blocksRemaining = src->Data().Length() / iBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   154
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   155
	//we need to cast away CONST even on the source, as the TClass needs a TUint8*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   156
	TUint8* pSrc = CONST_CAST(TUint8*,src->Data().Ptr());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   157
	TUint8* pDst = CONST_CAST(TUint8*,dst->Data().Ptr());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   158
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   159
	//[ [process full blocks ]
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   160
	TUint dstBytesAdded = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   161
	for( TUint count = 0; count < blocksRemaining; count++ )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   162
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   163
		iImaAdpcmTo16Pcm.Convert(pSrc, pDst, iSamplesPerBlock);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   164
		pSrc += iBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   165
		pDst += (iSamplesPerBlock * sizeof(TInt16));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   166
		dstBytesAdded += (iSamplesPerBlock * sizeof(TInt16));	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   167
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   168
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   169
	result.iCodecProcessStatus = TCodecProcessResult::EProcessComplete;	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   170
	result.iSrcBytesProcessed = blocksRemaining * iBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   171
	result.iDstBytesAdded = dstBytesAdded;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   172
	dst->Data().SetLength(result.iDstBytesAdded);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   173
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   174
	//[ check post conditions
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   175
	__ASSERT_DEBUG( (src->Position() == 0), TMmfAudioCodecPanicsNameSpace::Panic( 	TMmfAudioCodecPanicsNameSpace::EPostConditionViolation ));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   176
	__ASSERT_DEBUG( (dst->Position() == 0), TMmfAudioCodecPanicsNameSpace::Panic( 	TMmfAudioCodecPanicsNameSpace::EPostConditionViolation ));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   177
	TInt r1 = src->Data().Length();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   178
	r1 /= iBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   179
	TInt r2 =  dst->Data().Length();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   180
	r2 /=(iSamplesPerBlock * sizeof(TInt16));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   181
	__ASSERT_DEBUG(  r1== r2, TMmfAudioCodecPanicsNameSpace::Panic(TMmfAudioCodecPanicsNameSpace::EPostConditionViolation ));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   182
	__ASSERT_DEBUG( dst->Data().Length() % 2 == 0, TMmfAudioCodecPanicsNameSpace::Panic( 	TMmfAudioCodecPanicsNameSpace::EPostConditionViolation )); // pcm output
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   183
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   184
	return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   185
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   186
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   187
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   188
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   189
* Preconditions
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   190
* This methos tests the preconditions of the ProcessL method
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   191
* @return TBool ETrue for sucess and EFalse for failure of the preconditions
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   192
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   193
**/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   194
TBool CMMFImaAdpcmToPcm16Codec::CheckPreconditions( const CMMFDataBuffer* aSrcBuffer, CMMFDataBuffer* aDestBuffer )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   195
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   196
	TBool result = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   197
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   198
	if(! aSrcBuffer )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   199
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   200
		return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   201
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   202
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   203
	if( ! aDestBuffer )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   204
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   205
		return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   206
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   207
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   208
	// Check position of src and dest are 0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   209
	if( aSrcBuffer->Position() )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   210
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   211
		return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   212
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   213
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   214
	// Check position of src and dest are 0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   215
	if( aDestBuffer->Position() )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   216
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   217
		return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   218
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   219
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   220
	// check there are sufficient bytes in the output to consume the input
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   221
	const TUint KTempBufferSize = iSamplesPerBlock * 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   222
    TInt numInputSubFrames  = aSrcBuffer->Data().Length() / iBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   223
	TInt numOutputSubFrames = aDestBuffer->Data().MaxLength() / KTempBufferSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   224
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   225
	//[ we need modulo 1010 bytes on all src frames that are not the last
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   226
	// frame
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   227
	// For the last frame we will code only whole frames and effectively
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   228
	// drop any remaining samples]	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   229
	TBool validInputDataLength = (aSrcBuffer->Data().Length() % iBlockAlign == 0) ;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   230
    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   231
	if( (numInputSubFrames > numOutputSubFrames) ||  // sufficient space in the output for the input
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   232
        (aSrcBuffer->Position() > 0 )  ||                   // position must be zero since we can eat all the data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   233
		(aDestBuffer->Position() > 0 ) ||
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   234
		(!validInputDataLength))                         //position must be zero
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   235
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   236
		return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   237
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   238
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   239
	result = ETrue;  // preconditions have been satisfied
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   240
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   241
	return result;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   242
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   243
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   244
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   245
Configure
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   246
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   247
This function sets file's block length, channels & sample rate.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   248
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   249
@param aChannels
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   250
       The file's number of channels
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   251
@param aSampleRate
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   252
       The file's sample rate 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   253
@param aBlockAlign
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   254
       The file's block length 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   255
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   256
TInt CMMFImaAdpcmToPcm16Codec::Configure(TUint aChannels, TUint aSampleRate, TUint aBlockAlign)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   257
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   258
	iChannels = aChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   259
	iSampleRate = aSampleRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   260
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   261
	if (aBlockAlign < 256)	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   262
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   263
		switch (iSampleRate * iChannels)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   264
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   265
			case 8000: // fall through, same as 11025
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   266
			case 11025:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   267
			case 16000:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   268
				iBlockAlign = 256;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   269
				break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   270
			case 22050:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   271
				iBlockAlign = 512;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   272
				break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   273
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   274
			case 44100:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   275
				iBlockAlign = 1024;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   276
				break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   277
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   278
			case 88200:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   279
				iBlockAlign = 2048;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   280
				break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   281
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   282
			default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   283
				return KErrArgument;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   284
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   285
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   286
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   287
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   288
		iBlockAlign = aBlockAlign;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   289
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   290
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   291
	const TUint KImaAdpcmBitsPerSample = 4;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   292
	iSamplesPerBlock = (iBlockAlign - 4 * iChannels) * 8 / (KImaAdpcmBitsPerSample * iChannels) + 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   293
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   294
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   295
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   296
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   297
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   298
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   299
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   300
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   301