161 lines
4.8 KiB
C++
161 lines
4.8 KiB
C++
// 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;
|
|
};
|