windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmband/bandtrk.h

254 lines
6.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//
// bandtrk.h
//
// Copyright (c) 1997-2000 Microsoft Corporation
//
#ifndef BANDTRK_H
#define BANDTRK_H
#include "dmbndtrk.h"
#include "dmbandp.h"
class SeekEvent;
struct IDirectMusicPerformance;
class CRiffParser;
//////////////////////////////////////////////////////////////////////
// Class CBandTrk
class CBandTrk : public IDirectMusicTrack8, public IDirectMusicBandTrk, public IPersistStream
{
friend CBand;
public:
// IUnknown
//
STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IPersist
STDMETHODIMP GetClassID(CLSID* pClassID);
// IPersistStream
STDMETHODIMP IsDirty() {return S_FALSE;}
STDMETHODIMP Load(IStream* pStream);
STDMETHODIMP Save(IStream* pStream, BOOL fClearDirty) {return E_NOTIMPL;}
STDMETHODIMP GetSizeMax(ULARGE_INTEGER* pcbSize) {return E_NOTIMPL;}
// IDirectMusicTrack
STDMETHODIMP Init(IDirectMusicSegment* pSegment);
STDMETHODIMP InitPlay(IDirectMusicSegmentState* pSegmentState,
IDirectMusicPerformance* pPerformance,
void** ppStateData,
DWORD dwVirtualTrackID,
DWORD dwFlags);
STDMETHODIMP EndPlay(void* pStateData);
STDMETHODIMP Play(void* pStateData,
MUSIC_TIME mtStart,
MUSIC_TIME mtEnd,
MUSIC_TIME mtOffset,
DWORD dwFlags,
IDirectMusicPerformance* pPerf,
IDirectMusicSegmentState* pSegSt,
DWORD dwVirtualID);
STDMETHODIMP GetParam(REFGUID rguidDataType,
MUSIC_TIME mtTime,
MUSIC_TIME* pmtNext,
void* pData);
STDMETHODIMP SetParam(REFGUID rguidDataType,
MUSIC_TIME mtTime,
void* pData);
STDMETHODIMP IsParamSupported(REFGUID rguidDataType);
STDMETHODIMP AddNotificationType(REFGUID rguidNotify);
STDMETHODIMP RemoveNotificationType(REFGUID rguidNotify);
STDMETHODIMP Clone( MUSIC_TIME mtStart,
MUSIC_TIME mtEnd,
IDirectMusicTrack** ppTrack);
// IDirectMusicTrack8
STDMETHODIMP PlayEx(void* pStateData,REFERENCE_TIME rtStart,
REFERENCE_TIME rtEnd,REFERENCE_TIME rtOffset,
DWORD dwFlags,IDirectMusicPerformance* pPerf,
IDirectMusicSegmentState* pSegSt,DWORD dwVirtualID) ;
STDMETHODIMP GetParamEx(REFGUID rguidType,REFERENCE_TIME rtTime,
REFERENCE_TIME* prtNext,void* pParam,void * pStateData, DWORD dwFlags) ;
STDMETHODIMP SetParamEx(REFGUID rguidType,REFERENCE_TIME rtTime,void* pParam, void * pStateData, DWORD dwFlags) ;
STDMETHODIMP Compose(IUnknown* pContext,
DWORD dwTrackGroup,
IDirectMusicTrack** ppResultTrack) ;
STDMETHODIMP Join(IDirectMusicTrack* pNewTrack,
MUSIC_TIME mtJoin,
IUnknown* pContext,
DWORD dwTrackGroup,
IDirectMusicTrack** ppResultTrack) ;
// IDirectMusicCommon
STDMETHODIMP GetName(BSTR* pbstrName);
// IDirectMusicBandTrk (Private Interface)
STDMETHODIMP AddBand(DMUS_IO_PATCH_ITEM* BandEvent);
STDMETHODIMP AddBand(IDirectMusicBand* pIDMBand);
STDMETHODIMP SetGMGSXGMode(MUSIC_TIME mtTime, DWORD dwMidiMode)
{
TListItem<StampedGMGSXG>* pPair = new TListItem<StampedGMGSXG>;
if (!pPair) return E_OUTOFMEMORY;
pPair->GetItemValue().mtTime = mtTime;
pPair->GetItemValue().dwMidiMode = dwMidiMode;
TListItem<StampedGMGSXG>* pScan = m_MidiModeList.GetHead();
TListItem<StampedGMGSXG>* pPrev = NULL;
if(!pScan)
{
// Empty list
m_MidiModeList.AddHead(pPair);
}
else
{
while(pScan && pPair->GetItemValue().mtTime > pScan->GetItemValue().mtTime)
{
pPrev = pScan;
pScan = pScan->GetNext();
}
if(pPrev)
{
// Insert in the middle or end of list
pPair->SetNext(pScan);
pPrev->SetNext(pPair);
}
else
{
// Insert at beginning
m_MidiModeList.AddHead(pPair);
}
}
CBand* pBand = BandList.GetHead();
for(; pBand; pBand = pBand->GetNext())
{
// only set bands affected by new mode
if ( (pBand->m_lTimeLogical >= pPair->GetItemValue().mtTime) &&
( !pScan || pBand->m_lTimeLogical < pScan->GetItemValue().mtTime) )
{
pBand->SetGMGSXGMode(dwMidiMode);
}
}
return S_OK;
}
// Class
CBandTrk();
~CBandTrk();
private:
HRESULT BuildDirectMusicBandList(CRiffParser *pParser);
HRESULT ExtractBand(CRiffParser *pParser);
HRESULT LoadBand(IStream *pIStream, CBand* pBand);
HRESULT LoadClone(IDirectMusicBandTrk* pBandTrack,
MUSIC_TIME mtStart,
MUSIC_TIME mtEnd);
HRESULT InsertBand(CBand* pNewBand);
HRESULT Seek(CBandTrkStateData* pBandTrkStateData,
MUSIC_TIME mtStart,
MUSIC_TIME mtOffset,
REFERENCE_TIME rtOffset,
bool fClockTime);
HRESULT FindSEReplaceInstr(TList<SeekEvent>& SEList,
DWORD dwPChannel,
CBandInstrument* pInstrument);
// Shared implentation of play for either music or clock time.
HRESULT PlayMusicOrClock(
void *pStateData,
MUSIC_TIME mtStart,
MUSIC_TIME mtEnd,
MUSIC_TIME mtOffset,
REFERENCE_TIME rtOffset,
DWORD dwFlags,
IDirectMusicPerformance* pPerf,
IDirectMusicSegmentState* pSegSt,
DWORD dwVirtualID,
bool fClockTime);
HRESULT CBandTrk::JoinInternal(
IDirectMusicTrack* pNewTrack,
MUSIC_TIME mtJoin,
DWORD dwTrackGroup);
private:
CRITICAL_SECTION m_CriticalSection;
BOOL m_fCSInitialized;
DWORD m_dwValidate; // used to validate state data
CBandList BandList;
bool m_bAutoDownload;
bool m_fLockAutoDownload; // if true, this flag indicates that we've specifically
// commanded the band to autodownload. Otherwise,
// it gets its preference from the performance via
// GetGlobalParam.
DWORD m_dwFlags;
TList<StampedGMGSXG> m_MidiModeList; // List of time-stamped midi mode messages
long m_cRef;
};
//////////////////////////////////////////////////////////////////////
// Class BandTrkStateData
class CBandTrkStateData
{
public:
CBandTrkStateData() :
m_pSegmentState(NULL),
m_pPerformance(NULL),
m_pNextBandToSPE(NULL),
m_fPlayPreviousInSeek(FALSE),
m_dwVirtualTrackID(0),
dwValidate(0){}
~CBandTrkStateData(){}
public:
IDirectMusicSegmentState* m_pSegmentState;
IDirectMusicPerformance* m_pPerformance;
IDirectMusicBand* m_pNextBandToSPE;
DWORD m_dwVirtualTrackID;
BOOL m_fPlayPreviousInSeek;
DWORD dwValidate;
};
//////////////////////////////////////////////////////////////////////
// Class SeekEvent
class SeekEvent
{
public:
SeekEvent() :
m_pParentBand(NULL),
m_pInstrument(NULL),
m_dwPChannel(0) {}
~SeekEvent(){}
public:
CBand* m_pParentBand;
CBandInstrument* m_pInstrument;
DWORD m_dwPChannel;
};
#endif // #ifndef BANDTRK_H