os/mm/mmlibs/mmfw/src/server/BaseClasses/Mmfutilities.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) 2002-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 "MmfUtilities.h"
    17 #include "mmfutilitiespriv.h"
    18 #include "mmf/utils/rateconvert.h"
    19 
    20 const TInt KMaxInt16Bit = 65536 ; //Maximum for a 16bit int
    21 
    22 EXPORT_C CMMFChannelAndSampleRateConverterFactory::~CMMFChannelAndSampleRateConverterFactory()
    23 	{
    24 	delete iConverter;
    25 	}
    26 
    27 	
    28 EXPORT_C CMMFChannelAndSampleRateConverter* CMMFChannelAndSampleRateConverterFactory::CreateConverterL(TInt aFromRate,TInt aFromChannels,
    29 													   TInt aToRate,TInt aToChannels)
    30 	{
    31 	if(aFromRate<0 || aFromChannels<0 || aToRate<0 || aToChannels<0)
    32 		{
    33 		User::Leave(KErrArgument);
    34 		}
    35 
    36 	iFromRate=aFromRate;
    37 	iToRate=aToRate;
    38 	iFromChannels=aFromChannels;
    39 	iToChannels=aToChannels;
    40 	return CreateConverterL();
    41 	}
    42 
    43 EXPORT_C CMMFChannelAndSampleRateConverter* CMMFChannelAndSampleRateConverterFactory::CreateConverterL()
    44 	{
    45 	if (iConverter
    46 		&&(iFromRate==iConverter->iFromRate)
    47 		&&(iToRate==iConverter->iToRate)
    48 		&&(iFromChannels==iConverter->iFromChannels)
    49 		&&(iToChannels==iConverter->iToChannels))
    50 		return iConverter;
    51 
    52 	delete iConverter;
    53 	iConverter=NULL;
    54 	
    55 	iConverter = CMMFForwardingChannelAndSampleRateConverter::NewL(iFromRate, iFromChannels, iToRate, iToChannels);
    56 
    57 	return iConverter;
    58 	}
    59 	
    60 // SetRates kept for BC reasons - populates publically visible properties
    61 	
    62 void CMMFChannelAndSampleRateConverter::SetRates(TInt aFromRate,TInt aFromChannels,
    63 											 TInt aToRate,TInt aToChannels)
    64 	{
    65 	iFromRate=aFromRate;
    66 	iToRate=aToRate;
    67 	iFromChannels=aFromChannels;
    68 	iToChannels=aToChannels;
    69 
    70 	iRatio = (TReal)aFromRate / (TReal)aToRate;
    71 
    72 	TInt quotient = (TInt)iRatio;
    73 	TReal remainder = iRatio - (TReal)quotient;
    74 	iFraction = quotient * KMaxInt16Bit + (TInt32)(remainder * KMaxInt16Bit);
    75 
    76 	Reset();
    77 	}
    78 	
    79 //
    80 // Forwarding converter - adapt to the implementation in audioutils.
    81 //
    82 	
    83 CMMFForwardingChannelAndSampleRateConverter* CMMFForwardingChannelAndSampleRateConverter::NewL(TInt aFromRate,
    84 																							   TInt aFromChannels,
    85 										    			      								   TInt aToRate,
    86 										    			      								   TInt aToChannels)
    87 	{
    88 	CMMFForwardingChannelAndSampleRateConverter* self = new (ELeave) CMMFForwardingChannelAndSampleRateConverter;
    89 	CleanupStack::PushL(self);
    90 	self->ConstructL(aFromRate,aFromChannels,aToRate,aToChannels);
    91 	CleanupStack::Pop(self);
    92 	return self;
    93 	}
    94 	
    95 CMMFForwardingChannelAndSampleRateConverter::CMMFForwardingChannelAndSampleRateConverter()
    96 	{
    97 	}
    98 
    99 void CMMFForwardingChannelAndSampleRateConverter::ConstructL(TInt aFromRate,
   100 															 TInt aFromChannels,
   101 										    			     TInt aToRate,
   102 										    			     TInt aToChannels)
   103 	{
   104 	SetRates(aFromRate, aFromChannels, aToRate, aToChannels); 
   105 		// delib called before iRealConverter created. Reset() will be no-op.
   106 		// this is preserved solely to keep BC with original API that exposes too much
   107 	iRealConverter = CChannelAndSampleRateConverter::CreateL(aFromRate,aFromChannels,aToRate,aToChannels);
   108 	}
   109 	
   110 CMMFForwardingChannelAndSampleRateConverter::~CMMFForwardingChannelAndSampleRateConverter()
   111 	{
   112 	delete iRealConverter;
   113 	}
   114 	
   115 TInt CMMFForwardingChannelAndSampleRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   116 	{
   117 	TInt ignore = iRealConverter->Convert(aSrcBuffer.Data(), aDstBuffer.Data());
   118 	// CChannelAndSampleRateConverter returns the source length converted
   119 	// while the old API wants the destination generated, so change. 
   120 	TInt result = aDstBuffer.Data().Length(); 
   121 	return result;
   122 	}
   123 	
   124 void CMMFForwardingChannelAndSampleRateConverter::Reset()
   125 	{
   126 	// need to check iRealConverter created. Won't be true during construction
   127 	if (iRealConverter)
   128 		{
   129 		iRealConverter->Reset();
   130 		}
   131 	}
   132 	
   133 TUint CMMFForwardingChannelAndSampleRateConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
   134 	{
   135 	return TUint(iRealConverter->MaxConvertBufferSize(aSrcBufferSize));
   136 	}
   137 	
   138 //
   139 // Old derivatives of CMMFChannelAndSampleRateConverter. These were previously returned by
   140 // CreateConverterL(). Kept for BC, but no longer used by main code.
   141 //
   142 
   143 TInt CMMFStereoToStereoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   144 	{
   145 	TInt32* aSrc = (TInt32*)aSrcBuffer.Data().Ptr();
   146 	TInt32* aDst = (TInt32*)aDstBuffer.Data().Ptr();
   147 	TUint aSamples = aSrcBuffer.Data().Length()/4;
   148 
   149 	TInt32* src = aSrc;
   150 	TInt32* dst = aDst;
   151 	TInt32* limit=src+aSamples;
   152 	
   153 	// add left over from last buffer
   154 	TUint index = iIndex;
   155 	src = aSrc + (index>>16);
   156 
   157 	while(src<limit)
   158 		{
   159 		*dst++ = *src;
   160 		index += iFraction;
   161 		src = aSrc + (index>>16);
   162 		}
   163 	
   164 	// get amount by which index exceeded end of buffer
   165 	// so that we can add it back to start of next buffer
   166 	iIndex = index - (aSamples << 16);
   167 
   168 	// return sample byte count and setup output buffer
   169 	TInt length = (dst-(TInt32*)aDst)*4;	//dealing with 32bit values so multiply by 4 for bytes
   170 	aDstBuffer.Data().SetLength(length); //adjust length of destination buffer
   171 	return (length);
   172 	}	
   173 
   174 TInt CMMFMonoToStereoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   175 	{
   176 	TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
   177 	TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
   178 	TUint aSamples = aSrcBuffer.Data().Length()/2;
   179 
   180 	TInt16* src = aSrc;
   181 	TInt16* dst = aDst;
   182 	TInt16* limit=aSrc+aSamples;
   183 
   184 	// add left over from last buffer
   185 	TUint index = iIndex;
   186 	src = aSrc + (index>>16);
   187 
   188 	while(src<limit)
   189 		{
   190 		*dst++ = *src;
   191 		*dst++ = *src;
   192 		index += iFraction;
   193 		src = aSrc + (index>>16);
   194 		}
   195 
   196 	// get amount by which index exceeded end of buffer
   197 	// so that we can add it back to start of next buffer
   198 	iIndex = index - (aSamples << 16);
   199 
   200 	// return sample byte count and setup output buffer
   201 	TInt length = (dst-aDst) * 2;		// size in bytes
   202 	aDstBuffer.Data().SetLength(length); //adjust length of destination buffer
   203 	return (length);
   204 	}	
   205 	
   206 
   207 TUint CMMFMonoToStereoRateConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
   208 	{
   209 	return aSrcBufferSize*2;
   210 	}
   211 
   212 
   213 
   214 TInt CMMFMonoToMonoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   215 	{
   216 	TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
   217 	TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
   218 	TUint aSamples = aSrcBuffer.Data().Length()/2;
   219 
   220 	TInt16* src = aSrc;
   221 	TInt16* dst = aDst;
   222 	TInt16* limit=aSrc+aSamples; //*2 ???
   223 
   224 	// add left over from last buffer
   225 	TUint index = iIndex;
   226 	src = aSrc + (index>>16);
   227 
   228 	while(src<limit)
   229 		{
   230   		*dst++ = *src;
   231 		index += iFraction;
   232 		src = aSrc + (index>>16);
   233 		}
   234 
   235 	// get amount by which index exceeded end of buffer
   236 	// so that we can add it back to start of next buffer
   237 	iIndex = index - (aSamples << 16);
   238 
   239 	// return sample byte count and setup output buffer
   240 	TInt length = (dst-aDst)*2;			// size in bytes
   241 	aDstBuffer.Data().SetLength(length); //adjust length of destination buffer
   242 	return (length);
   243 	}	
   244 
   245 //This method takes the left and right sample of interleaved PCM and sums it, then divides by 2
   246 TInt CMMFStereoToMonoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   247 	{
   248 	TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
   249 	TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
   250 	TUint aSamples = aSrcBuffer.Data().Length()/4;
   251 
   252 	TInt16* src = aSrc;
   253 	TInt16* limit=aSrc+aSamples*2;	//because 1 sample = two TInt16s
   254 
   255 	// add left over from last buffer
   256 	TUint index = iIndex;
   257 	src = aSrc + (index>>16)*2;
   258 
   259 	TInt length = 0;
   260 
   261 	while(src<limit)
   262 		{
   263 		*aDst++ = (TInt16)((src[0] + (src[1])) / 2);
   264 		index += iFraction;
   265 		src = aSrc + (index>>16)*2;
   266 		length++;
   267 		}
   268 	// get amount by which index exceeded end of buffer
   269 	// so that we can add it back to start of next buffer
   270 	iIndex = index - (aSamples << 16);
   271 
   272 	// return sample byte count and setup output buffer
   273 	aDstBuffer.Data().SetLength(length * 2); //adjust length of destination buffer
   274 	return (length);
   275 	}
   276 
   277 
   278 TUint CMMFStereoToMonoRateConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
   279 	{
   280 	TUint size = aSrcBufferSize/2;
   281 	size += aSrcBufferSize & 1; //avoid round down error
   282 	return size;
   283 	}
   284 
   285 //This method takes the left and right sample of interleaved PCM and sums it, then divides by 2
   286 TInt CMMFStereoToMonoConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   287 	{
   288 	TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
   289 	TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
   290 	TUint aSamples = aSrcBuffer.Data().Length()/4;
   291 	for (TUint i=0;i<aSamples;i++)
   292 		{
   293 		*aDst++ = (TInt16)((aSrc[0] + (aSrc[1])) / 2);
   294 		aSrc+=2;
   295 		}
   296 	aDstBuffer.Data().SetLength(aSamples*2); //adjust length of destination buffer
   297 	return aSamples*2;
   298 	}	
   299 
   300 TUint CMMFStereoToMonoConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
   301 	{
   302 	TUint size = aSrcBufferSize/2;
   303 	size += aSrcBufferSize & 1; //avoid round down error
   304 	return size;
   305 	}
   306 
   307 
   308 
   309 TInt CMMFMonoToStereoConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
   310 	{
   311 	TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
   312 	TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
   313 	TUint aSamples = aSrcBuffer.Data().Length()/2;
   314 	for (TUint i=0;i<aSamples;i++)
   315 		{
   316 		*aDst++ = *aSrc;
   317 		*aDst++ = *aSrc++;
   318 		}
   319 	aDstBuffer.Data().SetLength(aSamples*4); //adjust length of destination buffer
   320 	return aSamples*4;
   321 	}	
   322 
   323 TUint CMMFMonoToStereoConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
   324 	{
   325 	return aSrcBufferSize*2;
   326 	}
   327 
   328 
   329 
   330 
   331