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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // wins\specific\winssoundsc.h
15 // Definitions for the emulator shared chunk sound driver PDD.
25 #ifndef __WINSSOUNDSC_H__
26 #define __WINSSOUNDSC_H__
28 #include <drivers/soundsc.h>
31 #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
34 #pragma warning(default : 4201)
37 //#define FORCE_NO_HARDWARE
39 //#define __KTRACE_SND(s) s;
40 #define __KTRACE_SND(s)
42 #define PANIC() Kern::Fault("WinsSoundScPdd", __LINE__)
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.
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);
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.
68 THostLock(TBool aLock);
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
88 // Forward declarations
89 class TWaveformBufMgr;
92 This the abstraction for a windows waveform audio buffer.
94 class TWaveformAudioBuf
98 inline void SetWaveformBufMgr(TWaveformBufMgr* aWaveformBufMgr)
99 {iWaveformBufMgr=aWaveformBufMgr;}
100 inline void SetBufNum(TInt aBufNum)
102 void Prepare(char* aBufAddr,TInt aBufLength,TInt aDeviceHandle);
103 void Unprepare(TInt aDeviceHandle);
105 void DoPrepareOut(HWAVEOUT aPlayDeviceHandle);
106 void DoUnprepareOut(HWAVEOUT aPlayDeviceHandle);
107 void DoPrepareIn(HWAVEIN aRecordDeviceHandle);
108 void DoUnprepareIn(HWAVEIN aRecordDeviceHandle);
110 /** The owning waveform audio buffer manager. */
111 TWaveformBufMgr* iWaveformBufMgr;
112 /** Set when the waveform audio buffer is currently prepared. */
114 /** Set when the waveform audio buffer is involved in an active transfer. */
116 /** The header used by windows to identify the waveform audio buffer. */
118 /** A value used to identify a particular waveform audio buffer within an array of these objects. */
120 /** The transfer ID supplied by the LDD when the buffer is involved in an active transfer. */
122 friend class TWaveformBufMgr;
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.
129 class TWaveformBufMgr
132 TWaveformBufMgr(TSoundDirection aDirection,TBool aIsHardware);
134 TInt ReAllocAndUpdate(TSoundSharedChunkBufConfig* aBufConfig,TLinAddr aChunkBase,TInt aDeviceHandle);
135 TWaveformAudioBuf* AcquireBuf(char* aStartAddress,TInt aBufLength,TInt aDeviceHandle);
137 /** The array of windows waveform audio buffer objects. There is at least one buffer object per buffer within the
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. */
149 /** The direction of the windows waveform audio buffer, record or playback. */
150 TSoundDirection iDirection;
154 The WINS physical device (factory class) for the shared chunk sound driver.
156 class DWinsSoundScPddFactory : public DPhysicalDevice
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);
166 /** The DFC queue (used also by the LDD). */
167 TDynamicDfcQue* iDfcQ;
168 /** DFC for terminating the DFC thread. */
170 friend class DWinsSoundScTxPdd;
171 friend class DWinsSoundScRxPdd;
175 The WINS physical device driver (PDD) for the playback shared chunk sound driver.
177 class DWinsSoundScTxPdd : public DSoundScPdd
180 enum TThreadCommand {ESendData, EStop, EExit, EPause, EResume};
181 enum TCreatePlayDeviceMode {EInit,ESetConfig,EStartTransfer};
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);
203 void WaveOutProc(WAVEHDR* aHdr);
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);
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. */
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. */
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. */
254 /** DFC which handes data block play completion. */
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. */
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. */
270 /** Indicates whether the 'no-hardware' timer is currently active. */
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. */
287 The WINS physical device driver (PDD) for the record shared chunk sound driver.
289 class DWinsSoundScRxPdd : public DSoundScPdd
292 enum TThreadCommand {ERecData, EStop, EExit, EPause, EResume};
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);
314 void WaveInProc(WAVEHDR* aHdr);
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);
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. */
363 /** DFC which handes data block record completion. */
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. */
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. */
381 /** Indicates whether the 'no-hardware' timer is currently active. */
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;
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
402 #endif /* __WINSSOUNDSC_H__ */