os/boardsupport/emulator/emulatorbsp/specific/winssoundsc.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2005-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 "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 // wins\specific\winssoundsc.h
    15 // Definitions for the emulator shared chunk sound driver PDD.
    16 // 
    17 //
    18 
    19 /**
    20  @file
    21  @internalTechnology
    22  @prototype
    23 */
    24 
    25 #ifndef __WINSSOUNDSC_H__
    26 #define __WINSSOUNDSC_H__
    27 
    28 #include <drivers/soundsc.h>
    29 #include "nk_priv.h"
    30 #include <emulator.h>
    31 #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
    32 #include <mmsystem.h>
    33 #include <mmreg.h>
    34 #pragma warning(default : 4201)
    35 #include <property.h>
    36 
    37 //#define FORCE_NO_HARDWARE
    38 
    39 //#define __KTRACE_SND(s) s;
    40 #define __KTRACE_SND(s)
    41 
    42 #define PANIC()	Kern::Fault("WinsSoundScPdd", __LINE__)
    43 
    44 const TInt KMMTimerRes = 5;	// Minimum timer resolution (5mS). Timer used only when no audio hardware present.
    45 const TInt KWinsMaxAudioTransferLen=0x8000;	// The maximum transfer length this PDD will accept (32K).
    46 const TInt KMinWaveHdrBufCount=8;			// The minimum number of record or playback waveform audio buffers.
    47 
    48 GLREF_C TInt RateInSamplesPerSecond(TSoundRate aRate);
    49 GLREF_C DWORD WaitForSingleObjectDualThread(HANDLE hHandle,DWORD dwMilliseconds);
    50 GLREF_C WAVEHDR* RemoveFromPendingList(WAVEHDR** aList);
    51 GLREF_C void AddToPendingList(WAVEHDR* aBuffer,WAVEHDR** aList);
    52 
    53 // Utility class used to lock the kernel for a short period while windows 
    54 // API calls are made. This is to stop a possible deadlock from occurring when 
    55 // a windows thread is suspended while a (windows) synchronization object is held
    56 // and a second thread tries to gain access to that object. Typically this object 
    57 // is declared on the stack - when the constructor is called, the kernel is locked; 
    58 // when the object goes out of scope, the destructor unlocks the kernel.
    59 // Used by the __HOST_LOCK macro.
    60 class THostLock
    61 	{
    62 public:
    63 	THostLock();
    64 	~THostLock();
    65 	void Lock();
    66 	void Unlock();
    67 protected:
    68 	THostLock(TBool aLock);
    69 private:
    70 	TBool iLocked;
    71 	};
    72 
    73 // Utility class used to lock the kernel for a short period while windows 
    74 // API calls are made. This is used instead of THostLock for functions
    75 // which are used by both the driver thread and the play thread - 
    76 // if the thread is a windows thread, then the kernel is not locked.
    77 // Used by the __COND_HOST_LOCK macro.
    78 class TCondHostLock : public THostLock
    79 	{
    80 public:
    81 	TCondHostLock();
    82 	void Lock();
    83 	void Unlock();
    84 private:
    85 	TBool iEpocThread;
    86 	};
    87 
    88 // Forward declarations
    89 class TWaveformBufMgr;
    90 
    91 /**
    92 This the abstraction for a windows waveform audio buffer.
    93 */
    94 class TWaveformAudioBuf
    95 	{
    96 public:
    97 	TWaveformAudioBuf();
    98 	inline void SetWaveformBufMgr(TWaveformBufMgr* aWaveformBufMgr)
    99 		{iWaveformBufMgr=aWaveformBufMgr;}
   100 	inline void SetBufNum(TInt aBufNum)
   101 		{iBufNum=aBufNum;}
   102 	void Prepare(char* aBufAddr,TInt aBufLength,TInt aDeviceHandle);
   103 	void Unprepare(TInt aDeviceHandle);
   104 private:		
   105 	void DoPrepareOut(HWAVEOUT aPlayDeviceHandle);
   106 	void DoUnprepareOut(HWAVEOUT aPlayDeviceHandle);
   107 	void DoPrepareIn(HWAVEIN aRecordDeviceHandle);
   108 	void DoUnprepareIn(HWAVEIN aRecordDeviceHandle);
   109 public:
   110 	/** The owning waveform audio buffer manager. */
   111 	TWaveformBufMgr* iWaveformBufMgr;
   112 	/** Set when the waveform audio buffer is currently prepared. */
   113 	TBool iIsPrepared;
   114 	/** Set when the waveform audio buffer is involved in an active transfer. */
   115 	TBool iIsInUse;
   116 	/** The header used by windows to identify the waveform audio buffer. */
   117 	WAVEHDR iBufHdr;
   118 	/** A value used to identify a particular waveform audio buffer within an array of these objects. */
   119 	TInt iBufNum;
   120 	/** The transfer ID supplied by the LDD when the buffer is involved in an active transfer. */
   121 	TUint iTransferID;
   122 	friend class TWaveformBufMgr;	
   123 	};
   124 
   125 /**
   126 The waveform audio buffer manager. This owns and maintains a set of windows waveform audio buffers which it makes
   127 available to the PDD for data block transfers.
   128 */	
   129 class TWaveformBufMgr
   130 	{
   131 public:	
   132 	TWaveformBufMgr(TSoundDirection aDirection,TBool aIsHardware);
   133 	~TWaveformBufMgr();
   134 	TInt ReAllocAndUpdate(TSoundSharedChunkBufConfig* aBufConfig,TLinAddr aChunkBase,TInt aDeviceHandle);
   135 	TWaveformAudioBuf* AcquireBuf(char* aStartAddress,TInt aBufLength,TInt aDeviceHandle);
   136 public:
   137 	/** The array of windows waveform audio buffer objects. There is at least one buffer object per buffer within the 
   138 	LDD shared chunk. */
   139 	TWaveformAudioBuf* iWaveformAudioBuf;
   140 	/** The count of the number of audio play buffers in the waveform buffer array. */
   141 	TInt iNumWaveformBufs;
   142 	/** The  default size of each audio buffer in the waveform buffer array. */
   143 	TInt iWaveformBufSize;
   144 	/** List of waveform audio buffer objects waiting to be played/recorded - in FIFO order. Used only when
   145 	no audio hardware is present.*/
   146 	WAVEHDR** iPendingBufList;
   147 	/** Set when no audio hardware is present. */
   148 	TBool iIsHardware;
   149 	/** The direction of the windows waveform audio buffer, record or playback. */
   150 	TSoundDirection iDirection;
   151 	};	
   152 	
   153 /**
   154 The WINS physical device (factory class) for the shared chunk sound driver.
   155 */	
   156 class DWinsSoundScPddFactory : public DPhysicalDevice
   157 	{
   158 public:
   159 	DWinsSoundScPddFactory();
   160 	~DWinsSoundScPddFactory();
   161 	virtual TInt Install();
   162 	virtual void GetCaps(TDes8 &aDes) const;
   163 	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
   164 	virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
   165 private:
   166 	/** The DFC queue (used also by the LDD). */ 
   167 	TDynamicDfcQue* iDfcQ;
   168 	/** DFC for terminating the DFC thread. */
   169    	static TDfc ExitDfc;
   170 	friend class DWinsSoundScTxPdd;
   171 	friend class DWinsSoundScRxPdd;
   172 	};
   173 	
   174 /**
   175 The WINS physical device driver (PDD) for the playback shared chunk sound driver.
   176 */
   177 class DWinsSoundScTxPdd : public DSoundScPdd
   178 	{
   179 private:
   180 	enum TThreadCommand {ESendData, EStop, EExit, EPause, EResume};
   181 	enum TCreatePlayDeviceMode {EInit,ESetConfig,EStartTransfer};
   182 public:
   183 	DWinsSoundScTxPdd();
   184 	~DWinsSoundScTxPdd();
   185 	TInt DoCreate(DWinsSoundScPddFactory* aPhysicalDevice);
   186 	// Implementations of the pure virtual functions inherited from DSoundScPdd.
   187 	virtual TDfcQue* DfcQ(TInt aUnit);
   188 	virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo);
   189 	virtual void Caps(TDes8& aCapsBuf) const;
   190 	virtual TInt MaxTransferLen() const;
   191 	virtual TInt SetConfig(const TDesC8& aConfigBuf);
   192 	virtual TInt SetVolume(TInt aVolume);
   193 	virtual TInt StartTransfer();
   194 	virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes);
   195 	virtual void StopTransfer();
   196 	virtual TInt PauseTransfer();
   197 	virtual TInt ResumeTransfer();
   198 	virtual TInt PowerUp();
   199 	virtual void PowerDown();
   200 	virtual TInt CustomConfig(TInt aFunction,TAny* aParam);
   201 	virtual TInt TimeTransferred(TInt64& aTime, TInt aState);
   202 public:
   203 	void WaveOutProc(WAVEHDR* aHdr);
   204 	void PlayThread();
   205 private:
   206 	void SetCaps();
   207 	TInt OpenWaveOutDevice();
   208 	TInt CreatePlayDevice(TCreatePlayDeviceMode aMode);
   209 	void ClosePlayDevice();
   210 	void PlayThreadCommand(TThreadCommand aCommand,TInt aArg0=0,TInt aArg1=0,TInt aArg2=0);
   211 	TInt ProcessPlayCommand(TThreadCommand aCommand,TInt aArg0,TInt aArg1,TInt aArg2);
   212 	void HandlePlayTimerEvent();
   213 	void HandleTransferComplete();
   214 	void PlayThreadNotifyDriver(TInt aError);
   215 	void StartTimer(WAVEHDR* aBuffer);
   216 	void StopTimer(TBool aCancelAll);
   217 	static void PlayDfc(TAny* aPtr);
   218 private:
   219 	/** A pointer to the PDD factory. */
   220 	DWinsSoundScPddFactory* iPhysicalDevice;
   221 	/** The capabilities of this device. */
   222 	TSoundFormatsSupportedV02 iCaps;
   223 	/** The current audio configuration of this device. */
   224 	TCurrentSoundFormatV02 iSoundConfig;
   225 	/** The current setting for the play volume - a value in the range 0 to 0xFFFF. */
   226 	TInt iVolume;
   227 	/** The driver thread semaphore - used by the windows thread to signal the driver thread. */
   228 	HANDLE iDriverThreadSem;
   229 	/** The handle for the play windows thread. */
   230 	HANDLE iPlayThread;
   231 	/** ETrue if the Windows thread is running, else EFalse.  Used when shutting down to decide whether to
   232 	signal the thread to exit. */
   233 	TBool iPlayThreadRunning;
   234 	/** The play thread mutuex - to serialise acccess to the play thread creation and destruction routines. */
   235 	HANDLE iPlayThreadMutex;
   236 	/** The play thread semaphore - indicates to the windows thread that the driver thread has issued a command. */
   237 	HANDLE iPlayThreadSem;
   238 	/** Semaphore to synchronise between driver thread and windows thread when closing the output device. */
   239 	HANDLE iStopSemaphore;
   240 	/** Semaphore to synchronise between driver thread and windows thread when closing the PDD. */
   241 	HANDLE iDeathSemaphore;
   242 	/** The handle on the waveform output device. */
   243 	HWAVEOUT iPlayDeviceHandle;
   244 	/** Used to transfer commands between the driver thread and the windows thread. */
   245 	TThreadCommand iPlayCommand;
   246 	/** Used to transfer commands between the driver thread and the windows thread. */
   247 	TInt iPlayCommandArg0;
   248 	/** Used to transfer commands between the driver thread and the windows thread. */
   249 	TInt iPlayCommandArg1;
   250 	/** Used to transfer commands between the driver thread and the windows thread. */
   251 	TInt iPlayCommandArg2;
   252 	// The number of outstanding data transfers on the waveform output device. */	
   253 	TInt iPendingPlay;
   254 	/** DFC which handes data block play completion. */
   255 	TDfc iDfc;
   256 	/** A variable used to pass a value from the windows thread to the driver thread. */
   257 	TInt iPlayThreadError;
   258 	/** The windows waveform audio buffer manager. */
   259 	TWaveformBufMgr* iWaveformBufMgr;
   260 	/** A mask used to pass information on transfers that have just completed between the window thread and the 
   261 	driver thread. Updates to this variable typically need to happen atomically. Bit positions are converted 
   262 	into windows waveform audio buffer IDs. */
   263 	TUint32 iCompletedPlayBufHdrMask;
   264 	/** Set when no audio hardware is present. */
   265 	TBool iNoHardware;
   266 	/** The timer event object - indicates the 'no-hardware' timer has gone off. */
   267 	HANDLE iPlayTimerEvent;
   268 	/** The identifier for the current 'no-hardware' timer event. */
   269 	UINT iTimerID;
   270 	/** Indicates whether the 'no-hardware' timer is currently active. */
   271 	TBool iTimerActive;
   272 	/** A variable used to save the play volume setting of the waveform output device at the point when this driver was opened. */
   273 	DWORD iWinWaveVolume;
   274 	/** The number of bytes (not samples) that will be played back per second, at the current sample rate. */
   275 	TUint iBytesPerSecond;
   276 	/** The simulated (ie. no hardware) microseconds played. */
   277 	TInt64 iSimulatedUSecPlayed;
   278 	/** The # of milliseconds that pass per block of data that is played. */
   279 	UINT iSimulatedMsecDuration;
   280 	/** The Windows system timer time at which the last block of data was played. */
   281 	DWORD iLastTimerEventTime;
   282 	/** The Windows system timer time at which playback was paused. */
   283 	DWORD iPauseTime;
   284 	};
   285 		
   286 /**
   287 The WINS physical device driver (PDD) for the record shared chunk sound driver.
   288 */
   289 class DWinsSoundScRxPdd : public DSoundScPdd
   290 	{
   291 private:
   292 	enum TThreadCommand {ERecData, EStop, EExit, EPause, EResume};	
   293 public:
   294 	DWinsSoundScRxPdd();
   295 	~DWinsSoundScRxPdd();
   296 	TInt DoCreate(DWinsSoundScPddFactory* aPhysicalDevice);
   297 	// Implementations of the pure virtual functions inherited from DSoundScPdd.
   298 	virtual TDfcQue* DfcQ(TInt aUnit);
   299 	virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo);
   300 	virtual void Caps(TDes8& aCapsBuf) const;
   301 	virtual TInt MaxTransferLen() const;
   302 	virtual TInt SetConfig(const TDesC8& aConfigBuf);
   303 	virtual TInt SetVolume(TInt aVolume);
   304 	virtual TInt StartTransfer();
   305 	virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes);
   306 	virtual void StopTransfer();
   307 	virtual TInt PauseTransfer();
   308 	virtual TInt ResumeTransfer();
   309 	virtual TInt PowerUp();
   310 	virtual void PowerDown();
   311 	virtual TInt CustomConfig(TInt aFunction,TAny* aParam);
   312 	virtual TInt TimeTransferred(TInt64& aTime, TInt aState);
   313 public:
   314 	void WaveInProc(WAVEHDR* aHdr);
   315 	void RecordThread();
   316 private:
   317 	void SetCaps();
   318 	TInt OpenWaveInDevice();
   319 	TInt CreateRecordDevice(TBool aCheckDevice=EFalse);
   320 	void CloseRecordDevice();	
   321 	void RecordThreadCommand(TThreadCommand aCommand,TInt aArg0=0,TInt aArg1=0,TInt aArg2=0);
   322 	TInt ProcessRecordCommand(TThreadCommand aCommand,TInt aArg0,TInt aArg1,TInt aArg2);
   323 	void HandleRecordTimerEvent();
   324 	void HandleTransferComplete();
   325 	void RecordThreadNotifyDriver(TInt aError);
   326 	void StartTimer(WAVEHDR* aBuffer);
   327 	void StopTimer(TBool aCancelAll);
   328 	static void RecordDfc(TAny* aPtr);
   329 private:
   330 	/** A pointer to the PDD factory. */
   331 	DWinsSoundScPddFactory* iPhysicalDevice;
   332 	/** The capabilities of this device. */
   333 	TSoundFormatsSupportedV02 iCaps;
   334 	/** The current audio configuration of this device. */
   335 	TCurrentSoundFormatV02 iSoundConfig;
   336 	/** The driver thread semaphore - used by the windows thread to signal the driver thread. */
   337 	HANDLE iDriverThreadSem;
   338 	/** The handle for the record windows thread. */
   339 	HANDLE iRecordThread;
   340 	/** ETrue if the Windows thread is running, else EFalse.  Used when shutting down to decide whether to
   341 	signal the thread to exit. */
   342 	TBool iRecordThreadRunning;
   343 	/** The record thread mutuex - to serialise acccess to the record thread creation and destruction routines. */
   344 	HANDLE iRecordThreadMutex;
   345 	/** The record thread semaphore - indicates to the windows thread that the driver thread has issued a command. */
   346 	HANDLE iRecordThreadSem;
   347 	/** Semaphore to synchronise between driver thread and windows thread when closing the input device. */
   348 	HANDLE iStopSemaphore;
   349 	/** Semaphore to synchronise between driver thread and windows thread when closing the PDD. */
   350 	HANDLE iDeathSemaphore;
   351 	/** The handle on the waveform input device. */
   352 	HWAVEIN iRecordDeviceHandle;
   353 	/** Used to transfer commands between the driver thread and the windows thread. */
   354 	TThreadCommand iRecordCommand;
   355 	/** Used to transfer commands between the driver thread and the windows thread. */
   356 	TInt iRecordCommandArg0;
   357 	/** Used to transfer commands between the driver thread and the windows thread. */
   358 	TInt iRecordCommandArg1;
   359 		/** Used to transfer commands between the driver thread and the windows thread. */
   360 	TInt iRecordCommandArg2;
   361 	// The number of outstanding data transfers on the waveform input device. */	
   362 	TInt iPendingRecord;
   363 	/** DFC which handes data block record completion. */
   364 	TDfc iDfc;
   365 	/** A variable used to pass a value from the windows thread to the driver thread. */
   366 	TInt iRecordThreadError;
   367 	/** The windows waveform audio buffer manager. */
   368 	TWaveformBufMgr* iWaveformBufMgr;
   369 	/** A mask used to pass information on transfers that have just completed between the window thread and the 
   370 	driver thread. Updates to this variable typically need to happen atomically. Bit positions are converted 
   371 	into windows waveform audio buffer IDs. */
   372 	TUint32 iCompletedRecordBufHdrMask;
   373 	/** Indicates when record mode is enabled. */
   374 	TBool iRecordEnabled;
   375 	/** Set when no audio hardware is present. */
   376 	TBool iNoHardware;
   377 	/** The timer event object - indicates the 'no-hardware' timer has gone off. */
   378 	HANDLE iRecordTimerEvent;
   379 	/** The identifier for the current 'no-hardware' timer event. */
   380 	UINT iTimerID;
   381 	/** Indicates whether the 'no-hardware' timer is currently active. */
   382 	TBool iTimerActive;
   383 	/** The number of bytes (not samples) that will be recorded back per second, at the current sample rate. */
   384 	TUint iBytesPerSecond;
   385 	/** The number of bytes recorded before the last pause command (when we pause the windows byte
   386 		count is reset so we need to add this on for the TimeRecorded API). */
   387 	TUint iBytesRecordedBeforeLastPause;
   388 	/** The number of recorded bytes reported to the LDD. Subtracted from the windows recorded byte count 
   389 		to calculate the last, partial buffer, transfer size */
   390 	TUint iBytesSincePauseReportedToLdd;
   391 	/** The # of milliseconds that pass per block of data that is recorded. */
   392 	UINT iSimulatedMsecDuration;
   393 	/** The Windows system timer time at which the last block of data was recorded. */
   394 	DWORD iLastTimerEventTime;
   395 	};	
   396 
   397 #define __HOST_LOCK			THostLock lock
   398 #define __HOST_LOCK_ON		lock.Lock();
   399 #define __HOST_LOCK_OFF		lock.Unlock();
   400 #define __COND_HOST_LOCK	TCondHostLock lock
   401 	
   402 #endif /* __WINSSOUNDSC_H__ */