windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmime/segtrtrk.h
2020-09-26 16:20:57 +08:00

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.
};