Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) 1998-1999 Microsoft Corporation
  6. //
  7. // File: ptrntrk.h
  8. //
  9. //--------------------------------------------------------------------------
  10. // PtrnTrk.h : Declaration of the Pattern Track info and state structs
  11. #ifndef __PATTERNTRACK_H_
  12. #define __PATTERNTRACK_H_
  13. #include "dmsect.h"
  14. #include "dmstyle.h"
  15. const MUSIC_TIME MAX_END = 2147483647; // max end time for a track
  16. #define DMUS_PATTERN_AUDITION 1
  17. #define DMUS_PATTERN_MOTIF 2
  18. #define DMUS_PATTERN_STYLE 3
  19. #include <time.h> // to seed random number generator
  20. const long MULTIPLIER = 48271;
  21. const long MODULUS = 2147483647;
  22. class CRandomNumbers
  23. {
  24. public:
  25. CRandomNumbers(long nSeed = 0)
  26. {
  27. nCurrent = (long)(nSeed ? nSeed : time(NULL));
  28. }
  29. void Seed(long nSeed)
  30. {
  31. nCurrent = nSeed;
  32. }
  33. long Next(long nCeiling = 0)
  34. {
  35. LONGLONG llProduct = MULTIPLIER * (LONGLONG) nCurrent;
  36. nCurrent = (long) (llProduct % MODULUS);
  37. return nCeiling ? nCurrent % nCeiling : nCurrent;
  38. }
  39. private:
  40. long nCurrent;
  41. };
  42. struct PatternTrackState;
  43. struct StylePair
  44. {
  45. StylePair() : m_mtTime(0), m_pStyle(NULL) {}
  46. ~StylePair() { if (m_pStyle) m_pStyle->Release(); }
  47. MUSIC_TIME m_mtTime;
  48. IDMStyle* m_pStyle;
  49. };
  50. struct StatePair
  51. {
  52. StatePair() : m_pSegState(NULL), m_pStateData(NULL) {}
  53. StatePair(const StatePair& rPair)
  54. {
  55. m_pSegState = rPair.m_pSegState;
  56. m_pStateData = rPair.m_pStateData;
  57. }
  58. StatePair(IDirectMusicSegmentState* pSegState, PatternTrackState* pStateData)
  59. {
  60. m_pSegState = pSegState;
  61. m_pStateData = pStateData;
  62. }
  63. StatePair& operator= (const StatePair& rPair)
  64. {
  65. if (this != &rPair)
  66. {
  67. m_pSegState = rPair.m_pSegState;
  68. m_pStateData = rPair.m_pStateData;
  69. }
  70. return *this;
  71. }
  72. ~StatePair()
  73. {
  74. }
  75. IDirectMusicSegmentState* m_pSegState;
  76. PatternTrackState* m_pStateData;
  77. };
  78. struct PatternTrackInfo
  79. {
  80. PatternTrackInfo();
  81. PatternTrackInfo(const PatternTrackInfo* pInfo, MUSIC_TIME mtStart, MUSIC_TIME mtEnd);
  82. virtual ~PatternTrackInfo();
  83. virtual HRESULT STDMETHODCALLTYPE Init(
  84. /*[in]*/ IDirectMusicSegment* pSegment
  85. ) = 0;
  86. virtual HRESULT STDMETHODCALLTYPE InitPlay(
  87. /*[in]*/ IDirectMusicTrack* pParentrack,
  88. /*[in]*/ IDirectMusicSegmentState* pSegmentState,
  89. /*[in]*/ IDirectMusicPerformance* pPerformance,
  90. /*[out]*/ void** ppStateData,
  91. /*[in]*/ DWORD dwTrackID,
  92. /*[in]*/ DWORD dwFlags
  93. ) = 0;
  94. HRESULT STDMETHODCALLTYPE EndPlay(
  95. /*[in]*/ PatternTrackState* pStateData
  96. );
  97. HRESULT STDMETHODCALLTYPE AddNotificationType(
  98. /* [in] */ REFGUID pGuidNotify
  99. );
  100. HRESULT STDMETHODCALLTYPE RemoveNotificationType(
  101. /* [in] */ REFGUID pGuidNotify
  102. );
  103. PatternTrackState* FindState(IDirectMusicSegmentState* pSegState);
  104. HRESULT MergePChannels();
  105. HRESULT InitTrackVariations(CDirectMusicPattern* pPattern);
  106. TList<StatePair> m_StateList; // The track's state information
  107. TList<StylePair> m_pISList; // The track's Style interfaces
  108. DWORD m_dwPChannels; // # of PChannels the track knows about
  109. DWORD* m_pdwPChannels; // dynamic array of PChannels
  110. BOOL m_fNotifyMeasureBeat;
  111. BOOL m_fActive;
  112. // BOOL m_fTrackPlay;
  113. BOOL m_fStateSetBySetParam; // If TRUE, active flag was set by GUID. Don't override.
  114. // BOOL m_fStatePlaySetBySetParam; // If TRUE, trackplay flag was set by GUID. Don't override.
  115. BOOL m_fChangeStateMappings; // If TRUE, state data needs to change m_pMappings
  116. long m_lRandomNumberSeed; // If non-zero, use as a seed for variation selection
  117. DWORD m_dwPatternTag; // replaces need for dynamic casting
  118. DWORD m_dwValidate; // used to validate state data
  119. BYTE* m_pVariations; // Track's array of variations (1 per part)
  120. DWORD* m_pdwRemoveVariations; // Track's array of variations already played (1 per part)
  121. };
  122. #define PLAYPARTSF_CLOCKTIME 0x1
  123. #define PLAYPARTSF_FIRST_CALL 0x2
  124. #define PLAYPARTSF_START 0x4
  125. #define PLAYPARTSF_RELOOP 0x8
  126. #define PLAYPARTSF_FLUSH 0x10
  127. struct PatternTrackState
  128. {
  129. PatternTrackState();
  130. virtual ~PatternTrackState();
  131. // methods
  132. virtual HRESULT Play(
  133. /*[in]*/ MUSIC_TIME mtStart,
  134. /*[in]*/ MUSIC_TIME mtEnd,
  135. /*[in]*/ MUSIC_TIME mtOffset,
  136. REFERENCE_TIME rtOffset,
  137. IDirectMusicPerformance* pPerformance,
  138. DWORD dwFlags,
  139. BOOL fClockTime
  140. ) = 0;
  141. void GetNextChord(MUSIC_TIME mtNow, MUSIC_TIME mtOffset, IDirectMusicPerformance* pPerformance, BOOL fStart = FALSE, BOOL fSkipVariations = FALSE);
  142. HRESULT ResetMappings()
  143. {
  144. HRESULT hr = S_OK;
  145. if (m_pMappings) delete [] m_pMappings;
  146. m_pMappings = new MuteMapping[m_pPatternTrack->m_dwPChannels];
  147. if (!m_pMappings)
  148. {
  149. hr = E_OUTOFMEMORY;
  150. }
  151. else
  152. {
  153. for (DWORD dw = 0; dw < m_pPatternTrack->m_dwPChannels; dw++)
  154. {
  155. m_pMappings[dw].m_mtTime = 0;
  156. m_pMappings[dw].m_dwPChannelMap = m_pPatternTrack->m_pdwPChannels[dw];
  157. m_pMappings[dw].m_fMute = FALSE;
  158. }
  159. }
  160. m_pPatternTrack->m_fChangeStateMappings = FALSE;
  161. return hr;
  162. }
  163. void GetNextMute(DWORD dwPart, MUSIC_TIME mtStart, MUSIC_TIME mtNow, MUSIC_TIME mtOffset, IDirectMusicPerformance* pPerformance, BOOL fClockTime)
  164. {
  165. HRESULT hr = S_OK;
  166. if (m_pPatternTrack->m_fChangeStateMappings)
  167. {
  168. hr = ResetMappings();
  169. }
  170. if (SUCCEEDED(hr))
  171. {
  172. for (DWORD dw = 0; dw < m_pPatternTrack->m_dwPChannels; dw++)
  173. {
  174. if ( (m_pPatternTrack->m_pdwPChannels[dw] == dwPart) &&
  175. (0 <= m_pMappings[dw].m_mtTime && m_pMappings[dw].m_mtTime <= mtNow) )
  176. {
  177. DMUS_MUTE_PARAM MD;
  178. MUSIC_TIME mtNext = 0;
  179. MD.dwPChannel = m_pPatternTrack->m_pdwPChannels[dw];
  180. if (fClockTime)
  181. {
  182. MUSIC_TIME mtMusic;
  183. REFERENCE_TIME rtTime = (mtNow + mtOffset) * 10000;
  184. pPerformance->ReferenceToMusicTime(rtTime,&mtMusic);
  185. hr = pPerformance->GetParam(GUID_MuteParam, m_dwGroupID, DMUS_SEG_ANYTRACK, mtMusic,
  186. &mtNext, (void*) &MD);
  187. if (SUCCEEDED(hr))
  188. {
  189. REFERENCE_TIME rtNext;
  190. // Convert to absolute reference time.
  191. pPerformance->MusicToReferenceTime(mtNext + mtMusic,&rtNext);
  192. rtNext -= (mtOffset * 10000); // Subtract out to get the time from segment start.
  193. m_pMappings[dw].m_mtTime = (MUSIC_TIME)(rtNext / 10000); // Convert to milliseconds. Could be problematic if there's a tempo change.
  194. m_pMappings[dw].m_dwPChannelMap = MD.dwPChannelMap;
  195. m_pMappings[dw].m_fMute = MD.fMute;
  196. }
  197. else
  198. {
  199. // If we fail, disable mapping
  200. m_pMappings[dw].m_mtTime = -1;
  201. m_pMappings[dw].m_dwPChannelMap = m_pPatternTrack->m_pdwPChannels[dw];
  202. m_pMappings[dw].m_fMute = FALSE;
  203. }
  204. }
  205. else
  206. {
  207. hr = pPerformance->GetParam(GUID_MuteParam, m_dwGroupID, DMUS_SEG_ANYTRACK, mtNow + mtOffset,
  208. &mtNext, (void*) &MD);
  209. if (SUCCEEDED(hr))
  210. {
  211. m_pMappings[dw].m_mtTime = (mtNext) ? (mtNext + mtNow) : 0;
  212. m_pMappings[dw].m_dwPChannelMap = MD.dwPChannelMap;
  213. m_pMappings[dw].m_fMute = MD.fMute;
  214. }
  215. else
  216. {
  217. // If we fail, disable mapping
  218. m_pMappings[dw].m_mtTime = -1;
  219. m_pMappings[dw].m_dwPChannelMap = m_pPatternTrack->m_pdwPChannels[dw];
  220. m_pMappings[dw].m_fMute = FALSE;
  221. }
  222. }
  223. }
  224. }
  225. }
  226. }
  227. BOOL MapPChannel(DWORD dwPChannel, DWORD& dwMapPChannel);
  228. HRESULT PlayParts(MUSIC_TIME mtStart,
  229. MUSIC_TIME mtFinish,
  230. MUSIC_TIME mtOffset,
  231. REFERENCE_TIME rtOffset,
  232. MUSIC_TIME mtSection,
  233. IDirectMusicPerformance* pPerformance,
  234. DWORD dwPartFlags,
  235. DWORD dwPlayFlags,
  236. bool& rfReloop);
  237. void PlayPatternEvent(
  238. MUSIC_TIME mtNow,
  239. CDirectMusicEventItem* pEventItem,
  240. DirectMusicTimeSig& TimeSig,
  241. MUSIC_TIME mtPartOffset,
  242. MUSIC_TIME mtSegmentOffset,
  243. REFERENCE_TIME rtOffset,
  244. IDirectMusicPerformance* pPerformance,
  245. short nPart,
  246. DirectMusicPartRef& rPartRef,
  247. BOOL fClockTime,
  248. MUSIC_TIME mtPartStart,
  249. bool& rfChangedVariation);
  250. void BumpTime(
  251. CDirectMusicEventItem* pEvent,
  252. DirectMusicTimeSig& TimeSig,
  253. MUSIC_TIME mtOffset,
  254. MUSIC_TIME& mtResult)
  255. {
  256. if (pEvent != NULL)
  257. {
  258. mtResult = TimeSig.GridToClocks(pEvent->m_nGridStart) + mtOffset;
  259. }
  260. }
  261. virtual DWORD Variations(DirectMusicPartRef& rPartRef, int nPartIndex);
  262. virtual BOOL PlayAsIs();
  263. DirectMusicTimeSig& PatternTimeSig()
  264. {
  265. return
  266. (m_pPattern && m_pPattern->m_timeSig.m_bBeat != 0) ?
  267. m_pPattern->m_timeSig :
  268. (m_pStyle != NULL ? m_pStyle->m_TimeSignature : (::DefaultTimeSig));
  269. }
  270. void SendTimeSigMessage(MUSIC_TIME mtNow, MUSIC_TIME mtOffset, MUSIC_TIME mtTime, IDirectMusicPerformance* pPerformance);
  271. short FindGroup(WORD wID);
  272. short AddGroup(WORD wID, WORD wCount, short m_nOffset);
  273. DMStyleStruct* FindStyle(MUSIC_TIME mtTime, MUSIC_TIME& rmtTime);
  274. MUSIC_TIME NotifyMeasureBeat(
  275. MUSIC_TIME mtStart, MUSIC_TIME mtEnd, MUSIC_TIME mtOffset, IDirectMusicPerformance* pPerformance, DWORD dwFlags);
  276. HRESULT InitVariationSeeds(long lBaseSeed);
  277. HRESULT RemoveVariationSeeds();
  278. long RandomVariation(MUSIC_TIME mtTime, long lModulus);
  279. virtual MUSIC_TIME PartOffset(int nPartIndex);
  280. HRESULT InitPattern(CDirectMusicPattern* pTargetPattern, MUSIC_TIME mtNow, CDirectMusicPattern* pOldPattern = NULL);
  281. // attributes
  282. PatternTrackInfo* m_pPatternTrack; // This track state's parent track info
  283. IDirectMusicTrack* m_pTrack; // This track state's parent track
  284. DMStyleStruct* m_pStyle; // The style struct for the current style
  285. IDirectMusicSegmentState* m_pSegState; // The segment state for a performance
  286. DWORD m_dwVirtualTrackID; // The track's ID
  287. MUSIC_TIME m_mtCurrentChordTime; // when the current chord began
  288. MUSIC_TIME m_mtNextChordTime; // when the next chord begins
  289. MUSIC_TIME m_mtLaterChordTime; // when the chord after the next chord begins
  290. DMUS_CHORD_PARAM m_CurrentChord; // current chord
  291. DMUS_CHORD_PARAM m_NextChord; // next chord
  292. CDirectMusicPattern* m_pPattern; // currently playing pattern
  293. DWORD* m_pdwPChannels; // array of PChannels for the pattern (1 per part)
  294. BYTE* m_pVariations; // array of variations (1 per part)
  295. DWORD* m_pdwVariationMask; // array of disabled variations (1 per part)
  296. DWORD* m_pdwRemoveVariations; // array of variations already played (1 per part)
  297. MUSIC_TIME* m_pmtPartOffset; // array of part offsets (1 per part)
  298. bool* m_pfChangedVariation; // array: have this part's variations changed?
  299. BOOL m_fNewPattern; // TRUE if we're starting a new pattern
  300. BOOL m_mtPatternStart; // Time the current pattern started
  301. BOOL m_fStateActive;
  302. // BOOL m_fStatePlay;
  303. InversionGroup m_aInversionGroups[INVERSIONGROUPLIMIT];
  304. short m_nInversionGroupCount;
  305. MuteMapping* m_pMappings; // dynamic array of PChannel mappings
  306. // (sized to # of PChannels)
  307. BYTE m_abVariationGroups[MAX_VARIATION_LOCKS];
  308. CDirectMusicEventItem** m_ppEventSeek; // dynamic array of event list seek pointers
  309. DWORD m_dwGroupID; // Track's group ID
  310. CRandomNumbers* m_plVariationSeeds; // dynamic array of random # generators (1 per beat)
  311. int m_nTotalGenerators; // size of m_plVariationSeeds
  312. DWORD m_dwValidate; // used to validate state data
  313. HRESULT m_hrPlayCode; // last HRESULT returned by Play
  314. IDirectMusicPerformance* m_pPerformance; // performance used to init the state data
  315. MUSIC_TIME m_mtPerformanceOffset; // from track::play
  316. };
  317. const int CURVE_TYPES = 258; // one for each CC, one for each PAT, one for PB, one for MAT
  318. class CurveSeek
  319. {
  320. public:
  321. CurveSeek();
  322. void AddCurve(CDirectMusicEventItem* pEvent, MUSIC_TIME mtTimeStamp);
  323. void PlayCurves(
  324. PatternTrackState* pStateData,
  325. DirectMusicTimeSig& TimeSig,
  326. MUSIC_TIME mtPatternOffset,
  327. MUSIC_TIME mtOffset,
  328. REFERENCE_TIME rtOffset,
  329. IDirectMusicPerformance* pPerformance,
  330. short nPart,
  331. DirectMusicPartRef& rPartRef,
  332. BOOL fClockTime,
  333. MUSIC_TIME mtPartStart);
  334. private:
  335. CDirectMusicEventItem* m_apCurves[CURVE_TYPES];
  336. MUSIC_TIME m_amtTimeStamps[CURVE_TYPES];
  337. bool m_fFoundCurve;
  338. };
  339. #endif //__PATTERNTRACK_H_