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.

500 lines
21 KiB

  1. // DMCompos.h : Declaration of the CDMCompos
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // @doc EXTERNAL
  6. //
  7. //
  8. #ifndef __DMCOMPOS_H_
  9. #define __DMCOMPOS_H_
  10. #include "ComposIn.h"
  11. #include "DMCompP.h"
  12. #include "..\dmstyle\dmstyleP.h"
  13. #include "..\shared\dmusicp.h"
  14. #define SUBCHORD_STANDARD_CHORD 1
  15. #define SUBCHORD_BASS 0
  16. #define NC_SELECTED 1 // This is the active connector.
  17. #define NC_PATH 2 // For walking the tree.
  18. #define NC_NOPATH 4 // Failed tree walk.
  19. #define NC_TREE 8 // For displaying a tree.
  20. #define COMPOSEF_USING_DX8 1
  21. inline WORD ClocksPerBeat(DMUS_TIMESIGNATURE& TimeSig)
  22. { return DMUS_PPQ * 4 / TimeSig.bBeat; }
  23. inline DWORD ClocksPerMeasure(DMUS_TIMESIGNATURE& TimeSig)
  24. { return ClocksPerBeat(TimeSig) * TimeSig.bBeatsPerMeasure; }
  25. inline WORD ClocksToMeasure(DWORD dwTotalClocks, DMUS_TIMESIGNATURE& TimeSig)
  26. { return (WORD) (dwTotalClocks / ClocksPerMeasure(TimeSig)); }
  27. struct DMSignPostStruct
  28. {
  29. MUSIC_TIME m_mtTime;
  30. DWORD m_dwChords;
  31. WORD m_wMeasure;
  32. };
  33. struct DMExtendedChord
  34. {
  35. DMExtendedChord() { m_nRefCount = 0; }
  36. void AddRef() { m_nRefCount++; }
  37. BOOL Release() { m_nRefCount--; if (m_nRefCount <= 0) { delete this; return TRUE; } else return FALSE; }
  38. BOOL Equals(DMExtendedChord& rhsChord);
  39. DWORD m_dwChordPattern;
  40. DWORD m_dwScalePattern;
  41. DWORD m_dwInvertPattern;
  42. BYTE m_bRoot;
  43. BYTE m_bScaleRoot;
  44. WORD m_wCFlags;
  45. DWORD m_dwParts;
  46. int m_nRefCount;
  47. };
  48. struct DMChordData
  49. {
  50. DMChordData() : m_pSubChords(NULL) {} // Default constructor
  51. DMChordData(DMChordData& rChord); // Copy constructor
  52. DMChordData(DMUS_CHORD_PARAM& DMC); // conversion from DMUS_CHORD_PARAM
  53. HRESULT Read(IAARIFFStream* pIRiffStream, MMCKINFO* pckParent, DMExtendedChord** apChordDB);
  54. void Release();
  55. BOOL Equals(DMChordData& rhsChord);
  56. DWORD GetChordPattern();
  57. char GetRoot();
  58. void SetRoot(char chNewRoot);
  59. String m_strName; // Name of the chord
  60. TListItem<DMExtendedChord*>* m_pSubChords; // List of pointers to subchords of the chord
  61. };
  62. struct DMChordEntry;
  63. struct SearchInfo;
  64. struct DMChordLink
  65. {
  66. BOOL Walk(SearchInfo *pSearch);
  67. TListItem<DMChordEntry>* m_pChord; // pointer to an entry in the Chord Map list
  68. DWORD m_dwFlags; // (?)
  69. short m_nID; // ID for matching up pointers
  70. WORD m_wWeight;
  71. WORD m_wMinBeats;
  72. WORD m_wMaxBeats;
  73. };
  74. struct DMChordEntry
  75. {
  76. TListItem<DMChordLink>* ChooseNextChord();
  77. BOOL Walk(SearchInfo *pSearch);
  78. DWORD m_dwFlags; // Flags (first chord in path, last chord in path, etc.)
  79. short m_nID; // ID for matching up pointers
  80. DMChordData m_ChordData; // Chord body
  81. TList<DMChordLink> m_Links; // List of links from this chord
  82. };
  83. struct DMSignPost
  84. {
  85. DWORD m_dwChords; // Which kinds of signposts are supported.
  86. DWORD m_dwFlags;
  87. DWORD m_dwTempFlags;
  88. DMChordData m_ChordData;
  89. DMChordData m_aCadence[2];
  90. };
  91. struct PlayChord
  92. {
  93. HRESULT Save(IAARIFFStream* pRIFF, DMUS_TIMESIGNATURE& rTimeSig);
  94. char GetRoot();
  95. void SetRoot(char chNewRoot);
  96. DMChordData* m_pChord; // Chord to perform.
  97. TListItem<DMChordLink>* m_pNext; // Next chord
  98. DWORD m_dwFlags;
  99. short m_nMeasure;
  100. short m_nBeat;
  101. short m_nMinbeats;
  102. short m_nMaxbeats;
  103. bool m_fSilent;
  104. };
  105. struct FailSearch
  106. {
  107. FailSearch() :
  108. m_nTooManybeats(0), m_nTooFewbeats(0), m_nTooManychords(0), m_nTooFewchords(0)
  109. {}
  110. short m_nTooManybeats;
  111. short m_nTooFewbeats;
  112. short m_nTooManychords;
  113. short m_nTooFewchords;
  114. };
  115. struct SearchInfo
  116. {
  117. SearchInfo() : m_pFirstChord(NULL), m_pPlayChord(NULL) {}
  118. //DMChordEntry m_Start;
  119. //DMChordEntry m_End;
  120. DMChordData m_Start;
  121. DMChordData m_End;
  122. TListItem<PlayChord>* m_pPlayChord;
  123. TListItem<DMChordEntry>* m_pFirstChord;
  124. short m_nBeats;
  125. short m_nMinBeats;
  126. short m_nMaxBeats;
  127. short m_nChords;
  128. short m_nMinChords;
  129. short m_nMaxChords;
  130. short m_nActivity;
  131. FailSearch m_Fail;
  132. };
  133. struct TemplateCommand
  134. {
  135. TemplateCommand() : m_nMeasure(0), m_dwChord(0)
  136. {
  137. m_Command.bCommand = m_Command.bGrooveLevel = m_Command.bGrooveRange = 0;
  138. m_Command.bRepeatMode = DMUS_PATTERNT_RANDOM;
  139. }
  140. short m_nMeasure; // Which measure
  141. DMUS_COMMAND_PARAM m_Command; // Command type
  142. DWORD m_dwChord; // Signpost flags
  143. };
  144. struct CompositionCommand : TemplateCommand
  145. {
  146. TListItem<DMSignPost>* m_pSignPost;
  147. TListItem<DMChordEntry>* m_pFirstChord;
  148. TList<PlayChord> m_PlayList;
  149. SearchInfo m_SearchInfo;
  150. };
  151. /*
  152. @interface IDirectMusicComposer |
  153. The <i IDirectMusicComposer> interface permits access to the Direct Music composition
  154. engine which
  155. composes chord progression to generate section segments. In addition to building new
  156. section segments from templates and personalities, it can generate transition segments to
  157. transition between different section segments. And, it can apply a ChordMap to an
  158. existing section segment to convert the chord progression to match the harmonic behavior
  159. of the ChordMap, a great way to alter the mood of a section while it plays.
  160. The composition engine uses template segments or predefined shapes to determine the
  161. structure of the composed section segment and personalities to determine the content of
  162. the segment.
  163. @base public | IUnknown
  164. @meth HRESULT | ComposeSegmentFromTemplate | Creates an original section segment from a
  165. style, ChordMap and template.
  166. @meth HRESULT | ComposeSegmentFromShape | Creates an original section segment from a
  167. style and ChordMap based on a predefined shape.
  168. @meth HRESULT | ComposeTransition | Composes a transition from a measure inside one
  169. Section Segment to another.
  170. @meth HRESULT | AutoTransition | Composes and performs a transition from one
  171. Section Segment to another.
  172. @meth HRESULT | ComposeTemplateFromShape | Allocates and composes a new template segment
  173. based on a predefined shape.
  174. @meth HRESULT | ChangeChordMap | Modifies the chords and scale pattern of an existing
  175. section segment to reflect the new ChordMap.
  176. */
  177. /////////////////////////////////////////////////////////////////////////////
  178. // CDMCompos
  179. class CDMCompos :
  180. public IDirectMusicComposer8,
  181. public IDirectMusicComposer8P
  182. {
  183. friend class CSPstTrk;
  184. public:
  185. CDMCompos();
  186. ~CDMCompos();
  187. // IUnknown
  188. //
  189. virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv);
  190. virtual STDMETHODIMP_(ULONG) AddRef();
  191. virtual STDMETHODIMP_(ULONG) Release();
  192. // IDirectMusicComposer
  193. HRESULT STDMETHODCALLTYPE ComposeSegmentFromTemplate(
  194. IDirectMusicStyle* pStyle,
  195. IDirectMusicSegment* pTempSeg,
  196. WORD wActivity,
  197. IDirectMusicChordMap* pChordMap,
  198. IDirectMusicSegment** ppSectionSeg
  199. );
  200. HRESULT STDMETHODCALLTYPE ComposeSegmentFromShape(
  201. IDirectMusicStyle* pStyle,
  202. WORD wNumMeasures,
  203. WORD wShape,
  204. WORD wActivity,
  205. BOOL fComposeIntro,
  206. BOOL fComposeEnding,
  207. IDirectMusicChordMap* pChordMap,
  208. IDirectMusicSegment** ppSectionSeg
  209. );
  210. HRESULT STDMETHODCALLTYPE ComposeTransition(
  211. IDirectMusicSegment* pFromSeg,
  212. IDirectMusicSegment* pToSeg,
  213. MUSIC_TIME mtTime,
  214. WORD wCommand,
  215. DWORD dwFlags,
  216. IDirectMusicChordMap* pChordMap,
  217. IDirectMusicSegment** ppSectionSeg
  218. );
  219. HRESULT STDMETHODCALLTYPE AutoTransition(
  220. IDirectMusicPerformance* pPerformance,
  221. IDirectMusicSegment* pToSeg,
  222. WORD wCommand,
  223. DWORD dwFlags,
  224. IDirectMusicChordMap* pChordMap,
  225. IDirectMusicSegment** ppTransSeg,
  226. IDirectMusicSegmentState** ppToSegState,
  227. IDirectMusicSegmentState** ppTransSegState
  228. );
  229. HRESULT STDMETHODCALLTYPE ComposeTemplateFromShape(
  230. WORD wNumMeasures,
  231. WORD wShape,
  232. BOOL fComposeIntro,
  233. BOOL fComposeEnding,
  234. WORD wEndLength,
  235. IDirectMusicSegment** ppTempSeg
  236. );
  237. HRESULT STDMETHODCALLTYPE ChangeChordMap(
  238. IDirectMusicSegment* pSectionSeg,
  239. BOOL fTrackScale,
  240. IDirectMusicChordMap* pChordMap
  241. );
  242. // IDirectMusicComposer8
  243. HRESULT STDMETHODCALLTYPE ComposeSegmentFromTemplateEx(
  244. IDirectMusicStyle* pStyle,
  245. IDirectMusicSegment* pTempSeg,
  246. DWORD dwFlags, // are we using activity levels?
  247. // Are we creating a new seg. or composing into the current one?
  248. DWORD dwActivity,
  249. IDirectMusicChordMap* pChordMap,
  250. IDirectMusicSegment** ppSectionSeg
  251. );
  252. HRESULT STDMETHODCALLTYPE ComposeTemplateFromShapeEx(
  253. WORD wNumMeasures, // Number of measures in template
  254. WORD wShape, // Shape for composition
  255. BOOL fIntro, // Compose an intro?
  256. BOOL fEnd, // Compose an ending?
  257. IDirectMusicStyle* pStyle, // Style used for embellishment lengths
  258. IDirectMusicSegment** ppTemplate // Template containing chord and command tracks
  259. );
  260. protected: // member functions
  261. void CleanUp();
  262. void AddChord(DMChordData* pChord);
  263. TListItem<PlayChord> *AddChord(TList<PlayChord>& rList, DMChordData *pChord, int nMeasure,int nBeat);
  264. TListItem<PlayChord> *AddCadence(TList<PlayChord>& rList, DMChordData *pChord, int nMax);
  265. void ChordConnections(TList<DMChordEntry>& ChordMap,
  266. CompositionCommand& rCommand,
  267. SearchInfo *pSearch,
  268. short nBPM,
  269. DMChordData *pCadence1,
  270. DMChordData *pCadence2);
  271. void ChordConnections2(TList<DMChordEntry>& ChordMap,
  272. CompositionCommand& rCommand,
  273. SearchInfo *pSearch,
  274. short nBPM,
  275. DMChordData *pCadence1,
  276. DMChordData *pCadence2);
  277. void ComposePlayList(TList<PlayChord>& PlayList,
  278. IDirectMusicStyle* pStyle,
  279. IDirectMusicChordMap* pPersonality,
  280. TList<TemplateCommand>& rCommandList,
  281. WORD wActivity);
  282. void ComposePlayList2(TList<PlayChord>& PlayList,
  283. IDirectMusicStyle* pStyle,
  284. IDirectMusicChordMap* pPersonality,
  285. TList<TemplateCommand>& rCommandList);
  286. HRESULT ComposePlayListFromShape(
  287. long lNumMeasures,
  288. WORD wShape,
  289. BOOL fComposeIntro,
  290. BOOL fComposeEnding,
  291. int nIntroLength,
  292. int nFillLength,
  293. int nBreakLength,
  294. int nEndLength,
  295. IDirectMusicStyle* pStyle,
  296. WORD wActivity,
  297. IDirectMusicChordMap* pPersonality,
  298. TList<TemplateCommand>& CommandList,
  299. TList<PlayChord>& PlayList
  300. );
  301. BOOL Compose(TList<DMChordEntry>& ChordMap,
  302. SearchInfo *pSearch,
  303. CompositionCommand& rCommand);
  304. void JostleBack(TList<PlayChord>& rList, TListItem<PlayChord> *pChord, int nBeats);
  305. BOOL AlignChords(TListItem<PlayChord> *pChord,int nLastbeat,int nRes);
  306. void ChooseSignPosts(TListItem<DMSignPost> *pSignPostHead,
  307. TListItem<CompositionCommand> *pTempCommand, DWORD dwType,
  308. bool fSecondPass);
  309. TListItem<CompositionCommand> *GetNextChord(TListItem<CompositionCommand> *pCommand);
  310. void FindEarlierSignpost(TListItem<CompositionCommand> *pCommand,
  311. TListItem<CompositionCommand> *pThis,
  312. SearchInfo *pSearch);
  313. void CleanUpBreaks(TList<PlayChord>& PlayList, TListItem<CompositionCommand> *pCommand);
  314. HRESULT GetStyle(IDirectMusicSegment* pFromSeg, MUSIC_TIME mt, DWORD dwGroupBits, IDirectMusicStyle*& rpStyle, bool fTryPattern);
  315. HRESULT GetPersonality(IDirectMusicSegment* pFromSeg, MUSIC_TIME mt, DWORD dwGroupBits, IDirectMusicChordMap*& rpPers);
  316. HRESULT ExtractCommandList(TList<TemplateCommand>& CommandList,
  317. IDirectMusicTrack* pSignPostTrack,
  318. IDirectMusicTrack* pCommandTrack,
  319. DWORD dwGroupBits);
  320. HRESULT AddToSegment(IDirectMusicSegment* pTempSeg,
  321. TList<PlayChord>& PlayList,
  322. IDirectMusicStyle* pStyle,
  323. DWORD dwGroupBits,
  324. BYTE bRoot, DWORD dwScale);
  325. HRESULT CopySegment(IDirectMusicSegment* pTempSeg,
  326. IDirectMusicSegment** ppSectionSeg,
  327. TList<PlayChord>& PlayList,
  328. IDirectMusicStyle* pStyle,
  329. IDirectMusicChordMap* pChordMap,
  330. BOOL fStyleFromTrack,
  331. BOOL fChordMapFromTrack,
  332. DWORD dwGroupBits,
  333. BYTE bRoot, DWORD dwScale);
  334. HRESULT BuildSegment(TList<TemplateCommand>& CommandList,
  335. TList<PlayChord>& PlayList,
  336. IDirectMusicStyle* pStyle,
  337. IDirectMusicChordMap* pChordMap,
  338. long lMeasures,
  339. IDirectMusicSegment** ppSectionSeg,
  340. BYTE bRoot, DWORD dwScale,
  341. double* pdblTempo = NULL,
  342. IDirectMusicBand* pCurrentBand = NULL,
  343. bool fAlign = false,
  344. IDirectMusicGraph* pGraph = NULL,
  345. IUnknown* pPath = NULL);
  346. HRESULT SaveChordList( IAARIFFStream* pRIFF, TList<PlayChord>& rPlayList,
  347. BYTE bRoot, DWORD dwScale, DMUS_TIMESIGNATURE& rTimeSig);
  348. HRESULT TransitionCommon(
  349. IDirectMusicStyle* pFromStyle,
  350. IDirectMusicBand* pCurrentBand,
  351. double* pdblFromTempo,
  352. DMUS_COMMAND_PARAM_2& rFromCommand,
  353. DMUS_CHORD_PARAM& rLastChord,
  354. DMUS_CHORD_PARAM& rNextChord,
  355. IDirectMusicSegment* pToSeg,
  356. WORD wCommand,
  357. DWORD dwFlags,
  358. IDirectMusicChordMap* pChordMap,
  359. IDirectMusicGraph* pFromGraph,
  360. IDirectMusicGraph* pToGraph,
  361. IUnknown* pFromPath,
  362. IUnknown* pToPath,
  363. IDirectMusicSegment** ppSectionSeg
  364. );
  365. HRESULT ComposeTemplateFromShapeInternal(
  366. WORD wNumMeasures,
  367. WORD wShape,
  368. BOOL fComposeIntro,
  369. BOOL fComposeEnding,
  370. int nIntroLength,
  371. int nBreakLength,
  372. int nFillLength,
  373. int nEndLength,
  374. IDirectMusicSegment** ppTempSeg
  375. );
  376. bool HasDX8Content(IDirectMusicStyle* pFromStyle,
  377. IDirectMusicChordMap* pFromChordMap = NULL,
  378. IDirectMusicSegment* pFromSegment = NULL,
  379. DMUS_COMMAND_PARAM_2* pCommand = NULL,
  380. DMUS_CHORD_PARAM* pLastChord = NULL)
  381. {
  382. // Currently this will return true if the Style is DX8. Should be sufficient (when called from
  383. // AutoTransition, at least), since the style is primarily responsible for the way the transition
  384. // will sound.
  385. bool fResult = false;
  386. IDMStyle* pDMStyle = NULL;
  387. if (pFromStyle && SUCCEEDED(pFromStyle->QueryInterface(IID_IDMStyle, (void**) &pDMStyle)))
  388. {
  389. if (pDMStyle->IsDX8() == S_OK) fResult = true;
  390. pDMStyle->Release();
  391. }
  392. return fResult;
  393. }
  394. bool UsingDX8(IDirectMusicStyle* pFromStyle = NULL,
  395. IDirectMusicChordMap* pFromChordMap = NULL,
  396. IDirectMusicSegment* pFromSegment = NULL,
  397. DMUS_COMMAND_PARAM_2* pCommand = NULL,
  398. DMUS_CHORD_PARAM* pLastChord = NULL)
  399. {
  400. return
  401. (m_dwFlags & COMPOSEF_USING_DX8) ||
  402. HasDX8Content(pFromStyle, pFromChordMap, pFromSegment, pCommand, pLastChord);
  403. }
  404. TListItem<DMSignPost>* ChooseSignPost(
  405. IDirectMusicChordMap* pChordMap,
  406. DMChordData* pNextChord,
  407. bool fEnding,
  408. DWORD dwScale,
  409. BYTE bRoot);
  410. HRESULT ComposePlayListFromTemplate(IDirectMusicStyle* pStyle,
  411. IDirectMusicChordMap* pChordMap,
  412. IDirectMusicTrack* pChordMapTrack,
  413. IDirectMusicTrack* pSignPostTrack,
  414. IDirectMusicTrack* pCommandTrack,
  415. DWORD dwGroupBits,
  416. MUSIC_TIME mtLength,
  417. bool fUseActivity,
  418. DWORD dwActivity,
  419. TList<PlayChord>& rPlayList,
  420. BYTE& rbRoot,
  421. DWORD& rdwScale);
  422. IDirectMusicGraph* CloneSegmentGraph(IDirectMusicSegment* pSegment);
  423. IUnknown* GetSegmentAudioPath(IDirectMusicSegment* pSegment, DWORD dwFlags, DWORD* pdwAudioPath = NULL);
  424. protected: // attributes
  425. long m_cRef;
  426. TListItem<DMChordData*>* m_pChords;
  427. DWORD m_dwFlags; // variaous flags
  428. CRITICAL_SECTION m_CriticalSection; // for i/o
  429. BOOL m_fCSInitialized;
  430. };
  431. void ChangeCommand(DMUS_COMMAND_PARAM& rResult, DMUS_COMMAND_PARAM& rCommand, int nDirection);
  432. #endif //__DMCOMPOS_H_