254 lines
6.5 KiB
C
254 lines
6.5 KiB
C
|
//
|
||
|
// 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
|