loupiottes/DMX-2.0/MidiEventProvider.cs

165 lines
4.2 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace DMX2
{
public partial class MidiEventProvider : IEventProvider, IDisposable
{
class internalEvent {
public string internalName;
public string description;
public internalEvent(string _id, string _desc)
{
internalName=_id;
description=_desc;
}
bool hasTargets;
public bool HasTargets {
get {
return hasTargets;
}
set {
hasTargets = value;
}
}
}
Dictionary<string,internalEvent> eventlist = new Dictionary<string, internalEvent>();
IntPtr midi_seq_handle = IntPtr.Zero;
public MidiEventProvider (EventManager manager)
{
snd_seq_open(out midi_seq_handle, "default",SND_SEQ_OPEN_DUPLEX,0);
snd_seq_set_client_name(midi_seq_handle,"DMX2");
snd_seq_create_simple_port(midi_seq_handle,"dmx_ctrl",
SND_SEQ_PORT_CAP_WRITE + SND_SEQ_PORT_CAP_SUBS_WRITE,
SND_SEQ_PORT_TYPE_APPLICATION);
manager.RegisterProvider(this);
}
#region IDisposable implementation
public void Dispose ()
{
snd_seq_close(midi_seq_handle);
}
#endregion
#region IEventProvider implementation
ICollection<string> IEventProvider.GetEventList ()
{
return eventlist.Keys;
}
bool IEventProvider.Bind (string eventId)
{
if (!eventlist.ContainsKey (eventId)) {
return false;
}
//TODO
eventlist[eventId].HasTargets = true;
return true;
}
void IEventProvider.Unbind (string eventId)
{
if (!eventlist.ContainsKey (eventId)) return;
eventlist[eventId].HasTargets =false;
return;
}
Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler)
{
Gtk.Menu retmenu = new Gtk.Menu ();
//Gtk.MenuItem evmenuitem = new Gtk.MenuItem ("Events");
//retmenu.Add (evmenuitem);
Gtk.Menu evmenu = retmenu ;// new Gtk.Menu ();
//evmenuitem.Submenu = evmenu;
List<string> sortedKeys = new List<string>(eventlist.Keys);
sortedKeys.Sort();
foreach ( string key in sortedKeys ) {
internalEvent evt= eventlist[key];
Gtk.MenuItem item = new Gtk.MenuItem(evt.description);
item.Data[EventManager.EventIdKey] = evt.internalName;
item.Data[EventManager.StateKey] = state;
item.ButtonPressEvent += handler;
evmenu.Add (item);
}
return retmenu;
}
void IEventProvider.ProcessEvents (EventManagerCallback callback)
{
IntPtr evPtr;
while ((snd_seq_event_input_pending(midi_seq_handle,1))>0) {
snd_seq_event_input(midi_seq_handle, out evPtr);
snd_seq_event_t evS =(snd_seq_event_t) Marshal.PtrToStructure(evPtr,typeof(snd_seq_event_t));
snd_seq_free_event(evPtr);
string id=null, description=null; int value=0;
switch (evS.type) {
case snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER:
id= string.Format("MIDI-CTRL-C{0}P{1}",evS.data_ev_ctrl.channel,evS.data_ev_ctrl.param);
description = string.Format("Controller Ch {0} Param {1}",evS.data_ev_ctrl.channel,evS.data_ev_ctrl.param);
value = 255 * evS.data_ev_ctrl.value / 127;
break;
case snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON:
id= string.Format("MIDI-NOTE-C{0}N{1}",evS.data_ev_note.channel, evS.data_ev_note.note );
description = string.Format("Note {1} Ch {0}",evS.data_ev_note.channel, evS.data_ev_note.note );
value = 255 ;
break;
case snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF:
id= string.Format("MIDI-NOTE-C{0}N{1}",evS.data_ev_note.channel, evS.data_ev_note.note );
description = string.Format("Note {1} Ch {0}",evS.data_ev_note.channel, evS.data_ev_note.note );
value = 0;
break;
//TODO : Regarder si d'autres controles interessants.
default:
id= null;
Info.Publish(string.Format ("event {0}", evS.type) );
break;
}
if(id!=null)
{
if(!eventlist.ContainsKey(id))
eventlist.Add(id,new internalEvent(id,description));
else{
if(eventlist[id].HasTargets)
{
EventData evData = new EventData();
evData.id = id;
evData.value = (byte)value;
callback(evData);
}
}
}
}
}
string IEventProvider.MenuName {
get {
return "Midi";
}
}
#endregion
}
}