DirectMedia.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using System;
  2. using System.IO;
  3. using Microsoft.Xna.Framework;
  4. #if _WINDOWS && !_X64
  5. using DirectMidi;
  6. #endif
  7. using System.Diagnostics;
  8. namespace OpenVIII.AV.Midi
  9. {
  10. /// <summary>
  11. /// Direct Music
  12. /// </summary>
  13. /// <see cref="http://directmidi.sourceforge.net/"/>
  14. /// <seealso cref="http://directmidinet.sourceforge.net/"/>
  15. public sealed class DirectMedia : IDisposable
  16. {
  17. #if _WINDOWS && (_X86 || !_X64)
  18. private CDirectMusic cdm;
  19. private CDLSLoader loader;
  20. private CSegment segment;
  21. private CAPathPerformance path;
  22. private CPortPerformance cport; //public explicit
  23. private COutputPort outport;
  24. private CCollection ccollection;
  25. private CInstrument[] instruments;
  26. public const int S_OK = 0x00000000;
  27. public void Play(string pt, bool loop = true)
  28. {
  29. if (cdm == null)
  30. {
  31. cdm = new CDirectMusic();
  32. cdm.Initialize();
  33. loader = new CDLSLoader();
  34. loader.Initialize();
  35. loader.LoadSegment(pt, out segment);
  36. ccollection = new CCollection();
  37. string pathDLS = Path.Combine(Memory.FF8DIRdata, "Music/dmusic_backup/FF8.dls");
  38. if (!File.Exists(pathDLS))
  39. {
  40. pathDLS = Path.Combine(Memory.FF8DIRdata, "Music/dmusic/FF8.dls");
  41. }
  42. loader.LoadDLS(pathDLS, out ccollection);
  43. uint dwInstrumentIndex = 0;
  44. while (ccollection.EnumInstrument(++dwInstrumentIndex, out INSTRUMENTINFO iInfo) == S_OK)
  45. {
  46. Debug.WriteLine(iInfo.szInstName);
  47. }
  48. instruments = new CInstrument[dwInstrumentIndex];
  49. path = new CAPathPerformance();
  50. path.Initialize(cdm, null, null, DMUS_APATH.DYNAMIC_3D, 128);
  51. cport = new CPortPerformance();
  52. cport.Initialize(cdm, null, null);
  53. outport = new COutputPort();
  54. outport.Initialize(cdm);
  55. uint dwPortCount = 0;
  56. INFOPORT infoport;
  57. do
  58. {
  59. outport.GetPortInfo(++dwPortCount, out infoport);
  60. }
  61. while ((infoport.dwFlags & DMUS_PC.SOFTWARESYNTH) == 0);
  62. outport.SetPortParams(0, 0, 0, DirectMidi.SET.REVERB | DirectMidi.SET.CHORUS, 44100);
  63. outport.ActivatePort(infoport);
  64. cport.AddPort(outport, 0, 1);
  65. for (int i = 0; i < dwInstrumentIndex; i++)
  66. {
  67. ccollection.GetInstrument(out instruments[i], i);
  68. outport.DownloadInstrument(instruments[i]);
  69. }
  70. segment.Download(cport);
  71. if(!loop)
  72. segment.SetRepeats(0);
  73. cport.PlaySegment(segment);
  74. }
  75. else
  76. {
  77. cport.Stop(segment);
  78. segment.Dispose();
  79. //segment.ConnectToDLS
  80. loader.LoadSegment(pt, out segment);
  81. segment.Download(cport);
  82. if (!loop)
  83. segment.SetRepeats(0);
  84. cport.PlaySegment(segment);
  85. cdm.Dispose();
  86. }
  87. //GCHandle.Alloc(cdm, GCHandleType.Pinned);
  88. //GCHandle.Alloc(loader, GCHandleType.Pinned);
  89. //GCHandle.Alloc(segment, GCHandleType.Pinned);
  90. //GCHandle.Alloc(path, GCHandleType.Pinned);
  91. //GCHandle.Alloc(cport, GCHandleType.Pinned);
  92. //GCHandle.Alloc(outport, GCHandleType.Pinned);
  93. //GCHandle.Alloc(infoport, GCHandleType.Pinned);
  94. }
  95. public void Stop() => cport.StopAll();
  96. public void Dispose()
  97. {
  98. Stop();
  99. segment.Dispose();
  100. instruments.ForEach(action => action.Dispose());
  101. cport.Dispose();
  102. ccollection.Dispose();
  103. loader.Dispose();
  104. outport.Dispose();
  105. path.Dispose();
  106. cdm.Dispose();
  107. }
  108. #else
  109. public void Play(string pt)
  110. {}
  111. public void Stop()
  112. {}
  113. public void Dispose()
  114. {}
  115. #endif
  116. }
  117. }