From 4075ca7f3427f6b16cbf3d2d702546f0f2623c23 Mon Sep 17 00:00:00 2001 From: tzim Date: Sat, 6 Oct 2018 23:35:45 +0200 Subject: [PATCH] =?UTF-8?q?Restauration=20de=20la=20d=C3=A9tection=20des?= =?UTF-8?q?=20perifs=20physiques?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DMX-2.0/AlsaSeqLib.MidiPort.cs | 6 +- DMX-2.0/AlsaSeqLib.cs | 13 +- DMX-2.0/MidiEventProvider.cs | 779 +++++++++++++++++++-------------- 3 files changed, 450 insertions(+), 348 deletions(-) diff --git a/DMX-2.0/AlsaSeqLib.MidiPort.cs b/DMX-2.0/AlsaSeqLib.MidiPort.cs index db700d1..4a7c656 100644 --- a/DMX-2.0/AlsaSeqLib.MidiPort.cs +++ b/DMX-2.0/AlsaSeqLib.MidiPort.cs @@ -70,12 +70,12 @@ namespace DMX2 return Invoke.snd_seq_connect_to (seq_handle.Handle, portid, p.ClientId, p.PortId) == 0; } - internal bool ConnectTo(int client, int port){ + /*internal bool ConnectTo(int client, int port){ if (seq_handle == null) throw new InvalidOperationException (); return Invoke.snd_seq_connect_to (seq_handle.Handle, portid, client, port) == 0; - } - + }*/ + public bool ConnectFrom(Port p){ if (seq_handle == null) throw new InvalidOperationException (); diff --git a/DMX-2.0/AlsaSeqLib.cs b/DMX-2.0/AlsaSeqLib.cs index 1c096d0..93fd5de 100644 --- a/DMX-2.0/AlsaSeqLib.cs +++ b/DMX-2.0/AlsaSeqLib.cs @@ -13,7 +13,7 @@ namespace DMX2 //static int outport; static System.Threading.Thread eventthread = null; - static MidiPort systemPort = null; + //static MidiPort systemPort = null; static internal Dictionary openports = new Dictionary(); @@ -129,6 +129,7 @@ namespace DMX2 clientId = _clientId; portId = _portId; srcid = clientId << 8 + portId; + ports.Add(srcid, this); } private void Updateinfo (PointerWrapper portInfo) @@ -177,8 +178,8 @@ namespace DMX2 System.Threading.ThreadStart ts = new System.Threading.ThreadStart (EventLoop); eventthread = new System.Threading.Thread (ts); eventthread.Start(); - systemPort = new MidiPort ("system"); - systemPort.ConnectTo (SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); + //systemPort = new MidiPort ("system"); + //systemPort.ConnectTo (SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); } public static void Close () @@ -201,16 +202,16 @@ namespace DMX2 // liberation du pointeur Invoke.snd_seq_free_event (evPtr); - if (ev.dest.port == systemPort.portid) { + /*if (ev.dest.port == systemPort.portid) { if (ev.type == AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_START) { } - } else { + } else {*/ // queue if (openports.ContainsKey (ev.dest.port)) { openports [ev.dest.port].eventqueue.Enqueue (ev); } - } + //} } System.Threading.Thread.Sleep (1); } diff --git a/DMX-2.0/MidiEventProvider.cs b/DMX-2.0/MidiEventProvider.cs index 5c83a39..b17b684 100644 --- a/DMX-2.0/MidiEventProvider.cs +++ b/DMX-2.0/MidiEventProvider.cs @@ -28,27 +28,27 @@ namespace DMX2 /// /// Etat interne des evenements midi paginés. /// - readonly Dictionary eventlist = new Dictionary (); + readonly Dictionary eventlist = new Dictionary(); /// /// Liste des peripheriques connus (presents ou non) /// - readonly Dictionary knowndevices = new Dictionary (); + readonly Dictionary knowndevices = new Dictionary(); /// /// Liste des ports connectés avec feedback /// - readonly List feedbacksources = new List (); + readonly List feedbacksources = new List(); //static readonly Dictionary srcidToDev = new Dictionary(); - readonly List unpaginatedchannels = new List (); + readonly List unpaginatedchannels = new List(); /// /// Derniere valeur connue pour une evenement sur source donnée : /// Soit recue, soit envoyée (feedback / changement de page) /// - readonly Dictionary lastValueOfSrc = new Dictionary (); - // EventData last; + readonly Dictionary lastValueOfSrc = new Dictionary(); + // EventData last; internalEventDesc levent = null; bool guirefreshflag = false; uint page = 1; @@ -62,68 +62,91 @@ namespace DMX2 AlsaSeqLib.MidiPort midiport; - public uint CurrentPage { - get { + public uint CurrentPage + { + get + { return page; } - set { + set + { if (value < 1 || value > maxpage) return; page = value; - Refresh (); + Refresh(); } } - public uint PageUpCC { - get { + public uint PageUpCC + { + get + { return pageUpCC; } - set { + set + { pageUpCC = value; } } - public uint PageDownCC { - get { + public uint PageDownCC + { + get + { return pageDownCC; } - set { + set + { pageDownCC = value; } } - public uint Maxpage { - get { + public uint Maxpage + { + get + { return maxpage; } - set { + set + { maxpage = value; } } - public List UnpaginatedChannels { - get { + public List UnpaginatedChannels + { + get + { return unpaginatedchannels; } } - public bool Use14bCC { - get { + public bool Use14bCC + { + get + { return use14b; } - set { + set + { use14b = value; } } - public int Max14bValue { - get { + public int Max14bValue + { + get + { return max14bValue; } - set { + set + { max14bValue = value; } } - public bool GuiRefreshFlag { - get { - if (guirefreshflag) { + public bool GuiRefreshFlag + { + get + { + if (guirefreshflag) + { guirefreshflag = false; return true; } @@ -131,75 +154,87 @@ namespace DMX2 } } - public void ConnectDevice (string name) + public void ConnectDevice(string name) { - knowndevices.Add (name, new MidiControler (name)); - AutoConnect (); + knowndevices.Add(name, new MidiControler(name)); + AutoConnect(); } - public void RefreshFeedback (string name) + public void RefreshFeedback(string name) { - foreach (AlsaSeqLib.Port port in knowndevices[name].ConnectedPorts) { - if (knowndevices [name].HasFeedback) { - if (!feedbacksources.Contains (port)) - feedbacksources.Add (port); - } else { - if (feedbacksources.Contains (port)) - feedbacksources.Remove (port); + foreach (AlsaSeqLib.Port port in knowndevices[name].ConnectedPorts) + { + if (knowndevices[name].HasFeedback) + { + if (!feedbacksources.Contains(port)) + feedbacksources.Add(port); + } + else + { + if (feedbacksources.Contains(port)) + feedbacksources.Remove(port); } } } - public void DisconnectDevice (MidiEventProvider.MidiControler dev) + public void DisconnectDevice(MidiEventProvider.MidiControler dev) { - if (!knowndevices.ContainsKey (dev.Name)) + if (!knowndevices.ContainsKey(dev.Name)) return; - knowndevices.Remove (dev.Name); + knowndevices.Remove(dev.Name); - foreach (AlsaSeqLib.Port connectedport in dev.ConnectedPorts) { - midiport.Deconnecte ( connectedport); + foreach (AlsaSeqLib.Port connectedport in dev.ConnectedPorts) + { + midiport.Deconnecte(connectedport); } } - public bool IsKnownDevice (string name) + public bool IsKnownDevice(string name) { - return knowndevices.ContainsKey (name); + return knowndevices.ContainsKey(name); } - public IEnumerable KnownDevices { - get { + public IEnumerable KnownDevices + { + get + { return knowndevices.Values; } } - public MidiEventProvider (EventManager manager) + public MidiEventProvider(EventManager manager) { #if DEBUG MidiControler dev = new MidiControler("VMPK Input:VMPK Input"); dev.HasFeedback = true; - knowndevices.Add(dev.Name,dev); + knowndevices.Add(dev.Name, dev); dev = new MidiControler("VMPK Output:VMPK Output"); dev.HasFeedback = true; - knowndevices.Add(dev.Name,dev); + knowndevices.Add(dev.Name, dev); #endif - manager.RegisterProvider (this); + manager.RegisterProvider(this); //AlsaSeqLib.Init (); midiport = new AlsaSeqLib.MidiPort("event_prov_in_out"); - - AutoConnect (); + //midiport.ConnectFrom(AlsaSeqLib.SND_SEQ_CLIENT_SYSTEM, AlsaSeqLib.SND_SEQ_PORT_SYSTEM_ANNOUNCE); + AlsaSeqLib.Port systemport = AlsaSeqLib.GetPortByIDs(AlsaSeqLib.SND_SEQ_CLIENT_SYSTEM, AlsaSeqLib.SND_SEQ_PORT_SYSTEM_ANNOUNCE); + midiport.ConnectFrom(systemport); + + AutoConnect(); } - void AutoConnect () + void AutoConnect() { - foreach (var cli in AlsaSeqLib.EnumClients()) { - foreach (var p in cli.Ports) { - PortDetected (cli, p); + foreach (var cli in AlsaSeqLib.EnumClients()) + { + foreach (var p in cli.Ports) + { + PortDetected(cli, p); } } } - void PortDetected (AlsaSeqLib.Client cli, AlsaSeqLib.Port p) + void PortDetected(AlsaSeqLib.Client cli, AlsaSeqLib.Port p) { // Execute a chaque 'apparition' d'un port midi @@ -208,39 +243,44 @@ namespace DMX2 guirefreshflag = true; string fullportname = cli.Name + ':' + p.Name; - if (knowndevices.ContainsKey (fullportname)) { + if (knowndevices.ContainsKey(fullportname)) + { int srcid = p.ClientId << 8 + p.PortId; - if (knowndevices [fullportname].ConnectedPorts.Contains (p)) + if (knowndevices[fullportname].ConnectedPorts.Contains(p)) return; midiport.ConnectFrom(p); midiport.ConnectTo(p); } } - - void PortConnect (AlsaSeqLib.snd_seq_connect_t cn, bool connect) + + void PortConnect(AlsaSeqLib.snd_seq_connect_t cn, bool connect) { int clientId, portId; - if (cn.dest.client == AlsaSeqLib.ClientId) { + if (cn.dest.client == AlsaSeqLib.ClientId) + { clientId = cn.sender.client; portId = cn.sender.port; - } else { + } + else + { clientId = cn.dest.client; portId = cn.dest.port; } - AlsaSeqLib.Port p = AlsaSeqLib.GetPortByIDs(clientId, portId); + AlsaSeqLib.Port p = AlsaSeqLib.GetPortByIDs(clientId, portId); - if (connect) { + if (connect) + { AlsaSeqLib.Client c = AlsaSeqLib.GetClientByID(clientId); string fpname = c.Name + ":" + p.Name; - if (!knowndevices.ContainsKey (fpname)) + if (!knowndevices.ContainsKey(fpname)) return; - if (knowndevices [fpname].ConnectedPorts.Contains (p)) + if (knowndevices[fpname].ConnectedPorts.Contains(p)) return; - knowndevices [fpname].ConnectedPorts.Add (p); - if (knowndevices [fpname].HasFeedback) - feedbacksources.Add (p); + knowndevices[fpname].ConnectedPorts.Add(p); + if (knowndevices[fpname].HasFeedback) + feedbacksources.Add(p); guirefreshflag = true; //srcidToDev[srcid] = knowndevices [fpname]; @@ -248,9 +288,11 @@ namespace DMX2 return; } - foreach (var dev in knowndevices.Values) { - if (dev.ConnectedPorts.Contains (p)) { - dev.ConnectedPorts.Remove (p); + foreach (var dev in knowndevices.Values) + { + if (dev.ConnectedPorts.Contains(p)) + { + dev.ConnectedPorts.Remove(p); guirefreshflag = true; return; } @@ -258,32 +300,36 @@ namespace DMX2 } - static int CombineHash (int hash1, int hash2) + static int CombineHash(int hash1, int hash2) { - unchecked { + unchecked + { return hash1 * 33 + hash2; } } - protected bool HasFeedback (AlsaSeqLib.Port source) + protected bool HasFeedback(AlsaSeqLib.Port source) { - return feedbacksources.Contains (source); + return feedbacksources.Contains(source); } - public void SendEvent (AlsaSeqLib.snd_seq_event_t ev) + public void SendEvent(AlsaSeqLib.snd_seq_event_t ev) { - midiport.SendEvent (ev); + midiport.SendEvent(ev); } - - public void Refresh () + + public void Refresh() { - foreach (var ievent in eventlist.Values) { - if (ievent.Page == page) { + foreach (var ievent in eventlist.Values) + { + if (ievent.Page == page) + { ievent.SendFeedback(); - foreach (AlsaSeqLib.Port src in feedbacksources) { - int lnvk = CombineHash (src.SrcId, ievent.MidiEvCode); + foreach (AlsaSeqLib.Port src in feedbacksources) + { + int lnvk = CombineHash(src.SrcId, ievent.MidiEvCode); if (ievent.LastKnownValue != -1) - lastValueOfSrc [lnvk] = (byte)ievent.LastKnownValue; + lastValueOfSrc[lnvk] = (byte)ievent.LastKnownValue; } } } @@ -293,299 +339,327 @@ namespace DMX2 - bool IEventProvider.Bind (string eventId) + bool IEventProvider.Bind(string eventId) { // On indique a l'EventManager qu'on traite, si l'ID commence par 'MIDI-' - if (! eventId.StartsWith ("MIDI-")) + if (!eventId.StartsWith("MIDI-")) return false; - if (! eventlist.ContainsKey (eventId)) { - Match res = regexEventID.Match (eventId); + if (!eventlist.ContainsKey(eventId)) + { + Match res = regexEventID.Match(eventId); if (!res.Success) return false; - uint _page = uint.Parse (res.Groups ["page"].Value); - int _evHC = res.Groups ["id"].Value.GetHashCode (); + uint _page = uint.Parse(res.Groups["page"].Value); + int _evHC = res.Groups["id"].Value.GetHashCode(); midiFeedbackSender sender = null; - res = regexCtrlEventID.Match (eventId); - if (res.Success) { - byte chan = byte.Parse (res.Groups ["chan"].Value); - uint param = uint.Parse (res.Groups ["param"].Value); - sender = new midiCCFbSender (this, chan, param); - } else if ((res = regexPbEventID.Match (eventId)).Success){ - byte chan = byte.Parse (res.Groups ["chan"].Value); - sender = new midiPBFbSender (this, chan); + res = regexCtrlEventID.Match(eventId); + if (res.Success) + { + byte chan = byte.Parse(res.Groups["chan"].Value); + uint param = uint.Parse(res.Groups["param"].Value); + sender = new midiCCFbSender(this, chan, param); } - eventlist.Add (eventId, new internalEventDesc (eventId, _page, _evHC,sender)); + else if ((res = regexPbEventID.Match(eventId)).Success) + { + byte chan = byte.Parse(res.Groups["chan"].Value); + sender = new midiPBFbSender(this, chan); + } + eventlist.Add(eventId, new internalEventDesc(eventId, _page, _evHC, sender)); } - eventlist [eventId].Bound = true; + eventlist[eventId].Bound = true; return true; } - void IEventProvider.Unbind (string eventId) + void IEventProvider.Unbind(string eventId) { - if (! eventlist.ContainsKey (eventId)) + if (!eventlist.ContainsKey(eventId)) return; - eventlist [eventId].Bound = false; + eventlist[eventId].Bound = false; return; } - Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler) + Gtk.Menu IEventProvider.GetProviderSubMenu(EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler) { - Gtk.Menu retmenu = new Gtk.Menu (); + Gtk.Menu retmenu = new Gtk.Menu(); - if (levent != null) { // Creation du sous menu "Dernier" - /*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 (GetDescription (levent.InternalName)); - item.Data [EventManager.EventIdKey] = levent.InternalName; - item.Data [EventManager.StateKey] = state; + if (levent != null) + { // Creation du sous menu "Dernier" + /*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(GetDescription(levent.InternalName)); + item.Data[EventManager.EventIdKey] = levent.InternalName; + item.Data[EventManager.StateKey] = state; item.ButtonPressEvent += handler; - retmenu.Add (item); + retmenu.Add(item); } - Gtk.MenuItem evmenuitem = new Gtk.MenuItem ("Events"); // Creation du sous menu "Events" - retmenu.Add (evmenuitem); - Gtk.Menu evmenu = new Gtk.Menu (); + Gtk.MenuItem evmenuitem = new Gtk.MenuItem("Events"); // Creation du sous menu "Events" + retmenu.Add(evmenuitem); + Gtk.Menu evmenu = new Gtk.Menu(); evmenuitem.Submenu = evmenu; - List sortedKeys = eventlist.Keys.ToList (); // On recupere des IDs - sortedKeys.Sort (); // et on les trie + List sortedKeys = eventlist.Keys.ToList(); // On recupere des IDs + sortedKeys.Sort(); // et on les trie - foreach (string key in sortedKeys) { - internalEventDesc evt = eventlist [key]; - Gtk.MenuItem item = new Gtk.MenuItem (GetDescription (evt.InternalName)); - item.Data [EventManager.EventIdKey] = evt.InternalName; - item.Data [EventManager.StateKey] = state; + foreach (string key in sortedKeys) + { + internalEventDesc evt = eventlist[key]; + Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(evt.InternalName)); + item.Data[EventManager.EventIdKey] = evt.InternalName; + item.Data[EventManager.StateKey] = state; item.ButtonPressEvent += handler; - evmenu.Add (item); + evmenu.Add(item); } return retmenu; } - void IEventProvider.ProcessEvents (EventManagerCallback callback) + void IEventProvider.ProcessEvents(EventManagerCallback callback) { AlsaSeqLib.snd_seq_event_t evS; uint evpage; // Tant qu'il y des evenements midi en attente - while (midiport.GetEvent(out evS)) { - Console.WriteLine(string.Format ("event {0}", evS.type) ); - string id = null; + while (midiport.GetEvent(out evS)) + { + Console.WriteLine(string.Format("event {0}", evS.type)); + string id = null; int value = 0; byte channel = 255; - switch (evS.type) { - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED: // Connection d'un périph midi - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_UNSUBSCRIBED: - PortConnect ( - evS.data_connect, - evS.type == AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED - ); - continue; - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: - if (evS.data_ev_ctrl.param == pageUpCC && evS.data_ev_ctrl.value > 0) { - CurrentPage++; + switch (evS.type) + { + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED: // Connection d'un périph midi + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_UNSUBSCRIBED: + PortConnect( + evS.data_connect, + evS.type == AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED + ); continue; - } - - if (evS.data_ev_ctrl.param == pageDownCC && evS.data_ev_ctrl.value > 0) { - CurrentPage--; - continue; - } - - channel = evS.data_ev_ctrl.channel; - - if (use14b && evS.data_ev_ctrl.param < 64) { - long msbAddr; - if (evS.data_ev_ctrl.param < 32) { - msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param; - fbTmpData [msbAddr] = (byte)evS.data_ev_ctrl.value; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: + if (evS.data_ev_ctrl.param == pageUpCC && evS.data_ev_ctrl.value > 0) + { + CurrentPage++; continue; } - evS.data_ev_ctrl.param -= 32; - msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param; - value = ((fbTmpData [msbAddr] << 7) ^ evS.data_ev_ctrl.value); - value = 255 * value / max14bValue; - if (value > 255) value = 255; - } else { - value = 255 * evS.data_ev_ctrl.value / 127; // Conversion {0,127} => {0,255} - } - id = string.Format ("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param); - break; - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON: - id = string.Format ("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note); - channel = evS.data_ev_note.channel; - value = 255; - break; - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF: - id = string.Format ("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note); - channel = evS.data_ev_note.channel; - value = 0; - break; - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND: - id = string.Format ("PB-C{0}", evS.data_ev_ctrl.channel); - channel = evS.data_ev_ctrl.channel; - value = ((evS.data_ev_ctrl.value + 7000) * 255 / 14000); - if (value < 0) - value = 0; - if (value > 255) + + if (evS.data_ev_ctrl.param == pageDownCC && evS.data_ev_ctrl.value > 0) + { + CurrentPage--; + continue; + } + + channel = evS.data_ev_ctrl.channel; + + if (use14b && evS.data_ev_ctrl.param < 64) + { + long msbAddr; + if (evS.data_ev_ctrl.param < 32) + { + msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param; + fbTmpData[msbAddr] = (byte)evS.data_ev_ctrl.value; + continue; + } + evS.data_ev_ctrl.param -= 32; + msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param; + value = ((fbTmpData[msbAddr] << 7) ^ evS.data_ev_ctrl.value); + value = 255 * value / max14bValue; + if (value > 255) value = 255; + } + else + { + value = 255 * evS.data_ev_ctrl.value / 127; // Conversion {0,127} => {0,255} + } + id = string.Format("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param); + break; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON: + id = string.Format("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note); + channel = evS.data_ev_note.channel; value = 255; - break; - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PGMCHANGE: - CurrentPage = (uint)evS.data_ev_ctrl.value; - continue; + break; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF: + id = string.Format("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note); + channel = evS.data_ev_note.channel; + value = 0; + break; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND: + id = string.Format("PB-C{0}", evS.data_ev_ctrl.channel); + channel = evS.data_ev_ctrl.channel; + value = ((evS.data_ev_ctrl.value + 7000) * 255 / 14000); + if (value < 0) + value = 0; + if (value > 255) + value = 255; + break; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PGMCHANGE: + CurrentPage = (uint)evS.data_ev_ctrl.value; + continue; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_START: + PortDetected( + AlsaSeqLib.GetClientByID(evS.data_addr.client), + AlsaSeqLib.GetPortByIDs(evS.data_addr.client,evS.data_addr.port) + ); + continue; + /*case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK: + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING: + continue;*/ - - /*case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK: - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING: - continue;*/ - - default: - id = null; + default: + id = null; #if DEBUG - Console.WriteLine(string.Format ("event {0}", evS.type) ); - Info.Publish(string.Format ("event {0}", evS.type) ); // On affiche les evenements inconnus + Console.WriteLine(string.Format("event {0}", evS.type)); + Info.Publish(string.Format("event {0}", evS.type)); // On affiche les evenements inconnus #endif - continue; + continue; } - if (id != null) { + if (id != null) + { // Hashcode de l'ev Midi, non pagine - int evHC = id.GetHashCode (); + int evHC = id.GetHashCode(); int srcid = evS.source.client << 8 + evS.source.port; - int lnvk = CombineHash (srcid, evHC); + int lnvk = CombineHash(srcid, evHC); - if (channel == 255 || unpaginatedchannels.Contains (channel)) + if (channel == 255 || unpaginatedchannels.Contains(channel)) evpage = 0; else evpage = page; // Construction de l'ID evenement - id = string.Format ("MIDI-PAGE{0}-{1}", evpage, id); - + id = string.Format("MIDI-PAGE{0}-{1}", evpage, id); + // Creation de l'objet interne si innexistant - if (!eventlist.ContainsKey (id)) { - switch (evS.type) { + if (!eventlist.ContainsKey(id)) + { + switch (evS.type) + { // TODO : Pitchbend feedback - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: - eventlist.Add (id, new internalEventDesc (id, evpage, evHC, - new midiCCFbSender(this,channel,evS.data_ev_ctrl.param)) - ); - break; - case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND: - eventlist.Add (id, new internalEventDesc (id, evpage, evHC, - new midiPBFbSender(this,channel)) - ); - break; - default: - eventlist.Add (id, new internalEventDesc (id, evpage, evHC, null)); - break; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: + eventlist.Add(id, new internalEventDesc(id, evpage, evHC, + new midiCCFbSender(this, channel, evS.data_ev_ctrl.param)) + ); + break; + case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND: + eventlist.Add(id, new internalEventDesc(id, evpage, evHC, + new midiPBFbSender(this, channel)) + ); + break; + default: + eventlist.Add(id, new internalEventDesc(id, evpage, evHC, null)); + break; } } - levent = eventlist [id]; //Dernier Evenement recu conserve pour menu + levent = eventlist[id]; //Dernier Evenement recu conserve pour menu - if (!lastValueOfSrc.ContainsKey (lnvk)) { - lastValueOfSrc [lnvk] = (byte)value; - } else if (lastValueOfSrc [lnvk] == (byte)value) + if (!lastValueOfSrc.ContainsKey(lnvk)) + { + lastValueOfSrc[lnvk] = (byte)value; + } + else if (lastValueOfSrc[lnvk] == (byte)value) continue; - EventData evData = new EventData (); + EventData evData = new EventData(); evData.id = id; evData.value = (byte)value; - evData.prev_value = lastValueOfSrc [lnvk]; + evData.prev_value = lastValueOfSrc[lnvk]; /*if (evData.Equals (last)) - continue; */ + continue; */ //last = evData; - eventlist [id].CallEvent (callback, evData); + eventlist[id].CallEvent(callback, evData); /*if (eventlist [id].Bound) { callback (evData); }*/ - lastValueOfSrc [lnvk] = (byte)value; - eventlist [id].LastKnownValue = (byte)value; + lastValueOfSrc[lnvk] = (byte)value; + eventlist[id].LastKnownValue = (byte)value; } } } - string IEventProvider.MenuName { - get { + string IEventProvider.MenuName + { + get + { return "Midi"; } } - static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex ( + static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex( @"MIDI-PAGE(?\d+)-(?.+)", System.Text.RegularExpressions.RegexOptions.Compiled); - static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex ( + static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex( @"MIDI-PAGE(?\d+)-CTRL-C(?\d+)P(?\d+)", System.Text.RegularExpressions.RegexOptions.Compiled); - static System.Text.RegularExpressions.Regex regexPbEventID = new System.Text.RegularExpressions.Regex ( + static System.Text.RegularExpressions.Regex regexPbEventID = new System.Text.RegularExpressions.Regex( @"MIDI-PAGE(?\d+)-PB-C(?\d+)", System.Text.RegularExpressions.RegexOptions.Compiled); - static System.Text.RegularExpressions.Regex regexNoteEventID = new System.Text.RegularExpressions.Regex ( + static System.Text.RegularExpressions.Regex regexNoteEventID = new System.Text.RegularExpressions.Regex( @"MIDI-PAGE(?\d+)-NOTE-C(?\d+)N(?\d+)", System.Text.RegularExpressions.RegexOptions.Compiled); - string GetDescription (string eventId) + string GetDescription(string eventId) { - if (!eventlist.ContainsKey (eventId)) + if (!eventlist.ContainsKey(eventId)) return null; - var res = regexCtrlEventID.Match (eventId); - if (res.Success) { - uint page = uint.Parse (res.Groups ["page"].Value); - byte chan = byte.Parse (res.Groups ["chan"].Value); - uint param = uint.Parse (res.Groups ["param"].Value); - return string.Format ("Page {2} => Control-Change C({0}) Param-{1}", chan + 1, param, page); + var res = regexCtrlEventID.Match(eventId); + if (res.Success) + { + uint page = uint.Parse(res.Groups["page"].Value); + byte chan = byte.Parse(res.Groups["chan"].Value); + uint param = uint.Parse(res.Groups["param"].Value); + return string.Format("Page {2} => Control-Change C({0}) Param-{1}", chan + 1, param, page); } - res = regexPbEventID.Match (eventId); - if (res.Success) { - uint page = uint.Parse (res.Groups ["page"].Value); - byte chan = byte.Parse (res.Groups ["chan"].Value); - return string.Format ("Page {1} => PitchBend C({0})", chan + 1, page); + res = regexPbEventID.Match(eventId); + if (res.Success) + { + uint page = uint.Parse(res.Groups["page"].Value); + byte chan = byte.Parse(res.Groups["chan"].Value); + return string.Format("Page {1} => PitchBend C({0})", chan + 1, page); } - res = regexNoteEventID.Match (eventId); - if (res.Success) { - uint page = uint.Parse (res.Groups ["page"].Value); - byte chan = byte.Parse (res.Groups ["chan"].Value); - byte note = byte.Parse (res.Groups ["note"].Value); - return string.Format ("Page {2} => Note C({0}) Note-{1}", chan + 1, note, page); + res = regexNoteEventID.Match(eventId); + if (res.Success) + { + uint page = uint.Parse(res.Groups["page"].Value); + byte chan = byte.Parse(res.Groups["chan"].Value); + byte note = byte.Parse(res.Groups["note"].Value); + return string.Format("Page {2} => Note C({0}) Note-{1}", chan + 1, note, page); } return eventId; } - IFeedbackInfo IEventProvider.GetFeedbackInfo (string eventId) + IFeedbackInfo IEventProvider.GetFeedbackInfo(string eventId) { - if (!eventlist.ContainsKey (eventId)) + if (!eventlist.ContainsKey(eventId)) return null; - return new midifeedbackinfo (this, eventlist [eventId]); + return new midifeedbackinfo(this, eventlist[eventId]); } - #endregion + #endregion #region IDisposable implementation bool disposed = false; - ~MidiEventProvider () + ~MidiEventProvider() { - Dispose (); + Dispose(); } - public void Dispose () + public void Dispose() { if (disposed) return; @@ -596,57 +670,61 @@ namespace DMX2 } #endregion - public void Save (System.Xml.XmlElement parent) + public void Save(System.Xml.XmlElement parent) { - System.Xml.XmlElement el = parent.OwnerDocument.CreateElement ("Midi"); - parent.AppendChild (el); - el.SetAttribute ("maxpage", maxpage.ToString ()); - el.SetAttribute ("pageUpCC", pageUpCC.ToString ()); - el.SetAttribute ("pageDownCC", pageDownCC.ToString ()); - el.SetAttribute ("fourteenbits", use14b?"true":"false"); - el.SetAttribute ("max14b", max14bValue.ToString ()); + System.Xml.XmlElement el = parent.OwnerDocument.CreateElement("Midi"); + parent.AppendChild(el); + el.SetAttribute("maxpage", maxpage.ToString()); + el.SetAttribute("pageUpCC", pageUpCC.ToString()); + el.SetAttribute("pageDownCC", pageDownCC.ToString()); + el.SetAttribute("fourteenbits", use14b ? "true" : "false"); + el.SetAttribute("max14b", max14bValue.ToString()); System.Xml.XmlElement xmlEl; - foreach (MidiControler dev in knowndevices.Values) { - el.AppendChild (xmlEl = parent.OwnerDocument.CreateElement ("MidiDev")); - xmlEl.SetAttribute ("name", dev.Name); - xmlEl.SetAttribute ("feedback", dev.HasFeedback.ToString ()); + foreach (MidiControler dev in knowndevices.Values) + { + el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement("MidiDev")); + xmlEl.SetAttribute("name", dev.Name); + xmlEl.SetAttribute("feedback", dev.HasFeedback.ToString()); } - foreach (byte ch in unpaginatedchannels) { - el.AppendChild (xmlEl = parent.OwnerDocument.CreateElement ("UPC")); - xmlEl.SetAttribute ("ch", ch.ToString ()); + foreach (byte ch in unpaginatedchannels) + { + el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement("UPC")); + xmlEl.SetAttribute("ch", ch.ToString()); } } - public void Load (System.Xml.XmlElement el) + public void Load(System.Xml.XmlElement el) { if (el == null) return; - maxpage = uint.Parse (el.TryGetAttribute ("maxpage", "8")); - pageUpCC = uint.Parse (el.TryGetAttribute ("pageUpCC", "127")); - pageDownCC = uint.Parse (el.TryGetAttribute ("pageDownCC", "126")); - use14b = el.TryGetAttribute ("fourteenbits", string.Empty).Equals ("true"); - max14bValue = int.Parse (el.TryGetAttribute ("max14b", "255")); + maxpage = uint.Parse(el.TryGetAttribute("maxpage", "8")); + pageUpCC = uint.Parse(el.TryGetAttribute("pageUpCC", "127")); + pageDownCC = uint.Parse(el.TryGetAttribute("pageDownCC", "126")); + use14b = el.TryGetAttribute("fourteenbits", string.Empty).Equals("true"); + max14bValue = int.Parse(el.TryGetAttribute("max14b", "255")); - foreach (var xd in el.GetElementsByTagName("MidiDev")) { + foreach (var xd in el.GetElementsByTagName("MidiDev")) + { System.Xml.XmlElement xdev = xd as System.Xml.XmlElement; - string name = xdev.GetAttribute ("name"); - if (!knowndevices.ContainsKey (name)) - knowndevices.Add (name, new MidiControler (name)); - knowndevices [name].HasFeedback = bool.Parse (xdev.TryGetAttribute ("feedback", "false")); + string name = xdev.GetAttribute("name"); + if (!knowndevices.ContainsKey(name)) + knowndevices.Add(name, new MidiControler(name)); + knowndevices[name].HasFeedback = bool.Parse(xdev.TryGetAttribute("feedback", "false")); } - unpaginatedchannels.Clear (); - foreach (var xu in el.GetElementsByTagName("UPC")) { + unpaginatedchannels.Clear(); + foreach (var xu in el.GetElementsByTagName("UPC")) + { System.Xml.XmlElement xupc = xu as System.Xml.XmlElement; - unpaginatedchannels.Add (byte.Parse (xupc.GetAttribute ("ch"))); + unpaginatedchannels.Add(byte.Parse(xupc.GetAttribute("ch"))); } - AutoConnect (); + AutoConnect(); } - + class internalEventDesc { @@ -657,34 +735,43 @@ namespace DMX2 readonly midiFeedbackSender fbSender; - public bool Bound { - get { + public bool Bound + { + get + { return bound; } - set { + set + { bound = value; } } - public string InternalName { - get { + public string InternalName + { + get + { return internalName; } } - public uint Page { - get { + public uint Page + { + get + { return page; } } - public int MidiEvCode { - get { + public int MidiEvCode + { + get + { return midiEvCode; } } - public internalEventDesc (string _id, uint _page, int _evHCode, midiFeedbackSender _evsender) + public internalEventDesc(string _id, uint _page, int _evHCode, midiFeedbackSender _evsender) { internalName = _id; page = _page; @@ -694,42 +781,48 @@ namespace DMX2 int lastknownvalue = -1; - public int LastKnownValue { - get { + public int LastKnownValue + { + get + { return lastknownvalue; } - set { + set + { lastknownvalue = value; } } - bool nofbflag=false; + bool nofbflag = false; - public void SendFeedback () + public void SendFeedback() { - if(fbSender !=null && !nofbflag) - fbSender.SendFeedback (lastknownvalue); + if (fbSender != null && !nofbflag) + fbSender.SendFeedback(lastknownvalue); } - public void CallEvent (EventManagerCallback callback, EventData evData) + public void CallEvent(EventManagerCallback callback, EventData evData) { nofbflag = true; - callback (evData); + callback(evData); nofbflag = false; } } - abstract class midiFeedbackSender { - public abstract void SendFeedback (int value); + abstract class midiFeedbackSender + { + public abstract void SendFeedback(int value); } - class midiCCFbSender : midiFeedbackSender { + class midiCCFbSender : midiFeedbackSender + { readonly MidiEventProvider prov; AlsaSeqLib.snd_seq_event_t ev; AlsaSeqLib.snd_seq_event_t ev2; - public midiCCFbSender (MidiEventProvider _prov, byte _chan, uint _param){ + public midiCCFbSender(MidiEventProvider _prov, byte _chan, uint _param) + { prov = _prov; ev = new AlsaSeqLib.snd_seq_event_t(); ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER; @@ -738,39 +831,44 @@ namespace DMX2 ev2 = ev; ev2.data_ev_ctrl.param += 32; } - public override void SendFeedback (int value) + public override void SendFeedback(int value) { - if (prov.use14b && ev.data_ev_ctrl.param <32 ) { + if (prov.use14b && ev.data_ev_ctrl.param < 32) + { value = value * prov.max14bValue / 255; ev.data_ev_ctrl.value = value >> 7; ev2.data_ev_ctrl.value = value & 0xFF; - prov.SendEvent (ev); - prov.SendEvent (ev2); - } else { + prov.SendEvent(ev); + prov.SendEvent(ev2); + } + else + { ev.data_ev_ctrl.value = value * 127 / 255; - prov.SendEvent (ev); + prov.SendEvent(ev); } } } - class midiPBFbSender : midiFeedbackSender { + class midiPBFbSender : midiFeedbackSender + { readonly MidiEventProvider prov; AlsaSeqLib.snd_seq_event_t ev; - public midiPBFbSender (MidiEventProvider _prov, byte _chan){ + public midiPBFbSender(MidiEventProvider _prov, byte _chan) + { prov = _prov; ev = new AlsaSeqLib.snd_seq_event_t(); ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND; ev.data_ev_ctrl.channel = _chan; } - public override void SendFeedback (int value) + public override void SendFeedback(int value) { // value = ((evS.data_ev_ctrl.value + 7000) * 255 / 14000); ev.data_ev_ctrl.value = value * 14000 / 255 - 7000; - prov.SendEvent (ev); + prov.SendEvent(ev); } } @@ -779,24 +877,26 @@ namespace DMX2 MidiEventProvider prov; readonly internalEventDesc iev; - public midifeedbackinfo (MidiEventProvider _prov, internalEventDesc _iev) + public midifeedbackinfo(MidiEventProvider _prov, internalEventDesc _iev) { prov = _prov; iev = _iev; } #region IFeedbackInfo implementation - bool IFeedbackInfo.FeedBack (byte data) + bool IFeedbackInfo.FeedBack(byte data) { - + iev.LastKnownValue = data; - if (prov.CurrentPage == iev.Page || iev.Page == 0) { + if (prov.CurrentPage == iev.Page || iev.Page == 0) + { iev.SendFeedback(); - foreach (AlsaSeqLib.Port src in prov.feedbacksources) { - int lnvk = CombineHash (src.SrcId, iev.MidiEvCode); + foreach (AlsaSeqLib.Port src in prov.feedbacksources) + { + int lnvk = CombineHash(src.SrcId, iev.MidiEvCode); if (iev.LastKnownValue != -1) - prov.lastValueOfSrc [lnvk] = (byte)iev.LastKnownValue; + prov.lastValueOfSrc[lnvk] = (byte)iev.LastKnownValue; } } @@ -813,13 +913,14 @@ namespace DMX2 public bool HasFeedback { get; set; } - readonly List connected = new List (); + readonly List connected = new List(); - public List ConnectedPorts { - get{ return connected;} + public List ConnectedPorts + { + get { return connected; } } - public MidiControler (string _name) + public MidiControler(string _name) { name = _name; }