Advertisement
Guest User

A sound player for .NET 2.0

a guest
Apr 26th, 2010
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.34 KB | None | 0 0
  1. // A sound player for .NET 2.0 (requires a C# 3.0 compiler)
  2. // Written by Allon Guralnek. No Rights Reserved. You may use this code anyway you like,
  3. // even without attribution.
  4.  
  5. // Combined: QueuedSamplesPlayer.cs + MessageNotifier.cs + EventArgs.cs
  6.  
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Windows.Forms;
  12.  
  13. class QueuedSamplesPlayer<T> : IDisposable where T : struct
  14. {
  15.     private Queue<T> SampleQueue { get; set; }
  16.     private List<T> LoadedSamples { get; set; }
  17.     public bool IsPlaying { get; private set; }
  18.     public MessageNotifier Notifier { get; private set; }
  19.  
  20.     public event EventHandler QueueEmpty;
  21.  
  22.     public QueuedSamplesPlayer()
  23.     {
  24.         SampleQueue = new Queue<T>();
  25.         LoadedSamples = new List<T>();
  26.         Notifier = new MessageNotifier(0x3B9);
  27.         Notifier.MessageRecieved += Notifier_MessageRecieved;
  28.     }
  29.  
  30.     public void AddSample(T key, string file)
  31.     {
  32.         SendCommand("open \"" + file + "\" type mpegvideo alias Sample" + key + " wait", false);
  33.         SendCommand("set Sample" + key + " time format milliseconds wait", false);
  34.         SendCommand("seek Sample" + key + " to 50 wait", false);
  35.         LoadedSamples.Add(key);
  36.     }
  37.  
  38.     public void Play(params T[] keys)
  39.     {
  40.         IsPlaying = true;
  41.  
  42.         foreach (T key in keys)
  43.         {
  44.             SendCommand("play Sample" + key + " wait", false);
  45.             SendCommand("seek Sample" + key + " to 50", false);
  46.         }
  47.  
  48.         IsPlaying = false;
  49.     }
  50.     public void PlayAsync(params T[] keys)
  51.     {
  52.         foreach (T key in keys)
  53.             SampleQueue.Enqueue(key);
  54.  
  55.         if (!IsPlaying)
  56.             PlayNext();
  57.     }
  58.     public void Stop()
  59.     {
  60.         SampleQueue.Clear();
  61.     }
  62.     private void PlayNext()
  63.     {
  64.         if (SampleQueue.Count > 0)
  65.         {
  66.             IsPlaying = true;
  67.             T key = SampleQueue.Dequeue();
  68.             SendCommand("seek Sample" + key + " to 50 wait", false);
  69.             SendCommand("play Sample" + key + " notify", true);
  70.         }
  71.         else
  72.         {
  73.             IsPlaying = false;
  74.             OnQueueEmpty();
  75.         }
  76.     }
  77.     private void Notifier_MessageRecieved(object sender, EventArgs<Message> e)
  78.     {
  79.         PlayNext();
  80.     }
  81.  
  82.     private void SendCommand(string command, bool notify)
  83.     {
  84.         int retVal;
  85.         if ((retVal = NativeMethods.mciSendString(command, null, 0, notify ? Notifier.Handle : IntPtr.Zero)) != 0)
  86.         {
  87.             var errorMessage = new StringBuilder(200);
  88.             NativeMethods.mciGetErrorString(retVal, errorMessage, errorMessage.Capacity);
  89.             throw new Exception("MCI Error " + retVal + ": " + errorMessage);
  90.         }
  91.     }
  92.     private void OnQueueEmpty()
  93.     {
  94.         if (QueueEmpty != null)
  95.             QueueEmpty(this, EventArgs.Empty);
  96.     }
  97.  
  98.     public void Dispose()
  99.     {
  100.         if (Notifier != null)
  101.             Notifier.Dispose();
  102.  
  103.         if (LoadedSamples != null)
  104.         {
  105.             foreach (var sample in LoadedSamples)
  106.             {
  107.                 SendCommand("stop Sample" + sample + " wait", false);
  108.                 SendCommand("close Sample" + sample + " wait", false);
  109.             }
  110.         }
  111.     }
  112. }
  113.  
  114. internal static class NativeMethods
  115. {
  116.     [DllImport("winmm.dll")]
  117.     public static extern int mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback);
  118.     [DllImport("winmm.dll")]
  119.     public static extern int mciGetErrorString(int errorCode, StringBuilder errorText, int errorTextSize);
  120. }
  121.  
  122.  
  123.  
  124. public class MessageNotifier : IDisposable
  125. {
  126.     public int Message { get; private set; }
  127.     public IntPtr Handle
  128.     {
  129.         get
  130.         {
  131.             return MessageNotifyingForm.Instance.Handle;
  132.         }
  133.     }
  134.  
  135.     public event EventHandler<EventArgs<Message>> MessageRecieved;
  136.  
  137.     public MessageNotifier(int message)
  138.     {
  139.         Message = message;
  140.         MessageNotifyingForm.Instance.RegisterMessageNotifiction(Message, MessageNotifingForm_MessageRecieved);
  141.     }
  142.  
  143.     private void MessageNotifingForm_MessageRecieved(object sender, EventArgs<Message> e)
  144.     {
  145.         if (MessageRecieved != null)
  146.             MessageRecieved(this, e);
  147.     }
  148.  
  149.     public void Dispose()
  150.     {
  151.         MessageNotifyingForm.Instance.UnregisterMessageNotifiction(Message, MessageNotifingForm_MessageRecieved);
  152.     }
  153.  
  154.  
  155.     private class MessageNotifyingForm : Form
  156.     {
  157.         private Dictionary<int, List<EventHandler<EventArgs<Message>>>> Listeners { get; set; }
  158.  
  159.         public static MessageNotifyingForm Instance
  160.         {
  161.             get
  162.             {
  163.                 return g_Instance ?? (g_Instance = new MessageNotifyingForm());
  164.             }
  165.             private set
  166.             {
  167.                 g_Instance = value;
  168.             }
  169.         }
  170.  
  171.         private MessageNotifyingForm()
  172.         {
  173.             Listeners = new Dictionary<int, List<EventHandler<EventArgs<Message>>>>();
  174.         }
  175.         public void RegisterMessageNotifiction(int message, EventHandler<EventArgs<Message>> eventHandler)
  176.         {
  177.             if (!Listeners.ContainsKey(message))
  178.                 Listeners[message] = new List<EventHandler<EventArgs<Message>>>();
  179.  
  180.             Listeners[message].Add(eventHandler);
  181.         }
  182.         public void UnregisterMessageNotifiction(int message, EventHandler<EventArgs<Message>> eventHandler)
  183.         {
  184.             var listenerList = Listeners[message];
  185.             listenerList.Remove(eventHandler);
  186.             if (listenerList.Count == 0)
  187.                 Listeners.Remove(message);
  188.  
  189.             if (listenerList.Count == 0)
  190.             {
  191.                 g_Instance = null;
  192.                 Dispose();
  193.             }
  194.         }
  195.         protected override void WndProc(ref Message m)
  196.         {
  197.             base.WndProc(ref m);
  198.  
  199.             if (Listeners.ContainsKey(m.Msg))
  200.             {
  201.                 foreach (var listener in Listeners[m.Msg])
  202.                 {
  203.                     listener(this, new EventArgs<Message>(m));
  204.                 }
  205.             }
  206.         }
  207.  
  208.         private static MessageNotifyingForm g_Instance;
  209.     }
  210. }
  211.  
  212. public class EventArgs<T> : EventArgs
  213. {
  214.     public T EventData { get; set; }
  215.  
  216.     public EventArgs(T eventData)
  217.     {
  218.         EventData = eventData;
  219.     }
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement