sl@0
|
1 |
// tonehwdevice.cpp
|
sl@0
|
2 |
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
3 |
// All rights reserved.
|
sl@0
|
4 |
// This component and the accompanying materials are made available
|
sl@0
|
5 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
6 |
// which accompanies this distribution, and is available
|
sl@0
|
7 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
8 |
//
|
sl@0
|
9 |
// Initial Contributors:
|
sl@0
|
10 |
// Nokia Corporation - initial contribution.
|
sl@0
|
11 |
//
|
sl@0
|
12 |
// Contributors:
|
sl@0
|
13 |
//
|
sl@0
|
14 |
// Description:
|
sl@0
|
15 |
//
|
sl@0
|
16 |
|
sl@0
|
17 |
|
sl@0
|
18 |
|
sl@0
|
19 |
// INCLUDE FILES
|
sl@0
|
20 |
#include <mmf/server/mmfhwdevice.h>
|
sl@0
|
21 |
#include "tonehwdevice.hrh" //for KUidToneHwDevice
|
sl@0
|
22 |
#include <ecom/implementationproxy.h> // For making it ECom plugin
|
sl@0
|
23 |
#include "tonehwdevice.h"
|
sl@0
|
24 |
|
sl@0
|
25 |
|
sl@0
|
26 |
// EXTERNAL DATA STRUCTURES
|
sl@0
|
27 |
|
sl@0
|
28 |
// EXTERNAL FUNCTION PROTOTYPES
|
sl@0
|
29 |
|
sl@0
|
30 |
// CONSTANTS
|
sl@0
|
31 |
const TImplementationProxy ImplementationTable[] =
|
sl@0
|
32 |
{
|
sl@0
|
33 |
IMPLEMENTATION_PROXY_ENTRY(KUidToneHwDevice, CToneHwDevice::NewL),
|
sl@0
|
34 |
};
|
sl@0
|
35 |
//current supported sample rate
|
sl@0
|
36 |
const TInt KSupportedSampleRate = 8000;
|
sl@0
|
37 |
|
sl@0
|
38 |
// ---------------------------------------------------------------------------
|
sl@0
|
39 |
// Default constructor
|
sl@0
|
40 |
// ---------------------------------------------------------------------------
|
sl@0
|
41 |
//
|
sl@0
|
42 |
CToneHwDevice::CToneHwDevice()
|
sl@0
|
43 |
{
|
sl@0
|
44 |
DP_CONTEXT(CToneHwDevice::CToneHwDevice *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
45 |
DP_IN();
|
sl@0
|
46 |
DP_OUT();
|
sl@0
|
47 |
}
|
sl@0
|
48 |
|
sl@0
|
49 |
// -----------------------------------------------------------------------------
|
sl@0
|
50 |
// Symbian 2nd phase constructor
|
sl@0
|
51 |
// -----------------------------------------------------------------------------
|
sl@0
|
52 |
//
|
sl@0
|
53 |
void CToneHwDevice::ConstructL()
|
sl@0
|
54 |
{
|
sl@0
|
55 |
DP_CONTEXT(CToneHwDevice::ConstructL *CD0*, CtxDevSound, DPLOCAL);
|
sl@0
|
56 |
DP_IN();
|
sl@0
|
57 |
|
sl@0
|
58 |
iHwDataBufferFill = CMMFDataBuffer::NewL(sizeof(TToneData));
|
sl@0
|
59 |
iHwDataBufferFill->SetLastBuffer(EFalse);
|
sl@0
|
60 |
iHwDataBufferFill->Data().SetLength(sizeof(TToneData));
|
sl@0
|
61 |
iHwDataBufferFill->SetRequestSizeL(sizeof(TToneData));
|
sl@0
|
62 |
|
sl@0
|
63 |
iCodec = new(ELeave)CToneCodec();
|
sl@0
|
64 |
|
sl@0
|
65 |
DP_OUT();
|
sl@0
|
66 |
}
|
sl@0
|
67 |
|
sl@0
|
68 |
// -----------------------------------------------------------------------------
|
sl@0
|
69 |
// Symbian constructor
|
sl@0
|
70 |
// -----------------------------------------------------------------------------
|
sl@0
|
71 |
//
|
sl@0
|
72 |
CToneHwDevice* CToneHwDevice::NewL()
|
sl@0
|
73 |
{
|
sl@0
|
74 |
DP_STATIC_CONTEXT(CToneHwDevice::NewL *CD0*, CtxDevSound, DPLOCAL);
|
sl@0
|
75 |
DP_IN();
|
sl@0
|
76 |
CToneHwDevice* self = new (ELeave) CToneHwDevice();
|
sl@0
|
77 |
CleanupStack::PushL(self);
|
sl@0
|
78 |
self->ConstructL();
|
sl@0
|
79 |
CleanupStack::Pop();
|
sl@0
|
80 |
DP0_RET(self, "0x%x");
|
sl@0
|
81 |
}
|
sl@0
|
82 |
|
sl@0
|
83 |
// ---------------------------------------------------------------------------
|
sl@0
|
84 |
// Destructor
|
sl@0
|
85 |
// ---------------------------------------------------------------------------
|
sl@0
|
86 |
//
|
sl@0
|
87 |
CToneHwDevice::~CToneHwDevice()
|
sl@0
|
88 |
{
|
sl@0
|
89 |
DP_CONTEXT(CToneHwDevice::~CToneHwDevice *CD0*, CtxDevSound, DPLOCAL);
|
sl@0
|
90 |
DP_IN();
|
sl@0
|
91 |
delete iHwDataBufferFill;
|
sl@0
|
92 |
delete iCodec;
|
sl@0
|
93 |
delete iPlayCustomInterface;
|
sl@0
|
94 |
|
sl@0
|
95 |
if(iDataPath)
|
sl@0
|
96 |
{
|
sl@0
|
97 |
delete iDataPath;
|
sl@0
|
98 |
}
|
sl@0
|
99 |
|
sl@0
|
100 |
if(iToneBuffer1)
|
sl@0
|
101 |
{
|
sl@0
|
102 |
delete iToneBuffer1;
|
sl@0
|
103 |
}
|
sl@0
|
104 |
if(iToneBuffer2)
|
sl@0
|
105 |
{
|
sl@0
|
106 |
delete iToneBuffer2;
|
sl@0
|
107 |
}
|
sl@0
|
108 |
DP_OUT();
|
sl@0
|
109 |
}
|
sl@0
|
110 |
|
sl@0
|
111 |
/**
|
sl@0
|
112 |
*
|
sl@0
|
113 |
* Codec
|
sl@0
|
114 |
*
|
sl@0
|
115 |
*/
|
sl@0
|
116 |
CToneCodec& CToneHwDevice::Codec()
|
sl@0
|
117 |
{
|
sl@0
|
118 |
return *iCodec;
|
sl@0
|
119 |
}
|
sl@0
|
120 |
|
sl@0
|
121 |
// ---------------------------------------------------------------------------
|
sl@0
|
122 |
// from class CMMFHwDevice
|
sl@0
|
123 |
// CToneHwDevice::Init
|
sl@0
|
124 |
// ---------------------------------------------------------------------------
|
sl@0
|
125 |
//
|
sl@0
|
126 |
TInt CToneHwDevice::Init(THwDeviceInitParams& aDevInfo)
|
sl@0
|
127 |
{
|
sl@0
|
128 |
DP_CONTEXT(CToneHwDevice::Init *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
129 |
DP_IN();
|
sl@0
|
130 |
|
sl@0
|
131 |
if (!iToneInitialized) // Check if tones is not initialized yet.
|
sl@0
|
132 |
{
|
sl@0
|
133 |
iToneInitialized = ETrue;
|
sl@0
|
134 |
}
|
sl@0
|
135 |
|
sl@0
|
136 |
// [ precondition that aDevInfo has a valid observer ]
|
sl@0
|
137 |
if (!aDevInfo.iHwDeviceObserver)
|
sl@0
|
138 |
{
|
sl@0
|
139 |
DP0_RET(KErrArgument, "%d");
|
sl@0
|
140 |
}
|
sl@0
|
141 |
|
sl@0
|
142 |
iHwDeviceObserver = aDevInfo.iHwDeviceObserver;
|
sl@0
|
143 |
|
sl@0
|
144 |
//[ assert the post condition ]
|
sl@0
|
145 |
if (!iCodec)
|
sl@0
|
146 |
{
|
sl@0
|
147 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
148 |
}
|
sl@0
|
149 |
|
sl@0
|
150 |
DP0_RET(KErrNone, "%d");
|
sl@0
|
151 |
}
|
sl@0
|
152 |
|
sl@0
|
153 |
// ---------------------------------------------------------------------------
|
sl@0
|
154 |
// from class CMMFHwDevice
|
sl@0
|
155 |
// CToneHwDevice::Start
|
sl@0
|
156 |
// ---------------------------------------------------------------------------
|
sl@0
|
157 |
//
|
sl@0
|
158 |
TInt CToneHwDevice::Start(TDeviceFunc /*aFuncCmd*/, TDeviceFlow /*aFlowCmd*/)
|
sl@0
|
159 |
{
|
sl@0
|
160 |
DP_CONTEXT(CToneHwDevice::Start *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
161 |
DP_IN();
|
sl@0
|
162 |
|
sl@0
|
163 |
TInt error = KErrNone;
|
sl@0
|
164 |
|
sl@0
|
165 |
// Start for first time OR resuming
|
sl@0
|
166 |
if (!iTonePlaying || iDataPath->State() == CToneDataPath::EPaused)
|
sl@0
|
167 |
{
|
sl@0
|
168 |
iLastBuffer = EFalse;
|
sl@0
|
169 |
//[ assert precondition that play custom interface is present]
|
sl@0
|
170 |
//if there is no tone play custom interface then the user of the CToneHwDevice
|
sl@0
|
171 |
//cannot have set any of the custom settings such as sample rate.
|
sl@0
|
172 |
if (!iPlayCustomInterface)
|
sl@0
|
173 |
{
|
sl@0
|
174 |
DP0_RET(KErrNotReady, "%d");
|
sl@0
|
175 |
}
|
sl@0
|
176 |
|
sl@0
|
177 |
//play
|
sl@0
|
178 |
if (!iDataPath)
|
sl@0
|
179 |
{
|
sl@0
|
180 |
//create a datapath
|
sl@0
|
181 |
TRAP(error,iDataPath = CToneDataPath::NewL());
|
sl@0
|
182 |
if ((iDataPath)&&(error == KErrNone))
|
sl@0
|
183 |
{
|
sl@0
|
184 |
ASSERT(iHwDeviceObserver);
|
sl@0
|
185 |
iDataPath->SetObserver(*this);
|
sl@0
|
186 |
error = iDataPath->AddCodec(*iCodec);
|
sl@0
|
187 |
if (error == KErrNone)
|
sl@0
|
188 |
{
|
sl@0
|
189 |
iDeviceBufferSize = (iCodec->SinkBufferSize());
|
sl@0
|
190 |
}
|
sl@0
|
191 |
}
|
sl@0
|
192 |
}
|
sl@0
|
193 |
if ((error == KErrNone) && (iDataPath->State() != CToneDataPath::EPlaying))
|
sl@0
|
194 |
{
|
sl@0
|
195 |
//datapath was created ok and we are not playing
|
sl@0
|
196 |
if (iDataPath->State() == CToneDataPath::EStopped)
|
sl@0
|
197 |
{
|
sl@0
|
198 |
// starting from 'fresh so set sound device settings
|
sl@0
|
199 |
if (!iDataPath->Device().Handle())
|
sl@0
|
200 |
{
|
sl@0
|
201 |
//if Device() is called then we need a valid sound device handle
|
sl@0
|
202 |
error = iDataPath->Device().Open();
|
sl@0
|
203 |
if (error != KErrNone)
|
sl@0
|
204 |
{
|
sl@0
|
205 |
DP0_RET(error, "%d");
|
sl@0
|
206 |
}
|
sl@0
|
207 |
|
sl@0
|
208 |
}
|
sl@0
|
209 |
static_cast<TToneCustomInterface*>(iPlayCustomInterface)->SetDevice(&(iDataPath->Device()));
|
sl@0
|
210 |
|
sl@0
|
211 |
TUint iVol = iPlayCustomInterface->Volume();
|
sl@0
|
212 |
iDataPath->Device().SetPlayVolume(iVol);
|
sl@0
|
213 |
|
sl@0
|
214 |
soundDeviceSettings().iRate = iSampleRate;
|
sl@0
|
215 |
|
sl@0
|
216 |
//this would normally be pcm16
|
sl@0
|
217 |
soundDeviceSettings().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
|
sl@0
|
218 |
|
sl@0
|
219 |
//1 = mono 2 = stereo
|
sl@0
|
220 |
soundDeviceSettings().iChannels = iChannels;
|
sl@0
|
221 |
|
sl@0
|
222 |
//tell sound driver what buffer size to expect
|
sl@0
|
223 |
//it is up the the implementor to make use the device can support
|
sl@0
|
224 |
//the required buffer size
|
sl@0
|
225 |
soundDeviceSettings().iBufferSize = iDeviceBufferSize;
|
sl@0
|
226 |
error = iDataPath->Device().SetPlayFormat(soundDeviceSettings);
|
sl@0
|
227 |
|
sl@0
|
228 |
} // End of iDataPath->State() == CToneDataPath::EStopped
|
sl@0
|
229 |
|
sl@0
|
230 |
//else resuming from pause
|
sl@0
|
231 |
if ((error == KErrNone)||(error == KErrInUse))
|
sl@0
|
232 |
{
|
sl@0
|
233 |
// Hw device hasn't played anything yet so don't change
|
sl@0
|
234 |
// active buffer. This is checked in FillThisHwBuffer.
|
sl@0
|
235 |
if(iDataPath->State() != CToneDataPath::EPaused)
|
sl@0
|
236 |
{
|
sl@0
|
237 |
iFirstCallFromHwDevice = ETrue;
|
sl@0
|
238 |
}
|
sl@0
|
239 |
iTonePlaying = ETrue;
|
sl@0
|
240 |
error = iDataPath->Start();
|
sl@0
|
241 |
}
|
sl@0
|
242 |
}//status == KErrNone
|
sl@0
|
243 |
}
|
sl@0
|
244 |
else // if tone playback is already ongoing do nothing
|
sl@0
|
245 |
{
|
sl@0
|
246 |
DP0(DLINFO,"Previous tone call is not completed yet");
|
sl@0
|
247 |
}
|
sl@0
|
248 |
DP0_RET(error, "%d");
|
sl@0
|
249 |
}
|
sl@0
|
250 |
|
sl@0
|
251 |
// ---------------------------------------------------------------------------
|
sl@0
|
252 |
// from class CMMFHwDevice
|
sl@0
|
253 |
// CToneHwDevice::Stop
|
sl@0
|
254 |
// ---------------------------------------------------------------------------
|
sl@0
|
255 |
TInt CToneHwDevice::Stop()
|
sl@0
|
256 |
{
|
sl@0
|
257 |
DP_CONTEXT(CToneHwDevice::Stop *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
258 |
DP_IN();
|
sl@0
|
259 |
if (iTonePlaying)
|
sl@0
|
260 |
{
|
sl@0
|
261 |
iTonePlaying = EFalse;
|
sl@0
|
262 |
}
|
sl@0
|
263 |
|
sl@0
|
264 |
if (!iDataPath)
|
sl@0
|
265 |
{
|
sl@0
|
266 |
DP0_RET(KErrNotReady, "%d");
|
sl@0
|
267 |
}
|
sl@0
|
268 |
|
sl@0
|
269 |
delete iDataPath;
|
sl@0
|
270 |
iDataPath = NULL;
|
sl@0
|
271 |
|
sl@0
|
272 |
//Setting device to NULL since after stop it doesn't exists any more
|
sl@0
|
273 |
if(iPlayCustomInterface)
|
sl@0
|
274 |
{
|
sl@0
|
275 |
static_cast<TToneCustomInterface*>(iPlayCustomInterface)->SetDevice(NULL);
|
sl@0
|
276 |
}
|
sl@0
|
277 |
|
sl@0
|
278 |
DP0_RET(KErrNone, "%d");
|
sl@0
|
279 |
}
|
sl@0
|
280 |
|
sl@0
|
281 |
// ---------------------------------------------------------------------------
|
sl@0
|
282 |
// from class CMMFHwDevice
|
sl@0
|
283 |
// CToneHwDevice::Pause
|
sl@0
|
284 |
// ---------------------------------------------------------------------------
|
sl@0
|
285 |
//
|
sl@0
|
286 |
TInt CToneHwDevice::Pause()
|
sl@0
|
287 |
{
|
sl@0
|
288 |
DP_CONTEXT(CToneHwDevice::Pause *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
289 |
DP_IN();
|
sl@0
|
290 |
|
sl@0
|
291 |
if (!iDataPath)
|
sl@0
|
292 |
{
|
sl@0
|
293 |
DP0_RET(KErrNotReady, "%d");
|
sl@0
|
294 |
}
|
sl@0
|
295 |
iDataPath->Pause();
|
sl@0
|
296 |
|
sl@0
|
297 |
DP0_RET(KErrNone, "%d");
|
sl@0
|
298 |
}
|
sl@0
|
299 |
|
sl@0
|
300 |
// ---------------------------------------------------------------------------
|
sl@0
|
301 |
// from class CMMFHwDevice
|
sl@0
|
302 |
// CToneHwDevice::StopAndDeleteCodec
|
sl@0
|
303 |
// ---------------------------------------------------------------------------
|
sl@0
|
304 |
//
|
sl@0
|
305 |
TInt CToneHwDevice::StopAndDeleteCodec()
|
sl@0
|
306 |
{
|
sl@0
|
307 |
DP_CONTEXT(CToneHwDevice::StopAndDeleteCodec *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
308 |
DP_IN();
|
sl@0
|
309 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
310 |
}
|
sl@0
|
311 |
|
sl@0
|
312 |
// ---------------------------------------------------------------------------
|
sl@0
|
313 |
// from class CMMFHwDevice
|
sl@0
|
314 |
// CToneHwDevice::DeleteCodec
|
sl@0
|
315 |
// ---------------------------------------------------------------------------
|
sl@0
|
316 |
//
|
sl@0
|
317 |
TInt CToneHwDevice::DeleteCodec()
|
sl@0
|
318 |
{
|
sl@0
|
319 |
DP_CONTEXT(CToneHwDevice::DeleteCodec *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
320 |
DP_IN();
|
sl@0
|
321 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
322 |
}
|
sl@0
|
323 |
|
sl@0
|
324 |
// ---------------------------------------------------------------------------
|
sl@0
|
325 |
// from class CMMFHwDevice
|
sl@0
|
326 |
// CToneHwDevice::SetConfig
|
sl@0
|
327 |
// ---------------------------------------------------------------------------
|
sl@0
|
328 |
//
|
sl@0
|
329 |
TInt CToneHwDevice::SetConfig(TTaskConfig& aConfig)
|
sl@0
|
330 |
{
|
sl@0
|
331 |
DP_CONTEXT(CToneHwDevice::SetConfig *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
332 |
DP_IN();
|
sl@0
|
333 |
|
sl@0
|
334 |
if (aConfig.iUid != KUidRefDevSoundTaskConfig)
|
sl@0
|
335 |
{
|
sl@0
|
336 |
DP0_RET(KErrArgument, "%d");
|
sl@0
|
337 |
}
|
sl@0
|
338 |
|
sl@0
|
339 |
if (aConfig.iRate != KSupportedSampleRate )
|
sl@0
|
340 |
{
|
sl@0
|
341 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
342 |
}
|
sl@0
|
343 |
|
sl@0
|
344 |
iSampleRate = aConfig.iRate;
|
sl@0
|
345 |
|
sl@0
|
346 |
if (aConfig.iStereoMode == ETaskMono)
|
sl@0
|
347 |
{
|
sl@0
|
348 |
iChannels = 1;
|
sl@0
|
349 |
}
|
sl@0
|
350 |
else if (aConfig.iStereoMode == ETaskInterleaved || aConfig.iStereoMode == ETaskNonInterleaved)
|
sl@0
|
351 |
{
|
sl@0
|
352 |
iChannels = 2;
|
sl@0
|
353 |
}
|
sl@0
|
354 |
else
|
sl@0
|
355 |
{
|
sl@0
|
356 |
DP0_RET(KErrArgument, "%d");
|
sl@0
|
357 |
}
|
sl@0
|
358 |
|
sl@0
|
359 |
DP0_RET(KErrNone, "%d");
|
sl@0
|
360 |
}
|
sl@0
|
361 |
|
sl@0
|
362 |
// CToneHwDevice::FillThisHwBuffer
|
sl@0
|
363 |
// ---------------------------------------------------------------------------
|
sl@0
|
364 |
TInt CToneHwDevice::FillThisHwBuffer(CMMFBuffer& aHwBuffer)
|
sl@0
|
365 |
{
|
sl@0
|
366 |
DP_CONTEXT(CToneHwDevice::FillThisHwBuffer *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
367 |
DP_IN();
|
sl@0
|
368 |
|
sl@0
|
369 |
TInt err(KErrNone);
|
sl@0
|
370 |
|
sl@0
|
371 |
if(iFirstCallFromHwDevice)
|
sl@0
|
372 |
{
|
sl@0
|
373 |
err = iHwDeviceObserver->FillThisHwBuffer(aHwBuffer);
|
sl@0
|
374 |
}
|
sl@0
|
375 |
else
|
sl@0
|
376 |
{
|
sl@0
|
377 |
err = ThisHwBufferFilled(aHwBuffer);
|
sl@0
|
378 |
}
|
sl@0
|
379 |
DP0_RET(err,"%d");
|
sl@0
|
380 |
}
|
sl@0
|
381 |
|
sl@0
|
382 |
// ---------------------------------------------------------------------------
|
sl@0
|
383 |
// from class CMMFHwDevice
|
sl@0
|
384 |
// CToneHwDevice::ThisHwBufferFilled
|
sl@0
|
385 |
// ---------------------------------------------------------------------------
|
sl@0
|
386 |
//
|
sl@0
|
387 |
TInt CToneHwDevice::ThisHwBufferFilled(CMMFBuffer& aMmfBuffer)
|
sl@0
|
388 |
{
|
sl@0
|
389 |
DP_CONTEXT(CToneHwDevice::ThisHwBufferFilled *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
390 |
DP_IN();
|
sl@0
|
391 |
|
sl@0
|
392 |
TInt err = KErrNone;
|
sl@0
|
393 |
CMMFDataBuffer* myBuffer = static_cast<CMMFDataBuffer*> (&aMmfBuffer);
|
sl@0
|
394 |
// Set the request length, From HwDevice this comes with buffer
|
sl@0
|
395 |
// length.
|
sl@0
|
396 |
TInt len = myBuffer->Data().MaxLength();
|
sl@0
|
397 |
// Ignore error. since buffer size = Buffer Length
|
sl@0
|
398 |
TRAP(err, myBuffer->SetRequestSizeL(len));
|
sl@0
|
399 |
|
sl@0
|
400 |
if(iFirstCallFromHwDevice)
|
sl@0
|
401 |
{
|
sl@0
|
402 |
myBuffer->SetLastBuffer(EFalse);
|
sl@0
|
403 |
|
sl@0
|
404 |
Mem::Copy((TAny*)(&myToneData), (TAny*)(myBuffer->Data().Ptr()), sizeof(TToneData));
|
sl@0
|
405 |
|
sl@0
|
406 |
err = ReadToneData();
|
sl@0
|
407 |
if(err==KErrNone)
|
sl@0
|
408 |
{
|
sl@0
|
409 |
err= GenerateBufferData();
|
sl@0
|
410 |
}
|
sl@0
|
411 |
}
|
sl@0
|
412 |
else
|
sl@0
|
413 |
{
|
sl@0
|
414 |
// Hw device will call this method right after its Start was called.
|
sl@0
|
415 |
// When it calls this for the first time it hasn't played one single
|
sl@0
|
416 |
// buffer yet so check that.
|
sl@0
|
417 |
// In this case there's no need to set the active buffer as it's already
|
sl@0
|
418 |
// waiting to be played.
|
sl@0
|
419 |
SetActiveToneBuffer();
|
sl@0
|
420 |
}
|
sl@0
|
421 |
|
sl@0
|
422 |
if (err == KErrNone)
|
sl@0
|
423 |
{
|
sl@0
|
424 |
// If there is no data in the active buffer, tone play is finished.
|
sl@0
|
425 |
// DevSound just have to wait for completion event from audio device.
|
sl@0
|
426 |
if (iActiveToneBuffer->Data().Length() == 0)
|
sl@0
|
427 |
{
|
sl@0
|
428 |
iActiveToneBuffer->SetLastBuffer(ETrue);
|
sl@0
|
429 |
myBuffer->SetLastBuffer(ETrue);
|
sl@0
|
430 |
iLastBuffer=ETrue;
|
sl@0
|
431 |
}
|
sl@0
|
432 |
|
sl@0
|
433 |
TInt tonelen = iActiveToneBuffer->Data().Length();
|
sl@0
|
434 |
|
sl@0
|
435 |
// don't enter more data than can be handled by the receiving buffer
|
sl@0
|
436 |
if (len >= tonelen)
|
sl@0
|
437 |
{
|
sl@0
|
438 |
len = tonelen;
|
sl@0
|
439 |
}
|
sl@0
|
440 |
|
sl@0
|
441 |
// Copy data from tone buffer to hw device buffer
|
sl@0
|
442 |
Mem::Copy((TAny*)(myBuffer->Data().Ptr()), (TAny*)(iActiveToneBuffer->Data().Ptr()), len);
|
sl@0
|
443 |
|
sl@0
|
444 |
myBuffer->Data().SetLength(len);
|
sl@0
|
445 |
|
sl@0
|
446 |
//Play data and try to generate next data block
|
sl@0
|
447 |
TRAP(err,iDataPath->BufferFilledL(static_cast<CMMFDataBuffer&> (*myBuffer)));
|
sl@0
|
448 |
if(err == KErrNone)
|
sl@0
|
449 |
{
|
sl@0
|
450 |
if(iLastBuffer)
|
sl@0
|
451 |
{
|
sl@0
|
452 |
// coverity[check_after_deref]
|
sl@0
|
453 |
if(myBuffer)
|
sl@0
|
454 |
{
|
sl@0
|
455 |
myBuffer = NULL;
|
sl@0
|
456 |
}
|
sl@0
|
457 |
FreeBuffers();
|
sl@0
|
458 |
iFirstCallFromHwDevice = EFalse;
|
sl@0
|
459 |
}
|
sl@0
|
460 |
else
|
sl@0
|
461 |
{
|
sl@0
|
462 |
// Check again whether this is the first call from Hw device.
|
sl@0
|
463 |
// FillFreeToneBuffer assumes the iActiveToneBuffer has already
|
sl@0
|
464 |
// been played.
|
sl@0
|
465 |
if (!iFirstCallFromHwDevice)
|
sl@0
|
466 |
{
|
sl@0
|
467 |
err = FillFreeToneBuffer();
|
sl@0
|
468 |
}
|
sl@0
|
469 |
else
|
sl@0
|
470 |
{
|
sl@0
|
471 |
iFirstCallFromHwDevice = EFalse; // Reset flag
|
sl@0
|
472 |
}
|
sl@0
|
473 |
}
|
sl@0
|
474 |
}
|
sl@0
|
475 |
}
|
sl@0
|
476 |
if ( err != KErrNone )
|
sl@0
|
477 |
{
|
sl@0
|
478 |
myBuffer->SetLastBuffer(ETrue);
|
sl@0
|
479 |
myBuffer->Data().SetLength(0);
|
sl@0
|
480 |
//Use error additional variable for sending last buffer so can still send Error(err)
|
sl@0
|
481 |
TRAPD(datapathErr, iDataPath->BufferFilledL(static_cast<CMMFDataBuffer&> (*myBuffer)));
|
sl@0
|
482 |
// coverity[check_after_deref]
|
sl@0
|
483 |
if(myBuffer)
|
sl@0
|
484 |
{
|
sl@0
|
485 |
myBuffer = NULL;
|
sl@0
|
486 |
}
|
sl@0
|
487 |
FreeBuffers();
|
sl@0
|
488 |
iFirstCallFromHwDevice = EFalse;
|
sl@0
|
489 |
if ( datapathErr != KErrNone )
|
sl@0
|
490 |
{
|
sl@0
|
491 |
iHwDeviceObserver->Error(datapathErr);
|
sl@0
|
492 |
DP0_RET(datapathErr, "%d");
|
sl@0
|
493 |
}
|
sl@0
|
494 |
iHwDeviceObserver->Error(err);
|
sl@0
|
495 |
}
|
sl@0
|
496 |
DP0_RET(err, "%d");
|
sl@0
|
497 |
}
|
sl@0
|
498 |
|
sl@0
|
499 |
// ---------------------------------------------------------------------------
|
sl@0
|
500 |
// from class MMMFHwDeviceObserver
|
sl@0
|
501 |
// CToneHwDevice::ThisHwBufferEmptied
|
sl@0
|
502 |
// ---------------------------------------------------------------------------
|
sl@0
|
503 |
TInt CToneHwDevice::ThisHwBufferEmptied(CMMFBuffer& /*aMmfBuffer*/)
|
sl@0
|
504 |
{
|
sl@0
|
505 |
DP_CONTEXT(CToneHwDevice::ThisHwBufferEmptied *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
506 |
DP_IN();
|
sl@0
|
507 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
508 |
}
|
sl@0
|
509 |
|
sl@0
|
510 |
// ---------------------------------------------------------------------------
|
sl@0
|
511 |
// from class MMMFHwDeviceObserver
|
sl@0
|
512 |
// CToneHwDevice::EmptyThisHwBuffer
|
sl@0
|
513 |
// ---------------------------------------------------------------------------
|
sl@0
|
514 |
TInt CToneHwDevice::EmptyThisHwBuffer(CMMFBuffer& /*aMmfBuffer*/)
|
sl@0
|
515 |
{
|
sl@0
|
516 |
DP_CONTEXT(CToneHwDevice::EmptyThisHwBuffer *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
517 |
DP_IN();
|
sl@0
|
518 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
519 |
}
|
sl@0
|
520 |
|
sl@0
|
521 |
// ---------------------------------------------------------------------------
|
sl@0
|
522 |
// from class MMMFHwDeviceObserver
|
sl@0
|
523 |
// CToneHwDevice::MsgFromHwDevice
|
sl@0
|
524 |
// ---------------------------------------------------------------------------
|
sl@0
|
525 |
TInt CToneHwDevice::MsgFromHwDevice(TUid aMessageType, const TDesC8& aMsg)
|
sl@0
|
526 |
{
|
sl@0
|
527 |
DP_CONTEXT(CToneHwDevice::MsgFromHwDevice *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
528 |
DP_IN();
|
sl@0
|
529 |
TInt err(KErrNone);
|
sl@0
|
530 |
err = iHwDeviceObserver->MsgFromHwDevice(aMessageType, aMsg);
|
sl@0
|
531 |
DP0_RET(err, "%d");
|
sl@0
|
532 |
}
|
sl@0
|
533 |
|
sl@0
|
534 |
// ---------------------------------------------------------------------------
|
sl@0
|
535 |
// from class MMMFHwDeviceObserver
|
sl@0
|
536 |
// CToneHwDevice::Stopped
|
sl@0
|
537 |
// ---------------------------------------------------------------------------
|
sl@0
|
538 |
void CToneHwDevice::Stopped()
|
sl@0
|
539 |
{
|
sl@0
|
540 |
DP_CONTEXT(CToneHwDevice::Stopped *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
541 |
DP_IN();
|
sl@0
|
542 |
iHwDeviceObserver->Stopped();
|
sl@0
|
543 |
DP_OUT();
|
sl@0
|
544 |
}
|
sl@0
|
545 |
|
sl@0
|
546 |
// ---------------------------------------------------------------------------
|
sl@0
|
547 |
// from class MMMFHwDeviceObserver
|
sl@0
|
548 |
// CToneHwDevice::Error
|
sl@0
|
549 |
// ---------------------------------------------------------------------------
|
sl@0
|
550 |
void CToneHwDevice::Error(TInt aError)
|
sl@0
|
551 |
{
|
sl@0
|
552 |
DP_CONTEXT(CToneHwDevice::Error *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
553 |
DP_IN();
|
sl@0
|
554 |
iHwDeviceObserver->Error(aError);
|
sl@0
|
555 |
DP_OUT();
|
sl@0
|
556 |
}
|
sl@0
|
557 |
|
sl@0
|
558 |
// ---------------------------------------------------------------------------
|
sl@0
|
559 |
// from class CMMFHwDevice
|
sl@0
|
560 |
// CToneHwDevice::CustomInterface
|
sl@0
|
561 |
// ---------------------------------------------------------------------------
|
sl@0
|
562 |
//
|
sl@0
|
563 |
TAny* CToneHwDevice::CustomInterface(TUid aInterfaceUid)
|
sl@0
|
564 |
{
|
sl@0
|
565 |
DP_CONTEXT(CToneHwDevice::CustomInterface *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
566 |
DP_IN();
|
sl@0
|
567 |
|
sl@0
|
568 |
TAny* ret = NULL;
|
sl@0
|
569 |
TInt err = KErrNone;
|
sl@0
|
570 |
|
sl@0
|
571 |
if (aInterfaceUid.iUid == KMmfPlaySettingsCustomInterface)
|
sl@0
|
572 |
{
|
sl@0
|
573 |
if (!iPlayCustomInterface)
|
sl@0
|
574 |
{
|
sl@0
|
575 |
TRAP(err,iPlayCustomInterface = new(ELeave)TToneCustomInterface());
|
sl@0
|
576 |
}
|
sl@0
|
577 |
if (err)
|
sl@0
|
578 |
{
|
sl@0
|
579 |
ret = NULL;
|
sl@0
|
580 |
}
|
sl@0
|
581 |
else
|
sl@0
|
582 |
{
|
sl@0
|
583 |
ret = static_cast<TAny*>(iPlayCustomInterface);
|
sl@0
|
584 |
}
|
sl@0
|
585 |
}
|
sl@0
|
586 |
else if (aInterfaceUid == KIgnoreUnderflowCustomInterfaceTypeUid)
|
sl@0
|
587 |
{
|
sl@0
|
588 |
if (!iDataPath)
|
sl@0
|
589 |
{
|
sl@0
|
590 |
ret = NULL;
|
sl@0
|
591 |
}
|
sl@0
|
592 |
else
|
sl@0
|
593 |
{
|
sl@0
|
594 |
ret = static_cast<CToneDataPath*>(iDataPath)->CustomInterface(aInterfaceUid);
|
sl@0
|
595 |
}
|
sl@0
|
596 |
}
|
sl@0
|
597 |
|
sl@0
|
598 |
DP_OUT();
|
sl@0
|
599 |
return ret;
|
sl@0
|
600 |
}
|
sl@0
|
601 |
|
sl@0
|
602 |
TInt CToneHwDevice::ReadToneData()
|
sl@0
|
603 |
{
|
sl@0
|
604 |
DP_CONTEXT(CToneHwDevice::ReadToneData *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
605 |
DP_IN();
|
sl@0
|
606 |
|
sl@0
|
607 |
TUint vol;
|
sl@0
|
608 |
myToneData.GetType(iToneType);
|
sl@0
|
609 |
TInt64 zeroInt64(0);
|
sl@0
|
610 |
iFrequency1 = myToneData.GetFrequencyOne();
|
sl@0
|
611 |
iFrequency2 = myToneData.GetFrequencyTwo();
|
sl@0
|
612 |
myToneData.GetDuration(iDuration);
|
sl@0
|
613 |
|
sl@0
|
614 |
myToneData.GetRepeatTrailingSilence(iRepeatTrailingSilence);
|
sl@0
|
615 |
iRepeatCount = myToneData.GetRepeatCount();
|
sl@0
|
616 |
iRampDuration = iPlayCustomInterface->VolumeRamp();
|
sl@0
|
617 |
vol = iPlayCustomInterface->Volume();
|
sl@0
|
618 |
iDataPath->Device().SetPlayVolume(vol);
|
sl@0
|
619 |
switch (iToneType)
|
sl@0
|
620 |
{
|
sl@0
|
621 |
case TToneData::ESimple:
|
sl@0
|
622 |
DP0(DLINFO, "Playing simple tone");
|
sl@0
|
623 |
iDataPath->Device().GetPlayFormat(soundDeviceSettings);
|
sl@0
|
624 |
if((iFrequency1<0) || (iDuration.Int64() < zeroInt64))
|
sl@0
|
625 |
{
|
sl@0
|
626 |
iHwDeviceObserver->Error(KErrArgument);
|
sl@0
|
627 |
DP0_RET(KErrArgument, "%d");
|
sl@0
|
628 |
}
|
sl@0
|
629 |
iToneGen.SetFrequencyAndDuration(iFrequency1,iDuration);
|
sl@0
|
630 |
// Configure tone generator
|
sl@0
|
631 |
iToneGen.Configure(
|
sl@0
|
632 |
soundDeviceSettings().iRate,
|
sl@0
|
633 |
soundDeviceSettings().iChannels,
|
sl@0
|
634 |
iRepeatCount,
|
sl@0
|
635 |
I64LOW((iRepeatTrailingSilence.Int64()*soundDeviceSettings().iRate)/1000000),
|
sl@0
|
636 |
I64LOW((iRampDuration.Int64()*soundDeviceSettings().iRate)/1000000)
|
sl@0
|
637 |
);
|
sl@0
|
638 |
iCurrentGenerator = &iToneGen;
|
sl@0
|
639 |
break;
|
sl@0
|
640 |
case TToneData::EDual:
|
sl@0
|
641 |
DP0(DLINFO, "Playing dual tone");
|
sl@0
|
642 |
iDataPath->Device().GetPlayFormat(soundDeviceSettings);
|
sl@0
|
643 |
if((iFrequency1<0) || (iFrequency2<0) || (iDuration.Int64() < zeroInt64))
|
sl@0
|
644 |
{
|
sl@0
|
645 |
iHwDeviceObserver->Error(KErrArgument);
|
sl@0
|
646 |
DP0_RET(KErrArgument, "%d");
|
sl@0
|
647 |
}
|
sl@0
|
648 |
iDualToneGen.SetFrequencyAndDuration(iFrequency1, iFrequency2, iDuration);
|
sl@0
|
649 |
// Configure dual tone generator
|
sl@0
|
650 |
iDualToneGen.Configure(
|
sl@0
|
651 |
soundDeviceSettings().iRate,
|
sl@0
|
652 |
soundDeviceSettings().iChannels,
|
sl@0
|
653 |
iRepeatCount,
|
sl@0
|
654 |
I64LOW((iRepeatTrailingSilence.Int64()*soundDeviceSettings().iRate)/KOneMillionMicroSeconds),
|
sl@0
|
655 |
I64LOW((iRampDuration.Int64()*soundDeviceSettings().iRate)/KOneMillionMicroSeconds)
|
sl@0
|
656 |
);
|
sl@0
|
657 |
iCurrentGenerator = &iDualToneGen;
|
sl@0
|
658 |
break;
|
sl@0
|
659 |
case TToneData::EDtmfString:
|
sl@0
|
660 |
DP0(DLINFO, "Playing DTMF string");
|
sl@0
|
661 |
myToneData.GetDtmfLenghts(myToneOnLength, myToneOffLength, myPauseLength);
|
sl@0
|
662 |
iDTMFGen.SetToneDurations(myToneOnLength, myToneOffLength, myPauseLength);
|
sl@0
|
663 |
iDTMFString = myToneData.GetDTMFString();
|
sl@0
|
664 |
if(!ValidDTMFString(const_cast<TDesC&>(*iDTMFString)))
|
sl@0
|
665 |
{
|
sl@0
|
666 |
DP0(DLINFO, "Invalid DTMF String");
|
sl@0
|
667 |
iHwDeviceObserver->Error(KErrCorrupt);
|
sl@0
|
668 |
DP0_RET(KErrCorrupt, "%d");
|
sl@0
|
669 |
}
|
sl@0
|
670 |
iDTMFGen.SetString(const_cast<TDesC&>(*iDTMFString));
|
sl@0
|
671 |
iDataPath->Device().GetPlayFormat(soundDeviceSettings);
|
sl@0
|
672 |
iDTMFGen.Configure(
|
sl@0
|
673 |
soundDeviceSettings().iRate,
|
sl@0
|
674 |
soundDeviceSettings().iChannels,
|
sl@0
|
675 |
iRepeatCount,
|
sl@0
|
676 |
I64LOW((iRepeatTrailingSilence.Int64()*soundDeviceSettings().iRate)/1000000),
|
sl@0
|
677 |
I64LOW((iRampDuration.Int64()*soundDeviceSettings().iRate)/1000000)
|
sl@0
|
678 |
);
|
sl@0
|
679 |
iCurrentGenerator = &iDTMFGen;
|
sl@0
|
680 |
break;
|
sl@0
|
681 |
case TToneData::ESequence:
|
sl@0
|
682 |
DP0(DLINFO, "Playing tone sequence");
|
sl@0
|
683 |
iSequenceData = myToneData.GetSequenceData();
|
sl@0
|
684 |
// Check whether the sequence is signed or not
|
sl@0
|
685 |
if (!RecognizeSequence(*iSequenceData))
|
sl@0
|
686 |
{
|
sl@0
|
687 |
DP0(DLINFO, "Invalid Sequence Sign");
|
sl@0
|
688 |
iHwDeviceObserver->Error(KErrCorrupt);
|
sl@0
|
689 |
DP0_RET(KErrCorrupt, "%d");
|
sl@0
|
690 |
}
|
sl@0
|
691 |
iSequenceGen.SetSequenceData(*iSequenceData);
|
sl@0
|
692 |
iDataPath->Device().GetPlayFormat(soundDeviceSettings);
|
sl@0
|
693 |
iSequenceGen.Configure(
|
sl@0
|
694 |
soundDeviceSettings().iRate,
|
sl@0
|
695 |
soundDeviceSettings().iChannels,
|
sl@0
|
696 |
iRepeatCount,
|
sl@0
|
697 |
I64LOW((iRepeatTrailingSilence.Int64()*soundDeviceSettings().iRate)/1000000),
|
sl@0
|
698 |
I64LOW((iRampDuration.Int64()*soundDeviceSettings().iRate)/1000000)
|
sl@0
|
699 |
);
|
sl@0
|
700 |
iCurrentGenerator = &iSequenceGen;
|
sl@0
|
701 |
break;
|
sl@0
|
702 |
case TToneData::EFixedSequence:
|
sl@0
|
703 |
DP0(DLINFO, "Playing FixedSequnce");
|
sl@0
|
704 |
iHwDeviceObserver->Error(KErrNotSupported);
|
sl@0
|
705 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
706 |
default:
|
sl@0
|
707 |
DP0_RET(KErrNotSupported, "%d");
|
sl@0
|
708 |
}
|
sl@0
|
709 |
DP0_RET(KErrNone, "%d");
|
sl@0
|
710 |
}
|
sl@0
|
711 |
|
sl@0
|
712 |
/*
|
sl@0
|
713 |
*
|
sl@0
|
714 |
* Creates buffer and begin playback using the specified tone generator.
|
sl@0
|
715 |
*
|
sl@0
|
716 |
*/
|
sl@0
|
717 |
TInt CToneHwDevice::GenerateBufferData()
|
sl@0
|
718 |
{
|
sl@0
|
719 |
DP_CONTEXT(CToneHwDevice::GenerateBufferData *CD1*, CtxDevSound, DPLOCAL);
|
sl@0
|
720 |
DP_IN();
|
sl@0
|
721 |
|
sl@0
|
722 |
TInt err;
|
sl@0
|
723 |
err = KErrNone;
|
sl@0
|
724 |
|
sl@0
|
725 |
// Delete any buffer from previous call and try to create maximum buffer
|
sl@0
|
726 |
// size. Double Buffer the Tone data.
|
sl@0
|
727 |
if (iToneBuffer1)
|
sl@0
|
728 |
{
|
sl@0
|
729 |
delete iToneBuffer1;
|
sl@0
|
730 |
iToneBuffer1 = NULL;
|
sl@0
|
731 |
}
|
sl@0
|
732 |
//note the tone buffer needs to be the same as the pcm16->pcm16 'null'
|
sl@0
|
733 |
//hw device plugin
|
sl@0
|
734 |
// Buffer size = (SampleRate * BytesPerSample * Channels) / 4
|
sl@0
|
735 |
TInt useBufferOfSize = ((SamplingFrequency() * 2 * NumberOfChannels())/KDevSoundFramesPerSecond + (KDevSoundDeltaFrameSize-1)) &~ (KDevSoundDeltaFrameSize-1);
|
sl@0
|
736 |
//clamp buffer to desired limits
|
sl@0
|
737 |
if(useBufferOfSize < KDevSoundMinFrameSize)
|
sl@0
|
738 |
{
|
sl@0
|
739 |
useBufferOfSize = KDevSoundMinFrameSize;
|
sl@0
|
740 |
}
|
sl@0
|
741 |
else if(useBufferOfSize > KDevSoundMaxFrameSize)
|
sl@0
|
742 |
{
|
sl@0
|
743 |
useBufferOfSize = KDevSoundMaxFrameSize;
|
sl@0
|
744 |
}
|
sl@0
|
745 |
|
sl@0
|
746 |
TRAP(err, iToneBuffer1 = CMMFDataBuffer::NewL(useBufferOfSize));
|
sl@0
|
747 |
if ( err != KErrNone )
|
sl@0
|
748 |
{
|
sl@0
|
749 |
DP0_RET(err, "%d");
|
sl@0
|
750 |
}
|
sl@0
|
751 |
|
sl@0
|
752 |
err = iCurrentGenerator->FillBuffer(iToneBuffer1->Data());
|
sl@0
|
753 |
if(err!=KErrNone)
|
sl@0
|
754 |
{
|
sl@0
|
755 |
DP0_RET(err, "%d");
|
sl@0
|
756 |
}
|
sl@0
|
757 |
|
sl@0
|
758 |
if (iToneBuffer2)
|
sl@0
|
759 |
{
|
sl@0
|
760 |
delete iToneBuffer2;
|
sl@0
|
761 |
iToneBuffer2 = NULL;
|
sl@0
|
762 |
}
|
sl@0
|
763 |
|
sl@0
|
764 |
TRAP(err, iToneBuffer2 = CMMFDataBuffer::NewL(useBufferOfSize));
|
sl@0
|
765 |
if ( err != KErrNone )
|
sl@0
|
766 |
{
|
sl@0
|
767 |
DP0_RET(err, "%d");
|
sl@0
|
768 |
}
|
sl@0
|
769 |
|
sl@0
|
770 |
err = iCurrentGenerator->FillBuffer(iToneBuffer2->Data());
|
sl@0
|
771 |
if(err!=KErrNone)
|
sl@0
|
772 |
{
|
sl@0
|
773 |
DP0_RET(err, "%d");
|
sl@0
|
774 |
}
|
sl@0
|
775 |
|
sl@0
|
776 |
// Assign active buffer
|
sl@0
|
777 |
iActiveToneBuffer = iToneBuffer1;
|
sl@0
|
778 |
DP0_RET(KErrNone, "%d");
|
sl@0
|
779 |
}
|
sl@0
|
780 |
|
sl@0
|
781 |
/*
|
sl@0
|
782 |
*
|
sl@0
|
783 |
* This method assigns the other buffer as active buffer. The tone audio
|
sl@0
|
784 |
* generator should fill data in the other buffer by now.
|
sl@0
|
785 |
*
|
sl@0
|
786 |
*/
|
sl@0
|
787 |
void CToneHwDevice::SetActiveToneBuffer()
|
sl@0
|
788 |
{
|
sl@0
|
789 |
if (iActiveToneBuffer == iToneBuffer1)
|
sl@0
|
790 |
iActiveToneBuffer = iToneBuffer2;
|
sl@0
|
791 |
else if (iActiveToneBuffer == iToneBuffer2)
|
sl@0
|
792 |
iActiveToneBuffer = iToneBuffer1;
|
sl@0
|
793 |
}
|
sl@0
|
794 |
|
sl@0
|
795 |
|
sl@0
|
796 |
void CToneHwDevice::FreeBuffers()
|
sl@0
|
797 |
{
|
sl@0
|
798 |
if(iToneBuffer1)
|
sl@0
|
799 |
{
|
sl@0
|
800 |
delete iToneBuffer1;
|
sl@0
|
801 |
iToneBuffer1 = NULL;
|
sl@0
|
802 |
}
|
sl@0
|
803 |
if(iToneBuffer2)
|
sl@0
|
804 |
{
|
sl@0
|
805 |
delete iToneBuffer2;
|
sl@0
|
806 |
iToneBuffer2 = NULL;
|
sl@0
|
807 |
}
|
sl@0
|
808 |
}
|
sl@0
|
809 |
|
sl@0
|
810 |
/*
|
sl@0
|
811 |
*
|
sl@0
|
812 |
* Returns an integer representing Sampling Frequency the device is currently
|
sl@0
|
813 |
* configured to.
|
sl@0
|
814 |
*
|
sl@0
|
815 |
* @return "TInt"
|
sl@0
|
816 |
* Sampling Frequency.
|
sl@0
|
817 |
*
|
sl@0
|
818 |
*/
|
sl@0
|
819 |
TInt CToneHwDevice::SamplingFrequency()
|
sl@0
|
820 |
{
|
sl@0
|
821 |
return iSampleRate;
|
sl@0
|
822 |
}
|
sl@0
|
823 |
|
sl@0
|
824 |
/*
|
sl@0
|
825 |
*
|
sl@0
|
826 |
* Returns an integer representing number of channels the device is currently
|
sl@0
|
827 |
* configured to.
|
sl@0
|
828 |
*
|
sl@0
|
829 |
* @return "TInt"
|
sl@0
|
830 |
* Number of audio channels 1 if mono, 2 if stereo.
|
sl@0
|
831 |
*
|
sl@0
|
832 |
*/
|
sl@0
|
833 |
TInt CToneHwDevice::NumberOfChannels()
|
sl@0
|
834 |
{
|
sl@0
|
835 |
if(iChannels == EMMFMono)
|
sl@0
|
836 |
return 1;
|
sl@0
|
837 |
else
|
sl@0
|
838 |
return 2;
|
sl@0
|
839 |
}
|
sl@0
|
840 |
|
sl@0
|
841 |
/*
|
sl@0
|
842 |
*
|
sl@0
|
843 |
* This method fills data into the free buffer.
|
sl@0
|
844 |
*
|
sl@0
|
845 |
* @return "TInt"
|
sl@0
|
846 |
* Error code. KErrNone if success.
|
sl@0
|
847 |
*
|
sl@0
|
848 |
*/
|
sl@0
|
849 |
TInt CToneHwDevice::FillFreeToneBuffer()
|
sl@0
|
850 |
{
|
sl@0
|
851 |
TInt err(KErrNone);
|
sl@0
|
852 |
if (iActiveToneBuffer == iToneBuffer1)
|
sl@0
|
853 |
{
|
sl@0
|
854 |
err = iCurrentGenerator->FillBuffer(iToneBuffer2->Data());
|
sl@0
|
855 |
}
|
sl@0
|
856 |
else if (iActiveToneBuffer == iToneBuffer2)
|
sl@0
|
857 |
{
|
sl@0
|
858 |
err = iCurrentGenerator->FillBuffer(iToneBuffer1->Data());
|
sl@0
|
859 |
}
|
sl@0
|
860 |
return err;
|
sl@0
|
861 |
}
|
sl@0
|
862 |
|
sl@0
|
863 |
TBool CToneHwDevice::RecognizeSequence(const TDesC8& aData)
|
sl@0
|
864 |
{
|
sl@0
|
865 |
// Reference plug-in only supports its own sequence format
|
sl@0
|
866 |
_LIT8(KSequenceSignature,"SQNC");
|
sl@0
|
867 |
if (aData.Length() > 4)
|
sl@0
|
868 |
{
|
sl@0
|
869 |
if (aData.Left(4) == KSequenceSignature)
|
sl@0
|
870 |
{
|
sl@0
|
871 |
return ETrue;
|
sl@0
|
872 |
}
|
sl@0
|
873 |
}
|
sl@0
|
874 |
// Didn't recognise
|
sl@0
|
875 |
return EFalse;
|
sl@0
|
876 |
}
|
sl@0
|
877 |
|
sl@0
|
878 |
TBool CToneHwDevice::ValidDTMFString(const TDesC& aDTMFString)
|
sl@0
|
879 |
{
|
sl@0
|
880 |
const TDesC* stringDTMF = &aDTMFString;;
|
sl@0
|
881 |
TInt stringPos = 0;
|
sl@0
|
882 |
if (stringPos == stringDTMF->Length())
|
sl@0
|
883 |
{
|
sl@0
|
884 |
return EFalse; // Finished. Nothing to do
|
sl@0
|
885 |
}
|
sl@0
|
886 |
do
|
sl@0
|
887 |
{
|
sl@0
|
888 |
TChar c((*stringDTMF)[stringPos++]);
|
sl@0
|
889 |
if (static_cast<TUint> (c)=='#' || static_cast<TUint> (c)=='*' || static_cast<TUint> (c)==',' || c.IsHexDigit() || c.IsSpace())
|
sl@0
|
890 |
{
|
sl@0
|
891 |
//Do nothing, valid character
|
sl@0
|
892 |
}
|
sl@0
|
893 |
else
|
sl@0
|
894 |
{
|
sl@0
|
895 |
return EFalse;
|
sl@0
|
896 |
}
|
sl@0
|
897 |
|
sl@0
|
898 |
}
|
sl@0
|
899 |
while(stringPos < stringDTMF->Length());
|
sl@0
|
900 |
return ETrue;
|
sl@0
|
901 |
}
|
sl@0
|
902 |
|
sl@0
|
903 |
|
sl@0
|
904 |
/************************************************************************
|
sl@0
|
905 |
* TToneCustomInterface *
|
sl@0
|
906 |
************************************************************************/
|
sl@0
|
907 |
/**
|
sl@0
|
908 |
* This method is not be exported as it is only
|
sl@0
|
909 |
* intended to be called within this DLL.
|
sl@0
|
910 |
* It's purpose is to assign an RMdaDevSound to the play
|
sl@0
|
911 |
* custom interface
|
sl@0
|
912 |
* @internalComponent
|
sl@0
|
913 |
*/
|
sl@0
|
914 |
void TToneCustomInterface::SetDevice(RMdaDevSound* aDevice)
|
sl@0
|
915 |
{
|
sl@0
|
916 |
iDevice = aDevice;
|
sl@0
|
917 |
}
|
sl@0
|
918 |
|
sl@0
|
919 |
void TToneCustomInterface::SetVolume(TUint aVolume)
|
sl@0
|
920 |
{
|
sl@0
|
921 |
iVolume = aVolume;
|
sl@0
|
922 |
if (iDevice && iDevice->Handle()!=0)
|
sl@0
|
923 |
{
|
sl@0
|
924 |
iDevice->SetPlayVolume(aVolume);
|
sl@0
|
925 |
}
|
sl@0
|
926 |
}
|
sl@0
|
927 |
|
sl@0
|
928 |
/**
|
sl@0
|
929 |
* Procedure to get the number of bytes played by the device driver
|
sl@0
|
930 |
* If there is no handle available to the device driver then the
|
sl@0
|
931 |
* procedure returns the last known value
|
sl@0
|
932 |
* @released
|
sl@0
|
933 |
* @return number of bytes played
|
sl@0
|
934 |
*/
|
sl@0
|
935 |
TUint TToneCustomInterface::BytesPlayed()
|
sl@0
|
936 |
{
|
sl@0
|
937 |
if(iDevice)
|
sl@0
|
938 |
{
|
sl@0
|
939 |
if (iDevice->Handle())
|
sl@0
|
940 |
{
|
sl@0
|
941 |
iBytesPlayed = iDevice->BytesPlayed();
|
sl@0
|
942 |
}
|
sl@0
|
943 |
}
|
sl@0
|
944 |
return iBytesPlayed;
|
sl@0
|
945 |
}
|
sl@0
|
946 |
|
sl@0
|
947 |
|
sl@0
|
948 |
//
|
sl@0
|
949 |
// class CToneCodec //
|
sl@0
|
950 |
//
|
sl@0
|
951 |
|
sl@0
|
952 |
// ---------------------------------------------------------------------------
|
sl@0
|
953 |
// from class CToneCodec
|
sl@0
|
954 |
// CToneCodec::CToneCodec
|
sl@0
|
955 |
// ---------------------------------------------------------------------------
|
sl@0
|
956 |
//
|
sl@0
|
957 |
CToneCodec::CToneCodec()
|
sl@0
|
958 |
{
|
sl@0
|
959 |
}
|
sl@0
|
960 |
|
sl@0
|
961 |
// ---------------------------------------------------------------------------
|
sl@0
|
962 |
// from class CToneCodec
|
sl@0
|
963 |
// CToneCodec::~CToneCodec
|
sl@0
|
964 |
// ---------------------------------------------------------------------------
|
sl@0
|
965 |
//
|
sl@0
|
966 |
CToneCodec::~CToneCodec()
|
sl@0
|
967 |
{
|
sl@0
|
968 |
}
|
sl@0
|
969 |
|
sl@0
|
970 |
// ---------------------------------------------------------------------------
|
sl@0
|
971 |
// from class CToneCodec
|
sl@0
|
972 |
// CToneCodec::ConstructL
|
sl@0
|
973 |
// ---------------------------------------------------------------------------
|
sl@0
|
974 |
//
|
sl@0
|
975 |
void CToneCodec::ConstructL()
|
sl@0
|
976 |
{
|
sl@0
|
977 |
}
|
sl@0
|
978 |
|
sl@0
|
979 |
|
sl@0
|
980 |
// ---------------------------------------------------------------------------
|
sl@0
|
981 |
// from class CToneCodec
|
sl@0
|
982 |
// CToneCodec::ProcessL
|
sl@0
|
983 |
// ---------------------------------------------------------------------------
|
sl@0
|
984 |
//
|
sl@0
|
985 |
CToneCodec::TCodecProcessResult CToneCodec::ProcessL(const CMMFBuffer& /*aSource*/, CMMFBuffer& /*aDest*/)
|
sl@0
|
986 |
{
|
sl@0
|
987 |
//no processing required for null codec
|
sl@0
|
988 |
User::Leave(KErrNotSupported);
|
sl@0
|
989 |
//to keep compiler happy
|
sl@0
|
990 |
TCodecProcessResult result;
|
sl@0
|
991 |
result.iCodecProcessStatus = TCodecProcessResult::EEndOfData;
|
sl@0
|
992 |
result.iSrcBytesProcessed = 0;
|
sl@0
|
993 |
result.iDstBytesAdded = 0;
|
sl@0
|
994 |
return result;
|
sl@0
|
995 |
}
|
sl@0
|
996 |
|
sl@0
|
997 |
// ---------------------------------------------------------------------------
|
sl@0
|
998 |
// from class CToneCodec
|
sl@0
|
999 |
// CToneCodec::SourceBufferSize
|
sl@0
|
1000 |
// ---------------------------------------------------------------------------
|
sl@0
|
1001 |
//
|
sl@0
|
1002 |
TUint CToneCodec::SourceBufferSize()
|
sl@0
|
1003 |
{
|
sl@0
|
1004 |
return KPCM16ToPCM16BufferSize;
|
sl@0
|
1005 |
}
|
sl@0
|
1006 |
|
sl@0
|
1007 |
// ---------------------------------------------------------------------------
|
sl@0
|
1008 |
// from class CToneCodec
|
sl@0
|
1009 |
// CToneCodec::SinkBufferSize
|
sl@0
|
1010 |
// ---------------------------------------------------------------------------
|
sl@0
|
1011 |
//
|
sl@0
|
1012 |
TUint CToneCodec::SinkBufferSize()
|
sl@0
|
1013 |
{
|
sl@0
|
1014 |
return KPCM16ToPCM16BufferSize;
|
sl@0
|
1015 |
}
|
sl@0
|
1016 |
|
sl@0
|
1017 |
|
sl@0
|
1018 |
// ========================== OTHER EXPORTED FUNCTIONS =========================
|
sl@0
|
1019 |
/**
|
sl@0
|
1020 |
* ImplementationGroupProxy
|
sl@0
|
1021 |
* is called to get a pointer to the plugin's implementation table, or table
|
sl@0
|
1022 |
* of functions used to instantiate the plugin.
|
sl@0
|
1023 |
* @since
|
sl@0
|
1024 |
* @param aTableCount returns the number of functions in the table.
|
sl@0
|
1025 |
* @return retuns a pointer to the table.
|
sl@0
|
1026 |
*/
|
sl@0
|
1027 |
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
|
sl@0
|
1028 |
{
|
sl@0
|
1029 |
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
|
sl@0
|
1030 |
return ImplementationTable;
|
sl@0
|
1031 |
}
|