101 lines
3.4 KiB
C
101 lines
3.4 KiB
C
|
// Copyright (c) 1999 Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// Declaration of CSegTriggerTrack.
|
||
|
//
|
||
|
|
||
|
// This track type holds events that cause other segments to be cued at
|
||
|
// specific points during playback of a segment.
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "trackhelp.h"
|
||
|
#include "tlist.h"
|
||
|
#include "smartref.h"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Types
|
||
|
|
||
|
// Items in list of events
|
||
|
struct TriggerInfo
|
||
|
{
|
||
|
TriggerInfo() : lTriggerTime(0), lTimePhysical(0), dwPlayFlags(0), dwFlags(0), pIDMSegment(NULL) {}
|
||
|
~TriggerInfo() {
|
||
|
RELEASE(pIDMSegment);
|
||
|
}
|
||
|
|
||
|
HRESULT Clone(const TriggerInfo &o, MUSIC_TIME mtStart)
|
||
|
{
|
||
|
lTriggerTime = o.lTriggerTime - mtStart;
|
||
|
lTimePhysical = o.lTimePhysical - mtStart;
|
||
|
dwPlayFlags = o.dwPlayFlags;
|
||
|
dwFlags = o.dwFlags;
|
||
|
pIDMSegment = o.pIDMSegment;
|
||
|
pIDMSegment->AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
// from event header chunk <scrh>
|
||
|
MUSIC_TIME lTriggerTime; // Logical time
|
||
|
MUSIC_TIME lTimePhysical;
|
||
|
DWORD dwPlayFlags;
|
||
|
DWORD dwFlags;
|
||
|
// from reference <DMRF>
|
||
|
IDirectMusicSegment *pIDMSegment;
|
||
|
};
|
||
|
|
||
|
// State data. This track needs to get the audio path that's currently playing so that it
|
||
|
// can use it when playing triggered segments.
|
||
|
struct CSegTriggerTrackState : public CStandardStateData<TriggerInfo>
|
||
|
{
|
||
|
CSegTriggerTrackState() : pAudioPath(NULL) {};
|
||
|
~CSegTriggerTrackState() { if (pAudioPath) pAudioPath->Release(); }
|
||
|
IDirectMusicAudioPath *pAudioPath;
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// CSegTriggerTrack
|
||
|
|
||
|
class CSegTriggerTrack;
|
||
|
typedef CPlayingTrack<CSegTriggerTrack, TriggerInfo, CSegTriggerTrackState> CSegTriggerTrackBase;
|
||
|
|
||
|
class CSegTriggerTrack
|
||
|
: public CSegTriggerTrackBase
|
||
|
{
|
||
|
public:
|
||
|
// When the segment trigger track plays one of its items, it plays a segment. If an invalidation occurs, that Play operation
|
||
|
// can't be retracted. Then the track is played again (with the FLUSH bit set). This was causing it to trigger the segment
|
||
|
// a second time. To fix this, the last parameter to the CSegTriggerTrackBase is false, which instructs it not to call play
|
||
|
// a second time when the FLUSH bit is set.
|
||
|
CSegTriggerTrack(HRESULT *pHr) : CSegTriggerTrackBase(&g_cComponent, CLSID_DirectMusicSegmentTriggerTrack, true, false), m_dwFlags(NULL), m_dwRecursionCount(0) {}
|
||
|
|
||
|
// Implement SetParam by calling SetParam in turn on all the child segments. This is needed, for example so that downloading a segment with a segment trigger track will download all the triggered segments as well.
|
||
|
STDMETHOD(IsParamSupported)(REFGUID rguid) { return S_OK; } // Once or more of our child segments could potentially support any type of parameter.
|
||
|
STDMETHOD(SetParam)(REFGUID rguid, MUSIC_TIME mtTime, void *pData);
|
||
|
|
||
|
STDMETHOD(InitPlay)(
|
||
|
IDirectMusicSegmentState *pSegmentState,
|
||
|
IDirectMusicPerformance *pPerformance,
|
||
|
void **ppStateData,
|
||
|
DWORD dwTrackID,
|
||
|
DWORD dwFlags);
|
||
|
|
||
|
protected:
|
||
|
HRESULT PlayItem(
|
||
|
const TriggerInfo &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 LoadTrigger(SmartRef::RiffIter ri, IDirectMusicLoader *pIDMLoader);
|
||
|
|
||
|
// Data
|
||
|
DWORD m_dwFlags; // from track header (sgth chunk)
|
||
|
BOOL m_dwRecursionCount; // Used to keep track of recursive calls to self.
|
||
|
};
|