|
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 |