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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "MmfUtilities.h"
17 #include "mmfutilitiespriv.h"
18 #include "mmf/utils/rateconvert.h"
20 const TInt KMaxInt16Bit = 65536 ; //Maximum for a 16bit int
22 EXPORT_C CMMFChannelAndSampleRateConverterFactory::~CMMFChannelAndSampleRateConverterFactory()
28 EXPORT_C CMMFChannelAndSampleRateConverter* CMMFChannelAndSampleRateConverterFactory::CreateConverterL(TInt aFromRate,TInt aFromChannels,
29 TInt aToRate,TInt aToChannels)
31 if(aFromRate<0 || aFromChannels<0 || aToRate<0 || aToChannels<0)
33 User::Leave(KErrArgument);
38 iFromChannels=aFromChannels;
39 iToChannels=aToChannels;
40 return CreateConverterL();
43 EXPORT_C CMMFChannelAndSampleRateConverter* CMMFChannelAndSampleRateConverterFactory::CreateConverterL()
46 &&(iFromRate==iConverter->iFromRate)
47 &&(iToRate==iConverter->iToRate)
48 &&(iFromChannels==iConverter->iFromChannels)
49 &&(iToChannels==iConverter->iToChannels))
55 iConverter = CMMFForwardingChannelAndSampleRateConverter::NewL(iFromRate, iFromChannels, iToRate, iToChannels);
60 // SetRates kept for BC reasons - populates publically visible properties
62 void CMMFChannelAndSampleRateConverter::SetRates(TInt aFromRate,TInt aFromChannels,
63 TInt aToRate,TInt aToChannels)
67 iFromChannels=aFromChannels;
68 iToChannels=aToChannels;
70 iRatio = (TReal)aFromRate / (TReal)aToRate;
72 TInt quotient = (TInt)iRatio;
73 TReal remainder = iRatio - (TReal)quotient;
74 iFraction = quotient * KMaxInt16Bit + (TInt32)(remainder * KMaxInt16Bit);
80 // Forwarding converter - adapt to the implementation in audioutils.
83 CMMFForwardingChannelAndSampleRateConverter* CMMFForwardingChannelAndSampleRateConverter::NewL(TInt aFromRate,
88 CMMFForwardingChannelAndSampleRateConverter* self = new (ELeave) CMMFForwardingChannelAndSampleRateConverter;
89 CleanupStack::PushL(self);
90 self->ConstructL(aFromRate,aFromChannels,aToRate,aToChannels);
91 CleanupStack::Pop(self);
95 CMMFForwardingChannelAndSampleRateConverter::CMMFForwardingChannelAndSampleRateConverter()
99 void CMMFForwardingChannelAndSampleRateConverter::ConstructL(TInt aFromRate,
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);
110 CMMFForwardingChannelAndSampleRateConverter::~CMMFForwardingChannelAndSampleRateConverter()
112 delete iRealConverter;
115 TInt CMMFForwardingChannelAndSampleRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
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();
124 void CMMFForwardingChannelAndSampleRateConverter::Reset()
126 // need to check iRealConverter created. Won't be true during construction
129 iRealConverter->Reset();
133 TUint CMMFForwardingChannelAndSampleRateConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
135 return TUint(iRealConverter->MaxConvertBufferSize(aSrcBufferSize));
139 // Old derivatives of CMMFChannelAndSampleRateConverter. These were previously returned by
140 // CreateConverterL(). Kept for BC, but no longer used by main code.
143 TInt CMMFStereoToStereoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
145 TInt32* aSrc = (TInt32*)aSrcBuffer.Data().Ptr();
146 TInt32* aDst = (TInt32*)aDstBuffer.Data().Ptr();
147 TUint aSamples = aSrcBuffer.Data().Length()/4;
151 TInt32* limit=src+aSamples;
153 // add left over from last buffer
154 TUint index = iIndex;
155 src = aSrc + (index>>16);
161 src = aSrc + (index>>16);
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);
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
174 TInt CMMFMonoToStereoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
176 TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
177 TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
178 TUint aSamples = aSrcBuffer.Data().Length()/2;
182 TInt16* limit=aSrc+aSamples;
184 // add left over from last buffer
185 TUint index = iIndex;
186 src = aSrc + (index>>16);
193 src = aSrc + (index>>16);
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);
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
207 TUint CMMFMonoToStereoRateConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
209 return aSrcBufferSize*2;
214 TInt CMMFMonoToMonoRateConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
216 TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
217 TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
218 TUint aSamples = aSrcBuffer.Data().Length()/2;
222 TInt16* limit=aSrc+aSamples; //*2 ???
224 // add left over from last buffer
225 TUint index = iIndex;
226 src = aSrc + (index>>16);
232 src = aSrc + (index>>16);
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);
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
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)
248 TInt16* aSrc = (TInt16*)aSrcBuffer.Data().Ptr();
249 TInt16* aDst = (TInt16*)aDstBuffer.Data().Ptr();
250 TUint aSamples = aSrcBuffer.Data().Length()/4;
253 TInt16* limit=aSrc+aSamples*2; //because 1 sample = two TInt16s
255 // add left over from last buffer
256 TUint index = iIndex;
257 src = aSrc + (index>>16)*2;
263 *aDst++ = (TInt16)((src[0] + (src[1])) / 2);
265 src = aSrc + (index>>16)*2;
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);
272 // return sample byte count and setup output buffer
273 aDstBuffer.Data().SetLength(length * 2); //adjust length of destination buffer
278 TUint CMMFStereoToMonoRateConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
280 TUint size = aSrcBufferSize/2;
281 size += aSrcBufferSize & 1; //avoid round down error
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)
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++)
293 *aDst++ = (TInt16)((aSrc[0] + (aSrc[1])) / 2);
296 aDstBuffer.Data().SetLength(aSamples*2); //adjust length of destination buffer
300 TUint CMMFStereoToMonoConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
302 TUint size = aSrcBufferSize/2;
303 size += aSrcBufferSize & 1; //avoid round down error
309 TInt CMMFMonoToStereoConverter::Convert(const CMMFDataBuffer& aSrcBuffer, CMMFDataBuffer& aDstBuffer)
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++)
319 aDstBuffer.Data().SetLength(aSamples*4); //adjust length of destination buffer
323 TUint CMMFMonoToStereoConverter::MaxConvertBufferSize(TUint aSrcBufferSize)
325 return aSrcBufferSize*2;