Source code of Windows XP (NT5)
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.

208 lines
6.8 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. // DSLink.h
  3. #ifndef __DS_LINK__
  4. #define __DS_LINK__
  5. #include <math.h>
  6. #include <mmsystem.h>
  7. #include <dsound.h>
  8. #include "dmusicc.h"
  9. #include "dmusics.h"
  10. #include "cclock.h"
  11. #include "PLClock.h"
  12. #include "clist.h"
  13. class CDSLink;
  14. typedef HRESULT (CDSLink::*SINKPROPHANDLER)(ULONG ulId, BOOL fSet, LPVOID pvPropertyData, PULONG pcbPropertyData);
  15. #define SINKPROP_F_STATIC 0x00000001
  16. #define SINKPROP_F_FNHANDLER 0x00000002
  17. #include <pshpack4.h>
  18. // Struct for holding a property item supported by the sink
  19. //
  20. struct SINKPROPERTY
  21. {
  22. const GUID *pguidPropertySet; // What property set?
  23. ULONG ulId; // What item?
  24. ULONG ulSupported; // Get/Set flags for QuerySupported
  25. ULONG ulFlags; // SINKPROP_F_xxx
  26. LPVOID pPropertyData;
  27. ULONG cbPropertyData; // and its size
  28. SINKPROPHANDLER pfnHandler; // Handler fn if SINKPROP_F_FNHANDLER
  29. };
  30. #include <poppack.h>
  31. class CDSLink : public CListItem, public IDirectMusicSynthSink, public IKsControl
  32. {
  33. friend class CClock;
  34. friend class CDSLinkList;
  35. public:
  36. CDSLink * GetNext();
  37. // IUnknown
  38. //
  39. virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
  40. virtual STDMETHODIMP_(ULONG) AddRef();
  41. virtual STDMETHODIMP_(ULONG) Release();
  42. // IDirectMusicSynthSink
  43. public:
  44. virtual STDMETHODIMP Init(IDirectMusicSynth *pSynth);
  45. virtual STDMETHODIMP SetMasterClock(IReferenceClock *pClock);
  46. virtual STDMETHODIMP GetLatencyClock(IReferenceClock **ppClock);
  47. virtual STDMETHODIMP Activate(BOOL fEnable);
  48. virtual STDMETHODIMP SampleToRefTime(LONGLONG llSampleTime,REFERENCE_TIME *prfTime);
  49. virtual STDMETHODIMP RefTimeToSample(REFERENCE_TIME rfTime, LONGLONG *pllSampleTime);
  50. virtual STDMETHODIMP SetDirectSound(LPDIRECTSOUND pDirectSound, LPDIRECTSOUNDBUFFER pDirectSoundBuffer);
  51. virtual STDMETHODIMP GetDesiredBufferSize(LPDWORD pdwBufferSizeInSamples);
  52. // IKsPropertySet
  53. virtual STDMETHODIMP KsProperty(
  54. IN PKSPROPERTY Property,
  55. IN ULONG PropertyLength,
  56. IN OUT LPVOID PropertyData,
  57. IN ULONG DataLength,
  58. OUT PULONG BytesReturned
  59. );
  60. virtual STDMETHODIMP KsMethod(
  61. IN PKSMETHOD Method,
  62. IN ULONG MethodLength,
  63. IN OUT LPVOID MethodData,
  64. IN ULONG DataLength,
  65. OUT PULONG BytesReturned
  66. );
  67. virtual STDMETHODIMP KsEvent(
  68. IN PKSEVENT Event,
  69. IN ULONG EventLength,
  70. IN OUT LPVOID EventData,
  71. IN ULONG DataLength,
  72. OUT PULONG BytesReturned
  73. );
  74. CDSLink();
  75. ~CDSLink();
  76. void Clear();
  77. private:
  78. IDirectMusicSynth * m_pSynth; // Reference to synth that uses this.
  79. CClock m_Clock; // Latency clock.
  80. IReferenceClock * m_pIMasterClock; // Master clock from app.
  81. CSampleClock m_SampleClock; // Use to synchronize timing with master clock.
  82. long m_cRef;
  83. WAVEFORMATEX m_wfSynth; // Waveform requested by synth.
  84. LPDIRECTSOUND m_pDSound;
  85. LPDIRECTSOUNDBUFFER m_pPrimary; // Primary buffer.
  86. LPDIRECTSOUNDBUFFER m_pBuffer; // Mix buffer.
  87. LPDIRECTSOUNDBUFFER m_pExtBuffer; // Optional buffer from SetDirectSound.
  88. CRITICAL_SECTION m_CriticalSection; // Critical section to manage access.
  89. BOOL m_fCSInitialized; // Was CS initialized?
  90. LONGLONG m_llAbsPlay; // Absolute point where play head is.
  91. DWORD m_dwLastPlay; // Point in buffer where play head is.
  92. LONGLONG m_llAbsWrite; // Absolute point we've written up to.
  93. DWORD m_dwLastWrite; // Last position we wrote to in buffer.
  94. DWORD m_dwBufferSize; // Size of buffer.
  95. DWORD m_dwWriteTo; // Distance between write head and where we are writing.
  96. DWORD m_dwWriteFromMax; // Max distance observed between play and write head.
  97. BOOL m_fActive; // Currently active.
  98. HRESULT Connect();
  99. HRESULT Disconnect();
  100. void SynthProc();
  101. static SINKPROPERTY m_aProperty[];
  102. static const int m_nProperty;
  103. static SINKPROPERTY *FindPropertyItem(REFGUID rguid, ULONG ulId);
  104. HRESULT HandleLatency(
  105. ULONG ulId,
  106. BOOL fSet,
  107. LPVOID pbBuffer,
  108. PULONG pcbBuffer);
  109. // helpers
  110. LONGLONG SampleToByte(LONGLONG llSamples) {return llSamples << m_wfSynth.nChannels;} // REVIEW: dwSamples * m_wfSynth.nBlockAlign
  111. DWORD SampleToByte(DWORD dwSamples) {return dwSamples << m_wfSynth.nChannels;} // REVIEW: dwSamples * m_wfSynth.nBlockAlign
  112. LONGLONG ByteToSample(LONGLONG llBytes) {return llBytes >> m_wfSynth.nChannels;} // REVIEW: dwBytes / m_wfSynth.nBlockAlign
  113. DWORD ByteToSample(DWORD dwBytes) {return dwBytes >> m_wfSynth.nChannels;} // REVIEW: dwBytes / m_wfSynth.nBlockAlign
  114. LONGLONG SampleAlign(LONGLONG llBytes) {return SampleToByte(ByteToSample(llBytes));}
  115. DWORD SampleAlign(DWORD dwBytes) {return SampleToByte(ByteToSample(dwBytes));}
  116. BOOL IsValidFormat(LPCWAVEFORMATEX pwf)
  117. {
  118. return (pwf &&
  119. pwf->wFormatTag == WAVE_FORMAT_PCM &&
  120. (pwf->nChannels == 1 || pwf->nChannels == 2) &&
  121. (pwf->nSamplesPerSec == 44100 || pwf->nSamplesPerSec == 22050 || pwf->nSamplesPerSec == 11025) &&
  122. pwf->wBitsPerSample == 16 &&
  123. pwf->nBlockAlign == (pwf->nChannels * (pwf->wBitsPerSample / 8)) &&
  124. pwf->nAvgBytesPerSec == (pwf->nSamplesPerSec * pwf->nBlockAlign));
  125. }
  126. };
  127. class CDSLinkList : public CList
  128. {
  129. public:
  130. CDSLinkList();
  131. BOOL OpenUp();
  132. void CloseDown();
  133. CDSLink * GetHead();
  134. CDSLink * RemoveHead();
  135. void Remove(CDSLink *pLink);
  136. void AddTail(CDSLink *pLink);
  137. CDSLink * GetItem(LONG index);
  138. BOOL InitThread();
  139. void ActivateLink(CDSLink *pLink);
  140. void DeactivateLink(CDSLink *pLink);
  141. void SynthProc();
  142. BOOL m_fOpened;
  143. CRITICAL_SECTION m_CriticalSection; // Critical section to manage access.
  144. HANDLE m_hThread; // Handle for synth thread.
  145. BOOL m_fPleaseDie; // Triggers exit.
  146. DWORD m_dwThread; // ID for thread.
  147. HANDLE m_hEvent; // Used to signal thread.
  148. DWORD m_dwCount; // Number of sinks
  149. DWORD m_dwResolution; // Synth thread timeout (ms)
  150. };
  151. // Class factory
  152. //
  153. // Common to emulation/WDM.
  154. //
  155. class CDirectMusicSynthSinkFactory : public IClassFactory
  156. {
  157. public:
  158. // IUnknown
  159. //
  160. virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
  161. virtual STDMETHODIMP_(ULONG) AddRef();
  162. virtual STDMETHODIMP_(ULONG) Release();
  163. // Interface IClassFactory
  164. //
  165. virtual STDMETHODIMP CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv);
  166. virtual STDMETHODIMP LockServer(BOOL bLock);
  167. // Constructor
  168. //
  169. CDirectMusicSynthSinkFactory();
  170. // Destructor
  171. ~CDirectMusicSynthSinkFactory();
  172. private:
  173. long m_cRef;
  174. };
  175. #endif // __DS_LINK__