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.

242 lines
5.5 KiB

  1. // Duration.cpp : Implementation of CDurationTool
  2. //
  3. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved
  4. //
  5. #include "dmusicc.h"
  6. #include "dmusici.h"
  7. #include "debug.h"
  8. #include "duration.h"
  9. #include "toolhelp.h"
  10. CDurationTool::CDurationTool()
  11. {
  12. ParamInfo Params[DMUS_DURATION_PARAMCOUNT] =
  13. {
  14. { DMUS_DURATION_SCALE, MPT_INT,MP_CAPS_ALL,0,8,1,
  15. L"Times",L"Scale",NULL}, // Scale - default to 1 (no change)
  16. };
  17. InitParams(DMUS_DURATION_PARAMCOUNT,Params);
  18. m_fMusicTime = TRUE; // override default setting.
  19. }
  20. STDMETHODIMP_(ULONG) CDurationTool::AddRef()
  21. {
  22. return InterlockedIncrement(&m_cRef);
  23. }
  24. STDMETHODIMP_(ULONG) CDurationTool::Release()
  25. {
  26. if( 0 == InterlockedDecrement(&m_cRef) )
  27. {
  28. delete this;
  29. return 0;
  30. }
  31. return m_cRef;
  32. }
  33. STDMETHODIMP CDurationTool::QueryInterface(const IID &iid, void **ppv)
  34. {
  35. if (iid == IID_IUnknown || iid == IID_IDirectMusicTool || iid == IID_IDirectMusicTool8)
  36. {
  37. *ppv = static_cast<IDirectMusicTool8*>(this);
  38. }
  39. else if(iid == IID_IPersistStream)
  40. {
  41. *ppv = static_cast<IPersistStream*>(this);
  42. }
  43. else if(iid == IID_IDirectMusicDurationTool)
  44. {
  45. *ppv = static_cast<IDirectMusicDurationTool*>(this);
  46. }
  47. else if(iid == IID_IMediaParams)
  48. {
  49. *ppv = static_cast<IMediaParams*>(this);
  50. }
  51. else if(iid == IID_IMediaParamInfo)
  52. {
  53. *ppv = static_cast<IMediaParamInfo*>(this);
  54. }
  55. else if(iid == IID_ISpecifyPropertyPages)
  56. {
  57. *ppv = static_cast<ISpecifyPropertyPages*>(this);
  58. }
  59. else
  60. {
  61. *ppv = NULL;
  62. return E_NOINTERFACE;
  63. }
  64. AddRef();
  65. return S_OK;
  66. }
  67. //////////////////////////////////////////////////////////////////////
  68. // IPersistStream
  69. STDMETHODIMP CDurationTool::GetClassID(CLSID* pClassID)
  70. {
  71. if (pClassID)
  72. {
  73. *pClassID = CLSID_DirectMusicDurationTool;
  74. return S_OK;
  75. }
  76. return E_POINTER;
  77. }
  78. //////////////////////////////////////////////////////////////////////
  79. // IPersistStream Methods:
  80. STDMETHODIMP CDurationTool::IsDirty()
  81. {
  82. if (m_fDirty) return S_OK;
  83. else return S_FALSE;
  84. }
  85. STDMETHODIMP CDurationTool::Load(IStream* pStream)
  86. {
  87. EnterCriticalSection(&m_CrSec);
  88. DWORD dwChunkID;
  89. DWORD dwSize;
  90. HRESULT hr = pStream->Read(&dwChunkID, sizeof(dwChunkID), NULL);
  91. hr = pStream->Read(&dwSize, sizeof(dwSize), NULL);
  92. if(SUCCEEDED(hr) && (dwChunkID == FOURCC_DURATION_CHUNK))
  93. {
  94. DMUS_IO_DURATION_HEADER Header;
  95. memset(&Header,0,sizeof(Header));
  96. hr = pStream->Read(&Header, min(sizeof(Header),dwSize), NULL);
  97. if (SUCCEEDED(hr))
  98. {
  99. SetParam(DMUS_DURATION_SCALE,(float) Header.flScale);
  100. }
  101. }
  102. m_fDirty = FALSE;
  103. LeaveCriticalSection(&m_CrSec);
  104. return hr;
  105. }
  106. STDMETHODIMP CDurationTool::Save(IStream* pStream, BOOL fClearDirty)
  107. {
  108. EnterCriticalSection(&m_CrSec);
  109. DWORD dwChunkID = FOURCC_DURATION_CHUNK;
  110. DWORD dwSize = sizeof(DMUS_IO_DURATION_HEADER);
  111. HRESULT hr = pStream->Write(&dwChunkID, sizeof(dwChunkID), NULL);
  112. if (SUCCEEDED(hr))
  113. {
  114. hr = pStream->Write(&dwSize, sizeof(dwSize), NULL);
  115. }
  116. if (SUCCEEDED(hr))
  117. {
  118. DMUS_IO_DURATION_HEADER Header;
  119. GetParamFloat(DMUS_DURATION_SCALE,MAX_REF_TIME,&Header.flScale);
  120. hr = pStream->Write(&Header, sizeof(Header),NULL);
  121. }
  122. if (fClearDirty) m_fDirty = FALSE;
  123. LeaveCriticalSection(&m_CrSec);
  124. return hr;
  125. }
  126. STDMETHODIMP CDurationTool::GetSizeMax(ULARGE_INTEGER* pcbSize)
  127. {
  128. if (pcbSize == NULL)
  129. {
  130. return E_POINTER;
  131. }
  132. pcbSize->QuadPart = sizeof(DMUS_IO_DURATION_HEADER) + 8; // Data plus RIFF header.
  133. return S_OK;
  134. }
  135. STDMETHODIMP CDurationTool::GetPages(CAUUID * pPages)
  136. {
  137. pPages->cElems = 1;
  138. pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
  139. if (pPages->pElems == NULL)
  140. return E_OUTOFMEMORY;
  141. *(pPages->pElems) = CLSID_DurationPage;
  142. return NOERROR;
  143. }
  144. /////////////////////////////////////////////////////////////////
  145. // IDirectMusicTool
  146. STDMETHODIMP CDurationTool::ProcessPMsg( IDirectMusicPerformance* pPerf,
  147. DMUS_PMSG* pPMsg )
  148. {
  149. // returning S_FREE frees the message. If StampPMsg()
  150. // fails, there is no destination for this message so
  151. // free it.
  152. if(NULL == pPMsg->pGraph )
  153. {
  154. return DMUS_S_FREE;
  155. }
  156. if (FAILED(pPMsg->pGraph->StampPMsg(pPMsg)))
  157. {
  158. return DMUS_S_FREE;
  159. }
  160. // Only adjust the durations of notes.
  161. if( pPMsg->dwType == DMUS_PMSGT_NOTE )
  162. {
  163. REFERENCE_TIME rtTime;
  164. if (m_fMusicTime) rtTime = pPMsg->mtTime;
  165. else rtTime = pPMsg->rtTime;
  166. DMUS_NOTE_PMSG *pNote = (DMUS_NOTE_PMSG *) pPMsg;
  167. float flScale;
  168. GetParamFloat(DMUS_DURATION_SCALE,rtTime,&flScale);
  169. if (flScale >= 0)
  170. {
  171. flScale *= pNote->mtDuration;
  172. pNote->mtDuration = (MUSIC_TIME) flScale;
  173. }
  174. }
  175. return DMUS_S_REQUEUE;
  176. }
  177. STDMETHODIMP CDurationTool::Clone( IDirectMusicTool ** ppTool)
  178. {
  179. CDurationTool *pNew = new CDurationTool;
  180. if (pNew)
  181. {
  182. HRESULT hr = pNew->CopyParamsFromSource(this);
  183. if (SUCCEEDED(hr))
  184. {
  185. *ppTool = (IDirectMusicTool *) pNew;
  186. }
  187. else
  188. {
  189. delete pNew;
  190. }
  191. return hr;
  192. }
  193. else
  194. {
  195. return E_OUTOFMEMORY;
  196. }
  197. }
  198. STDMETHODIMP CDurationTool::SetScale(float flScale)
  199. {
  200. return SetParam(DMUS_DURATION_SCALE,flScale);
  201. }
  202. STDMETHODIMP CDurationTool::GetScale(float * pflScale)
  203. {
  204. return GetParamFloat(DMUS_DURATION_SCALE,MAX_REF_TIME, pflScale);
  205. }