Advertisement
Guest User

Untitled

a guest
Oct 6th, 2015
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.92 KB | None | 0 0
  1. using System;
  2. using System.Threading;
  3. using System.Runtime.InteropServices;
  4. using System.Collections;
  5. using System.Linq;
  6.  
  7. namespace LowLevelAudio
  8. {
  9. internal class WaveOutHelper
  10. {
  11. public static void Try(int err)
  12. {
  13. if (err != WaveNative.MMSYSERR_NOERROR)
  14. throw new Exception(err.ToString());
  15. }
  16. }
  17.  
  18. public delegate void BufferFillEventHandler(IntPtr data, int size);
  19.  
  20. public class WaveOutBuffer : IDisposable
  21. {
  22. private AutoResetEvent m_PlayEvent = new AutoResetEvent(false);
  23. private IntPtr m_WaveOut;
  24. private int m_buffersize;
  25. private static byte[] m_samples;
  26. private static double[] m_fftsamples;
  27. private WaveNative.WaveHdr m_Header;
  28. private byte[] m_HeaderData;
  29. private GCHandle m_HeaderHandle;
  30. private GCHandle m_HeaderDataHandle;
  31. private WaveFormat m_waveformat;
  32. private double[] m_fftOccurances;
  33. private double[] m_fftHertzlist;
  34. private bool m_Playing;
  35.  
  36. public int ID
  37. {
  38. get; set;
  39. }
  40.  
  41.  
  42.  
  43. internal static void WaveOutProc(IntPtr hdrvr, int uMsg, int dwUser, ref WaveNative.WaveHdr wavhdr, int dwParam2)
  44. {
  45. if (uMsg == WaveNative.MM_WOM_DONE)
  46. {
  47. try
  48. {
  49. GCHandle h = (GCHandle)wavhdr.dwUser;
  50. WaveOutBuffer buf = (WaveOutBuffer)h.Target;
  51. buf.OnPlayCompleted();
  52. }
  53. catch(Exception ex)
  54. {
  55. Console.WriteLine("Exception: " + ex.Message);
  56. }
  57. }
  58. }
  59.  
  60. public WaveOutBuffer(IntPtr waveOutHandle, int size, WaveFormat format)
  61. {
  62. m_WaveOut = waveOutHandle;
  63. m_waveformat = format;
  64. m_HeaderHandle = GCHandle.Alloc(m_Header, GCHandleType.Pinned);
  65. m_Header.dwUser = (IntPtr)GCHandle.Alloc(this);
  66. m_HeaderData = new byte[size];
  67. m_HeaderDataHandle = GCHandle.Alloc(m_HeaderData, GCHandleType.Pinned);
  68. m_Header.lpData = m_HeaderDataHandle.AddrOfPinnedObject();
  69. m_Header.dwBufferLength = size;
  70. m_buffersize = size;
  71. m_samples = new byte[m_buffersize];
  72. WaveOutHelper.Try(WaveNative.waveOutPrepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)));
  73. }
  74. ~WaveOutBuffer()
  75. {
  76. Dispose();
  77. }
  78.  
  79. public int Size
  80. {
  81. get { return m_Header.dwBufferLength; }
  82. }
  83.  
  84. public IntPtr Data
  85. {
  86. get { return m_Header.lpData; }
  87. }
  88.  
  89. public void Dispose()
  90. {
  91. if (m_Header.lpData != IntPtr.Zero)
  92. {
  93. WaveNative.waveOutUnprepareHeader(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header));
  94. m_HeaderHandle.Free();
  95. m_Header.lpData = IntPtr.Zero;
  96. }
  97. m_PlayEvent.Close();
  98. if (m_HeaderDataHandle.IsAllocated)
  99. m_HeaderDataHandle.Free();
  100. }
  101.  
  102. public bool Play()
  103. {
  104. lock(this) // works, but has to be fine tuned... (to do)
  105. {
  106. m_PlayEvent.Reset();
  107. m_Playing = WaveNative.waveOutWrite(m_WaveOut, ref m_Header, Marshal.SizeOf(m_Header)) == WaveNative.MMSYSERR_NOERROR;
  108. if (!m_Playing)
  109. throw new Exception("test exception");
  110. return m_Playing;
  111. }
  112. }
  113.  
  114. public void WaitForMe()
  115. {
  116. Console.WriteLine(this.ID + " WaitFor()");
  117. if (m_Playing)
  118. {
  119. m_Playing = m_PlayEvent.WaitOne();
  120. }
  121. else
  122. {
  123. m_Playing = false;
  124. }
  125. }
  126.  
  127. public void OnPlayCompleted()
  128. {
  129. Console.WriteLine(this.ID + " OnCompleted()");
  130. m_PlayEvent.Set();
  131. m_Playing = false;
  132. }
  133. }
  134.  
  135. public class WaveOutPlayer : IDisposable
  136. {
  137. private IntPtr m_WaveOut;
  138. private WaveOutBuffer[] m_bufferlist;
  139. private Thread m_Thread;
  140. private BufferFillEventHandler m_FillProc;
  141. private bool m_Finished;
  142. private byte m_zero;
  143. private int m_buffercount = 0;
  144. private int m_buffersize = 0;
  145. private WaveFormat m_waveformat;
  146.  
  147. private WaveNative.WaveDelegate m_BufferProc = new WaveNative.WaveDelegate(WaveOutBuffer.WaveOutProc);
  148.  
  149. public static int DeviceCount
  150. {
  151. get { return WaveNative.waveOutGetNumDevs(); }
  152. }
  153.  
  154. public WaveOutPlayer(int device, WaveFormat format, int bufferSize, BufferFillEventHandler fillProc)
  155. {
  156. m_zero = format.wBitsPerSample == 8 ? (byte)128 : (byte)0;
  157. m_FillProc = fillProc;
  158. m_buffercount = 2;
  159. m_buffersize = bufferSize;
  160. m_waveformat = format;
  161. WaveOutHelper.Try(WaveNative.waveOutOpen(out m_WaveOut, device, format, m_BufferProc, 0, WaveNative.CALLBACK_FUNCTION));
  162. AllocateBuffers(bufferSize, m_buffercount, format);
  163. m_Thread = new Thread(new ThreadStart(ThreadProc));
  164. m_Thread.Start();
  165. }
  166.  
  167. ~WaveOutPlayer()
  168. {
  169. Dispose();
  170. }
  171.  
  172. public void Dispose()
  173. {
  174. if (m_Thread != null)
  175. {
  176. try
  177. {
  178. m_Finished = true;
  179. if (m_WaveOut != IntPtr.Zero)
  180. WaveNative.waveOutReset(m_WaveOut);
  181. m_Thread.Join();
  182. m_FillProc = null;
  183. FreeBuffers();
  184. if (m_WaveOut != IntPtr.Zero)
  185. WaveNative.waveOutClose(m_WaveOut);
  186. }
  187. finally
  188. {
  189. m_Thread = null;
  190. m_WaveOut = IntPtr.Zero;
  191. }
  192. }
  193. }
  194.  
  195. private void ThreadProc()
  196. {
  197. WaveOutBuffer b0 = m_bufferlist[0];
  198. WaveOutBuffer b1 = m_bufferlist[1];
  199. MainForm form = Program.getUI();
  200.  
  201. bool s = true;
  202. m_FillProc(b0.Data, b0.Size);
  203.  
  204. while (!m_Finished)
  205. {
  206. if (s)
  207. {
  208. Console.WriteLine("-------------------------");
  209. Console.WriteLine("Playing b0, filling b1");
  210. b0.Play();
  211. m_FillProc(b1.Data, b1.Size);
  212.  
  213. form.paintEqualizer(b0);
  214. Console.WriteLine("callng waitFor on b0");
  215. b0.WaitForMe();
  216. }
  217. else
  218. {
  219. Console.WriteLine("-------------------------");
  220. Console.WriteLine("Playing b1, filling b0");
  221. b1.Play();
  222. m_FillProc(b0.Data, b0.Size);
  223.  
  224. form.paintEqualizer(b1);
  225. Console.WriteLine("callng waitFor on b1");
  226. b1.WaitForMe();
  227.  
  228. }
  229. s = !s;
  230. }
  231. }
  232.  
  233. private void AllocateBuffers(int bufferSize, int bufferCount, WaveFormat format)
  234. {
  235. FreeBuffers();
  236. m_bufferlist = new WaveOutBuffer[m_buffercount];
  237. if (bufferCount > 0)
  238. {
  239. for (int i = 0; i < m_buffercount; i++)
  240. {
  241. m_bufferlist[i] = new WaveOutBuffer(m_WaveOut, bufferSize, format);
  242. m_bufferlist[i].ID = i;
  243. }
  244. }
  245. }
  246.  
  247. private void FreeBuffers()
  248. {
  249. if (m_bufferlist != null)
  250. {
  251. foreach (WaveOutBuffer currentBuffer in m_bufferlist)
  252. {
  253. if (currentBuffer != null)
  254. {
  255. currentBuffer.Dispose();
  256. }
  257. }
  258. }
  259. }
  260. }
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement