sl@0
|
1 |
// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// * INCLUDE FILES:
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
|
sl@0
|
18 |
// Standard includes
|
sl@0
|
19 |
#include <e32std.h>
|
sl@0
|
20 |
|
sl@0
|
21 |
// Private Generic Library includes
|
sl@0
|
22 |
#include <ecom/implementationproxy.h>
|
sl@0
|
23 |
#include "GSM610.H"
|
sl@0
|
24 |
#include "gsm610fr.h"
|
sl@0
|
25 |
#include <mmf/plugin/mmfcodecimplementationuids.hrh>
|
sl@0
|
26 |
|
sl@0
|
27 |
|
sl@0
|
28 |
//*******************************************************************
|
sl@0
|
29 |
//* GSM Codec to 16 bit PCM Class:
|
sl@0
|
30 |
//*******************************************************************
|
sl@0
|
31 |
|
sl@0
|
32 |
// __________________________________________________________________________
|
sl@0
|
33 |
// Implementation
|
sl@0
|
34 |
|
sl@0
|
35 |
CMMFCodec* CMMFGsmTo16PcmCodec::NewL(TAny* aInitParams)
|
sl@0
|
36 |
{
|
sl@0
|
37 |
CMMFGsmTo16PcmCodec* self=new(ELeave) CMMFGsmTo16PcmCodec();
|
sl@0
|
38 |
CleanupStack::PushL(self);
|
sl@0
|
39 |
self->ConstructL(aInitParams);
|
sl@0
|
40 |
CleanupStack::Pop(self);
|
sl@0
|
41 |
return STATIC_CAST( CMMFCodec*, self );
|
sl@0
|
42 |
}
|
sl@0
|
43 |
|
sl@0
|
44 |
CMMFGsmTo16PcmCodec::~CMMFGsmTo16PcmCodec()
|
sl@0
|
45 |
{
|
sl@0
|
46 |
delete iCodecPtr;
|
sl@0
|
47 |
}
|
sl@0
|
48 |
|
sl@0
|
49 |
CMMFGsmTo16PcmCodec::CMMFGsmTo16PcmCodec()
|
sl@0
|
50 |
{
|
sl@0
|
51 |
|
sl@0
|
52 |
}
|
sl@0
|
53 |
|
sl@0
|
54 |
void CMMFGsmTo16PcmCodec::ConstructL(TAny* /*aInitParams*/)
|
sl@0
|
55 |
{
|
sl@0
|
56 |
iCodecPtr = new (ELeave) CGsmTo16PcmWavCodec();
|
sl@0
|
57 |
iCodecPtr->ConstructL();
|
sl@0
|
58 |
iLastFrameNumber = 0;
|
sl@0
|
59 |
}
|
sl@0
|
60 |
|
sl@0
|
61 |
|
sl@0
|
62 |
//handy porting stuff from old MS
|
sl@0
|
63 |
|
sl@0
|
64 |
//to convert from a CMMFBuffer to a TUint8*
|
sl@0
|
65 |
//--- iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
|
sl@0
|
66 |
//--- TUint8* pSrc = CONST_CAST(TUint8*,iSrc->Data().Ptr());
|
sl@0
|
67 |
|
sl@0
|
68 |
//to convert from a CMMFBuffer to a TMMFPtr8 (TMMFPtr8)
|
sl@0
|
69 |
//--- TMMFPtr8 codecSrc;
|
sl@0
|
70 |
//--- iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
|
sl@0
|
71 |
//--- codecSrc.Set(iSrc->Data());
|
sl@0
|
72 |
|
sl@0
|
73 |
|
sl@0
|
74 |
TCodecProcessResult CMMFGsmTo16PcmCodec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
|
sl@0
|
75 |
{
|
sl@0
|
76 |
|
sl@0
|
77 |
TMMFPtr8 codecSrc;
|
sl@0
|
78 |
TMMFPtr8 codecDst;
|
sl@0
|
79 |
|
sl@0
|
80 |
TCodecProcessResult result;
|
sl@0
|
81 |
result.iStatus = TCodecProcessResult::EProcessIncomplete;
|
sl@0
|
82 |
|
sl@0
|
83 |
//convert from generic CMMFBuffer to CMMFDataBuffer
|
sl@0
|
84 |
iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
|
sl@0
|
85 |
iDst = STATIC_CAST(CMMFDataBuffer*, &aDst);
|
sl@0
|
86 |
|
sl@0
|
87 |
const TUint srcLen = iSrc->Data().Length();
|
sl@0
|
88 |
const TUint dstMaxLen = iDst->Data().MaxLength() - iDst->Position();
|
sl@0
|
89 |
|
sl@0
|
90 |
// This is checked only on the first frame.
|
sl@0
|
91 |
if ((dstMaxLen < KPcmInputFrameSize) && (iSrc->FrameNumber() <= 1))
|
sl@0
|
92 |
User::Leave(KErrArgument);
|
sl@0
|
93 |
|
sl@0
|
94 |
TUint dstAccumulator = 0;
|
sl@0
|
95 |
TUint srcAccumulator = 0;
|
sl@0
|
96 |
|
sl@0
|
97 |
TUint dstAdded = KPcmInputFrameSize;
|
sl@0
|
98 |
TUint srcAdded = 0;
|
sl@0
|
99 |
|
sl@0
|
100 |
if ((iSrc->FrameNumber() == 1) && (iSrc->Position() == 0))
|
sl@0
|
101 |
{
|
sl@0
|
102 |
iCodecPtr->ResetAllL();
|
sl@0
|
103 |
}
|
sl@0
|
104 |
|
sl@0
|
105 |
if ((iLastFrameNumber != 0) && (iSrc->FrameNumber() <= 1) &&
|
sl@0
|
106 |
(iDst->Position() == 0) && (iSrc->Position() == 0))
|
sl@0
|
107 |
{
|
sl@0
|
108 |
iCodecPtr->ResetAllL();
|
sl@0
|
109 |
}
|
sl@0
|
110 |
|
sl@0
|
111 |
iLastFrameNumber = iSrc->FrameNumber();
|
sl@0
|
112 |
|
sl@0
|
113 |
TInt srcShift = iSrc->Position();
|
sl@0
|
114 |
TInt dstShift = iDst->Position(); // Add offset for Dst Buffer
|
sl@0
|
115 |
|
sl@0
|
116 |
while ((dstAccumulator < dstMaxLen) && (dstAdded))
|
sl@0
|
117 |
{
|
sl@0
|
118 |
//this code chops the data buffer into 65 (or less) byte chunks
|
sl@0
|
119 |
codecSrc.Set(iSrc->Data());
|
sl@0
|
120 |
codecDst.Set(iDst->Data());
|
sl@0
|
121 |
codecDst.SetLength(iDst->Data().MaxLength());
|
sl@0
|
122 |
//move the data to the end of the last bit of the buffer processed
|
sl@0
|
123 |
codecSrc.Shift(srcAccumulator + srcShift);
|
sl@0
|
124 |
|
sl@0
|
125 |
//codecDst.Shift(dstAccumulator);
|
sl@0
|
126 |
codecDst.Shift(dstAccumulator + dstShift); // Add offset for Dst Buffer
|
sl@0
|
127 |
|
sl@0
|
128 |
iCodecPtr->ProcessL(&codecSrc, &codecDst);
|
sl@0
|
129 |
|
sl@0
|
130 |
dstAdded = codecDst.Length();
|
sl@0
|
131 |
srcAdded = codecSrc.Length();
|
sl@0
|
132 |
|
sl@0
|
133 |
//rules to trigger a codec reset
|
sl@0
|
134 |
if (dstAdded == KPcmInputFrameSize)
|
sl@0
|
135 |
iCodecPtr->Reset();
|
sl@0
|
136 |
if (srcAdded == 0)
|
sl@0
|
137 |
iCodecPtr->Reset();
|
sl@0
|
138 |
|
sl@0
|
139 |
dstAccumulator += codecDst.Length();
|
sl@0
|
140 |
srcAccumulator += codecSrc.Length();
|
sl@0
|
141 |
|
sl@0
|
142 |
}
|
sl@0
|
143 |
|
sl@0
|
144 |
//iDst->Data().SetLength(dstAccumulator);
|
sl@0
|
145 |
iDst->Data().SetLength(dstAccumulator + dstShift); // Add offset for Dst Buffer
|
sl@0
|
146 |
|
sl@0
|
147 |
result.iSrcBytesProcessed = srcAccumulator;
|
sl@0
|
148 |
result.iDstBytesAdded = dstAccumulator;
|
sl@0
|
149 |
|
sl@0
|
150 |
if (!srcAdded)
|
sl@0
|
151 |
{
|
sl@0
|
152 |
srcAdded = srcAdded;
|
sl@0
|
153 |
}
|
sl@0
|
154 |
|
sl@0
|
155 |
if (result.iSrcBytesProcessed + iSrc->Position() >= srcLen)
|
sl@0
|
156 |
result.iStatus = TCodecProcessResult::EProcessComplete;
|
sl@0
|
157 |
|
sl@0
|
158 |
if (result.iDstBytesAdded < dstMaxLen)
|
sl@0
|
159 |
result.iStatus = TCodecProcessResult::EDstNotFilled;
|
sl@0
|
160 |
|
sl@0
|
161 |
return result;
|
sl@0
|
162 |
}
|
sl@0
|
163 |
|
sl@0
|
164 |
|
sl@0
|
165 |
//*******************************************************************
|
sl@0
|
166 |
//* 16 bit PCM to GSM Codec Class:
|
sl@0
|
167 |
//*******************************************************************
|
sl@0
|
168 |
|
sl@0
|
169 |
// __________________________________________________________________________
|
sl@0
|
170 |
// Implementation
|
sl@0
|
171 |
|
sl@0
|
172 |
CMMFCodec* CMMF16PcmToGsmCodec::NewL(TAny* aInitParams)
|
sl@0
|
173 |
{
|
sl@0
|
174 |
CMMF16PcmToGsmCodec* self=new(ELeave) CMMF16PcmToGsmCodec();
|
sl@0
|
175 |
CleanupStack::PushL(self);
|
sl@0
|
176 |
self->ConstructL(aInitParams);
|
sl@0
|
177 |
CleanupStack::Pop(self);
|
sl@0
|
178 |
return STATIC_CAST( CMMFCodec*, self );
|
sl@0
|
179 |
}
|
sl@0
|
180 |
|
sl@0
|
181 |
CMMF16PcmToGsmCodec::~CMMF16PcmToGsmCodec()
|
sl@0
|
182 |
{
|
sl@0
|
183 |
delete iCodecPtr;
|
sl@0
|
184 |
}
|
sl@0
|
185 |
|
sl@0
|
186 |
CMMF16PcmToGsmCodec::CMMF16PcmToGsmCodec()
|
sl@0
|
187 |
{
|
sl@0
|
188 |
|
sl@0
|
189 |
}
|
sl@0
|
190 |
|
sl@0
|
191 |
void CMMF16PcmToGsmCodec::ConstructL(TAny* /*aInitParams*/)
|
sl@0
|
192 |
{
|
sl@0
|
193 |
iCodecPtr = new (ELeave) C16PcmToGsmWavCodec();
|
sl@0
|
194 |
iCodecPtr->ConstructL();
|
sl@0
|
195 |
iLastFrameNumber = 0;
|
sl@0
|
196 |
}
|
sl@0
|
197 |
|
sl@0
|
198 |
//handy porting stuff from old MS
|
sl@0
|
199 |
|
sl@0
|
200 |
//to convert from a CMMFBuffer to a TUint8*
|
sl@0
|
201 |
//--- iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
|
sl@0
|
202 |
//--- TUint8* pSrc = CONST_CAST(TUint8*,iSrc->Data().Ptr());
|
sl@0
|
203 |
|
sl@0
|
204 |
//to convert from a CMMFBuffer to a TMMFPtr8 (TMMFPtr8)
|
sl@0
|
205 |
//--- TMMFPtr8 codecSrc;
|
sl@0
|
206 |
//--- iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
|
sl@0
|
207 |
//--- codecSrc.Set(iSrc->Data());
|
sl@0
|
208 |
|
sl@0
|
209 |
|
sl@0
|
210 |
|
sl@0
|
211 |
TCodecProcessResult CMMF16PcmToGsmCodec::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
|
sl@0
|
212 |
{
|
sl@0
|
213 |
|
sl@0
|
214 |
TMMFPtr8 codecSrc;
|
sl@0
|
215 |
TMMFPtr8 codecDst;
|
sl@0
|
216 |
|
sl@0
|
217 |
|
sl@0
|
218 |
TCodecProcessResult result;
|
sl@0
|
219 |
result.iStatus = TCodecProcessResult::EProcessIncomplete;
|
sl@0
|
220 |
|
sl@0
|
221 |
//convert from generic CMMFBuffer to CMMFDataBuffer
|
sl@0
|
222 |
iSrc = STATIC_CAST(const CMMFDataBuffer*, &aSrc);
|
sl@0
|
223 |
iDst = STATIC_CAST(CMMFDataBuffer*, &aDst);
|
sl@0
|
224 |
|
sl@0
|
225 |
//const TUint srcLen = iSrc->Data().Length();
|
sl@0
|
226 |
TUint srcLen = iSrc->Data().Length();
|
sl@0
|
227 |
const TUint dstMaxLen = iDst->Data().MaxLength() - iDst->Position();
|
sl@0
|
228 |
|
sl@0
|
229 |
// This is checked only on the first frame.
|
sl@0
|
230 |
if ((dstMaxLen < KGsmEncodedFrameSize) && (iSrc->FrameNumber() <= 1))
|
sl@0
|
231 |
User::Leave(KErrArgument);
|
sl@0
|
232 |
|
sl@0
|
233 |
|
sl@0
|
234 |
TUint dstAccumulator = 0;
|
sl@0
|
235 |
TUint srcAccumulator = iSrc->Position();
|
sl@0
|
236 |
|
sl@0
|
237 |
TUint dstAdded = 0;
|
sl@0
|
238 |
TUint srcAdded = 0;
|
sl@0
|
239 |
|
sl@0
|
240 |
if ((iSrc->FrameNumber() == 1) && (iSrc->Position() == 0))
|
sl@0
|
241 |
{
|
sl@0
|
242 |
iCodecPtr->ResetAllL();
|
sl@0
|
243 |
}
|
sl@0
|
244 |
|
sl@0
|
245 |
if ((iLastFrameNumber != 0) && (iSrc->FrameNumber() <= 1) &&
|
sl@0
|
246 |
(iDst->Position() == 0) && (iSrc->Position() == 0))
|
sl@0
|
247 |
{
|
sl@0
|
248 |
iCodecPtr->ResetAllL();
|
sl@0
|
249 |
}
|
sl@0
|
250 |
|
sl@0
|
251 |
iLastFrameNumber = iSrc->FrameNumber();
|
sl@0
|
252 |
|
sl@0
|
253 |
// TInt dstShift = iSrc->Position();
|
sl@0
|
254 |
TInt dstShift = iDst->Position();
|
sl@0
|
255 |
|
sl@0
|
256 |
while (srcAccumulator < srcLen)
|
sl@0
|
257 |
{
|
sl@0
|
258 |
// Create a copy of iSrc and pass that to the Codec as the Codec,
|
sl@0
|
259 |
// for some reason, alters the source(iSrc).
|
sl@0
|
260 |
// Easier (& quicker) to make copy than to fix the actual Codec as the code is
|
sl@0
|
261 |
// old and the GSM610 Codec is already quite slow.
|
sl@0
|
262 |
HBufC* copySrc = HBufC::NewLC(srcLen);
|
sl@0
|
263 |
TPtr8 copySrcPtr((TUint8*)copySrc->Ptr(), srcLen, srcLen);
|
sl@0
|
264 |
copySrcPtr.Copy((TUint8*)iSrc->Data().Ptr(), srcLen);
|
sl@0
|
265 |
|
sl@0
|
266 |
//this code chops the data buffer into 640 (or less) byte chunks
|
sl@0
|
267 |
codecSrc.Set(copySrcPtr/*iSrc->Data()*/);
|
sl@0
|
268 |
|
sl@0
|
269 |
//codecSrc.Set(iSrc->Data());
|
sl@0
|
270 |
codecDst.Set(iDst->Data());
|
sl@0
|
271 |
codecDst.SetLength(iDst->Data().MaxLength());
|
sl@0
|
272 |
//move the data to the end of the last bit of the buffer processed
|
sl@0
|
273 |
codecSrc.Shift(srcAccumulator);
|
sl@0
|
274 |
codecDst.Shift(dstAccumulator + dstShift);
|
sl@0
|
275 |
|
sl@0
|
276 |
iCodecPtr->ProcessL(&codecSrc, &codecDst);
|
sl@0
|
277 |
|
sl@0
|
278 |
dstAdded = codecDst.Length();
|
sl@0
|
279 |
srcAdded = codecSrc.Length();
|
sl@0
|
280 |
|
sl@0
|
281 |
//rules to trigger a codec reset
|
sl@0
|
282 |
if ((dstAdded == KGsmEncodedFrameSize) && (srcAdded == KPcmInputFrameSize))
|
sl@0
|
283 |
iCodecPtr->Reset();
|
sl@0
|
284 |
if (srcAdded == 0)
|
sl@0
|
285 |
iCodecPtr->Reset();
|
sl@0
|
286 |
|
sl@0
|
287 |
dstAccumulator += codecDst.Length();
|
sl@0
|
288 |
srcAccumulator += codecSrc.Length();
|
sl@0
|
289 |
|
sl@0
|
290 |
CleanupStack::PopAndDestroy(copySrc);
|
sl@0
|
291 |
|
sl@0
|
292 |
//need to check that we don't process too much of the destination such that it won't fit in the dst buf
|
sl@0
|
293 |
if ((dstAccumulator + KGsmEncodedFrameSize) > dstMaxLen)
|
sl@0
|
294 |
break;
|
sl@0
|
295 |
}
|
sl@0
|
296 |
|
sl@0
|
297 |
iDst->Data().SetLength(dstAccumulator + iDst->Position());
|
sl@0
|
298 |
|
sl@0
|
299 |
result.iSrcBytesProcessed = srcAccumulator;
|
sl@0
|
300 |
result.iDstBytesAdded = dstAccumulator;
|
sl@0
|
301 |
|
sl@0
|
302 |
if (!srcAdded)
|
sl@0
|
303 |
{
|
sl@0
|
304 |
srcAdded = srcAdded;
|
sl@0
|
305 |
}
|
sl@0
|
306 |
|
sl@0
|
307 |
if (result.iSrcBytesProcessed + iSrc->Position() >= srcLen)
|
sl@0
|
308 |
result.iStatus = TCodecProcessResult::EProcessComplete;
|
sl@0
|
309 |
|
sl@0
|
310 |
if (result.iDstBytesAdded < dstMaxLen)
|
sl@0
|
311 |
{ //need to check that there is space remaining in the destination buffer to process more
|
sl@0
|
312 |
//need at least KGsmEncodeFrameSize bytes
|
sl@0
|
313 |
if ((dstMaxLen - result.iDstBytesAdded) >= KGsmEncodedFrameSize)
|
sl@0
|
314 |
result.iStatus = TCodecProcessResult::EDstNotFilled; //still space for more frames
|
sl@0
|
315 |
// else result.iStatus = TCodecProcessResult::EProcessComplete; //can't do anything more with src or dest
|
sl@0
|
316 |
}
|
sl@0
|
317 |
|
sl@0
|
318 |
return result;
|
sl@0
|
319 |
}
|
sl@0
|
320 |
|
sl@0
|
321 |
|
sl@0
|
322 |
|
sl@0
|
323 |
// __________________________________________________________________________
|
sl@0
|
324 |
// Exported proxy for instantiation method resolution
|
sl@0
|
325 |
// Define the interface UIDs
|
sl@0
|
326 |
|
sl@0
|
327 |
|
sl@0
|
328 |
const TImplementationProxy ImplementationTable[] =
|
sl@0
|
329 |
{
|
sl@0
|
330 |
IMPLEMENTATION_PROXY_ENTRY(KMmfUidCodecGSM610ToPCM16, CMMFGsmTo16PcmCodec::NewL),
|
sl@0
|
331 |
IMPLEMENTATION_PROXY_ENTRY(KMmfUidCodecPCM16ToGSM610, CMMF16PcmToGsmCodec::NewL)
|
sl@0
|
332 |
|
sl@0
|
333 |
};
|
sl@0
|
334 |
|
sl@0
|
335 |
|
sl@0
|
336 |
|
sl@0
|
337 |
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
|
sl@0
|
338 |
{
|
sl@0
|
339 |
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
|
sl@0
|
340 |
|
sl@0
|
341 |
return ImplementationTable;
|
sl@0
|
342 |
}
|
sl@0
|
343 |
|
sl@0
|
344 |
|
sl@0
|
345 |
//*******************************************************************
|
sl@0
|
346 |
//* FUNCTION: CGsmTo16PcmWavCodec::CGsmTo16PcmWavCodec
|
sl@0
|
347 |
//* Constructor for GSM to 16 bit PCM Codec.
|
sl@0
|
348 |
//*******************************************************************
|
sl@0
|
349 |
|
sl@0
|
350 |
CGsmTo16PcmWavCodec::CGsmTo16PcmWavCodec()
|
sl@0
|
351 |
{
|
sl@0
|
352 |
|
sl@0
|
353 |
Reset();
|
sl@0
|
354 |
|
sl@0
|
355 |
}
|
sl@0
|
356 |
|
sl@0
|
357 |
|
sl@0
|
358 |
//*******************************************************************
|
sl@0
|
359 |
//* FUNCTION: CGsmTo16PcmWavCodec::~CGsmTo16PcmWavCodec
|
sl@0
|
360 |
//* Destructor for GSM to 16 bit PCM Codec.
|
sl@0
|
361 |
//*******************************************************************
|
sl@0
|
362 |
|
sl@0
|
363 |
CGsmTo16PcmWavCodec::~CGsmTo16PcmWavCodec()
|
sl@0
|
364 |
{
|
sl@0
|
365 |
|
sl@0
|
366 |
delete iGsmDecoder;
|
sl@0
|
367 |
|
sl@0
|
368 |
}
|
sl@0
|
369 |
|
sl@0
|
370 |
|
sl@0
|
371 |
//*******************************************************************
|
sl@0
|
372 |
//* FUNCTION: CGsmTo16PcmWavCodec::ConstructL
|
sl@0
|
373 |
//* Perform 2nd pass of object construction (allocating data on heap).
|
sl@0
|
374 |
//*******************************************************************
|
sl@0
|
375 |
|
sl@0
|
376 |
void CGsmTo16PcmWavCodec::ConstructL()
|
sl@0
|
377 |
{
|
sl@0
|
378 |
iGsmDecoder = new (ELeave) CGSM610FR_Decoder;
|
sl@0
|
379 |
iGsmDecoder->ConstructL();
|
sl@0
|
380 |
iGsmDecoder->StartL();
|
sl@0
|
381 |
|
sl@0
|
382 |
iInBufferCount = 0;
|
sl@0
|
383 |
iOutBufferCount = 0;
|
sl@0
|
384 |
}
|
sl@0
|
385 |
|
sl@0
|
386 |
|
sl@0
|
387 |
//*******************************************************************
|
sl@0
|
388 |
//* FUNCTION: CGsmTo16PcmWavCodec::Reset
|
sl@0
|
389 |
//* Reset the input/output buffer states.
|
sl@0
|
390 |
//*******************************************************************
|
sl@0
|
391 |
|
sl@0
|
392 |
void CGsmTo16PcmWavCodec::Reset()
|
sl@0
|
393 |
{
|
sl@0
|
394 |
iInBufferPtr = iInBuffer;
|
sl@0
|
395 |
iOutBufferPtr = iOutBuffer;
|
sl@0
|
396 |
}
|
sl@0
|
397 |
|
sl@0
|
398 |
|
sl@0
|
399 |
//*******************************************************************
|
sl@0
|
400 |
//* FUNCTION: CGsmTo16PcmWavCodec::Reset
|
sl@0
|
401 |
//* Reset the input/output buffer states.
|
sl@0
|
402 |
//*******************************************************************
|
sl@0
|
403 |
|
sl@0
|
404 |
void CGsmTo16PcmWavCodec::ResetAllL()
|
sl@0
|
405 |
{
|
sl@0
|
406 |
Reset();
|
sl@0
|
407 |
iInBufferCount = 0;
|
sl@0
|
408 |
iOutBufferCount = 0;
|
sl@0
|
409 |
|
sl@0
|
410 |
iGsmDecoder->StartL();
|
sl@0
|
411 |
}
|
sl@0
|
412 |
|
sl@0
|
413 |
|
sl@0
|
414 |
//*******************************************************************
|
sl@0
|
415 |
//* FUNCTION: CGsmTo16PcmWavCodec::ProcessL
|
sl@0
|
416 |
//* Read GSM data (contained in aSrc) and convert it to raw 16 bit
|
sl@0
|
417 |
//* PCM data (contained in aDst).
|
sl@0
|
418 |
//*
|
sl@0
|
419 |
//* NOTE that amount of data contained in input/output buffers
|
sl@0
|
420 |
//* varies, so if there is not enough input data or not enough
|
sl@0
|
421 |
//* room for the output data, then this function must buffer
|
sl@0
|
422 |
//* the data until enough data is received (or removed).
|
sl@0
|
423 |
//*
|
sl@0
|
424 |
//* NOTE that this function only buffers input (or output) data
|
sl@0
|
425 |
//* if there is not enough data (or room for output) available
|
sl@0
|
426 |
//* in the input (output) stream. Otherwise, the data is accessed
|
sl@0
|
427 |
//* directly from the input (output) stream which saves unnecessary
|
sl@0
|
428 |
//* copying of data.
|
sl@0
|
429 |
//*******************************************************************
|
sl@0
|
430 |
|
sl@0
|
431 |
void CGsmTo16PcmWavCodec::ProcessL(TMMFPtr8* aSrc, TMMFPtr8* aDst)
|
sl@0
|
432 |
{
|
sl@0
|
433 |
|
sl@0
|
434 |
TUint8* srcPtr = NULL;
|
sl@0
|
435 |
TUint8* dstPtr = NULL;
|
sl@0
|
436 |
const TUint srcLen = aSrc->Length();
|
sl@0
|
437 |
const TUint dstLen = aDst->Length();
|
sl@0
|
438 |
TInt srcUsed = 0;
|
sl@0
|
439 |
TInt dstUsed = 0;
|
sl@0
|
440 |
|
sl@0
|
441 |
|
sl@0
|
442 |
//**************************************************
|
sl@0
|
443 |
//* Get Input Data: Only want to process more input
|
sl@0
|
444 |
//* data if the output buffer is empty.
|
sl@0
|
445 |
//**************************************************
|
sl@0
|
446 |
|
sl@0
|
447 |
if ( iOutBufferCount == 0 )
|
sl@0
|
448 |
{
|
sl@0
|
449 |
srcPtr = CONST_CAST(TUint8*, aSrc->Ptr());
|
sl@0
|
450 |
|
sl@0
|
451 |
|
sl@0
|
452 |
//*************************************************
|
sl@0
|
453 |
//* If the input buffer is empty, and there is
|
sl@0
|
454 |
//* enough data in the input stream, then use the
|
sl@0
|
455 |
//* data from the input stream. Else must append
|
sl@0
|
456 |
//* available input data to the input buffer.
|
sl@0
|
457 |
//*************************************************
|
sl@0
|
458 |
|
sl@0
|
459 |
if ( (iInBufferCount == 0) && (srcLen >= KGsmEncodedFrameSize) )
|
sl@0
|
460 |
{
|
sl@0
|
461 |
srcUsed = KGsmEncodedFrameSize;
|
sl@0
|
462 |
}
|
sl@0
|
463 |
else
|
sl@0
|
464 |
{
|
sl@0
|
465 |
TInt canCache = KGsmEncodedFrameSize - iInBufferCount;
|
sl@0
|
466 |
srcUsed = Min (canCache, srcLen);
|
sl@0
|
467 |
|
sl@0
|
468 |
for (TInt count = 0; count < srcUsed; count++)
|
sl@0
|
469 |
{
|
sl@0
|
470 |
//not worth use a mem copy
|
sl@0
|
471 |
*iInBufferPtr++ = *srcPtr++;
|
sl@0
|
472 |
}
|
sl@0
|
473 |
|
sl@0
|
474 |
|
sl@0
|
475 |
//*************************************************
|
sl@0
|
476 |
//* If the input buffer is now full, then we can
|
sl@0
|
477 |
//* process this data. Otherwise, we don't have
|
sl@0
|
478 |
//* enough data so set srcPtr to NULL to indicate
|
sl@0
|
479 |
//* that there's no data to process yet.
|
sl@0
|
480 |
//*************************************************
|
sl@0
|
481 |
|
sl@0
|
482 |
srcPtr = NULL;
|
sl@0
|
483 |
iInBufferCount += srcUsed;
|
sl@0
|
484 |
if ( iInBufferCount == KGsmEncodedFrameSize )
|
sl@0
|
485 |
{
|
sl@0
|
486 |
srcPtr = iInBuffer;
|
sl@0
|
487 |
iInBufferPtr = iInBuffer;
|
sl@0
|
488 |
iInBufferCount = 0;
|
sl@0
|
489 |
}
|
sl@0
|
490 |
}
|
sl@0
|
491 |
}
|
sl@0
|
492 |
|
sl@0
|
493 |
|
sl@0
|
494 |
//*************************************************
|
sl@0
|
495 |
//* If there is enough input data, then determine
|
sl@0
|
496 |
//* where the output should go (output stream or
|
sl@0
|
497 |
//* output buffer if output stream doesn't have
|
sl@0
|
498 |
//* enough room). Then decode the data.
|
sl@0
|
499 |
//*************************************************
|
sl@0
|
500 |
|
sl@0
|
501 |
if ( srcPtr != NULL )
|
sl@0
|
502 |
{
|
sl@0
|
503 |
// Determine where to put output data
|
sl@0
|
504 |
dstPtr = CONST_CAST(TUint8*, aDst->Ptr());
|
sl@0
|
505 |
dstUsed = KPcmInputFrameSize;
|
sl@0
|
506 |
|
sl@0
|
507 |
if ( dstLen < KPcmInputFrameSize )
|
sl@0
|
508 |
{
|
sl@0
|
509 |
dstPtr = iOutBuffer;
|
sl@0
|
510 |
iOutBufferCount = KPcmInputFrameSize;
|
sl@0
|
511 |
}
|
sl@0
|
512 |
|
sl@0
|
513 |
// Decode the data
|
sl@0
|
514 |
iGsmDecoder->ExecuteL (srcPtr, dstPtr);
|
sl@0
|
515 |
}
|
sl@0
|
516 |
|
sl@0
|
517 |
|
sl@0
|
518 |
//*************************************************
|
sl@0
|
519 |
//* If any data is stored in the output buffer,
|
sl@0
|
520 |
//* then output as much of it as well fit in the
|
sl@0
|
521 |
//* output stream.
|
sl@0
|
522 |
//*************************************************
|
sl@0
|
523 |
|
sl@0
|
524 |
if ( iOutBufferCount > 0 )
|
sl@0
|
525 |
{
|
sl@0
|
526 |
dstUsed = Min ((TInt)iOutBufferCount, (TInt)dstLen);
|
sl@0
|
527 |
TPtrC8 outPtr (iOutBufferPtr, dstUsed);
|
sl@0
|
528 |
|
sl@0
|
529 |
aDst->SetLength(0);
|
sl@0
|
530 |
aDst->Append (outPtr);
|
sl@0
|
531 |
|
sl@0
|
532 |
iOutBufferCount -= dstUsed;
|
sl@0
|
533 |
iOutBufferPtr += dstUsed;
|
sl@0
|
534 |
|
sl@0
|
535 |
if ( iOutBufferCount == 0 )
|
sl@0
|
536 |
{
|
sl@0
|
537 |
iOutBufferPtr = iOutBuffer;
|
sl@0
|
538 |
}
|
sl@0
|
539 |
}
|
sl@0
|
540 |
|
sl@0
|
541 |
|
sl@0
|
542 |
//*************************************************
|
sl@0
|
543 |
//* Modify the length attributes of the source and
|
sl@0
|
544 |
//* destination data streams to inform the caller
|
sl@0
|
545 |
//* of how much data was used in each buffer.
|
sl@0
|
546 |
//*************************************************
|
sl@0
|
547 |
|
sl@0
|
548 |
aSrc->SetLength(srcUsed);
|
sl@0
|
549 |
aDst->SetLength(dstUsed);
|
sl@0
|
550 |
|
sl@0
|
551 |
}
|
sl@0
|
552 |
|
sl@0
|
553 |
|
sl@0
|
554 |
//*******************************************************************
|
sl@0
|
555 |
//* FUNCTION: C16PcmToGsmWavCodec::C16PcmToGsmWavCodec
|
sl@0
|
556 |
//* Constructor for 16 bit PCM to GSM Codec.
|
sl@0
|
557 |
//*******************************************************************
|
sl@0
|
558 |
|
sl@0
|
559 |
C16PcmToGsmWavCodec::C16PcmToGsmWavCodec()
|
sl@0
|
560 |
{
|
sl@0
|
561 |
|
sl@0
|
562 |
Reset();
|
sl@0
|
563 |
|
sl@0
|
564 |
}
|
sl@0
|
565 |
|
sl@0
|
566 |
|
sl@0
|
567 |
//*******************************************************************
|
sl@0
|
568 |
//* FUNCTION: C16PcmToGsmWavCodec::~C16PcmToGsmWavCodec
|
sl@0
|
569 |
//* Destructor for 16 bit PCM to GSM Codec.
|
sl@0
|
570 |
//*******************************************************************
|
sl@0
|
571 |
|
sl@0
|
572 |
C16PcmToGsmWavCodec::~C16PcmToGsmWavCodec()
|
sl@0
|
573 |
{
|
sl@0
|
574 |
|
sl@0
|
575 |
delete iGsmEncoder;
|
sl@0
|
576 |
|
sl@0
|
577 |
}
|
sl@0
|
578 |
|
sl@0
|
579 |
|
sl@0
|
580 |
//*******************************************************************
|
sl@0
|
581 |
//* FUNCTION: C16PcmToGsmWavCodec::ConstructL
|
sl@0
|
582 |
//* Perform 2nd pass of object construction (allocating data on heap).
|
sl@0
|
583 |
//*******************************************************************
|
sl@0
|
584 |
|
sl@0
|
585 |
void C16PcmToGsmWavCodec::ConstructL()
|
sl@0
|
586 |
{
|
sl@0
|
587 |
|
sl@0
|
588 |
iGsmEncoder = new (ELeave) CGSM610FR_Encoder;
|
sl@0
|
589 |
iGsmEncoder->ConstructL();
|
sl@0
|
590 |
iGsmEncoder->StartL();
|
sl@0
|
591 |
iInBufferCount = 0;
|
sl@0
|
592 |
iOutBufferCount = 0;
|
sl@0
|
593 |
|
sl@0
|
594 |
}
|
sl@0
|
595 |
|
sl@0
|
596 |
|
sl@0
|
597 |
//*******************************************************************
|
sl@0
|
598 |
//* FUNCTION: C16PcmToGsmWavCodec::Reset
|
sl@0
|
599 |
//* Reset the input/output buffer states.
|
sl@0
|
600 |
//*******************************************************************
|
sl@0
|
601 |
|
sl@0
|
602 |
void C16PcmToGsmWavCodec::Reset()
|
sl@0
|
603 |
{
|
sl@0
|
604 |
|
sl@0
|
605 |
iInBufferPtr = iInBuffer;
|
sl@0
|
606 |
iOutBufferPtr = iOutBuffer;
|
sl@0
|
607 |
}
|
sl@0
|
608 |
|
sl@0
|
609 |
|
sl@0
|
610 |
void C16PcmToGsmWavCodec::ResetAllL()
|
sl@0
|
611 |
{
|
sl@0
|
612 |
Reset();
|
sl@0
|
613 |
iInBufferCount = 0;
|
sl@0
|
614 |
iOutBufferCount = 0;
|
sl@0
|
615 |
|
sl@0
|
616 |
iGsmEncoder->StartL();
|
sl@0
|
617 |
}
|
sl@0
|
618 |
|
sl@0
|
619 |
|
sl@0
|
620 |
//*******************************************************************
|
sl@0
|
621 |
//* FUNCTION: C16PcmToGsmWavCodec::ProcessL
|
sl@0
|
622 |
//* Read raw 16 bit PCM data (contained in aSrc) and convert to
|
sl@0
|
623 |
//* GSM data and return to caller (in aDst).
|
sl@0
|
624 |
//*
|
sl@0
|
625 |
//* NOTE that amount of data contained in input/output buffers
|
sl@0
|
626 |
//* varies, so if there is not enough input data or not enough
|
sl@0
|
627 |
//* room for the output data, then this function must buffer
|
sl@0
|
628 |
//* the data until enough data is received (or removed).
|
sl@0
|
629 |
//*
|
sl@0
|
630 |
//* NOTE that this function only buffers input (or output) data
|
sl@0
|
631 |
//* if there is not enough data (or room for output) available
|
sl@0
|
632 |
//* in the input (output) stream. Otherwise, the data is accessed
|
sl@0
|
633 |
//* directly from the input (output) stream which saves unnecessary
|
sl@0
|
634 |
//* copying of data.
|
sl@0
|
635 |
//*******************************************************************
|
sl@0
|
636 |
|
sl@0
|
637 |
|
sl@0
|
638 |
void C16PcmToGsmWavCodec::ProcessL(TMMFPtr8* aSrc, TMMFPtr8* aDst)
|
sl@0
|
639 |
{
|
sl@0
|
640 |
TUint8* srcPtr = NULL;
|
sl@0
|
641 |
TUint8* dstPtr = NULL;
|
sl@0
|
642 |
const TUint srcLen = aSrc->Length();
|
sl@0
|
643 |
const TUint dstLen = aDst->Length();
|
sl@0
|
644 |
TInt srcUsed = 0;
|
sl@0
|
645 |
TInt dstUsed = 0;
|
sl@0
|
646 |
|
sl@0
|
647 |
|
sl@0
|
648 |
//**************************************************
|
sl@0
|
649 |
//* Get Input Data: Only want to process more input
|
sl@0
|
650 |
//* data if the output buffer is empty.
|
sl@0
|
651 |
//**************************************************
|
sl@0
|
652 |
|
sl@0
|
653 |
if ( iOutBufferCount == 0 )
|
sl@0
|
654 |
{
|
sl@0
|
655 |
srcPtr = CONST_CAST(TUint8*, aSrc->Ptr());
|
sl@0
|
656 |
|
sl@0
|
657 |
|
sl@0
|
658 |
//*************************************************
|
sl@0
|
659 |
//* If the input buffer is empty, and there is
|
sl@0
|
660 |
//* enough data in the input stream, then use the
|
sl@0
|
661 |
//* data from the input stream. Else must append
|
sl@0
|
662 |
//* available input data to the input buffer.
|
sl@0
|
663 |
//*************************************************
|
sl@0
|
664 |
|
sl@0
|
665 |
if ( (iInBufferCount == 0) && (srcLen >= KPcmInputFrameSize) )
|
sl@0
|
666 |
{
|
sl@0
|
667 |
srcUsed = KPcmInputFrameSize;
|
sl@0
|
668 |
}
|
sl@0
|
669 |
else
|
sl@0
|
670 |
{
|
sl@0
|
671 |
TInt canCache = KPcmInputFrameSize - iInBufferCount;
|
sl@0
|
672 |
srcUsed = Min (canCache, srcLen);
|
sl@0
|
673 |
|
sl@0
|
674 |
for (TInt count = 0; count < srcUsed; count++)
|
sl@0
|
675 |
{
|
sl@0
|
676 |
*iInBufferPtr++ = *srcPtr++;
|
sl@0
|
677 |
}
|
sl@0
|
678 |
|
sl@0
|
679 |
|
sl@0
|
680 |
//*************************************************
|
sl@0
|
681 |
//* If the input buffer is now full, then we can
|
sl@0
|
682 |
//* process this data. Otherwise, we don't have
|
sl@0
|
683 |
//* enough data so set srcPtr to NULL to indicate
|
sl@0
|
684 |
//* that there's no data to process yet.
|
sl@0
|
685 |
//*************************************************
|
sl@0
|
686 |
|
sl@0
|
687 |
srcPtr = NULL;
|
sl@0
|
688 |
iInBufferCount += srcUsed;
|
sl@0
|
689 |
if ( iInBufferCount == KPcmInputFrameSize )
|
sl@0
|
690 |
{
|
sl@0
|
691 |
srcPtr = iInBuffer;
|
sl@0
|
692 |
iInBufferPtr = iInBuffer;
|
sl@0
|
693 |
iInBufferCount = 0;
|
sl@0
|
694 |
}
|
sl@0
|
695 |
}
|
sl@0
|
696 |
}
|
sl@0
|
697 |
|
sl@0
|
698 |
|
sl@0
|
699 |
//*************************************************
|
sl@0
|
700 |
//* If there is enough input data, then determine
|
sl@0
|
701 |
//* where the output should go (output stream or
|
sl@0
|
702 |
//* output buffer if output stream doesn't have
|
sl@0
|
703 |
//* enough room). Then encode the data.
|
sl@0
|
704 |
//*************************************************
|
sl@0
|
705 |
|
sl@0
|
706 |
if ( srcPtr != NULL )
|
sl@0
|
707 |
{
|
sl@0
|
708 |
// Determine where to put output data
|
sl@0
|
709 |
dstPtr = CONST_CAST(TUint8*, aDst->Ptr());
|
sl@0
|
710 |
dstUsed = KGsmEncodedFrameSize;
|
sl@0
|
711 |
|
sl@0
|
712 |
if ( dstLen < KGsmEncodedFrameSize )
|
sl@0
|
713 |
{
|
sl@0
|
714 |
dstPtr = iOutBuffer;
|
sl@0
|
715 |
iOutBufferCount = KGsmEncodedFrameSize;
|
sl@0
|
716 |
}
|
sl@0
|
717 |
|
sl@0
|
718 |
// Encode the data
|
sl@0
|
719 |
iGsmEncoder->ExecuteL (srcPtr, dstPtr);
|
sl@0
|
720 |
}
|
sl@0
|
721 |
|
sl@0
|
722 |
|
sl@0
|
723 |
//*************************************************
|
sl@0
|
724 |
//* If any data is stored in the output buffer,
|
sl@0
|
725 |
//* then output as much of it as well fit in the
|
sl@0
|
726 |
//* output stream.
|
sl@0
|
727 |
//*************************************************
|
sl@0
|
728 |
|
sl@0
|
729 |
if ( iOutBufferCount > 0 )
|
sl@0
|
730 |
{
|
sl@0
|
731 |
dstUsed = Min ((TInt)iOutBufferCount, (TInt)dstLen);
|
sl@0
|
732 |
TPtrC8 outPtr (iOutBufferPtr, dstUsed);
|
sl@0
|
733 |
|
sl@0
|
734 |
aDst->SetLength(0);
|
sl@0
|
735 |
aDst->Append (outPtr);
|
sl@0
|
736 |
|
sl@0
|
737 |
iOutBufferCount -= dstUsed;
|
sl@0
|
738 |
iOutBufferPtr += dstUsed;
|
sl@0
|
739 |
|
sl@0
|
740 |
if ( iOutBufferCount == 0 )
|
sl@0
|
741 |
{
|
sl@0
|
742 |
iOutBufferPtr = iOutBuffer;
|
sl@0
|
743 |
}
|
sl@0
|
744 |
}
|
sl@0
|
745 |
|
sl@0
|
746 |
|
sl@0
|
747 |
//*************************************************
|
sl@0
|
748 |
//* Modify the length attributes of the source and
|
sl@0
|
749 |
//* destination data streams to inform the caller
|
sl@0
|
750 |
//* of how much data was used in each buffer.
|
sl@0
|
751 |
//*************************************************
|
sl@0
|
752 |
|
sl@0
|
753 |
aSrc->SetLength(srcUsed);
|
sl@0
|
754 |
aDst->SetLength(dstUsed);
|
sl@0
|
755 |
|
sl@0
|
756 |
|
sl@0
|
757 |
}
|
sl@0
|
758 |
|