|
|
// Copyright (c) 1999 Microsoft Corporation. All rights reserved.
//
// Declaration of CDirectMusicScriptTrack.
//
// This track type holds events that cause script routines to be called during
// playback of a segment.
#pragma once
#include "tlist.h"
#include "trackhelp.h"
#include "trackshared.h"
//////////////////////////////////////////////////////////////////////
// Types
// List of events
struct EventInfo { EventInfo() : dwFlags(0), lTriggerTime(0), lTimePhysical(0), pIDMScript(NULL), pIDMScriptPrivate(NULL), pwszRoutineName(NULL) {} ~EventInfo() { SafeRelease(pIDMScript); SafeRelease(pIDMScriptPrivate); delete[] pwszRoutineName; }
HRESULT Clone(const EventInfo &o, MUSIC_TIME mtStart) { pwszRoutineName = new WCHAR[wcslen(o.pwszRoutineName) + 1]; if (!pwszRoutineName) return E_OUTOFMEMORY; wcscpy(pwszRoutineName, o.pwszRoutineName);
dwFlags = o.dwFlags; lTriggerTime = o.lTriggerTime - mtStart; lTimePhysical = o.lTimePhysical - mtStart;
pIDMScript = o.pIDMScript; pIDMScript->AddRef(); pIDMScriptPrivate = o.pIDMScriptPrivate; pIDMScriptPrivate->AddRef();
return S_OK; }
// from event header chunk <scrh>
DWORD dwFlags; MUSIC_TIME lTriggerTime; // logical time
MUSIC_TIME lTimePhysical; // from reference <DMRF>
IDirectMusicScript *pIDMScript; IDirectMusicScriptPrivate *pIDMScriptPrivate; WCHAR *pwszRoutineName; };
class CScriptTrackEvent : public IUnknown { public: CScriptTrackEvent() : m_pSegSt(NULL), m_pEvent(NULL), m_i64IntendedStartTime(0), m_dwIntendedStartTimeFlags(0), m_cRef(1) { }
~CScriptTrackEvent();
// IUnknown
STDMETHOD(QueryInterface)(const IID &iid, void **ppv); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// CScriptTrackEvent
HRESULT Init(const EventInfo &item, IDirectMusicSegmentState* pSegSt);
void SetTime(REFERENCE_TIME rtTime, DWORD dwFlags) { m_i64IntendedStartTime = rtTime; m_dwIntendedStartTimeFlags = dwFlags; }
void Call(DWORD dwdwVirtualTrackID, bool fErrorPMsgsEnabled);
private: IDirectMusicSegmentState *m_pSegSt; EventInfo *m_pEvent; // event to execute
// scheduled time of the routine call
__int64 m_i64IntendedStartTime; DWORD m_dwIntendedStartTimeFlags;
long m_cRef; };
//////////////////////////////////////////////////////////////////////
// CDirectMusicScriptTrack
class CDirectMusicScriptTrack; typedef CPlayingTrack<CDirectMusicScriptTrack, EventInfo> CDirectMusicScriptTrackBase;
class CDirectMusicScriptTrack : public CDirectMusicScriptTrackBase, public IDirectMusicTool { public: CDirectMusicScriptTrack(HRESULT *pHr); ~CDirectMusicScriptTrack() { TListItem<EventInfo>* pItem = m_EventList.GetHead(); for ( ; pItem; pItem = pItem->GetNext() ) { SafeRelease(pItem->GetItemValue().pIDMScript); SafeRelease(pItem->GetItemValue().pIDMScriptPrivate); } }
// initialize each referenced script in InitPlay
STDMETHOD(InitPlay)( IDirectMusicSegmentState *pSegmentState, IDirectMusicPerformance *pPerformance, void **ppStateData, DWORD dwTrackID, DWORD dwFlags);
// Need to implement IUnknown as part of the IDirectMusic tool interface. (Just used to receive callbacks -- you can't actually QI to it.)
STDMETHOD(QueryInterface)(const IID &iid, void **ppv) { return CDirectMusicScriptTrackBase::QueryInterface(iid, ppv); } STDMETHOD_(ULONG, AddRef)() { return CDirectMusicScriptTrackBase::AddRef(); } STDMETHOD_(ULONG, Release)() { return CDirectMusicScriptTrackBase::Release(); }
// IDirectMusicTool methods (since we aren't in a graph, only ProcessPMsg and Flush are called)
STDMETHOD(Init)(IDirectMusicGraph* pGraph) { return E_UNEXPECTED; } STDMETHOD(GetMsgDeliveryType)(DWORD* pdwDeliveryType) { return E_UNEXPECTED; } STDMETHOD(GetMediaTypeArraySize)(DWORD* pdwNumElements) { return E_UNEXPECTED; } STDMETHOD(GetMediaTypes)(DWORD** padwMediaTypes, DWORD dwNumElements) { return E_UNEXPECTED; } STDMETHOD(ProcessPMsg)(IDirectMusicPerformance* pPerf, DMUS_PMSG* pPMSG); 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.
// IDirectMusicTrack methods
STDMETHOD(IsParamSupported)(REFGUID rguid); STDMETHOD(SetParam)(REFGUID rguid,MUSIC_TIME mtTime,void *pData);
protected: HRESULT PlayItem( const EventInfo &item, statedata &state, IDirectMusicPerformance *pPerf, IDirectMusicSegmentState* pSegSt, DWORD dwVirtualID, MUSIC_TIME mtOffset, REFERENCE_TIME rtOffset, bool fClockTime); HRESULT LoadRiff(SmartRef::RiffIter &ri, IDirectMusicLoader *pIDMLoader);
private: HRESULT LoadEvent(SmartRef::RiffIter ri, IDirectMusicLoader *pIDMLoader);
bool m_fErrorPMsgsEnabled; };
|