|
|
//
// dmbandp.h
//
// Copyright (c) 1997-2000 Microsoft Corporation
//
//
#ifndef DMBANDP_H
#define DMBANDP_H
#include "dmusici.h"
#include "dmusicf.h"
#include "bandinst.h"
#include "dmbndtrk.h"
#include "..\shared\validate.h"
#include "PChMap.h"
#include "..\shared\dmusicp.h"
class CRiffParser;
#define REF_PER_MIL 10000 // For converting from reference time to mils
#define DM_LEGACY_BAND_COLLECTION_NAME_LEN (32)
#define MIDI_PROGRAM_CHANGE 0xc0
#define MIDI_CONTROL_CHANGE 0xb0
#define MIDI_CC_BS_MSB 0x00
#define MIDI_CC_BS_LSB 0x20
#define MIDI_CC_VOLUME 0x07
#define MIDI_CC_PAN 0x0a
// registered parameter numbers
#define RPN_PITCHBEND 0x00
#define FOURCC_BAND_FORM mmioFOURCC('A','A','B','N')
#define FOURCC_BAND mmioFOURCC('b','a','n','d')
// This structure is the format used by band files created with SuperJam and
// earlier versions of Jazz. It was taken from band.h found in the Band Editor
// subdirectory of the Jazz project tree.
#pragma pack(2)
typedef struct ioBandLegacy { wchar_t wstrName[20]; // Band name
BYTE abPatch[16]; // GM
BYTE abVolume[16]; BYTE abPan[16]; signed char achOctave[16]; char fDefault; // This band is the style's default band
char chPad; WORD awDLSBank[16]; // if GM bit set use abPatch
// if GS bit set, use this plus abDLSPatch
// else use both as a DLS
BYTE abDLSPatch[16]; GUID guidCollection; // wchar_t wstrCollection[16];
char szCollection[32]; // this only needs to be single-wide chars
} ioBandLegacy;
#pragma pack()
#define DMB_LOADED (1 << 0) /* Set when band has been loaded */
#define DMB_DEFAULT (1 << 1) /* Set when band is default band for a style */
class CBandInstrument; class CBandTrkStateData;
//////////////////////////////////////////////////////////////////////
// Class CBand
class CBand : public IDirectMusicBand, public IDirectMusicBandP, public IDirectMusicBandPrivate, public IPersistStream, public IDirectMusicObject, public AListItem { friend class CBandTrk;
public: enum {DMBAND_NUM_LEGACY_INSTRUMENTS = 16};
// IUnknown
virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv); virtual STDMETHODIMP_(ULONG) AddRef(); virtual STDMETHODIMP_(ULONG) Release();
// IPersist functions
STDMETHODIMP GetClassID(CLSID* pClassID) {return E_NOTIMPL;}
// IPersistStream functions
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;}
// IDirectMusicObject
STDMETHODIMP GetDescriptor(LPDMUS_OBJECTDESC pDesc); STDMETHODIMP SetDescriptor(LPDMUS_OBJECTDESC pDesc); STDMETHODIMP ParseDescriptor(LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc);
// IDirectMusicBand
STDMETHODIMP CreateSegment(IDirectMusicSegment** ppSegment); STDMETHODIMP Download(IDirectMusicPerformance* pPerformance); STDMETHODIMP Unload(IDirectMusicPerformance* pPerformance);
/* IDirectMusicBand8 */ STDMETHODIMP DownloadEx( IUnknown *pAudioPath) ; STDMETHODIMP UnloadEx( IUnknown *pAudioPath) ;
// IDirectMusicBandPrivate
STDMETHODIMP GetFlags(DWORD* dwFlags) { V_INAME(CBand::GetFlags);
// Make sure we have a valid pointer
V_PTR_WRITE(dwFlags, DWORD);
*dwFlags = m_dwFlags;
return S_OK; } STDMETHODIMP SetGMGSXGMode(DWORD dwMidiMode) { m_dwMidiMode = dwMidiMode; return S_OK; }
// Class
CBand(); ~CBand();
private: CBand* GetNext(){return(CBand*)AListItem::GetNext();}
HRESULT ParseLegacyDescriptor(CRiffParser *pParser, LPDMUS_OBJECTDESC pDesc); HRESULT ParseDirectMusicDescriptor(CRiffParser *pParser, LPDMUS_OBJECTDESC pDesc);
HRESULT LoadDirectMusicBand(CRiffParser *pParser, IDirectMusicLoader *pIDMLoader); HRESULT LoadLegacyBand(CRiffParser *pParser, IDirectMusicLoader *pIDMLoader);
HRESULT BuildLegacyInstrumentList(const ioBandLegacy& iob, IDirectMusicLoader* pIDMLoader);
HRESULT ExtractBandInstrument(CRiffParser *pParser, IDirectMusicLoader* pIDMLoader); HRESULT GetCollectionRefAndLoad(CRiffParser *pParser, IDirectMusicLoader *pIDMLoader, CBandInstrument *pBandInstrument); HRESULT Load(DMUS_IO_PATCH_ITEM& rPatchEvent); // Assumes event come from a MIDI file
HRESULT Load(CBandInstrument* pInstrument); // Assumes Instrument come from a band during cloning
HRESULT SendMessages(CBandTrkStateData* pBTStateData, MUSIC_TIME mtOffset, REFERENCE_TIME rtOffset, bool fClockTime);
HRESULT AllocPMsgFromGenericTemplate( DWORD dwType, IDirectMusicPerformance *pPerformance, DMUS_PMSG **ppMsg, ULONG cb, DMUS_PMSG *pMsgGenericFields);
HRESULT StampSendFreePMsg( IDirectMusicPerformance *pPerformance, IDirectMusicGraph *pGraph, DMUS_PMSG *pMsg);
HRESULT SendInstrumentAtTime(CBandInstrument* pInstrument, CBandTrkStateData* pBTStateData, MUSIC_TIME mtTimeToPlay, MUSIC_TIME mtOffset, REFERENCE_TIME rtOffset, bool fClockTime); HRESULT LoadCollection(IDirectMusicCollection** ppIDMCollection, char* szCollection, IDirectMusicLoader* pIDMLoader); DWORD GetPChannelCount(); HRESULT GetPChannels(DWORD *pdwPChannels, DWORD *pdwNumWritten); bool IsGS(DMUS_IO_PATCH_ITEM& rPatchEvent); bool XGInHardware( IDirectMusicPerformance *pPerformance, IDirectMusicSegmentState *pSegState, DWORD dwPChannel); HRESULT ConnectToDLSCollection(IDirectMusicCollection *pCollection); HRESULT MakeGMOnly();
private: CRITICAL_SECTION m_CriticalSection; BOOL m_fCSInitialized; CBandInstrumentList m_BandInstrumentList; MUSIC_TIME m_lTimeLogical; MUSIC_TIME m_lTimePhysical; DWORD m_dwFlags; long m_cRef; CPChMap m_PChMap; DWORD m_dwGroupBits; DWORD m_dwMidiMode; // midi mode message
// IDirectMusicObject variables
DWORD m_dwValidData; GUID m_guidObject; FILETIME m_ftDate; /* Last edited date of object. */ DMUS_VERSION m_vVersion; /* Version. */ WCHAR m_wszName[DMUS_MAX_NAME]; /* Name of object. */ WCHAR m_wszCategory[DMUS_MAX_CATEGORY]; /* Category for object */ WCHAR m_wszFileName[DMUS_MAX_FILENAME]; /* File path. */
};
//////////////////////////////////////////////////////////////////////
// Class CBandList
class CBandList : public AList {
public: CBandList(){} ~CBandList() { while(!IsEmpty()) { CBand* pBand = RemoveHead(); delete pBand; } }
CBand* GetHead(){return(CBand *)AList::GetHead();} CBand* GetItem(LONG lIndex){return(CBand*)AList::GetItem(lIndex);} CBand* RemoveHead(){return(CBand *)AList::RemoveHead();} void Remove(CBand* pBand){AList::Remove((AListItem *)pBand);} void AddTail(CBand* pBand){AList::AddTail((AListItem *)pBand);} };
class CClassFactory : public IClassFactory { public: // IUnknown
//
STDMETHODIMP QueryInterface(const IID &iid, void **ppv); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release();
// Interface IClassFactory
//
STDMETHODIMP CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv); STDMETHODIMP LockServer(BOOL bLock);
// Constructor
//
CClassFactory(DWORD dwToolType);
// Destructor
~CClassFactory();
private: long m_cRef; DWORD m_dwClassType; };
// We use one class factory to create all classes. We need an identifier for each
// type so the class factory knows what it is creating.
#define CLASS_BAND 1
#define CLASS_BANDTRACK 2
#endif // #ifndef DMBANDP_H
|