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.

160 lines
4.8 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Declaration of CDirectMusicScriptTrack.
  4. //
  5. // This track type holds events that cause script routines to be called during
  6. // playback of a segment.
  7. #pragma once
  8. #include "tlist.h"
  9. #include "trackhelp.h"
  10. #include "trackshared.h"
  11. //////////////////////////////////////////////////////////////////////
  12. // Types
  13. // List of events
  14. struct EventInfo
  15. {
  16. EventInfo() : dwFlags(0), lTriggerTime(0), lTimePhysical(0), pIDMScript(NULL), pIDMScriptPrivate(NULL), pwszRoutineName(NULL) {}
  17. ~EventInfo() {
  18. SafeRelease(pIDMScript);
  19. SafeRelease(pIDMScriptPrivate);
  20. delete[] pwszRoutineName;
  21. }
  22. HRESULT Clone(const EventInfo &o, MUSIC_TIME mtStart)
  23. {
  24. pwszRoutineName = new WCHAR[wcslen(o.pwszRoutineName) + 1];
  25. if (!pwszRoutineName)
  26. return E_OUTOFMEMORY;
  27. wcscpy(pwszRoutineName, o.pwszRoutineName);
  28. dwFlags = o.dwFlags;
  29. lTriggerTime = o.lTriggerTime - mtStart;
  30. lTimePhysical = o.lTimePhysical - mtStart;
  31. pIDMScript = o.pIDMScript;
  32. pIDMScript->AddRef();
  33. pIDMScriptPrivate = o.pIDMScriptPrivate;
  34. pIDMScriptPrivate->AddRef();
  35. return S_OK;
  36. }
  37. // from event header chunk <scrh>
  38. DWORD dwFlags;
  39. MUSIC_TIME lTriggerTime; // logical time
  40. MUSIC_TIME lTimePhysical;
  41. // from reference <DMRF>
  42. IDirectMusicScript *pIDMScript;
  43. IDirectMusicScriptPrivate *pIDMScriptPrivate;
  44. WCHAR *pwszRoutineName;
  45. };
  46. class CScriptTrackEvent : public IUnknown
  47. {
  48. public:
  49. CScriptTrackEvent() :
  50. m_pSegSt(NULL),
  51. m_pEvent(NULL),
  52. m_i64IntendedStartTime(0),
  53. m_dwIntendedStartTimeFlags(0),
  54. m_cRef(1)
  55. {
  56. }
  57. ~CScriptTrackEvent();
  58. // IUnknown
  59. STDMETHOD(QueryInterface)(const IID &iid, void **ppv);
  60. STDMETHOD_(ULONG, AddRef)();
  61. STDMETHOD_(ULONG, Release)();
  62. // CScriptTrackEvent
  63. HRESULT Init(const EventInfo &item, IDirectMusicSegmentState* pSegSt);
  64. void SetTime(REFERENCE_TIME rtTime, DWORD dwFlags)
  65. {
  66. m_i64IntendedStartTime = rtTime;
  67. m_dwIntendedStartTimeFlags = dwFlags;
  68. }
  69. void Call(DWORD dwdwVirtualTrackID, bool fErrorPMsgsEnabled);
  70. private:
  71. IDirectMusicSegmentState *m_pSegSt;
  72. EventInfo *m_pEvent; // event to execute
  73. // scheduled time of the routine call
  74. __int64 m_i64IntendedStartTime;
  75. DWORD m_dwIntendedStartTimeFlags;
  76. long m_cRef;
  77. };
  78. //////////////////////////////////////////////////////////////////////
  79. // CDirectMusicScriptTrack
  80. class CDirectMusicScriptTrack;
  81. typedef CPlayingTrack<CDirectMusicScriptTrack, EventInfo> CDirectMusicScriptTrackBase;
  82. class CDirectMusicScriptTrack
  83. : public CDirectMusicScriptTrackBase,
  84. public IDirectMusicTool
  85. {
  86. public:
  87. CDirectMusicScriptTrack(HRESULT *pHr);
  88. ~CDirectMusicScriptTrack()
  89. {
  90. TListItem<EventInfo>* pItem = m_EventList.GetHead();
  91. for ( ; pItem; pItem = pItem->GetNext() )
  92. {
  93. SafeRelease(pItem->GetItemValue().pIDMScript);
  94. SafeRelease(pItem->GetItemValue().pIDMScriptPrivate);
  95. }
  96. }
  97. // initialize each referenced script in InitPlay
  98. STDMETHOD(InitPlay)(
  99. IDirectMusicSegmentState *pSegmentState,
  100. IDirectMusicPerformance *pPerformance,
  101. void **ppStateData,
  102. DWORD dwTrackID,
  103. DWORD dwFlags);
  104. // Need to implement IUnknown as part of the IDirectMusic tool interface. (Just used to receive callbacks -- you can't actually QI to it.)
  105. STDMETHOD(QueryInterface)(const IID &iid, void **ppv) { return CDirectMusicScriptTrackBase::QueryInterface(iid, ppv); }
  106. STDMETHOD_(ULONG, AddRef)() { return CDirectMusicScriptTrackBase::AddRef(); }
  107. STDMETHOD_(ULONG, Release)() { return CDirectMusicScriptTrackBase::Release(); }
  108. // IDirectMusicTool methods (since we aren't in a graph, only ProcessPMsg and Flush are called)
  109. STDMETHOD(Init)(IDirectMusicGraph* pGraph) { return E_UNEXPECTED; }
  110. STDMETHOD(GetMsgDeliveryType)(DWORD* pdwDeliveryType) { return E_UNEXPECTED; }
  111. STDMETHOD(GetMediaTypeArraySize)(DWORD* pdwNumElements) { return E_UNEXPECTED; }
  112. STDMETHOD(GetMediaTypes)(DWORD** padwMediaTypes, DWORD dwNumElements) { return E_UNEXPECTED; }
  113. STDMETHOD(ProcessPMsg)(IDirectMusicPerformance* pPerf, DMUS_PMSG* pPMSG);
  114. STDMETHOD(Flush)(IDirectMusicPerformance* pPerf, DMUS_PMSG* pPMSG, REFERENCE_TIME rtTime) { return DMUS_S_FREE; } // If the performance was stopped before the event actually fired, just ignore it.
  115. // IDirectMusicTrack methods
  116. STDMETHOD(IsParamSupported)(REFGUID rguid);
  117. STDMETHOD(SetParam)(REFGUID rguid,MUSIC_TIME mtTime,void *pData);
  118. protected:
  119. HRESULT PlayItem(
  120. const EventInfo &item,
  121. statedata &state,
  122. IDirectMusicPerformance *pPerf,
  123. IDirectMusicSegmentState* pSegSt,
  124. DWORD dwVirtualID,
  125. MUSIC_TIME mtOffset,
  126. REFERENCE_TIME rtOffset,
  127. bool fClockTime);
  128. HRESULT LoadRiff(SmartRef::RiffIter &ri, IDirectMusicLoader *pIDMLoader);
  129. private:
  130. HRESULT LoadEvent(SmartRef::RiffIter ri, IDirectMusicLoader *pIDMLoader);
  131. bool m_fErrorPMsgsEnabled;
  132. };