// // 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* pPair = new TListItem; if (!pPair) return E_OUTOFMEMORY; pPair->GetItemValue().mtTime = mtTime; pPair->GetItemValue().dwMidiMode = dwMidiMode; TListItem* pScan = m_MidiModeList.GetHead(); TListItem* 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& 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 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