os/kernelhwsrv/kernel/eka/include/drivers/soundsc.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/soundsc.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,621 @@
     1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32\include\drivers\soundsc.h
    1.18 +// Kernel side definitions for the shared chunk sound driver.
    1.19 +//
    1.20 +//
    1.21 +
    1.22 +/**
    1.23 + @file
    1.24 + @internalTechnology
    1.25 + @prototype
    1.26 +*/
    1.27 +
    1.28 +#ifndef __SOUNDSC_H__
    1.29 +#define __SOUNDSC_H__
    1.30 +
    1.31 +#include <d32soundsc.h>
    1.32 +#include <platform.h>
    1.33 +#include <kernel/kpower.h>
    1.34 +#include <e32ver.h>
    1.35 +
    1.36 +/** The maximum number of client transfer requests which may be outstanding in a particular direction at any time. */
    1.37 +const TInt KMaxSndScRequestsPending=8;
    1.38 +
    1.39 +/**
    1.40 +A bit-mask value for the sound configuration status variable DSoundScLdd::iSoundConfigFlags. This being set signifies
    1.41 +that the sound configuration has been set in hardware by the driver.
    1.42 +*/
    1.43 +const TUint KSndScSoundConfigIsSetup=0x00000001;
    1.44 +/**
    1.45 +A bit-mask value for the sound configuration status variable DSoundScLdd::iSoundConfigFlags. This being set signifies
    1.46 +that the record level / play volume has been set in hardware by the driver.
    1.47 +*/
    1.48 +const TUint KSndScVolumeIsSetup=0x00000002;
    1.49 +
    1.50 +// Bit-mask values used when testing the driver
    1.51 +const TUint KSoundScTest_StartTransferError=0x01;
    1.52 +const TUint KSoundScTest_TransferDataError=0x02;
    1.53 +const TUint KSoundScTest_TransferTimeout=0x04;
    1.54 +
    1.55 +// Forward declarations
    1.56 +class TAudioBuffer;
    1.57 +class DBufferManager;
    1.58 +class DSoundScLdd;
    1.59 +
    1.60 +/**
    1.61 +@publishedPartner
    1.62 +@prototype
    1.63 +*/
    1.64 +class TSoundSharedChunkBufConfig : public TSharedChunkBufConfigBase
    1.65 +	{
    1.66 +public:
    1.67 +	/** The first entry of the buffer offset list. This list holds the offset from the start of the chunk
    1.68 +	for each buffer. This list is only valid if the flag KScFlagBufOffsetListInUse is set in
    1.69 +	TSharedChunkBufConfigBase::iFlags. */
    1.70 +	TInt iBufferOffsetListStart;
    1.71 +	};
    1.72 +
    1.73 +/**
    1.74 +The sound driver power handler class.
    1.75 +*/
    1.76 +class DSoundScPowerHandler : public DPowerHandler
    1.77 +	{
    1.78 +public:
    1.79 +	DSoundScPowerHandler(DSoundScLdd* aChannel);
    1.80 +	// Inherited from DPowerHandler
    1.81 +	void PowerUp();
    1.82 +	void PowerDown(TPowerState aPowerState);
    1.83 +private:
    1.84 +	DSoundScLdd* iChannel;
    1.85 +	};
    1.86 +
    1.87 +/**
    1.88 +An object encapsulating an audio data transfer - either record or playback.
    1.89 +*/
    1.90 +class TSndScTransfer
    1.91 +	{
    1.92 +public:
    1.93 +	enum TTfState
    1.94 +		{
    1.95 +		/** None of the data for this transfer has been queued on the device. */
    1.96 +		ETfNotStarted,
    1.97 +		/** Some of the data for this transfer has been queued on the device - but there is more that needs queuing. */
    1.98 +		ETfPartlyStarted,
    1.99 +		/** All the data for this transfer has been queued on the device - but transfer is not complete. */
   1.100 +		ETfFullyStarted,
   1.101 +		/** All the data for this transfer has been transferred. */
   1.102 +		ETfDone
   1.103 +		};
   1.104 +public:
   1.105 +	TSndScTransfer();
   1.106 +	void Init(TUint aId,TInt aChunkOffset,TInt aLength,TAudioBuffer* anAudioBuffer);
   1.107 +	inline TInt GetNotStartedLen();
   1.108 +	inline TInt GetStartOffset();
   1.109 +	inline TInt GetLengthTransferred();
   1.110 +	void SetStarted(TInt aLength);
   1.111 +	TBool SetCompleted(TInt aLength);
   1.112 +public:
   1.113 +	/** A value which uniquely identifies a particular audio data transfer. */
   1.114 +	TUint iId;
   1.115 +	/** The status of this transfer. */
   1.116 +	TTfState iTfState;
   1.117 +	/** The audio buffer associated with this transfer. */
   1.118 +	TAudioBuffer* iAudioBuffer;
   1.119 +private:
   1.120 +	/** An offset within the shared chunk indicating the progress of the transfer. Data between the initial offset
   1.121 +	and this value has either been successfully been transferred or has been queued for transfer. */
   1.122 +	TUint iStartedOffset;
   1.123 +	/** An offset within the shared chunk indicating the end of the data to be transferred. */
   1.124 +	TUint iEndOffset;
   1.125 +	/** This holds the count of the number of bytes which have been successfully transferred. */
   1.126 +	TInt iLengthTransferred;
   1.127 +	/** This holds the count of the number of transfer fragments which are currently in progress for this transfer. */
   1.128 +	TInt iTransfersInProgress;
   1.129 +	};
   1.130 +
   1.131 +/**
   1.132 +An object encapsulating an audio request from the client - either record or playback.
   1.133 +*/
   1.134 +class TSoundScRequest : public SDblQueLink
   1.135 +	{
   1.136 +public:
   1.137 +	inline TSoundScRequest();
   1.138 +	virtual ~TSoundScRequest();
   1.139 +	virtual TInt Construct();
   1.140 +public:
   1.141 +	/** The thread which issued the request and which supplied the request status. */
   1.142 +	DThread* iOwningThread;
   1.143 +	/** The client request completion object
   1.144 +		This is the base class and may be constructed as a derived type*/
   1.145 +	TClientRequest* iClientRequest;
   1.146 +	};
   1.147 +
   1.148 +/**
   1.149 +A play request object.
   1.150 +*/
   1.151 +class TSoundScPlayRequest : public TSoundScRequest
   1.152 +	{
   1.153 +public:
   1.154 +	TSoundScPlayRequest();
   1.155 +	inline void SetFail(TInt aCompletionReason);
   1.156 +	inline void UpdateProgress(TInt aLength);
   1.157 +	TInt Construct();
   1.158 +public:
   1.159 +	/** The transfer information associated with this play request. */
   1.160 +	TSndScTransfer iTf;
   1.161 +	/** The play request flags which were supplied by the client for this request - see KSndFlagLastSample. */
   1.162 +	TUint iFlags;
   1.163 +	/** The error value to be returned when completing the request. */
   1.164 +	TInt iCompletionReason;
   1.165 +	};
   1.166 +
   1.167 +/**
   1.168 +An object encapsulating a queue of audio requests from the client.
   1.169 +*/
   1.170 +class TSoundScRequestQueue
   1.171 +	{
   1.172 +public:
   1.173 +	TSoundScRequestQueue(DSoundScLdd* aLdd);
   1.174 +	virtual ~TSoundScRequestQueue();
   1.175 +	virtual TInt Create();
   1.176 +	TSoundScRequest* NextFree();
   1.177 +	void Add(TSoundScRequest* aReq);
   1.178 +	TSoundScRequest* Remove();
   1.179 +	TSoundScRequest* Remove(TSoundScRequest* aReq);
   1.180 +	TSoundScRequest* Find(TRequestStatus* aStatus);
   1.181 +	void Free(TSoundScRequest* aReq);
   1.182 +	inline TBool IsEmpty();
   1.183 +	inline TBool IsAnchor(TSoundScRequest* aReq);
   1.184 +	void CompleteAll(TInt aCompletionReason,NFastMutex* aMutex=NULL);
   1.185 +protected:
   1.186 +	/** The queue of pending audio requests. */
   1.187 +	SDblQue iPendRequestQ;
   1.188 +	/** The queue of unused audio requests. */
   1.189 +	SDblQue iUnusedRequestQ;
   1.190 +	/** The actual array of request objects. */
   1.191 +	TSoundScRequest* iRequest[KMaxSndScRequestsPending];
   1.192 +	/** Mutex used to protect the unused queue from corruption */
   1.193 +	NFastMutex iUnusedRequestQLock;
   1.194 +private:
   1.195 +	/** The owning LDD object. */
   1.196 +	DSoundScLdd* iLdd;
   1.197 +	};
   1.198 +
   1.199 +/**
   1.200 +An object encapsulating a queue of play requests from the client.
   1.201 +*/
   1.202 +class TSoundScPlayRequestQueue : public TSoundScRequestQueue
   1.203 +	{
   1.204 +public:
   1.205 +	TSoundScPlayRequestQueue(DSoundScLdd* aLdd);
   1.206 +	virtual TInt Create();
   1.207 +	TSoundScPlayRequest* NextRequestForTransfer();
   1.208 +	TSoundScPlayRequest* Find(TUint aTransferID,TBool& aIsNextToComplete);
   1.209 +	};
   1.210 +
   1.211 +/**
   1.212 +The buffer manager base class.
   1.213 +*/
   1.214 +class DBufferManager : public DBase
   1.215 +	{
   1.216 +public:
   1.217 +	enum TFlushOp
   1.218 +		{
   1.219 +		/** Flush before a DMA write. */
   1.220 +		EFlushBeforeDmaWrite,
   1.221 +		/** Flush before a DMA read. */
   1.222 +		EFlushBeforeDmaRead,
   1.223 +		/** Flush after a DMA read. */
   1.224 +		EFlushAfterDmaRead
   1.225 +		};
   1.226 +public:
   1.227 +	DBufferManager(DSoundScLdd* aLdd);
   1.228 +	~DBufferManager();
   1.229 +	TInt Create(TSoundSharedChunkBufConfig* aBufConfig);
   1.230 +	TInt Create(TSoundSharedChunkBufConfig& aBufConfig,TInt aChunkHandle,DThread* anOwningThread);
   1.231 +	void FlushData(TInt aChunkOffset,TInt aLength,TFlushOp aFlushOp);
   1.232 +protected:
   1.233 +	TInt ValidateBufferOffsets(TInt* aBufferOffsetList,TInt aNumBuffers,TInt aBufferSizeInBytes);
   1.234 +	TInt ValidateRegion(TUint aChunkOffset,TUint aLength,TAudioBuffer*& anAudioBuffer);
   1.235 +	TInt CreateBufferLists(TInt aNumBuffers);
   1.236 +	TInt CommitMemoryForBuffer(TInt aChunkOffset,TInt aSize,TBool& aIsContiguous);
   1.237 +	void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo);
   1.238 +protected:
   1.239 +	/** The owning LDD object. */
   1.240 +	DSoundScLdd* iLdd;
   1.241 +	/** The chunk which contains the buffers. */
   1.242 +	DChunk* iChunk;
   1.243 +	/** The linear address in kernel process for the start of the chunk. */
   1.244 +	TLinAddr iChunkBase;
   1.245 +	/** MMU mapping attributes that the chunk has actually been mapped with. */
   1.246 +	TUint32 iChunkMapAttr;
   1.247 +	/** The number of buffers. */
   1.248 +	TInt iNumBuffers;
   1.249 +	/** The actual array of buffer objects. */
   1.250 +	TAudioBuffer* iAudioBuffers;
   1.251 +	/** The maximum transfer length that the owning audio channel can support in a single data transfer. */
   1.252 +	TInt iMaxTransferLen;
   1.253 +protected:
   1.254 +	friend class DSoundScLdd;
   1.255 +	friend class TAudioBuffer;
   1.256 +	};
   1.257 +
   1.258 +/**
   1.259 +The record buffer manager class.
   1.260 +*/
   1.261 +class DRecordBufferManager : public DBufferManager
   1.262 +	{
   1.263 +public:
   1.264 +	DRecordBufferManager(DSoundScLdd* aLdd);
   1.265 +	void Reset();
   1.266 +	inline TAudioBuffer* GetCurrentRecordBuffer();
   1.267 +	inline TAudioBuffer* GetNextRecordBuffer();
   1.268 +	TAudioBuffer* GetBufferForClient();
   1.269 +	TAudioBuffer* SetBufferFilled(TInt aBytesAdded,TInt aTransferResult);
   1.270 +	TAudioBuffer* ReleaseBuffer(TInt aChunkOffset);
   1.271 +protected:
   1.272 +	/** The buffer currently being filled with record data. (Not in any list). */
   1.273 +	TAudioBuffer* iCurrentBuffer;
   1.274 +	/** The next buffer to use to capture record data. (Not in any list). */
   1.275 +	TAudioBuffer* iNextBuffer;
   1.276 +	/** A queue of those buffers which are currently free. */
   1.277 +	SDblQue iFreeBufferQ;
   1.278 +	/** A queue of those buffers which currently contain record data (and which aren't being used by the client). */
   1.279 +	SDblQue iCompletedBufferQ;
   1.280 +	/** A queue of those buffers which are currently being used by the client. */
   1.281 +	SDblQue iInUseBufferQ;
   1.282 +	/** A flag set within SetBufferFilled() each time it is necessary to use a buffer from the completed list rather
   1.283 +	than the free list as the next buffer for capture (i.e. 'iNextBuffer'). */
   1.284 +	TBool iBufOverflow;
   1.285 +private:
   1.286 +	friend class DSoundScLdd;
   1.287 +	};
   1.288 +
   1.289 +/**
   1.290 +The class representing a single record/play buffer.
   1.291 +*/
   1.292 +class TAudioBuffer : public SDblQueLink
   1.293 +	{
   1.294 +public:
   1.295 +	TAudioBuffer();
   1.296 +	~TAudioBuffer();
   1.297 +	TInt Create(DChunk* aChunk,TInt aChunkOffset,TInt aSize,TBool aIsContiguous,DBufferManager* aBufManager);
   1.298 +	TInt GetFragmentLength(TInt aChunkOffset,TInt aLengthRemaining,TPhysAddr& aPhysAddr);
   1.299 +	void Flush(DBufferManager::TFlushOp aFlushOp);
   1.300 +public:
   1.301 +	/** The owning buffer manager. */
   1.302 +	DBufferManager* iBufManager;
   1.303 +	/** The offset, in bytes, of the start of the buffer within the chunk. */
   1.304 +	TInt iChunkOffset;
   1.305 +	/** The size of the buffer in bytes. */
   1.306 +	TInt iSize;
   1.307 +	/** The physical address of the start of the buffer. KPhysAddrInvalid if the buffer is not physically contiguous. */
   1.308 +	TPhysAddr iPhysicalAddress;
   1.309 +	/** A list of physical addresses for buffer pages. 0 if the buffer is physically contiguous. */
   1.310 +	TPhysAddr* iPhysicalPages;
   1.311 +	/** Used for record only this is the number of bytes added into this buffer during recording. */
   1.312 +	TInt iBytesAdded;
   1.313 +	/** Used for record only this is the result of the transfer into this buffer. */
   1.314 +	TInt iResult;
   1.315 +	};
   1.316 +
   1.317 +/**
   1.318 +The physical device driver (PDD) base class for the sound driver - for either playback or record.
   1.319 +@publishedPartner
   1.320 +@prototype
   1.321 +*/
   1.322 +class DSoundScPdd : public DBase
   1.323 +	{
   1.324 +public:
   1.325 +	/**
   1.326 +	Return the DFC queue to be used by this device.
   1.327 +	@param	aUnit	The record or playback unit for which to return the DFC queue.  This is for use by
   1.328 +			SMP optimised drivers to return different DFC queues for different units that can
   1.329 +			then run on separate CPU cores.
   1.330 +	@return The DFC queue to use.
   1.331 +	*/
   1.332 +	virtual TDfcQue* DfcQ(TInt aUnit)=0;
   1.333 +
   1.334 +	/**
   1.335 +	Return the shared chunk create information to be used by this device.
   1.336 +	@param aChunkCreateInfo A chunk create info. object to be to be filled with the settings
   1.337 +							required for this device.
   1.338 +	*/
   1.339 +	virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)=0;
   1.340 +
   1.341 +	/**
   1.342 +	Return the capabilities of this audio device.
   1.343 +	This includes information on the direction of the device (i.e. play or record), the number of audio channels
   1.344 +	supported (mono, stereo etc), the encoding formats and sample rates supported and so on.
   1.345 +	@param aCapsBuf A packaged TSoundFormatsSupportedV02 object to be filled with the capabilities
   1.346 +		of this device. This descriptor is in kernel memory and can be accessed directly.
   1.347 +	@see TSoundFormatsSupportedV02.
   1.348 +	*/
   1.349 +	virtual void Caps(TDes8& aCapsBuf) const=0;
   1.350 +
   1.351 +	/**
   1.352 +	Return the maximum transfer length in bytes that this device can support in a single data transfer.
   1.353 +	(If the device is using the Symbian DMA framework to handle data transfers then the framework handles data
   1.354 +	transfers which exceed the maximum transfer length for the platform. However, some PDD implementations
   1.355 +	may not use the DMA framework).
   1.356 +	@return The maximum transfer length in bytes.
   1.357 +	*/
   1.358 +	virtual TInt MaxTransferLen() const=0;
   1.359 +
   1.360 +	/**
   1.361 +	Configure or reconfigure the device using the configuration supplied.
   1.362 +	@param aConfigBuf A packaged TCurrentSoundFormatV02 object which contains the new configuration settings.
   1.363 +		This descriptor is in kernel memory and can be accessed directly.
   1.364 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.365 +	@see TCurrentSoundFormatV02.
   1.366 +	*/
   1.367 +	virtual TInt SetConfig(const TDesC8& aConfigBuf)=0;
   1.368 +
   1.369 +	/**
   1.370 +	Set the volume or record level.
   1.371 +	@param aVolume The play volume or record level to be set - a value in the range 0 to 255. The value 255
   1.372 +		equates to the maximum volume and each value below this equates to a 0.5dB step below it.
   1.373 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.374 +	*/
   1.375 +	virtual TInt SetVolume(TInt aVolume)=0;
   1.376 +
   1.377 +	/**
   1.378 +	Prepare the audio device for data transfer.
   1.379 +	This may be preparing it either for record or playback - depending on the direction of the channel.
   1.380 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.381 +	*/
   1.382 +	virtual TInt StartTransfer()=0;
   1.383 +
   1.384 +	/**
   1.385 +	Initiate the transfer of a portion of data from/to the audio device.
   1.386 +	This may be to either record or playback the data - depending on the direction of the channel. When the transfer is
   1.387 +	complete, the PDD should signal this event using the LDD function PlayCallback() or RecordCallback() as appropriate.
   1.388 +	@param aTransferID A value assigned by the LDD to allow it to uniquely identify a particular transfer fragment.
   1.389 +	@param aLinAddr A linear address within the shared chunk. For playback this is the address of the start of the data
   1.390 +		to be transferred. For record, this is the start address for storing the recorded data.
   1.391 +	@param aPhysAddr The physical address within the shared chunk that corresponds to the linear address: aLinAddr.
   1.392 +	@param aNumBytes The number of bytes to be transferred.
   1.393 +	@return KErrNone if the transfer has been initiated successfully;
   1.394 +  			KErrNotReady if the device is unable to accept the transfer for the moment;
   1.395 +		  	otherwise one of the other system-wide error codes.
   1.396 +	*/
   1.397 +	virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes)=0;
   1.398 +
   1.399 +	/**
   1.400 +	Terminate the transfer of a data to/from the device and to release any resources necessary for transfer.
   1.401 +	In the case of playback, this is called soon after the last pending play request from the client has been completed.
   1.402 +	In the case of record, the LDD will leave the audio device capturing record data even when there are no record
   1.403 +	requests pending from the client. Transfer will only be terminated when the client either issues
   1.404 +	RSoundSc::CancelRecordData() or closes the channel. Once this function had been called, the LDD will not issue
   1.405 +	any further TransferData() commands without first issueing a StartTransfer() command.
   1.406 +	*/
   1.407 +	virtual void StopTransfer()=0;
   1.408 +
   1.409 +	/**
   1.410 +	Halt the transfer of data to/from the sound device but don't release any resources necessary for transfer.
   1.411 +	In the case of playback, if possible, any active transfer should be suspended in such a way that it can be
   1.412 +	resumed later - starting from next sample following the one last played.
   1.413 +	In the case of record, any active transfer should be aborted. When recording is halted the PDD should signal this event
   1.414 +	with a single call of the LDD function RecordCallback() - reporting back any partial data already received. In this
   1.415 +	case, if transfer is resumed later, the LDD will issue a new TransferData() request to re-commence data transfer.
   1.416 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.417 +	*/
   1.418 +	virtual TInt PauseTransfer()=0;
   1.419 +
   1.420 +	/**
   1.421 +	Resume the transfer of data to/from the sound device following a request to halt the transfer.
   1.422 +	In the case of playback, if possible, any transfer which was active when the device was halted should be resumed -
   1.423 +	starting from next sample following the one last played. Once complete, it should be reported using PlayCallback()
   1.424 +	as normal.
   1.425 +	In the case of record, any active transfer would have been aborted when the device was halted so its just a case
   1.426 +	of re-creating the same setup achieved following StartTransfer().
   1.427 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.428 +	*/
   1.429 +	virtual TInt ResumeTransfer()=0;
   1.430 +
   1.431 +	/**
   1.432 +	Power up the sound device. This is called when the channel is first opened and if ever the phone is brought out
   1.433 +	of standby mode.
   1.434 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.435 +	*/
   1.436 +	virtual TInt PowerUp()=0;
   1.437 +
   1.438 +	/**
   1.439 +	Power down the sound device. This is called when the channel is closed and just before the phone powers down when
   1.440 +	being turned off or going into standby.
   1.441 +	*/
   1.442 +	virtual void PowerDown()=0;
   1.443 +
   1.444 +	/**
   1.445 +	Handle a custom configuration request.
   1.446 +	@param aFunction A number identifying the request.
   1.447 +	@param aParam A 32-bit value passed to the driver. Its meaning depends on the request.
   1.448 +	@return KErrNone if successful, otherwise one of the other system wide error codes.
   1.449 +	*/
   1.450 +	virtual TInt CustomConfig(TInt aFunction,TAny* aParam)=0;
   1.451 +
   1.452 +	/**
   1.453 +	Calculates and returns the number of microseconds of data transferred since the start of transfer.
   1.454 +	@param aTime	A reference to a variable into which to place the number of microseconds played or recorded.
   1.455 +	@param aState	The current state of the transfer (from TSoundScLdd::TState).  Included so that paused
   1.456 +					and Active transfers can be treated differently.
   1.457 +	@return			KErrNone if successful, otherwise one of the other system wide error codes.
   1.458 +	*/
   1.459 +	virtual TInt TimeTransferred(TInt64& aTime, TInt aState);
   1.460 +protected:
   1.461 +	inline DSoundScLdd* Ldd();
   1.462 +private:
   1.463 +	DSoundScLdd* iLdd;
   1.464 +	friend class DSoundScLdd;
   1.465 +	};
   1.466 +
   1.467 +/**
   1.468 +The logical device (factory class) for the sound driver.
   1.469 +*/
   1.470 +class DSoundScLddFactory : public DLogicalDevice
   1.471 +	{
   1.472 +public:
   1.473 +	DSoundScLddFactory();
   1.474 +	virtual TInt Install();
   1.475 +	virtual void GetCaps(TDes8 &aDes) const;
   1.476 +	virtual TInt Create(DLogicalChannelBase*& aChannel);
   1.477 +	TBool IsUnitOpen(TInt aUnit);
   1.478 +	TInt SetUnitOpen(TInt aUnit,TBool aIsOpenSetting);
   1.479 +private:
   1.480 +	/** Mask to keep track of which units have a channel open on them. */
   1.481 +	TUint iUnitsOpenMask;
   1.482 +	/** A mutex to protect access to the unit info. mask. */
   1.483 +	NFastMutex iUnitInfoMutex;
   1.484 +	};
   1.485 +
   1.486 +/**
   1.487 +The logical channel class for the sound driver.
   1.488 +*/
   1.489 +class DSoundScLdd : public DLogicalChannel
   1.490 +	{
   1.491 +public:
   1.492 +	enum TState
   1.493 +		{
   1.494 +		/** Channel is open - but not configured. */
   1.495 +		EOpen,
   1.496 +		/** Channel is configured - but inactive. */
   1.497 +		EConfigured,
   1.498 +		/** Channel is active - recording or playing data. */
   1.499 +		EActive,
   1.500 +		/** Channel is paused - recording or playing has been suspended. */
   1.501 +		EPaused
   1.502 +		};
   1.503 +public:
   1.504 +	DSoundScLdd();
   1.505 +	virtual ~DSoundScLdd();
   1.506 +	// Inherited from DLogicalChannel
   1.507 +	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
   1.508 +	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
   1.509 + 	virtual TInt SendMsg(TMessageBase* aMsg);
   1.510 +	virtual void HandleMsg(TMessageBase* aMsg);
   1.511 +	void Shutdown();
   1.512 +	// Functions used by the PDD
   1.513 +	virtual void PlayCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesPlayed);
   1.514 +	virtual void RecordCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesRecorded);
   1.515 +	virtual void NotifyChangeOfHwConfigCallback(TBool aHeadsetPresent);
   1.516 +	virtual TSoundSharedChunkBufConfig* BufConfig();
   1.517 +	virtual TLinAddr ChunkBase();
   1.518 +private:
   1.519 +	// Implementations for the different kinds of requests
   1.520 +	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2,DThread* aThread);
   1.521 +	TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2,DThread* aThread);
   1.522 +	TInt DoCancel(TUint aMask);
   1.523 +	TInt SetBufferConfig(DThread* aThread);
   1.524 +	TInt SetBufferConfig(TInt aChunkHandle,DThread* aThread);
   1.525 +	TInt SetSoundConfig();
   1.526 +	TInt DoSetSoundConfig(const TCurrentSoundFormatV02& aSoundConfig);
   1.527 +	TInt SetVolume(TInt aVolume);
   1.528 +	TInt PlayData(TRequestStatus* aStatus,TSoundScPlayRequest* aRequest,DThread* aThread);
   1.529 +	TInt RecordData(TRequestStatus* aStatus,TInt* aLengthPtr,DThread* aThread);
   1.530 +	TInt StartRecord();
   1.531 +	TInt ReleaseBuffer(TInt aChunkOffset);
   1.532 +	TInt CustomConfig(TInt aFunction,TAny* aParam);
   1.533 +	TInt ValidateConfig(const TCurrentSoundFormatV02& aConfig);
   1.534 +	TInt ReAllocBufferConfigInfo(TInt aNumBuffers);
   1.535 +	void StartNextPlayTransfers();
   1.536 +	inline void CompletePlayRequest(TSoundScPlayRequest* aReq,TInt aResult);
   1.537 +	void DoCompletePlayRequest(TSoundScPlayRequest* aReq);
   1.538 +	void CompleteAllDonePlayRequests(TSoundScPlayRequest* aReq);
   1.539 +	void HandleCurrentRecordBufferDone(TInt aTransferResult);
   1.540 +	void CompleteRequest(DThread* aThread,TRequestStatus* aStatus,TInt aReason,TClientRequest* aClientRequest=NULL);
   1.541 +	TInt StartNextRecordTransfers();
   1.542 +	void StartPlayEofTimer();
   1.543 +	void CancelPlayEofTimer();
   1.544 +	inline DSoundScPdd* Pdd();
   1.545 +	static void PlayEofTimerExpired(TAny* aChannel);
   1.546 +	static void PlayEofTimerDfc(TAny* aChannel);
   1.547 +	static void PowerUpDfc(TAny* aChannel);
   1.548 +	static void PowerDownDfc(TAny* aChannel);
   1.549 +	TInt PrePlay(TMessageBase* aMsg);
   1.550 +	TInt PreSetBufferChunkCreateOrOpen(TMessageBase* aMsg);
   1.551 +	TInt PreSetSoundConfig(TMessageBase* aMsg);
   1.552 +private:
   1.553 +	/** The handle to the chunk that is returned to the user side code. */
   1.554 +	TInt iChunkHandle;
   1.555 +	/** The handle of the thread that created the chunk referenced by iChunkHandle */
   1.556 +	DThread* iChunkHandleThread;
   1.557 +	/** The unit number of this channel. */
   1.558 +	TInt iUnit;
   1.559 +	/** The data transfer direction for this unit: play or record. */
   1.560 +	TSoundDirection iDirection;
   1.561 +	/** The operating state of the channel. */
   1.562 +	TState iState;
   1.563 +	/** Spare. */
   1.564 +	TInt iSpare;
   1.565 +	/** The buffer manager - managing the shared chunk and the record/play buffers within this. */
   1.566 +	DBufferManager* iBufManager;
   1.567 +	/** A mutex to protect access to the buffer lists and the pending request list. */
   1.568 +	NFastMutex iMutex;
   1.569 +	/** The transfer status of the record buffer currently being filled. */
   1.570 +	TSndScTransfer iCurrentRecBufTf;
   1.571 +	/** The transfer status of the record buffer which is next to be filled. */
   1.572 +	TSndScTransfer iNextRecBufTf;
   1.573 +	/** The current buffer configuration in the play/record chunk. */
   1.574 +	TSoundSharedChunkBufConfig* iBufConfig;
   1.575 +	/** The size in bytes of the play/record buffer configuration info. structure. */
   1.576 +	TInt iBufConfigSize;
   1.577 +	/** The sound driver power handler. */
   1.578 +	DSoundScPowerHandler* iPowerHandler;
   1.579 +	/** DFC used to handle power down requests from the power manager before a transition into system shutdown/standby. */
   1.580 +	TDfc iPowerDownDfc;
   1.581 +	/** DFC used to handle power up requests from the power manager following a transition out of system standby. */
   1.582 +	TDfc iPowerUpDfc;
   1.583 +	/** The capabilities of this device. */
   1.584 +	TSoundFormatsSupportedV02 iCaps;
   1.585 +	/** The current audio configuration of the driver. */
   1.586 +	TCurrentSoundFormatV02 iSoundConfig;
   1.587 +	/** The requested audio configuration of the driver before validation. */
   1.588 +	TCurrentSoundFormatV02 iTempSoundConfig;
   1.589 +	/** A bitmask holding sound configuration status information. */
   1.590 +	TUint32 iSoundConfigFlags;
   1.591 +	/** The current setting for the record level / play volume. */
   1.592 +	TInt iVolume;
   1.593 +	/** The queue of pending play or record requests. */
   1.594 +	TSoundScRequestQueue* iReqQueue;
   1.595 +	/** Used to complete the change of hardware notification. */
   1.596 +	TClientDataRequest<TBool>* iNotifyChangeOfHwClientRequest;
   1.597 +	/** The thread which has registered for the hardware configuration change notifier. */
   1.598 +	DThread* iChangeOfHwConfigThread;
   1.599 +	/** A pointer to the headset present boolean variable in client memory which is updated on a notification. */
   1.600 +	TBool* iHeadsetPresentStatPtr;
   1.601 +	/** To keep track of the number of bytes transferred. */
   1.602 +	TInt iBytesTransferred;
   1.603 +	/** Count of the number of times the PDD completes a record transfer fragment just after being paused. */
   1.604 +	TInt iCompletesWhilePausedCount;
   1.605 +	/** A timer used to delay exiting play transfer mode at EOF. */
   1.606 +	NTimer iEofTimer;
   1.607 +	/** DFC used to delay exiting play transfer mode at EOF. */
   1.608 +	TDfc iPlayEofDfc;
   1.609 +	/** Used for testing and debugging. */
   1.610 +	TUint iTestSettings;
   1.611 +	/** A flag to indicate whether the play EOF timer is active. */
   1.612 +	TBool iPlayEofTimerActive;
   1.613 +	/** Used in debug builds to track that all calls to DThread::Open() are balanced with a close before the driver closes. */
   1.614 +	TInt iThreadOpenCount;
   1.615 +	/** Used to complete requests in the DFC thread. */
   1.616 +	TClientRequest** iClientRequests;
   1.617 +
   1.618 +	friend class DBufferManager;
   1.619 +	friend class DSoundScPowerHandler;
   1.620 +	friend class TSoundScRequestQueue;
   1.621 +	};
   1.622 +
   1.623 +#include <drivers/soundsc.inl>
   1.624 +#endif	// __SOUNDSC_H__