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 |
// e32\include\drivers\soundsc.h
|
|
15 |
// Kernel side definitions for the shared chunk sound driver.
|
|
16 |
//
|
|
17 |
//
|
|
18 |
|
|
19 |
/**
|
|
20 |
@file
|
|
21 |
@internalTechnology
|
|
22 |
@prototype
|
|
23 |
*/
|
|
24 |
|
|
25 |
#ifndef __SOUNDSC_H__
|
|
26 |
#define __SOUNDSC_H__
|
|
27 |
|
|
28 |
#include <d32soundsc.h>
|
|
29 |
#include <platform.h>
|
|
30 |
#include <kernel/kpower.h>
|
|
31 |
#include <e32ver.h>
|
|
32 |
|
|
33 |
/** The maximum number of client transfer requests which may be outstanding in a particular direction at any time. */
|
|
34 |
const TInt KMaxSndScRequestsPending=8;
|
|
35 |
|
|
36 |
/**
|
|
37 |
A bit-mask value for the sound configuration status variable DSoundScLdd::iSoundConfigFlags. This being set signifies
|
|
38 |
that the sound configuration has been set in hardware by the driver.
|
|
39 |
*/
|
|
40 |
const TUint KSndScSoundConfigIsSetup=0x00000001;
|
|
41 |
/**
|
|
42 |
A bit-mask value for the sound configuration status variable DSoundScLdd::iSoundConfigFlags. This being set signifies
|
|
43 |
that the record level / play volume has been set in hardware by the driver.
|
|
44 |
*/
|
|
45 |
const TUint KSndScVolumeIsSetup=0x00000002;
|
|
46 |
|
|
47 |
// Bit-mask values used when testing the driver
|
|
48 |
const TUint KSoundScTest_StartTransferError=0x01;
|
|
49 |
const TUint KSoundScTest_TransferDataError=0x02;
|
|
50 |
const TUint KSoundScTest_TransferTimeout=0x04;
|
|
51 |
|
|
52 |
// Forward declarations
|
|
53 |
class TAudioBuffer;
|
|
54 |
class DBufferManager;
|
|
55 |
class DSoundScLdd;
|
|
56 |
|
|
57 |
/**
|
|
58 |
@publishedPartner
|
|
59 |
@prototype
|
|
60 |
*/
|
|
61 |
class TSoundSharedChunkBufConfig : public TSharedChunkBufConfigBase
|
|
62 |
{
|
|
63 |
public:
|
|
64 |
/** The first entry of the buffer offset list. This list holds the offset from the start of the chunk
|
|
65 |
for each buffer. This list is only valid if the flag KScFlagBufOffsetListInUse is set in
|
|
66 |
TSharedChunkBufConfigBase::iFlags. */
|
|
67 |
TInt iBufferOffsetListStart;
|
|
68 |
};
|
|
69 |
|
|
70 |
/**
|
|
71 |
The sound driver power handler class.
|
|
72 |
*/
|
|
73 |
class DSoundScPowerHandler : public DPowerHandler
|
|
74 |
{
|
|
75 |
public:
|
|
76 |
DSoundScPowerHandler(DSoundScLdd* aChannel);
|
|
77 |
// Inherited from DPowerHandler
|
|
78 |
void PowerUp();
|
|
79 |
void PowerDown(TPowerState aPowerState);
|
|
80 |
private:
|
|
81 |
DSoundScLdd* iChannel;
|
|
82 |
};
|
|
83 |
|
|
84 |
/**
|
|
85 |
An object encapsulating an audio data transfer - either record or playback.
|
|
86 |
*/
|
|
87 |
class TSndScTransfer
|
|
88 |
{
|
|
89 |
public:
|
|
90 |
enum TTfState
|
|
91 |
{
|
|
92 |
/** None of the data for this transfer has been queued on the device. */
|
|
93 |
ETfNotStarted,
|
|
94 |
/** Some of the data for this transfer has been queued on the device - but there is more that needs queuing. */
|
|
95 |
ETfPartlyStarted,
|
|
96 |
/** All the data for this transfer has been queued on the device - but transfer is not complete. */
|
|
97 |
ETfFullyStarted,
|
|
98 |
/** All the data for this transfer has been transferred. */
|
|
99 |
ETfDone
|
|
100 |
};
|
|
101 |
public:
|
|
102 |
TSndScTransfer();
|
|
103 |
void Init(TUint aId,TInt aChunkOffset,TInt aLength,TAudioBuffer* anAudioBuffer);
|
|
104 |
inline TInt GetNotStartedLen();
|
|
105 |
inline TInt GetStartOffset();
|
|
106 |
inline TInt GetLengthTransferred();
|
|
107 |
void SetStarted(TInt aLength);
|
|
108 |
TBool SetCompleted(TInt aLength);
|
|
109 |
public:
|
|
110 |
/** A value which uniquely identifies a particular audio data transfer. */
|
|
111 |
TUint iId;
|
|
112 |
/** The status of this transfer. */
|
|
113 |
TTfState iTfState;
|
|
114 |
/** The audio buffer associated with this transfer. */
|
|
115 |
TAudioBuffer* iAudioBuffer;
|
|
116 |
private:
|
|
117 |
/** An offset within the shared chunk indicating the progress of the transfer. Data between the initial offset
|
|
118 |
and this value has either been successfully been transferred or has been queued for transfer. */
|
|
119 |
TUint iStartedOffset;
|
|
120 |
/** An offset within the shared chunk indicating the end of the data to be transferred. */
|
|
121 |
TUint iEndOffset;
|
|
122 |
/** This holds the count of the number of bytes which have been successfully transferred. */
|
|
123 |
TInt iLengthTransferred;
|
|
124 |
/** This holds the count of the number of transfer fragments which are currently in progress for this transfer. */
|
|
125 |
TInt iTransfersInProgress;
|
|
126 |
};
|
|
127 |
|
|
128 |
/**
|
|
129 |
An object encapsulating an audio request from the client - either record or playback.
|
|
130 |
*/
|
|
131 |
class TSoundScRequest : public SDblQueLink
|
|
132 |
{
|
|
133 |
public:
|
|
134 |
inline TSoundScRequest();
|
|
135 |
virtual ~TSoundScRequest();
|
|
136 |
virtual TInt Construct();
|
|
137 |
public:
|
|
138 |
/** The thread which issued the request and which supplied the request status. */
|
|
139 |
DThread* iOwningThread;
|
|
140 |
/** The client request completion object
|
|
141 |
This is the base class and may be constructed as a derived type*/
|
|
142 |
TClientRequest* iClientRequest;
|
|
143 |
};
|
|
144 |
|
|
145 |
/**
|
|
146 |
A play request object.
|
|
147 |
*/
|
|
148 |
class TSoundScPlayRequest : public TSoundScRequest
|
|
149 |
{
|
|
150 |
public:
|
|
151 |
TSoundScPlayRequest();
|
|
152 |
inline void SetFail(TInt aCompletionReason);
|
|
153 |
inline void UpdateProgress(TInt aLength);
|
|
154 |
TInt Construct();
|
|
155 |
public:
|
|
156 |
/** The transfer information associated with this play request. */
|
|
157 |
TSndScTransfer iTf;
|
|
158 |
/** The play request flags which were supplied by the client for this request - see KSndFlagLastSample. */
|
|
159 |
TUint iFlags;
|
|
160 |
/** The error value to be returned when completing the request. */
|
|
161 |
TInt iCompletionReason;
|
|
162 |
};
|
|
163 |
|
|
164 |
/**
|
|
165 |
An object encapsulating a queue of audio requests from the client.
|
|
166 |
*/
|
|
167 |
class TSoundScRequestQueue
|
|
168 |
{
|
|
169 |
public:
|
|
170 |
TSoundScRequestQueue(DSoundScLdd* aLdd);
|
|
171 |
virtual ~TSoundScRequestQueue();
|
|
172 |
virtual TInt Create();
|
|
173 |
TSoundScRequest* NextFree();
|
|
174 |
void Add(TSoundScRequest* aReq);
|
|
175 |
TSoundScRequest* Remove();
|
|
176 |
TSoundScRequest* Remove(TSoundScRequest* aReq);
|
|
177 |
TSoundScRequest* Find(TRequestStatus* aStatus);
|
|
178 |
void Free(TSoundScRequest* aReq);
|
|
179 |
inline TBool IsEmpty();
|
|
180 |
inline TBool IsAnchor(TSoundScRequest* aReq);
|
|
181 |
void CompleteAll(TInt aCompletionReason,NFastMutex* aMutex=NULL);
|
|
182 |
protected:
|
|
183 |
/** The queue of pending audio requests. */
|
|
184 |
SDblQue iPendRequestQ;
|
|
185 |
/** The queue of unused audio requests. */
|
|
186 |
SDblQue iUnusedRequestQ;
|
|
187 |
/** The actual array of request objects. */
|
|
188 |
TSoundScRequest* iRequest[KMaxSndScRequestsPending];
|
|
189 |
/** Mutex used to protect the unused queue from corruption */
|
|
190 |
NFastMutex iUnusedRequestQLock;
|
|
191 |
private:
|
|
192 |
/** The owning LDD object. */
|
|
193 |
DSoundScLdd* iLdd;
|
|
194 |
};
|
|
195 |
|
|
196 |
/**
|
|
197 |
An object encapsulating a queue of play requests from the client.
|
|
198 |
*/
|
|
199 |
class TSoundScPlayRequestQueue : public TSoundScRequestQueue
|
|
200 |
{
|
|
201 |
public:
|
|
202 |
TSoundScPlayRequestQueue(DSoundScLdd* aLdd);
|
|
203 |
virtual TInt Create();
|
|
204 |
TSoundScPlayRequest* NextRequestForTransfer();
|
|
205 |
TSoundScPlayRequest* Find(TUint aTransferID,TBool& aIsNextToComplete);
|
|
206 |
};
|
|
207 |
|
|
208 |
/**
|
|
209 |
The buffer manager base class.
|
|
210 |
*/
|
|
211 |
class DBufferManager : public DBase
|
|
212 |
{
|
|
213 |
public:
|
|
214 |
enum TFlushOp
|
|
215 |
{
|
|
216 |
/** Flush before a DMA write. */
|
|
217 |
EFlushBeforeDmaWrite,
|
|
218 |
/** Flush before a DMA read. */
|
|
219 |
EFlushBeforeDmaRead,
|
|
220 |
/** Flush after a DMA read. */
|
|
221 |
EFlushAfterDmaRead
|
|
222 |
};
|
|
223 |
public:
|
|
224 |
DBufferManager(DSoundScLdd* aLdd);
|
|
225 |
~DBufferManager();
|
|
226 |
TInt Create(TSoundSharedChunkBufConfig* aBufConfig);
|
|
227 |
TInt Create(TSoundSharedChunkBufConfig& aBufConfig,TInt aChunkHandle,DThread* anOwningThread);
|
|
228 |
void FlushData(TInt aChunkOffset,TInt aLength,TFlushOp aFlushOp);
|
|
229 |
protected:
|
|
230 |
TInt ValidateBufferOffsets(TInt* aBufferOffsetList,TInt aNumBuffers,TInt aBufferSizeInBytes);
|
|
231 |
TInt ValidateRegion(TUint aChunkOffset,TUint aLength,TAudioBuffer*& anAudioBuffer);
|
|
232 |
TInt CreateBufferLists(TInt aNumBuffers);
|
|
233 |
TInt CommitMemoryForBuffer(TInt aChunkOffset,TInt aSize,TBool& aIsContiguous);
|
|
234 |
void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo);
|
|
235 |
protected:
|
|
236 |
/** The owning LDD object. */
|
|
237 |
DSoundScLdd* iLdd;
|
|
238 |
/** The chunk which contains the buffers. */
|
|
239 |
DChunk* iChunk;
|
|
240 |
/** The linear address in kernel process for the start of the chunk. */
|
|
241 |
TLinAddr iChunkBase;
|
|
242 |
/** MMU mapping attributes that the chunk has actually been mapped with. */
|
|
243 |
TUint32 iChunkMapAttr;
|
|
244 |
/** The number of buffers. */
|
|
245 |
TInt iNumBuffers;
|
|
246 |
/** The actual array of buffer objects. */
|
|
247 |
TAudioBuffer* iAudioBuffers;
|
|
248 |
/** The maximum transfer length that the owning audio channel can support in a single data transfer. */
|
|
249 |
TInt iMaxTransferLen;
|
|
250 |
protected:
|
|
251 |
friend class DSoundScLdd;
|
|
252 |
friend class TAudioBuffer;
|
|
253 |
};
|
|
254 |
|
|
255 |
/**
|
|
256 |
The record buffer manager class.
|
|
257 |
*/
|
|
258 |
class DRecordBufferManager : public DBufferManager
|
|
259 |
{
|
|
260 |
public:
|
|
261 |
DRecordBufferManager(DSoundScLdd* aLdd);
|
|
262 |
void Reset();
|
|
263 |
inline TAudioBuffer* GetCurrentRecordBuffer();
|
|
264 |
inline TAudioBuffer* GetNextRecordBuffer();
|
|
265 |
TAudioBuffer* GetBufferForClient();
|
|
266 |
TAudioBuffer* SetBufferFilled(TInt aBytesAdded,TInt aTransferResult);
|
|
267 |
TAudioBuffer* ReleaseBuffer(TInt aChunkOffset);
|
|
268 |
protected:
|
|
269 |
/** The buffer currently being filled with record data. (Not in any list). */
|
|
270 |
TAudioBuffer* iCurrentBuffer;
|
|
271 |
/** The next buffer to use to capture record data. (Not in any list). */
|
|
272 |
TAudioBuffer* iNextBuffer;
|
|
273 |
/** A queue of those buffers which are currently free. */
|
|
274 |
SDblQue iFreeBufferQ;
|
|
275 |
/** A queue of those buffers which currently contain record data (and which aren't being used by the client). */
|
|
276 |
SDblQue iCompletedBufferQ;
|
|
277 |
/** A queue of those buffers which are currently being used by the client. */
|
|
278 |
SDblQue iInUseBufferQ;
|
|
279 |
/** A flag set within SetBufferFilled() each time it is necessary to use a buffer from the completed list rather
|
|
280 |
than the free list as the next buffer for capture (i.e. 'iNextBuffer'). */
|
|
281 |
TBool iBufOverflow;
|
|
282 |
private:
|
|
283 |
friend class DSoundScLdd;
|
|
284 |
};
|
|
285 |
|
|
286 |
/**
|
|
287 |
The class representing a single record/play buffer.
|
|
288 |
*/
|
|
289 |
class TAudioBuffer : public SDblQueLink
|
|
290 |
{
|
|
291 |
public:
|
|
292 |
TAudioBuffer();
|
|
293 |
~TAudioBuffer();
|
|
294 |
TInt Create(DChunk* aChunk,TInt aChunkOffset,TInt aSize,TBool aIsContiguous,DBufferManager* aBufManager);
|
|
295 |
TInt GetFragmentLength(TInt aChunkOffset,TInt aLengthRemaining,TPhysAddr& aPhysAddr);
|
|
296 |
void Flush(DBufferManager::TFlushOp aFlushOp);
|
|
297 |
public:
|
|
298 |
/** The owning buffer manager. */
|
|
299 |
DBufferManager* iBufManager;
|
|
300 |
/** The offset, in bytes, of the start of the buffer within the chunk. */
|
|
301 |
TInt iChunkOffset;
|
|
302 |
/** The size of the buffer in bytes. */
|
|
303 |
TInt iSize;
|
|
304 |
/** The physical address of the start of the buffer. KPhysAddrInvalid if the buffer is not physically contiguous. */
|
|
305 |
TPhysAddr iPhysicalAddress;
|
|
306 |
/** A list of physical addresses for buffer pages. 0 if the buffer is physically contiguous. */
|
|
307 |
TPhysAddr* iPhysicalPages;
|
|
308 |
/** Used for record only this is the number of bytes added into this buffer during recording. */
|
|
309 |
TInt iBytesAdded;
|
|
310 |
/** Used for record only this is the result of the transfer into this buffer. */
|
|
311 |
TInt iResult;
|
|
312 |
};
|
|
313 |
|
|
314 |
/**
|
|
315 |
The physical device driver (PDD) base class for the sound driver - for either playback or record.
|
|
316 |
@publishedPartner
|
|
317 |
@prototype
|
|
318 |
*/
|
|
319 |
class DSoundScPdd : public DBase
|
|
320 |
{
|
|
321 |
public:
|
|
322 |
/**
|
|
323 |
Return the DFC queue to be used by this device.
|
|
324 |
@param aUnit The record or playback unit for which to return the DFC queue. This is for use by
|
|
325 |
SMP optimised drivers to return different DFC queues for different units that can
|
|
326 |
then run on separate CPU cores.
|
|
327 |
@return The DFC queue to use.
|
|
328 |
*/
|
|
329 |
virtual TDfcQue* DfcQ(TInt aUnit)=0;
|
|
330 |
|
|
331 |
/**
|
|
332 |
Return the shared chunk create information to be used by this device.
|
|
333 |
@param aChunkCreateInfo A chunk create info. object to be to be filled with the settings
|
|
334 |
required for this device.
|
|
335 |
*/
|
|
336 |
virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)=0;
|
|
337 |
|
|
338 |
/**
|
|
339 |
Return the capabilities of this audio device.
|
|
340 |
This includes information on the direction of the device (i.e. play or record), the number of audio channels
|
|
341 |
supported (mono, stereo etc), the encoding formats and sample rates supported and so on.
|
|
342 |
@param aCapsBuf A packaged TSoundFormatsSupportedV02 object to be filled with the capabilities
|
|
343 |
of this device. This descriptor is in kernel memory and can be accessed directly.
|
|
344 |
@see TSoundFormatsSupportedV02.
|
|
345 |
*/
|
|
346 |
virtual void Caps(TDes8& aCapsBuf) const=0;
|
|
347 |
|
|
348 |
/**
|
|
349 |
Return the maximum transfer length in bytes that this device can support in a single data transfer.
|
|
350 |
(If the device is using the Symbian DMA framework to handle data transfers then the framework handles data
|
|
351 |
transfers which exceed the maximum transfer length for the platform. However, some PDD implementations
|
|
352 |
may not use the DMA framework).
|
|
353 |
@return The maximum transfer length in bytes.
|
|
354 |
*/
|
|
355 |
virtual TInt MaxTransferLen() const=0;
|
|
356 |
|
|
357 |
/**
|
|
358 |
Configure or reconfigure the device using the configuration supplied.
|
|
359 |
@param aConfigBuf A packaged TCurrentSoundFormatV02 object which contains the new configuration settings.
|
|
360 |
This descriptor is in kernel memory and can be accessed directly.
|
|
361 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
362 |
@see TCurrentSoundFormatV02.
|
|
363 |
*/
|
|
364 |
virtual TInt SetConfig(const TDesC8& aConfigBuf)=0;
|
|
365 |
|
|
366 |
/**
|
|
367 |
Set the volume or record level.
|
|
368 |
@param aVolume The play volume or record level to be set - a value in the range 0 to 255. The value 255
|
|
369 |
equates to the maximum volume and each value below this equates to a 0.5dB step below it.
|
|
370 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
371 |
*/
|
|
372 |
virtual TInt SetVolume(TInt aVolume)=0;
|
|
373 |
|
|
374 |
/**
|
|
375 |
Prepare the audio device for data transfer.
|
|
376 |
This may be preparing it either for record or playback - depending on the direction of the channel.
|
|
377 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
378 |
*/
|
|
379 |
virtual TInt StartTransfer()=0;
|
|
380 |
|
|
381 |
/**
|
|
382 |
Initiate the transfer of a portion of data from/to the audio device.
|
|
383 |
This may be to either record or playback the data - depending on the direction of the channel. When the transfer is
|
|
384 |
complete, the PDD should signal this event using the LDD function PlayCallback() or RecordCallback() as appropriate.
|
|
385 |
@param aTransferID A value assigned by the LDD to allow it to uniquely identify a particular transfer fragment.
|
|
386 |
@param aLinAddr A linear address within the shared chunk. For playback this is the address of the start of the data
|
|
387 |
to be transferred. For record, this is the start address for storing the recorded data.
|
|
388 |
@param aPhysAddr The physical address within the shared chunk that corresponds to the linear address: aLinAddr.
|
|
389 |
@param aNumBytes The number of bytes to be transferred.
|
|
390 |
@return KErrNone if the transfer has been initiated successfully;
|
|
391 |
KErrNotReady if the device is unable to accept the transfer for the moment;
|
|
392 |
otherwise one of the other system-wide error codes.
|
|
393 |
*/
|
|
394 |
virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes)=0;
|
|
395 |
|
|
396 |
/**
|
|
397 |
Terminate the transfer of a data to/from the device and to release any resources necessary for transfer.
|
|
398 |
In the case of playback, this is called soon after the last pending play request from the client has been completed.
|
|
399 |
In the case of record, the LDD will leave the audio device capturing record data even when there are no record
|
|
400 |
requests pending from the client. Transfer will only be terminated when the client either issues
|
|
401 |
RSoundSc::CancelRecordData() or closes the channel. Once this function had been called, the LDD will not issue
|
|
402 |
any further TransferData() commands without first issueing a StartTransfer() command.
|
|
403 |
*/
|
|
404 |
virtual void StopTransfer()=0;
|
|
405 |
|
|
406 |
/**
|
|
407 |
Halt the transfer of data to/from the sound device but don't release any resources necessary for transfer.
|
|
408 |
In the case of playback, if possible, any active transfer should be suspended in such a way that it can be
|
|
409 |
resumed later - starting from next sample following the one last played.
|
|
410 |
In the case of record, any active transfer should be aborted. When recording is halted the PDD should signal this event
|
|
411 |
with a single call of the LDD function RecordCallback() - reporting back any partial data already received. In this
|
|
412 |
case, if transfer is resumed later, the LDD will issue a new TransferData() request to re-commence data transfer.
|
|
413 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
414 |
*/
|
|
415 |
virtual TInt PauseTransfer()=0;
|
|
416 |
|
|
417 |
/**
|
|
418 |
Resume the transfer of data to/from the sound device following a request to halt the transfer.
|
|
419 |
In the case of playback, if possible, any transfer which was active when the device was halted should be resumed -
|
|
420 |
starting from next sample following the one last played. Once complete, it should be reported using PlayCallback()
|
|
421 |
as normal.
|
|
422 |
In the case of record, any active transfer would have been aborted when the device was halted so its just a case
|
|
423 |
of re-creating the same setup achieved following StartTransfer().
|
|
424 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
425 |
*/
|
|
426 |
virtual TInt ResumeTransfer()=0;
|
|
427 |
|
|
428 |
/**
|
|
429 |
Power up the sound device. This is called when the channel is first opened and if ever the phone is brought out
|
|
430 |
of standby mode.
|
|
431 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
432 |
*/
|
|
433 |
virtual TInt PowerUp()=0;
|
|
434 |
|
|
435 |
/**
|
|
436 |
Power down the sound device. This is called when the channel is closed and just before the phone powers down when
|
|
437 |
being turned off or going into standby.
|
|
438 |
*/
|
|
439 |
virtual void PowerDown()=0;
|
|
440 |
|
|
441 |
/**
|
|
442 |
Handle a custom configuration request.
|
|
443 |
@param aFunction A number identifying the request.
|
|
444 |
@param aParam A 32-bit value passed to the driver. Its meaning depends on the request.
|
|
445 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
446 |
*/
|
|
447 |
virtual TInt CustomConfig(TInt aFunction,TAny* aParam)=0;
|
|
448 |
|
|
449 |
/**
|
|
450 |
Calculates and returns the number of microseconds of data transferred since the start of transfer.
|
|
451 |
@param aTime A reference to a variable into which to place the number of microseconds played or recorded.
|
|
452 |
@param aState The current state of the transfer (from TSoundScLdd::TState). Included so that paused
|
|
453 |
and Active transfers can be treated differently.
|
|
454 |
@return KErrNone if successful, otherwise one of the other system wide error codes.
|
|
455 |
*/
|
|
456 |
virtual TInt TimeTransferred(TInt64& aTime, TInt aState);
|
|
457 |
protected:
|
|
458 |
inline DSoundScLdd* Ldd();
|
|
459 |
private:
|
|
460 |
DSoundScLdd* iLdd;
|
|
461 |
friend class DSoundScLdd;
|
|
462 |
};
|
|
463 |
|
|
464 |
/**
|
|
465 |
The logical device (factory class) for the sound driver.
|
|
466 |
*/
|
|
467 |
class DSoundScLddFactory : public DLogicalDevice
|
|
468 |
{
|
|
469 |
public:
|
|
470 |
DSoundScLddFactory();
|
|
471 |
virtual TInt Install();
|
|
472 |
virtual void GetCaps(TDes8 &aDes) const;
|
|
473 |
virtual TInt Create(DLogicalChannelBase*& aChannel);
|
|
474 |
TBool IsUnitOpen(TInt aUnit);
|
|
475 |
TInt SetUnitOpen(TInt aUnit,TBool aIsOpenSetting);
|
|
476 |
private:
|
|
477 |
/** Mask to keep track of which units have a channel open on them. */
|
|
478 |
TUint iUnitsOpenMask;
|
|
479 |
/** A mutex to protect access to the unit info. mask. */
|
|
480 |
NFastMutex iUnitInfoMutex;
|
|
481 |
};
|
|
482 |
|
|
483 |
/**
|
|
484 |
The logical channel class for the sound driver.
|
|
485 |
*/
|
|
486 |
class DSoundScLdd : public DLogicalChannel
|
|
487 |
{
|
|
488 |
public:
|
|
489 |
enum TState
|
|
490 |
{
|
|
491 |
/** Channel is open - but not configured. */
|
|
492 |
EOpen,
|
|
493 |
/** Channel is configured - but inactive. */
|
|
494 |
EConfigured,
|
|
495 |
/** Channel is active - recording or playing data. */
|
|
496 |
EActive,
|
|
497 |
/** Channel is paused - recording or playing has been suspended. */
|
|
498 |
EPaused
|
|
499 |
};
|
|
500 |
public:
|
|
501 |
DSoundScLdd();
|
|
502 |
virtual ~DSoundScLdd();
|
|
503 |
// Inherited from DLogicalChannel
|
|
504 |
virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
|
|
505 |
virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
|
|
506 |
virtual TInt SendMsg(TMessageBase* aMsg);
|
|
507 |
virtual void HandleMsg(TMessageBase* aMsg);
|
|
508 |
void Shutdown();
|
|
509 |
// Functions used by the PDD
|
|
510 |
virtual void PlayCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesPlayed);
|
|
511 |
virtual void RecordCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesRecorded);
|
|
512 |
virtual void NotifyChangeOfHwConfigCallback(TBool aHeadsetPresent);
|
|
513 |
virtual TSoundSharedChunkBufConfig* BufConfig();
|
|
514 |
virtual TLinAddr ChunkBase();
|
|
515 |
private:
|
|
516 |
// Implementations for the different kinds of requests
|
|
517 |
TInt DoControl(TInt aFunction, TAny* a1, TAny* a2,DThread* aThread);
|
|
518 |
TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2,DThread* aThread);
|
|
519 |
TInt DoCancel(TUint aMask);
|
|
520 |
TInt SetBufferConfig(DThread* aThread);
|
|
521 |
TInt SetBufferConfig(TInt aChunkHandle,DThread* aThread);
|
|
522 |
TInt SetSoundConfig();
|
|
523 |
TInt DoSetSoundConfig(const TCurrentSoundFormatV02& aSoundConfig);
|
|
524 |
TInt SetVolume(TInt aVolume);
|
|
525 |
TInt PlayData(TRequestStatus* aStatus,TSoundScPlayRequest* aRequest,DThread* aThread);
|
|
526 |
TInt RecordData(TRequestStatus* aStatus,TInt* aLengthPtr,DThread* aThread);
|
|
527 |
TInt StartRecord();
|
|
528 |
TInt ReleaseBuffer(TInt aChunkOffset);
|
|
529 |
TInt CustomConfig(TInt aFunction,TAny* aParam);
|
|
530 |
TInt ValidateConfig(const TCurrentSoundFormatV02& aConfig);
|
|
531 |
TInt ReAllocBufferConfigInfo(TInt aNumBuffers);
|
|
532 |
void StartNextPlayTransfers();
|
|
533 |
inline void CompletePlayRequest(TSoundScPlayRequest* aReq,TInt aResult);
|
|
534 |
void DoCompletePlayRequest(TSoundScPlayRequest* aReq);
|
|
535 |
void CompleteAllDonePlayRequests(TSoundScPlayRequest* aReq);
|
|
536 |
void HandleCurrentRecordBufferDone(TInt aTransferResult);
|
|
537 |
void CompleteRequest(DThread* aThread,TRequestStatus* aStatus,TInt aReason,TClientRequest* aClientRequest=NULL);
|
|
538 |
TInt StartNextRecordTransfers();
|
|
539 |
void StartPlayEofTimer();
|
|
540 |
void CancelPlayEofTimer();
|
|
541 |
inline DSoundScPdd* Pdd();
|
|
542 |
static void PlayEofTimerExpired(TAny* aChannel);
|
|
543 |
static void PlayEofTimerDfc(TAny* aChannel);
|
|
544 |
static void PowerUpDfc(TAny* aChannel);
|
|
545 |
static void PowerDownDfc(TAny* aChannel);
|
|
546 |
TInt PrePlay(TMessageBase* aMsg);
|
|
547 |
TInt PreSetBufferChunkCreateOrOpen(TMessageBase* aMsg);
|
|
548 |
TInt PreSetSoundConfig(TMessageBase* aMsg);
|
|
549 |
private:
|
|
550 |
/** The handle to the chunk that is returned to the user side code. */
|
|
551 |
TInt iChunkHandle;
|
|
552 |
/** The handle of the thread that created the chunk referenced by iChunkHandle */
|
|
553 |
DThread* iChunkHandleThread;
|
|
554 |
/** The unit number of this channel. */
|
|
555 |
TInt iUnit;
|
|
556 |
/** The data transfer direction for this unit: play or record. */
|
|
557 |
TSoundDirection iDirection;
|
|
558 |
/** The operating state of the channel. */
|
|
559 |
TState iState;
|
|
560 |
/** Spare. */
|
|
561 |
TInt iSpare;
|
|
562 |
/** The buffer manager - managing the shared chunk and the record/play buffers within this. */
|
|
563 |
DBufferManager* iBufManager;
|
|
564 |
/** A mutex to protect access to the buffer lists and the pending request list. */
|
|
565 |
NFastMutex iMutex;
|
|
566 |
/** The transfer status of the record buffer currently being filled. */
|
|
567 |
TSndScTransfer iCurrentRecBufTf;
|
|
568 |
/** The transfer status of the record buffer which is next to be filled. */
|
|
569 |
TSndScTransfer iNextRecBufTf;
|
|
570 |
/** The current buffer configuration in the play/record chunk. */
|
|
571 |
TSoundSharedChunkBufConfig* iBufConfig;
|
|
572 |
/** The size in bytes of the play/record buffer configuration info. structure. */
|
|
573 |
TInt iBufConfigSize;
|
|
574 |
/** The sound driver power handler. */
|
|
575 |
DSoundScPowerHandler* iPowerHandler;
|
|
576 |
/** DFC used to handle power down requests from the power manager before a transition into system shutdown/standby. */
|
|
577 |
TDfc iPowerDownDfc;
|
|
578 |
/** DFC used to handle power up requests from the power manager following a transition out of system standby. */
|
|
579 |
TDfc iPowerUpDfc;
|
|
580 |
/** The capabilities of this device. */
|
|
581 |
TSoundFormatsSupportedV02 iCaps;
|
|
582 |
/** The current audio configuration of the driver. */
|
|
583 |
TCurrentSoundFormatV02 iSoundConfig;
|
|
584 |
/** The requested audio configuration of the driver before validation. */
|
|
585 |
TCurrentSoundFormatV02 iTempSoundConfig;
|
|
586 |
/** A bitmask holding sound configuration status information. */
|
|
587 |
TUint32 iSoundConfigFlags;
|
|
588 |
/** The current setting for the record level / play volume. */
|
|
589 |
TInt iVolume;
|
|
590 |
/** The queue of pending play or record requests. */
|
|
591 |
TSoundScRequestQueue* iReqQueue;
|
|
592 |
/** Used to complete the change of hardware notification. */
|
|
593 |
TClientDataRequest<TBool>* iNotifyChangeOfHwClientRequest;
|
|
594 |
/** The thread which has registered for the hardware configuration change notifier. */
|
|
595 |
DThread* iChangeOfHwConfigThread;
|
|
596 |
/** A pointer to the headset present boolean variable in client memory which is updated on a notification. */
|
|
597 |
TBool* iHeadsetPresentStatPtr;
|
|
598 |
/** To keep track of the number of bytes transferred. */
|
|
599 |
TInt iBytesTransferred;
|
|
600 |
/** Count of the number of times the PDD completes a record transfer fragment just after being paused. */
|
|
601 |
TInt iCompletesWhilePausedCount;
|
|
602 |
/** A timer used to delay exiting play transfer mode at EOF. */
|
|
603 |
NTimer iEofTimer;
|
|
604 |
/** DFC used to delay exiting play transfer mode at EOF. */
|
|
605 |
TDfc iPlayEofDfc;
|
|
606 |
/** Used for testing and debugging. */
|
|
607 |
TUint iTestSettings;
|
|
608 |
/** A flag to indicate whether the play EOF timer is active. */
|
|
609 |
TBool iPlayEofTimerActive;
|
|
610 |
/** Used in debug builds to track that all calls to DThread::Open() are balanced with a close before the driver closes. */
|
|
611 |
TInt iThreadOpenCount;
|
|
612 |
/** Used to complete requests in the DFC thread. */
|
|
613 |
TClientRequest** iClientRequests;
|
|
614 |
|
|
615 |
friend class DBufferManager;
|
|
616 |
friend class DSoundScPowerHandler;
|
|
617 |
friend class TSoundScRequestQueue;
|
|
618 |
};
|
|
619 |
|
|
620 |
#include <drivers/soundsc.inl>
|
|
621 |
#endif // __SOUNDSC_H__
|