0
|
1 |
// Copyright (c) 2006-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 the License "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 |
// template\template_variant\specific\soundsc_rx.cpp
|
|
15 |
// Implementation of the Template record shared chunk sound physical device driver (PDD).
|
|
16 |
// This file is part of the Template Base port
|
|
17 |
//
|
|
18 |
//
|
|
19 |
|
|
20 |
/**
|
|
21 |
@file
|
|
22 |
*/
|
|
23 |
|
|
24 |
#include "soundsc_plat.h"
|
|
25 |
|
|
26 |
|
|
27 |
/**
|
|
28 |
Constructor for the Template record shared chunk sound driver physical device driver (PDD).
|
|
29 |
*/
|
|
30 |
DTemplateSoundScRxPdd::DTemplateSoundScRxPdd()
|
|
31 |
{
|
|
32 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::DTemplateSoundScRxPdd"));
|
|
33 |
|
|
34 |
// iDmaChan=NULL;
|
|
35 |
// iPendingRecord=0;
|
|
36 |
// iFlag=0;
|
|
37 |
}
|
|
38 |
|
|
39 |
/**
|
|
40 |
Destructor for the Template record shared chunk sound driver physical device driver (PDD).
|
|
41 |
*/
|
|
42 |
DTemplateSoundScRxPdd::~DTemplateSoundScRxPdd()
|
|
43 |
{
|
|
44 |
// Delete the DMA request objects
|
|
45 |
for (TInt i=0; i<KTemplateMaxRxDmaRequests; i++)
|
|
46 |
{
|
|
47 |
if (iDmaRequest[i])
|
|
48 |
delete iDmaRequest[i];
|
|
49 |
}
|
|
50 |
|
|
51 |
// Close the DMA channel.
|
|
52 |
if (iDmaChannel)
|
|
53 |
iDmaChannel->Close();
|
|
54 |
}
|
|
55 |
|
|
56 |
/**
|
|
57 |
Second stage constructor for the Template record shared chunk sound driver physical device driver (PDD).
|
|
58 |
Note that this constructor is called before the second stage constructor for the LDD so it is not
|
|
59 |
possible to call methods on the LDD here.
|
|
60 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
61 |
*/
|
|
62 |
TInt DTemplateSoundScRxPdd::DoCreate()
|
|
63 |
{
|
|
64 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::DoCreate"));
|
|
65 |
|
|
66 |
SetCaps(); // Setup the capabilities of this device.
|
|
67 |
|
|
68 |
// Setup a DMA channel for record
|
|
69 |
// TO DO: (mandatory)
|
|
70 |
// Setup the DMA channel information for this record device.
|
|
71 |
TDmaChannel::SCreateInfo info;
|
|
72 |
// info.iCookie=???
|
|
73 |
info.iDfcQ=DfcQ(KSoundScRxUnit0);
|
|
74 |
// info.iDfcPriority=???
|
|
75 |
info.iDesCount=KTemplateMaxRxDmaRequests;
|
|
76 |
// coverity[uninit_use_in_call]
|
|
77 |
// The values info.iCookie and info.iDfcPriority are to be initialized when implemented
|
|
78 |
TInt r=TDmaChannel::Open(info,iDmaChannel);
|
|
79 |
|
|
80 |
// Create the DMA request objects for use with the DMA channel.
|
|
81 |
if (r==KErrNone)
|
|
82 |
{
|
|
83 |
for (TInt i=0; i<KTemplateMaxRxDmaRequests; i++)
|
|
84 |
{
|
|
85 |
iDmaRequest[i] = new DTemplateSoundScRxDmaRequest(*iDmaChannel,this);
|
|
86 |
if (iDmaRequest[i] == NULL)
|
|
87 |
{
|
|
88 |
r=KErrNoMemory;
|
|
89 |
break;
|
|
90 |
}
|
|
91 |
}
|
|
92 |
}
|
|
93 |
|
|
94 |
__KTRACE_SND(Kern::Printf("<DTemplateSoundScRxPdd::DoCreate - %d",r));
|
|
95 |
return(r);
|
|
96 |
}
|
|
97 |
|
|
98 |
/**
|
|
99 |
Return the DFC queue to be used by this record device.
|
|
100 |
@return The DFC queue to use.
|
|
101 |
*/
|
|
102 |
TDfcQue* DTemplateSoundScRxPdd::DfcQ(TInt /*aUnit*/)
|
|
103 |
{
|
|
104 |
return(iPhysicalDevice->iDfcQ);
|
|
105 |
}
|
|
106 |
|
|
107 |
/**
|
|
108 |
Called from the LDD to return the shared chunk create information to be used by this record device.
|
|
109 |
@param aChunkCreateInfo A chunk create info. object to be to be filled with the settings
|
|
110 |
required for this device.
|
|
111 |
*/
|
|
112 |
void DTemplateSoundScRxPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)
|
|
113 |
{
|
|
114 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::GetChunkCreateInfo"));
|
|
115 |
|
|
116 |
// TO DO: (mandatory)
|
|
117 |
// Setup the shared chunk create information in aChunkCreateInfo for this record device.
|
|
118 |
aChunkCreateInfo.iType=TChunkCreateInfo::ESharedKernelMultiple;
|
|
119 |
// aChunkCreateInfo.iMapAttr=???
|
|
120 |
aChunkCreateInfo.iOwnsMemory=ETrue; // Using RAM pages.
|
|
121 |
aChunkCreateInfo.iDestroyedDfc=NULL; // No chunk destroy DFC.
|
|
122 |
}
|
|
123 |
|
|
124 |
/**
|
|
125 |
Called from the LDD to return the capabilities of this device.
|
|
126 |
@param aCapsBuf A packaged TSoundFormatsSupportedV02 object to be filled with the record
|
|
127 |
capabilities of this device. This descriptor is in kernel memory and can be accessed directly.
|
|
128 |
@see TSoundFormatsSupportedV02.
|
|
129 |
*/
|
|
130 |
void DTemplateSoundScRxPdd::Caps(TDes8& aCapsBuf) const
|
|
131 |
{
|
|
132 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::Caps"));
|
|
133 |
|
|
134 |
// Copy iCaps back.
|
|
135 |
TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps));
|
|
136 |
aCapsBuf.FillZ(aCapsBuf.MaxLength());
|
|
137 |
aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength()));
|
|
138 |
}
|
|
139 |
|
|
140 |
/**
|
|
141 |
Called from the LDD to return the maximum transfer length in bytes that this device can support in a single data transfer.
|
|
142 |
@return The maximum transfer length in bytes.
|
|
143 |
*/
|
|
144 |
TInt DTemplateSoundScRxPdd::MaxTransferLen() const
|
|
145 |
{
|
|
146 |
return(KTemplateMaxRxDmaTransferLen);
|
|
147 |
}
|
|
148 |
|
|
149 |
/**
|
|
150 |
Called from the LDD to configure or reconfigure the device using the the configuration supplied.
|
|
151 |
@param aConfigBuf A packaged TCurrentSoundFormatV02 object which contains the new configuration settings.
|
|
152 |
This descriptor is in kernel memory and can be accessed directly.
|
|
153 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
154 |
@see TCurrentSoundFormatV02.
|
|
155 |
*/
|
|
156 |
TInt DTemplateSoundScRxPdd::SetConfig(const TDesC8& aConfigBuf)
|
|
157 |
{
|
|
158 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::SetConfig"));
|
|
159 |
|
|
160 |
// Read the new configuration from the LDD.
|
|
161 |
TCurrentSoundFormatV02 config;
|
|
162 |
TPtr8 ptr((TUint8*)&config,sizeof(config));
|
|
163 |
Kern::InfoCopy(ptr,aConfigBuf);
|
|
164 |
|
|
165 |
// TO DO: (mandatory)
|
|
166 |
// Apply the specified audio configuration to the audio device.
|
|
167 |
TInt r=KErrNone;
|
|
168 |
|
|
169 |
__KTRACE_SND(Kern::Printf("<DTemplateSoundScRxPdd::SetConfig - %d",r));
|
|
170 |
return(r);
|
|
171 |
}
|
|
172 |
|
|
173 |
/**
|
|
174 |
Called from the LDD to set the record level.
|
|
175 |
@param aVolume The record level to be set - a value in the range 0 to 255. The value 255 equates
|
|
176 |
to the maximum record level and each value below this equates to a 0.5dB step below it.
|
|
177 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
178 |
*/
|
|
179 |
TInt DTemplateSoundScRxPdd::SetVolume(TInt aVolume)
|
|
180 |
{
|
|
181 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::SetVolume"));
|
|
182 |
|
|
183 |
// TO DO: (mandatory)
|
|
184 |
// Set the specified record volume on the audio device.
|
|
185 |
TInt r=KErrNone;
|
|
186 |
|
|
187 |
return(r);
|
|
188 |
}
|
|
189 |
|
|
190 |
/**
|
|
191 |
Called from the LDD to prepare the audio device for recording.
|
|
192 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
193 |
*/
|
|
194 |
TInt DTemplateSoundScRxPdd::StartTransfer()
|
|
195 |
{
|
|
196 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::StartTransfer"));
|
|
197 |
|
|
198 |
// TO DO: (mandatory)
|
|
199 |
// Prepare the audio device for record.
|
|
200 |
TInt r=KErrNone;
|
|
201 |
|
|
202 |
__KTRACE_SND(Kern::Printf("<DTemplateSoundScRxPdd::StartTransfer - %d",r));
|
|
203 |
return(r);
|
|
204 |
}
|
|
205 |
|
|
206 |
/**
|
|
207 |
Called from the LDD to initiate the recording of a portion of data from the audio device.
|
|
208 |
When the transfer is complete, the PDD signals this event using the LDD function RecordCallback().
|
|
209 |
@param aTransferID A value assigned by the LDD to allow it to uniquely identify a particular transfer fragment.
|
|
210 |
@param aLinAddr The linear address within the shared chunk for storing the recorded data.
|
|
211 |
@param aPhysAddr The physical address within the shared chunk for storing the recorded data.
|
|
212 |
@param aNumBytes The number of bytes to be recorded.
|
|
213 |
@return KErrNone if the transfer has been initiated successfully;
|
|
214 |
KErrNotReady if the device is unable to accept the transfer for the moment;
|
|
215 |
otherwise one of the other system-wide error codes.
|
|
216 |
*/
|
|
217 |
TInt DTemplateSoundScRxPdd::TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr /*aPhysAddr*/,TInt aNumBytes)
|
|
218 |
{
|
|
219 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::TransferData(ID:%xH,Addr:%xH,Len:%d)",aLinAddr,aNumBytes));
|
|
220 |
|
|
221 |
TInt r=KErrNone;
|
|
222 |
|
|
223 |
// Check that we can accept the request
|
|
224 |
if (iPendingRecord>=KTemplateMaxRxDmaRequests)
|
|
225 |
r=KErrNotReady;
|
|
226 |
else
|
|
227 |
{
|
|
228 |
// Start a DMA transfer.
|
|
229 |
iDmaRequest[iFlag]->iTransferID=aTransferID;
|
|
230 |
iDmaRequest[iFlag]->iTransferSize=aNumBytes;
|
|
231 |
// TO DO: (mandatory)
|
|
232 |
// Supply the DMA source information.
|
|
233 |
TUint32 src=0; // ???
|
|
234 |
r=iDmaRequest[iFlag]->Fragment(src,aLinAddr,aNumBytes,KDmaMemDest|KDmaIncDest,0);
|
|
235 |
if (r==KErrNone)
|
|
236 |
{
|
|
237 |
iDmaRequest[iFlag]->Queue();
|
|
238 |
iPendingRecord++;
|
|
239 |
if ((++iFlag)>=KTemplateMaxRxDmaRequests)
|
|
240 |
iFlag=0;
|
|
241 |
|
|
242 |
// TO DO: (mandatory)
|
|
243 |
// Start the audio device transfering data.
|
|
244 |
}
|
|
245 |
}
|
|
246 |
|
|
247 |
__KTRACE_SND(Kern::Printf("<DTemplateSoundScRxPdd::TransferData - %d",r));
|
|
248 |
return(r);
|
|
249 |
}
|
|
250 |
|
|
251 |
/**
|
|
252 |
Called from the LDD to terminate the recording of a data from the device and to release any resources necessary for
|
|
253 |
recording.
|
|
254 |
The LDD will leave the audio device capturing record data even when there are no record requests pending from the client.
|
|
255 |
Transfer will only be terminated when the client either issues RSoundSc::CancelRecordData() or closes the channel. Once
|
|
256 |
this function had been called, the LDD will not issue any further TransferData() commands without first issueing a
|
|
257 |
StartTransfer() command.
|
|
258 |
*/
|
|
259 |
void DTemplateSoundScRxPdd::StopTransfer()
|
|
260 |
{
|
|
261 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::StopTransfer"));
|
|
262 |
|
|
263 |
// Stop the DMA channel.
|
|
264 |
iDmaChannel->CancelAll();
|
|
265 |
iFlag=0;
|
|
266 |
iPendingRecord=0;
|
|
267 |
|
|
268 |
// TO DO: (mandatory)
|
|
269 |
// Stop the audio device transfering data.
|
|
270 |
}
|
|
271 |
|
|
272 |
/**
|
|
273 |
Called from the LDD to halt the recording of data from the sound device but not to release any resources necessary for
|
|
274 |
recording.
|
|
275 |
All active transfers should be aborted. When recording is halted the PDD signals this event with a single call of the LDD
|
|
276 |
function RecordCallback() - reporting back any partial data already received. If transfer is resumed later, the LDD will
|
|
277 |
issue a new TransferData() request to re-commence data transfer.
|
|
278 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
279 |
*/
|
|
280 |
TInt DTemplateSoundScRxPdd::PauseTransfer()
|
|
281 |
{
|
|
282 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::PauseTransfer"));
|
|
283 |
|
|
284 |
// Stop the DMA channel.
|
|
285 |
iDmaChannel->CancelAll();
|
|
286 |
|
|
287 |
if (iPendingRecord)
|
|
288 |
{
|
|
289 |
// TO DO: (mandatory)
|
|
290 |
// Determine how much data was successfully transferred to the record buffer before transfer was aborted.
|
|
291 |
TInt byteCount=0; // ???
|
|
292 |
Ldd()->RecordCallback(0,KErrNone,byteCount); // We can use a NULL transfer ID when pausing.
|
|
293 |
iPendingRecord=0;
|
|
294 |
}
|
|
295 |
iFlag=0;
|
|
296 |
|
|
297 |
// TO DO: (mandatory)
|
|
298 |
// Halt recording on the audio device.
|
|
299 |
TInt r=KErrNone;
|
|
300 |
|
|
301 |
return(r);
|
|
302 |
}
|
|
303 |
|
|
304 |
/**
|
|
305 |
Called from the LDD to resume the recording of data from the sound device following a request to halt recording.
|
|
306 |
Any active transfer would have been aborted when the device was halted so its just a case of re-creating the same setup
|
|
307 |
acheived following StartTransfer().
|
|
308 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
309 |
*/
|
|
310 |
TInt DTemplateSoundScRxPdd::ResumeTransfer()
|
|
311 |
{
|
|
312 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::ResumeTransfer"));
|
|
313 |
|
|
314 |
// TO DO: (mandatory)
|
|
315 |
// Resume recording on the audio device.
|
|
316 |
TInt r=KErrNone;
|
|
317 |
|
|
318 |
return(r);
|
|
319 |
}
|
|
320 |
|
|
321 |
/**
|
|
322 |
Called from the LDD to power up the sound device when the channel is first opened and if ever the phone is brought out
|
|
323 |
of standby mode.
|
|
324 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
325 |
*/
|
|
326 |
TInt DTemplateSoundScRxPdd::PowerUp()
|
|
327 |
{
|
|
328 |
// TO DO: (mandatory)
|
|
329 |
// Power up the audio device.
|
|
330 |
|
|
331 |
return(KErrNone);
|
|
332 |
}
|
|
333 |
|
|
334 |
/**
|
|
335 |
Called from the LDD to power down the sound device when the channel is closed and just before the phone powers down when
|
|
336 |
being turned off or going into standby.
|
|
337 |
*/
|
|
338 |
void DTemplateSoundScRxPdd::PowerDown()
|
|
339 |
{
|
|
340 |
// TO DO: (mandatory)
|
|
341 |
// Power down the audio device.
|
|
342 |
}
|
|
343 |
|
|
344 |
/**
|
|
345 |
Called from the LDD to handle a custom configuration request.
|
|
346 |
@param aFunction A number identifying the request.
|
|
347 |
@param aParam A 32-bit value passed to the driver. Its meaning depends on the request.
|
|
348 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
349 |
*/
|
|
350 |
TInt DTemplateSoundScRxPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/)
|
|
351 |
{
|
|
352 |
return(KErrNotSupported);
|
|
353 |
}
|
|
354 |
|
|
355 |
/**
|
|
356 |
Called from the LDD to find out how many microseconds of data have been recorded. This is called
|
|
357 |
in the context of the DFC thread.
|
|
358 |
@param aTimeTransferred A reference to a variable into which to place the number of microseconds of audio.
|
|
359 |
@param aStatus The current status of this channel
|
|
360 |
@return KErrNone if time is valid or KErrNotSupported.
|
|
361 |
*/
|
|
362 |
TInt DTemplateSoundScRxPdd::TimeTransferred(TInt64& aTimeTransferred, TInt aStatus)
|
|
363 |
{
|
|
364 |
return(KErrNotSupported);
|
|
365 |
}
|
|
366 |
|
|
367 |
/**
|
|
368 |
Called each time a record DMA transfer completes - from the DMA callback function in the sound thread's DFC context.
|
|
369 |
@param aTransferID The transfer ID of the DMA transfer.
|
|
370 |
@param aTransferResult The result of the DMA transfer.
|
|
371 |
@param aBytesTransferred The number of bytes transferred.
|
|
372 |
*/
|
|
373 |
void DTemplateSoundScRxPdd::RecordCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesTransferred)
|
|
374 |
{
|
|
375 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::RecordCallback"));
|
|
376 |
|
|
377 |
iPendingRecord--;
|
|
378 |
|
|
379 |
Ldd()->RecordCallback(aTransferID,aTransferResult,aBytesTransferred);
|
|
380 |
}
|
|
381 |
|
|
382 |
/**
|
|
383 |
Initialise the data member DTemplateSoundScRxPdd::iCaps with the record capabilities of this audio device.
|
|
384 |
*/
|
|
385 |
void DTemplateSoundScRxPdd::SetCaps()
|
|
386 |
{
|
|
387 |
__KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::SetCaps"));
|
|
388 |
|
|
389 |
// The data transfer direction for this unit is record.
|
|
390 |
iCaps.iDirection=ESoundDirRecord;
|
|
391 |
|
|
392 |
// TO DO: (mandatory)
|
|
393 |
// Setup the rest of the capabilities structure DTemplateSoundScRxPdd::iCaps with the capabilities of this
|
|
394 |
// audio record device.
|
|
395 |
}
|
|
396 |
|
|
397 |
/**
|
|
398 |
Constructor for a shared chunk sound driver record DMA request.
|
|
399 |
*/
|
|
400 |
DTemplateSoundScRxDmaRequest::DTemplateSoundScRxDmaRequest(TDmaChannel& aChannel,DTemplateSoundScRxPdd* aPdd,TInt aMaxTransferSize)
|
|
401 |
: DDmaRequest(aChannel,DTemplateSoundScRxDmaRequest::DmaService,this,aMaxTransferSize),
|
|
402 |
iPdd(aPdd)
|
|
403 |
{}
|
|
404 |
|
|
405 |
/**
|
|
406 |
DMA rx service routine. Called in the sound thread's DFC context by the s/w DMA controller.
|
|
407 |
@param aResult Status of DMA transfer.
|
|
408 |
@param aArg Argument passed to DMA controller.
|
|
409 |
*/
|
|
410 |
void DTemplateSoundScRxDmaRequest::DmaService(TResult aResult, TAny* aArg)
|
|
411 |
{
|
|
412 |
__KTRACE_SND(Kern::Printf(">SndRxDmaService - %d",aResult));
|
|
413 |
DTemplateSoundScRxDmaRequest& req=*(DTemplateSoundScRxDmaRequest*)aArg;
|
|
414 |
|
|
415 |
TInt res=KErrNone;
|
|
416 |
TInt bytesTransferred=req.iTransferSize;
|
|
417 |
if (aResult!=DDmaRequest::EOk)
|
|
418 |
{
|
|
419 |
res=KErrCorrupt;
|
|
420 |
bytesTransferred=0;
|
|
421 |
}
|
|
422 |
|
|
423 |
// Inform the LDD of the result of the transfer.
|
|
424 |
req.iPdd->RecordCallback(req.iTransferID,res,bytesTransferred);
|
|
425 |
return;
|
|
426 |
}
|
|
427 |
|