Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
10 KiB

  1. // dswave.h
  2. // (c) 1999-2000 Microsoft Corp.
  3. #ifndef _DSWAVE_H_
  4. #define _DSWAVE_H_
  5. #include <mmsystem.h>
  6. #include <mmreg.h>
  7. #include <msacm.h>
  8. #include "dsoundp.h" // For IDirectSoundWave and IDirectSoundSource
  9. #include "dmusicc.h"
  10. #include "dmusici.h"
  11. #include "riff.h"
  12. extern long g_cComponent;
  13. #define REF_PER_MIL 10000 // For converting from reference time to mils
  14. #define CONVERTLENGTH 250
  15. // #define DSWCS_F_DEINTERLEAVED 0x00000001 // Multi-channel data as multiple buffers
  16. // FIXME: unimplemented so far?
  17. typedef struct tCREATEVIEWPORT
  18. {
  19. IStream *pStream;
  20. DWORD cSamples;
  21. DWORD dwDecompressedStart;
  22. DWORD cbStream;
  23. LPWAVEFORMATEX pwfxSource;
  24. LPWAVEFORMATEX pwfxTarget;
  25. DWORD fdwOptions;
  26. } CREATEVIEWPORT, *PCREATEVIEWPORT;
  27. // Private interface for getting the length of a wave
  28. interface IPrivateWave : IUnknown
  29. {
  30. virtual HRESULT STDMETHODCALLTYPE GetLength(REFERENCE_TIME *prtLength)=0;
  31. };
  32. DEFINE_GUID(IID_IPrivateWave, 0xce6ae366, 0x9d61, 0x420a, 0xad, 0x53, 0xe5, 0xe5, 0xf6, 0xa8, 0x4a, 0xe4);
  33. // Flags for SetWaveBehavior()
  34. #define DSOUND_WAVEF_ONESHOT 1 /* The wave will be played as a one shot */
  35. #define DSOUND_WAVEF_PORT 2 /* The wave will be played via a DMusic port. */
  36. #define DSOUND_WAVEF_SINK 4 /* The wave will be played via a streamed sink interface. */
  37. #define DSOUND_WAVEF_CREATEMASK 0x00000001 /* Currently only ONESHOT is define for CreateSource */
  38. #define DSOUND_WVP_NOCONVERT 0x80000000 /* The viewport data is the same format as the wave */
  39. #define DSOUND_WVP_STREAMEND 0x40000000 /* The viewport data is the same format as the wave */
  40. #define DSOUND_WVP_CONVERTSTATE_01 0x01000000
  41. #define DSOUND_WVP_CONVERTSTATE_02 0x02000000
  42. #define DSOUND_WVP_CONVERTSTATE_03 0x04000000
  43. #define DSOUND_WVP_CONVERTMASK 0x0f000000
  44. /* The CWaveViewPort structure represents one instance, or "view", of the
  45. wave object. It manages the reading of the wave data, ACM decompression,
  46. and demultiplexing into mono buffers. If a wave object is being
  47. streamed, each playback instance gets a unique CWaveViewPort.
  48. However, in the more typical case where the wave object is being
  49. played as a one shot, each playback instance uses the same
  50. CWaveViewPort.
  51. Each additional CWaveViewPort owns a cloned instance of the IStream.
  52. */
  53. class CWaveViewPort :
  54. public IDirectSoundSource // Used by a port or sink to pull data.
  55. {
  56. public:
  57. CWaveViewPort(); // Constructor receives stream.
  58. ~CWaveViewPort(); // Destructor releases memory, streams, etc.
  59. // IUnknown
  60. STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
  61. STDMETHODIMP_(ULONG) AddRef();
  62. STDMETHODIMP_(ULONG) Release();
  63. // IDirectSoundSource
  64. STDMETHODIMP SetSink(IDirectSoundConnect *pSinkConnect);
  65. STDMETHODIMP GetFormat(LPWAVEFORMATEX pwfx, DWORD dwSizeAllocated, LPDWORD pdwSizeWritten);
  66. STDMETHODIMP Seek(ULONGLONG sp);
  67. STDMETHODIMP Read(LPVOID *ppvBuffer, LPDWORD pdwBusIds, LPDWORD pdwFuncIds, LPLONG plPitchShifts, DWORD cpvBuffer, ULONGLONG *pcb);
  68. STDMETHODIMP GetSize(ULONGLONG *pcb);
  69. // Misc
  70. HRESULT Create(PCREATEVIEWPORT pCreate);
  71. private:
  72. HRESULT acmRead();
  73. // General stuff...
  74. CRITICAL_SECTION m_CriticalSection; // Used to ensure thread safe
  75. long m_cRef; // COM reference counter.
  76. // Details about original data stream...
  77. IStream * m_pStream; // IStream pointer which is connected to IPersistStream
  78. // interface to pull data from file.
  79. DWORD m_cSamples; // Number of samples (if available)
  80. DWORD m_cbStream; // Number of bytes in stream.
  81. DWORD m_dwStart; // Offset into stream where data starts
  82. //LPWAVEFORMATEX m_pwfxSource; // Do we need to hold on to this?
  83. // Details needed for this viewport.
  84. DWORD m_dwOffset; // Current byte offset into data stream
  85. DWORD m_dwStartPos; // Initial Start Offset
  86. LPWAVEFORMATEX m_pwfxTarget; // Target destination format.
  87. ACMSTREAMHEADER m_ash; // ACM Stream header (used for conversion)
  88. HACMSTREAM m_hStream; // ACM Stream handle for conversion
  89. LPBYTE m_pDst; // Pointer to (decompressed) destination
  90. LPBYTE m_pRaw; // Pointer to compressed source buffer
  91. DWORD m_fdwOptions; // Options for viewport
  92. DWORD m_dwDecompressedStart; // Actual start for the data after decompression in Samples
  93. // This is important for MP3 and WMA codecs that
  94. // insert some amount of silence in the beginning
  95. DWORD m_dwDecompStartOffset; // Byte Offset in the compressed stream to the block which
  96. // needs to be decompressed to get to the right start value
  97. DWORD m_dwDecompStartOffsetPCM;// Byte offset in the decompressed stream...corresponds to
  98. // m_dwDecompressedStart samples
  99. DWORD m_dwDecompStartDelta; // The delta (in bytes) to add when we decompress the block starting
  100. // from m_dwDecompStartOffset
  101. // Only used to accurately get data after precached data for DirectSoundWave in DMusic
  102. DWORD m_dwPreCacheFilePos;
  103. DWORD m_dwFirstPCMSample;
  104. DWORD m_dwPCMSampleOut;
  105. };
  106. /* The CWave class represents one instance of a wave object. It
  107. supports the IDirectSoundWave interface, which the application
  108. uses to access the wave. It also support IPersistStream and
  109. IDirectMusicObject, which are used by the loader to load the
  110. wave data from a stream into the wave object.
  111. And, the IDirectSoundSource interface manages the direct
  112. transfer of the wave data from the object to the
  113. synth or DirectSound. This is for internal use, not by the
  114. application (though it represents an easy way for an app
  115. to load wave data and then extract it.)
  116. CWave maintains a list of CWaveViewPorts, though typically
  117. there is only one.
  118. */
  119. class CWave :
  120. public IDirectSoundWave, // Standard interface.
  121. public IPersistStream, // For file io
  122. public IDirectMusicObject, // For DirectMusic loader
  123. public IPrivateWave // For GetLength
  124. {
  125. public:
  126. CWave();
  127. ~CWave();
  128. // IUnknown
  129. STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
  130. STDMETHODIMP_(ULONG) AddRef();
  131. STDMETHODIMP_(ULONG) Release();
  132. // IDirectSoundWave
  133. STDMETHODIMP GetFormat(LPWAVEFORMATEX pWaveFormatEx, DWORD dwSizeAllocated, LPDWORD pdwSizeWritten);
  134. STDMETHODIMP CreateSource(IDirectSoundSource **ppSource, LPWAVEFORMATEX pwfx, DWORD dwFlags);
  135. STDMETHODIMP GetStreamingParms(LPDWORD pdwFlags, LPREFERENCE_TIME prtReadahread);
  136. // IPersist functions (base class for IPersistStream)
  137. STDMETHODIMP GetClassID( CLSID* pClsId );
  138. // IPersistStream functions
  139. STDMETHODIMP IsDirty();
  140. STDMETHODIMP Load( IStream* pIStream );
  141. STDMETHODIMP Save( IStream* pIStream, BOOL fClearDirty );
  142. STDMETHODIMP GetSizeMax( ULARGE_INTEGER FAR* pcbSize );
  143. // IDirectMusicObject
  144. STDMETHODIMP GetDescriptor(LPDMUS_OBJECTDESC pDesc);
  145. STDMETHODIMP SetDescriptor(LPDMUS_OBJECTDESC pDesc);
  146. STDMETHODIMP ParseDescriptor(LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc);
  147. // IPrivateWave
  148. STDMETHODIMP GetLength(REFERENCE_TIME *prtLength);
  149. private:
  150. // Internal methods.
  151. BOOL ParseHeader(IStream *pIStream, IRIFFStream* pIRiffStream, LPMMCKINFO pckMain);
  152. void FallbackStreamingBehavior()
  153. {
  154. REFERENCE_TIME rtLength = 0;
  155. if (SUCCEEDED(GetLength(&rtLength)))
  156. {
  157. // if > 5000 milliseconds, set to streaming with a 500 ms readahead
  158. if (rtLength > 5000)
  159. {
  160. m_rtReadAheadTime = 500 * REF_PER_MIL;
  161. m_fdwFlags &= ~DSOUND_WAVEF_ONESHOT;
  162. }
  163. else
  164. {
  165. m_rtReadAheadTime = 0;
  166. m_fdwFlags |= DSOUND_WAVEF_ONESHOT;
  167. }
  168. }
  169. }
  170. CRITICAL_SECTION m_CriticalSection; // Used to ensure thread safe
  171. LPWAVEFORMATEX m_pwfxDst; // Destination format, if compressed
  172. REFERENCE_TIME m_rtReadAheadTime; // Readahead for streaming.
  173. DWORD m_fdwFlags; // Various flags, including whether this is a one-shot.
  174. long m_cRef; // COM reference counter.
  175. IStream * m_pStream; // IStream pointer which is connected to IPersistStream
  176. DWORD m_fdwOptions; // Flags set by call to SetWaveBehavior().
  177. LPWAVEFORMATEX m_pwfx; // File's format
  178. DWORD m_cbStream;
  179. DWORD m_cSamples;
  180. GUID m_guid;
  181. FILETIME m_ftDate;
  182. DMUS_VERSION m_vVersion;
  183. WCHAR m_wszFilename[DMUS_MAX_FILENAME];
  184. DWORD m_dwDecompressedStart;
  185. };
  186. class CDirectSoundWaveFactory : public IClassFactory
  187. {
  188. public:
  189. // IUnknown
  190. //
  191. virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
  192. virtual STDMETHODIMP_(ULONG) AddRef();
  193. virtual STDMETHODIMP_(ULONG) Release();
  194. // Interface IClassFactory
  195. //
  196. virtual STDMETHODIMP CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv);
  197. virtual STDMETHODIMP LockServer(BOOL bLock);
  198. // Constructor
  199. //
  200. CDirectSoundWaveFactory();
  201. // Destructor
  202. ~CDirectSoundWaveFactory();
  203. private:
  204. long m_cRef;
  205. };
  206. #endif // _DSWAVE_H_