kernel/eka/include/drivers/soundsc.h
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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__