diff -r 000000000000 -r cec860690d41 emulator/emulatorbsp/specific/winssoundsc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emulator/emulatorbsp/specific/winssoundsc.h Tue Feb 02 01:39:10 2010 +0200 @@ -0,0 +1,402 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// wins\specific\winssoundsc.h +// Definitions for the emulator shared chunk sound driver PDD. +// +// + +/** + @file + @internalTechnology + @prototype +*/ + +#ifndef __WINSSOUNDSC_H__ +#define __WINSSOUNDSC_H__ + +#include +#include "nk_priv.h" +#include +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +#include +#include +#pragma warning(default : 4201) +#include + +//#define FORCE_NO_HARDWARE + +//#define __KTRACE_SND(s) s; +#define __KTRACE_SND(s) + +#define PANIC() Kern::Fault("WinsSoundScPdd", __LINE__) + +const TInt KMMTimerRes = 5; // Minimum timer resolution (5mS). Timer used only when no audio hardware present. +const TInt KWinsMaxAudioTransferLen=0x8000; // The maximum transfer length this PDD will accept (32K). +const TInt KMinWaveHdrBufCount=8; // The minimum number of record or playback waveform audio buffers. + +GLREF_C TInt RateInSamplesPerSecond(TSoundRate aRate); +GLREF_C DWORD WaitForSingleObjectDualThread(HANDLE hHandle,DWORD dwMilliseconds); +GLREF_C WAVEHDR* RemoveFromPendingList(WAVEHDR** aList); +GLREF_C void AddToPendingList(WAVEHDR* aBuffer,WAVEHDR** aList); + +// Utility class used to lock the kernel for a short period while windows +// API calls are made. This is to stop a possible deadlock from occurring when +// a windows thread is suspended while a (windows) synchronization object is held +// and a second thread tries to gain access to that object. Typically this object +// is declared on the stack - when the constructor is called, the kernel is locked; +// when the object goes out of scope, the destructor unlocks the kernel. +// Used by the __HOST_LOCK macro. +class THostLock + { +public: + THostLock(); + ~THostLock(); + void Lock(); + void Unlock(); +protected: + THostLock(TBool aLock); +private: + TBool iLocked; + }; + +// Utility class used to lock the kernel for a short period while windows +// API calls are made. This is used instead of THostLock for functions +// which are used by both the driver thread and the play thread - +// if the thread is a windows thread, then the kernel is not locked. +// Used by the __COND_HOST_LOCK macro. +class TCondHostLock : public THostLock + { +public: + TCondHostLock(); + void Lock(); + void Unlock(); +private: + TBool iEpocThread; + }; + +// Forward declarations +class TWaveformBufMgr; + +/** +This the abstraction for a windows waveform audio buffer. +*/ +class TWaveformAudioBuf + { +public: + TWaveformAudioBuf(); + inline void SetWaveformBufMgr(TWaveformBufMgr* aWaveformBufMgr) + {iWaveformBufMgr=aWaveformBufMgr;} + inline void SetBufNum(TInt aBufNum) + {iBufNum=aBufNum;} + void Prepare(char* aBufAddr,TInt aBufLength,TInt aDeviceHandle); + void Unprepare(TInt aDeviceHandle); +private: + void DoPrepareOut(HWAVEOUT aPlayDeviceHandle); + void DoUnprepareOut(HWAVEOUT aPlayDeviceHandle); + void DoPrepareIn(HWAVEIN aRecordDeviceHandle); + void DoUnprepareIn(HWAVEIN aRecordDeviceHandle); +public: + /** The owning waveform audio buffer manager. */ + TWaveformBufMgr* iWaveformBufMgr; + /** Set when the waveform audio buffer is currently prepared. */ + TBool iIsPrepared; + /** Set when the waveform audio buffer is involved in an active transfer. */ + TBool iIsInUse; + /** The header used by windows to identify the waveform audio buffer. */ + WAVEHDR iBufHdr; + /** A value used to identify a particular waveform audio buffer within an array of these objects. */ + TInt iBufNum; + /** The transfer ID supplied by the LDD when the buffer is involved in an active transfer. */ + TUint iTransferID; + friend class TWaveformBufMgr; + }; + +/** +The waveform audio buffer manager. This owns and maintains a set of windows waveform audio buffers which it makes +available to the PDD for data block transfers. +*/ +class TWaveformBufMgr + { +public: + TWaveformBufMgr(TSoundDirection aDirection,TBool aIsHardware); + ~TWaveformBufMgr(); + TInt ReAllocAndUpdate(TSoundSharedChunkBufConfig* aBufConfig,TLinAddr aChunkBase,TInt aDeviceHandle); + TWaveformAudioBuf* AcquireBuf(char* aStartAddress,TInt aBufLength,TInt aDeviceHandle); +public: + /** The array of windows waveform audio buffer objects. There is at least one buffer object per buffer within the + LDD shared chunk. */ + TWaveformAudioBuf* iWaveformAudioBuf; + /** The count of the number of audio play buffers in the waveform buffer array. */ + TInt iNumWaveformBufs; + /** The default size of each audio buffer in the waveform buffer array. */ + TInt iWaveformBufSize; + /** List of waveform audio buffer objects waiting to be played/recorded - in FIFO order. Used only when + no audio hardware is present.*/ + WAVEHDR** iPendingBufList; + /** Set when no audio hardware is present. */ + TBool iIsHardware; + /** The direction of the windows waveform audio buffer, record or playback. */ + TSoundDirection iDirection; + }; + +/** +The WINS physical device (factory class) for the shared chunk sound driver. +*/ +class DWinsSoundScPddFactory : public DPhysicalDevice + { +public: + DWinsSoundScPddFactory(); + ~DWinsSoundScPddFactory(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); +private: + /** The DFC queue (used also by the LDD). */ + TDynamicDfcQue* iDfcQ; + /** DFC for terminating the DFC thread. */ + static TDfc ExitDfc; + friend class DWinsSoundScTxPdd; + friend class DWinsSoundScRxPdd; + }; + +/** +The WINS physical device driver (PDD) for the playback shared chunk sound driver. +*/ +class DWinsSoundScTxPdd : public DSoundScPdd + { +private: + enum TThreadCommand {ESendData, EStop, EExit, EPause, EResume}; + enum TCreatePlayDeviceMode {EInit,ESetConfig,EStartTransfer}; +public: + DWinsSoundScTxPdd(); + ~DWinsSoundScTxPdd(); + TInt DoCreate(DWinsSoundScPddFactory* aPhysicalDevice); + // Implementations of the pure virtual functions inherited from DSoundScPdd. + virtual TDfcQue* DfcQ(TInt aUnit); + virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo); + virtual void Caps(TDes8& aCapsBuf) const; + virtual TInt MaxTransferLen() const; + virtual TInt SetConfig(const TDesC8& aConfigBuf); + virtual TInt SetVolume(TInt aVolume); + virtual TInt StartTransfer(); + virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes); + virtual void StopTransfer(); + virtual TInt PauseTransfer(); + virtual TInt ResumeTransfer(); + virtual TInt PowerUp(); + virtual void PowerDown(); + virtual TInt CustomConfig(TInt aFunction,TAny* aParam); + virtual TInt TimeTransferred(TInt64& aTime, TInt aState); +public: + void WaveOutProc(WAVEHDR* aHdr); + void PlayThread(); +private: + void SetCaps(); + TInt OpenWaveOutDevice(); + TInt CreatePlayDevice(TCreatePlayDeviceMode aMode); + void ClosePlayDevice(); + void PlayThreadCommand(TThreadCommand aCommand,TInt aArg0=0,TInt aArg1=0,TInt aArg2=0); + TInt ProcessPlayCommand(TThreadCommand aCommand,TInt aArg0,TInt aArg1,TInt aArg2); + void HandlePlayTimerEvent(); + void HandleTransferComplete(); + void PlayThreadNotifyDriver(TInt aError); + void StartTimer(WAVEHDR* aBuffer); + void StopTimer(TBool aCancelAll); + static void PlayDfc(TAny* aPtr); +private: + /** A pointer to the PDD factory. */ + DWinsSoundScPddFactory* iPhysicalDevice; + /** The capabilities of this device. */ + TSoundFormatsSupportedV02 iCaps; + /** The current audio configuration of this device. */ + TCurrentSoundFormatV02 iSoundConfig; + /** The current setting for the play volume - a value in the range 0 to 0xFFFF. */ + TInt iVolume; + /** The driver thread semaphore - used by the windows thread to signal the driver thread. */ + HANDLE iDriverThreadSem; + /** The handle for the play windows thread. */ + HANDLE iPlayThread; + /** ETrue if the Windows thread is running, else EFalse. Used when shutting down to decide whether to + signal the thread to exit. */ + TBool iPlayThreadRunning; + /** The play thread mutuex - to serialise acccess to the play thread creation and destruction routines. */ + HANDLE iPlayThreadMutex; + /** The play thread semaphore - indicates to the windows thread that the driver thread has issued a command. */ + HANDLE iPlayThreadSem; + /** Semaphore to synchronise between driver thread and windows thread when closing the output device. */ + HANDLE iStopSemaphore; + /** Semaphore to synchronise between driver thread and windows thread when closing the PDD. */ + HANDLE iDeathSemaphore; + /** The handle on the waveform output device. */ + HWAVEOUT iPlayDeviceHandle; + /** Used to transfer commands between the driver thread and the windows thread. */ + TThreadCommand iPlayCommand; + /** Used to transfer commands between the driver thread and the windows thread. */ + TInt iPlayCommandArg0; + /** Used to transfer commands between the driver thread and the windows thread. */ + TInt iPlayCommandArg1; + /** Used to transfer commands between the driver thread and the windows thread. */ + TInt iPlayCommandArg2; + // The number of outstanding data transfers on the waveform output device. */ + TInt iPendingPlay; + /** DFC which handes data block play completion. */ + TDfc iDfc; + /** A variable used to pass a value from the windows thread to the driver thread. */ + TInt iPlayThreadError; + /** The windows waveform audio buffer manager. */ + TWaveformBufMgr* iWaveformBufMgr; + /** A mask used to pass information on transfers that have just completed between the window thread and the + driver thread. Updates to this variable typically need to happen atomically. Bit positions are converted + into windows waveform audio buffer IDs. */ + TUint32 iCompletedPlayBufHdrMask; + /** Set when no audio hardware is present. */ + TBool iNoHardware; + /** The timer event object - indicates the 'no-hardware' timer has gone off. */ + HANDLE iPlayTimerEvent; + /** The identifier for the current 'no-hardware' timer event. */ + UINT iTimerID; + /** Indicates whether the 'no-hardware' timer is currently active. */ + TBool iTimerActive; + /** A variable used to save the play volume setting of the waveform output device at the point when this driver was opened. */ + DWORD iWinWaveVolume; + /** The number of bytes (not samples) that will be played back per second, at the current sample rate. */ + TUint iBytesPerSecond; + /** The simulated (ie. no hardware) microseconds played. */ + TInt64 iSimulatedUSecPlayed; + /** The # of milliseconds that pass per block of data that is played. */ + UINT iSimulatedMsecDuration; + /** The Windows system timer time at which the last block of data was played. */ + DWORD iLastTimerEventTime; + /** The Windows system timer time at which playback was paused. */ + DWORD iPauseTime; + }; + +/** +The WINS physical device driver (PDD) for the record shared chunk sound driver. +*/ +class DWinsSoundScRxPdd : public DSoundScPdd + { +private: + enum TThreadCommand {ERecData, EStop, EExit, EPause, EResume}; +public: + DWinsSoundScRxPdd(); + ~DWinsSoundScRxPdd(); + TInt DoCreate(DWinsSoundScPddFactory* aPhysicalDevice); + // Implementations of the pure virtual functions inherited from DSoundScPdd. + virtual TDfcQue* DfcQ(TInt aUnit); + virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo); + virtual void Caps(TDes8& aCapsBuf) const; + virtual TInt MaxTransferLen() const; + virtual TInt SetConfig(const TDesC8& aConfigBuf); + virtual TInt SetVolume(TInt aVolume); + virtual TInt StartTransfer(); + virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes); + virtual void StopTransfer(); + virtual TInt PauseTransfer(); + virtual TInt ResumeTransfer(); + virtual TInt PowerUp(); + virtual void PowerDown(); + virtual TInt CustomConfig(TInt aFunction,TAny* aParam); + virtual TInt TimeTransferred(TInt64& aTime, TInt aState); +public: + void WaveInProc(WAVEHDR* aHdr); + void RecordThread(); +private: + void SetCaps(); + TInt OpenWaveInDevice(); + TInt CreateRecordDevice(TBool aCheckDevice=EFalse); + void CloseRecordDevice(); + void RecordThreadCommand(TThreadCommand aCommand,TInt aArg0=0,TInt aArg1=0,TInt aArg2=0); + TInt ProcessRecordCommand(TThreadCommand aCommand,TInt aArg0,TInt aArg1,TInt aArg2); + void HandleRecordTimerEvent(); + void HandleTransferComplete(); + void RecordThreadNotifyDriver(TInt aError); + void StartTimer(WAVEHDR* aBuffer); + void StopTimer(TBool aCancelAll); + static void RecordDfc(TAny* aPtr); +private: + /** A pointer to the PDD factory. */ + DWinsSoundScPddFactory* iPhysicalDevice; + /** The capabilities of this device. */ + TSoundFormatsSupportedV02 iCaps; + /** The current audio configuration of this device. */ + TCurrentSoundFormatV02 iSoundConfig; + /** The driver thread semaphore - used by the windows thread to signal the driver thread. */ + HANDLE iDriverThreadSem; + /** The handle for the record windows thread. */ + HANDLE iRecordThread; + /** ETrue if the Windows thread is running, else EFalse. Used when shutting down to decide whether to + signal the thread to exit. */ + TBool iRecordThreadRunning; + /** The record thread mutuex - to serialise acccess to the record thread creation and destruction routines. */ + HANDLE iRecordThreadMutex; + /** The record thread semaphore - indicates to the windows thread that the driver thread has issued a command. */ + HANDLE iRecordThreadSem; + /** Semaphore to synchronise between driver thread and windows thread when closing the input device. */ + HANDLE iStopSemaphore; + /** Semaphore to synchronise between driver thread and windows thread when closing the PDD. */ + HANDLE iDeathSemaphore; + /** The handle on the waveform input device. */ + HWAVEIN iRecordDeviceHandle; + /** Used to transfer commands between the driver thread and the windows thread. */ + TThreadCommand iRecordCommand; + /** Used to transfer commands between the driver thread and the windows thread. */ + TInt iRecordCommandArg0; + /** Used to transfer commands between the driver thread and the windows thread. */ + TInt iRecordCommandArg1; + /** Used to transfer commands between the driver thread and the windows thread. */ + TInt iRecordCommandArg2; + // The number of outstanding data transfers on the waveform input device. */ + TInt iPendingRecord; + /** DFC which handes data block record completion. */ + TDfc iDfc; + /** A variable used to pass a value from the windows thread to the driver thread. */ + TInt iRecordThreadError; + /** The windows waveform audio buffer manager. */ + TWaveformBufMgr* iWaveformBufMgr; + /** A mask used to pass information on transfers that have just completed between the window thread and the + driver thread. Updates to this variable typically need to happen atomically. Bit positions are converted + into windows waveform audio buffer IDs. */ + TUint32 iCompletedRecordBufHdrMask; + /** Indicates when record mode is enabled. */ + TBool iRecordEnabled; + /** Set when no audio hardware is present. */ + TBool iNoHardware; + /** The timer event object - indicates the 'no-hardware' timer has gone off. */ + HANDLE iRecordTimerEvent; + /** The identifier for the current 'no-hardware' timer event. */ + UINT iTimerID; + /** Indicates whether the 'no-hardware' timer is currently active. */ + TBool iTimerActive; + /** The number of bytes (not samples) that will be recorded back per second, at the current sample rate. */ + TUint iBytesPerSecond; + /** The number of bytes recorded before the last pause command (when we pause the windows byte + count is reset so we need to add this on for the TimeRecorded API). */ + TUint iBytesRecordedBeforeLastPause; + /** The number of recorded bytes reported to the LDD. Subtracted from the windows recorded byte count + to calculate the last, partial buffer, transfer size */ + TUint iBytesSincePauseReportedToLdd; + /** The # of milliseconds that pass per block of data that is recorded. */ + UINT iSimulatedMsecDuration; + /** The Windows system timer time at which the last block of data was recorded. */ + DWORD iLastTimerEventTime; + }; + +#define __HOST_LOCK THostLock lock +#define __HOST_LOCK_ON lock.Lock(); +#define __HOST_LOCK_OFF lock.Unlock(); +#define __COND_HOST_LOCK TCondHostLock lock + +#endif /* __WINSSOUNDSC_H__ */