Skip to content

Instantly share code, notes, and snippets.

@atsushieno
Created September 6, 2009 18:26
Show Gist options
  • Save atsushieno/181910 to your computer and use it in GitHub Desktop.
Save atsushieno/181910 to your computer and use it in GitHub Desktop.
diff --git a/samples/WebMidiPlayer.cs b/samples/WebMidiPlayer.cs
index 2eb8b7c..b7b61c7 100644
--- a/samples/WebMidiPlayer.cs
+++ b/samples/WebMidiPlayer.cs
@@ -1,30 +1,45 @@
using System;
using System.ServiceModel;
+using System.Threading;
namespace Commons.Music.Midi.Player
{
public class WebMidiPlayer : MidiPlayer
{
IMidiDeviceClient client;
+ AutoResetEvent wait = new AutoResetEvent (false);
+ int began = 0, done = 0;
+ object lockobj = new object ();
+
public WebMidiPlayer (Uri uri, SmfMusic music)
: base (music)
{
- client = ChannelFactory<IMidiDeviceClient>.CreateChannel (new BasicHttpBinding (), new EndpointAddress (uri));
+ client = new ChannelFactory<IMidiDeviceClient> (new BasicHttpBinding (), new EndpointAddress (uri)).CreateChannel ();
client.Open ();
MessageReceived += delegate (SmfMessage msg) {
- switch (msg.StatusByte) {
- case 0xF0:
- case 0xF7:
- client.ProcessSysExMessage (msg.Data);
- break;
- case 0xFF:
- // do nothing
- break;
- default:
- client.ProcessMessage (msg.Value);
- break;
+ lock (lockobj) {
+Console.Write ("[{0} / {1}]", began, done);
+#if ASYNC
+ while (began > done)
+ wait.WaitOne (); // skip wait on the first one
+#endif
+ began++;
+ if (msg.Data != null) {
+ if (msg.StatusByte != 0xFF)
+#if ASYNC
+ client.BeginProcessSysExMessage (msg.Data, delegate (IAsyncResult result) { try { client.EndProcessSysExMessage (result); done++; wait.Set (); } catch (Exception ex) { Console.WriteLine (ex); } }, null);
+#else
+ client.ProcessSysExMessage (msg.Data);
+#endif
}
+ else
+#if ASYNC
+ client.BeginProcessMessage (msg.Value, delegate (IAsyncResult result) { try { client.EndProcessMessage (result); done++; wait.Set (); } catch (Exception ex) { Console.WriteLine (ex); } }, null);
+#else
+ client.ProcessMessage (msg.Value);
+#endif
+ }
};
}
}
diff --git a/samples/WebMidiPlayerService.cs b/samples/WebMidiPlayerService.cs
index dc2c9f2..9df0c62 100644
--- a/samples/WebMidiPlayerService.cs
+++ b/samples/WebMidiPlayerService.cs
@@ -1,7 +1,10 @@
// gmcs WebMidiPlayerService.cs SMF.cs MidiPlayer.cs MidiMachine.cs ../PortMidiSharp.cs -pkg:wcf
using System;
+using System.Collections.Generic;
using System.ServiceModel;
+using System.ServiceModel.Description;
+using System.Threading;
using PortMidiSharp;
namespace Commons.Music.Midi.Player
@@ -24,6 +27,8 @@ namespace Commons.Music.Midi.Player
MidiDeviceManager.OpenOutput (MidiDeviceManager.DefaultOutputDeviceID), true));
host.AddServiceEndpoint (typeof (IMidiDeviceContract), new BasicHttpBinding (),
"http://localhost:9090");
+ host.Description.Behaviors.Find<ServiceBehaviorAttribute> ()
+ .IncludeExceptionDetailInFaults = true;
host.Open ();
Console.WriteLine ("type [CR] to stop...");
Console.ReadLine ();
@@ -35,26 +40,41 @@ namespace Commons.Music.Midi.Player
public class MidiDeviceService : IMidiDeviceContract, IDisposable
{
MidiOutput output;
- bool dispose_device;
+ bool dispose_device, loop = true;
+ Queue<SmfMessage> queue = new Queue<SmfMessage> ();
public MidiDeviceService (MidiOutput output, bool disposeDevice)
{
this.output = output;
dispose_device = disposeDevice;
+ new Action (Loop).BeginInvoke (null, null);
+ }
+
+ void Loop ()
+ {
+ while (loop) {
+Thread.Sleep (10);
+ if (queue.Count > 0) {
+ var m = queue.Dequeue ();
+ if (m.StatusByte >= 0xF0)
+ WriteSysEx (0xF0, m.Data);
+ else
+ output.Write (0, new MidiMessage (m.Value));
+ }
+ }
}
public void ProcessMessage (int msg)
{
var m = new SmfMessage (msg);
- output.Write (0, new MidiMessage (m.StatusByte, m.Msb, m.Lsb));
+ queue.Enqueue (m);
}
public void ProcessSysExMessage (byte [] data)
{
- WriteSysEx (0xF0, data);
+ queue.Enqueue (new SmfMessage (0xF0, 0, 0, data));
}
-
void WriteSysEx (byte status, byte [] sysex)
{
var buf = new byte [sysex.Length + 1];
@@ -65,6 +85,7 @@ namespace Commons.Music.Midi.Player
public void Dispose ()
{
+ loop = false;
if (dispose_device)
output.Close ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment