166 lines
4.5 KiB
C#
166 lines
4.5 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
// TODO : check if "MIDI ..."
|
|
return true;
|
|
}
|
|
|
|
void IEventProvider.Unbind (string eventId)
|
|
{
|
|
|
|
return;
|
|
}
|
|
|
|
Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler)
|
|
{
|
|
Gtk.Menu retmenu = new Gtk.Menu ();
|
|
if (levent != null) {
|
|
Gtk.MenuItem lmenuitem = new Gtk.MenuItem ("Dernier");
|
|
retmenu.Add (lmenuitem);
|
|
Gtk.Menu lmenu = new Gtk.Menu ();
|
|
lmenuitem.Submenu = lmenu;
|
|
Gtk.MenuItem item = new Gtk.MenuItem(levent.description);
|
|
item.Data[EventManager.EventIdKey] = levent.internalName;
|
|
item.Data[EventManager.StateKey] = state;
|
|
item.ButtonPressEvent += handler;
|
|
lmenu.Add (item);
|
|
}
|
|
Gtk.MenuItem evmenuitem = new Gtk.MenuItem ("Events");
|
|
retmenu.Add (evmenuitem);
|
|
Gtk.Menu evmenu = new Gtk.Menu ();
|
|
evmenuitem.Submenu = evmenu;
|
|
|
|
List<string> sortedKeys = eventlist.Keys.ToList();
|
|
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;
|
|
|
|
}
|
|
|
|
EventData last; internalEvent levent=null;
|
|
|
|
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;
|
|
case snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK:
|
|
case snd_seq_event_type_t.SND_SEQ_EVENT_SENSING:
|
|
continue;
|
|
|
|
//TODO : Regarder si d'autres controles interessants.
|
|
default:
|
|
id= null;
|
|
Info.Publish(string.Format ("event {0}", evS.type) );
|
|
continue;
|
|
}
|
|
|
|
if(id!=null)
|
|
{
|
|
if(!eventlist.ContainsKey(id))
|
|
eventlist.Add(id,new internalEvent(id,description));
|
|
levent= eventlist[id];
|
|
EventData evData = new EventData();
|
|
evData.id = id;
|
|
evData.value = (byte)value;
|
|
if(evData.Equals(last)) continue;
|
|
callback(evData);
|
|
last = evData;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
string IEventProvider.MenuName {
|
|
get {
|
|
return "Midi";
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|