Restauration de la détection des perifs physiques

This commit is contained in:
tzim 2018-10-06 23:35:45 +02:00
parent 4bae84ee23
commit 4075ca7f34
3 changed files with 450 additions and 348 deletions

View file

@ -70,11 +70,11 @@ namespace DMX2
return Invoke.snd_seq_connect_to (seq_handle.Handle, portid, p.ClientId, p.PortId) == 0; 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) if (seq_handle == null)
throw new InvalidOperationException (); throw new InvalidOperationException ();
return Invoke.snd_seq_connect_to (seq_handle.Handle, portid, client, port) == 0; return Invoke.snd_seq_connect_to (seq_handle.Handle, portid, client, port) == 0;
} }*/
public bool ConnectFrom(Port p){ public bool ConnectFrom(Port p){
if (seq_handle == null) if (seq_handle == null)

View file

@ -13,7 +13,7 @@ namespace DMX2
//static int outport; //static int outport;
static System.Threading.Thread eventthread = null; static System.Threading.Thread eventthread = null;
static MidiPort systemPort = null; //static MidiPort systemPort = null;
static internal Dictionary<int, MidiPort> openports = new Dictionary<int, MidiPort>(); static internal Dictionary<int, MidiPort> openports = new Dictionary<int, MidiPort>();
@ -129,6 +129,7 @@ namespace DMX2
clientId = _clientId; clientId = _clientId;
portId = _portId; portId = _portId;
srcid = clientId << 8 + portId; srcid = clientId << 8 + portId;
ports.Add(srcid, this);
} }
private void Updateinfo (PointerWrapper portInfo) private void Updateinfo (PointerWrapper portInfo)
@ -177,8 +178,8 @@ namespace DMX2
System.Threading.ThreadStart ts = new System.Threading.ThreadStart (EventLoop); System.Threading.ThreadStart ts = new System.Threading.ThreadStart (EventLoop);
eventthread = new System.Threading.Thread (ts); eventthread = new System.Threading.Thread (ts);
eventthread.Start(); eventthread.Start();
systemPort = new MidiPort ("system"); //systemPort = new MidiPort ("system");
systemPort.ConnectTo (SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); //systemPort.ConnectTo (SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE);
} }
public static void Close () public static void Close ()
@ -201,16 +202,16 @@ namespace DMX2
// liberation du pointeur // liberation du pointeur
Invoke.snd_seq_free_event (evPtr); 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) { if (ev.type == AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_START) {
} }
} else { } else {*/
// queue // queue
if (openports.ContainsKey (ev.dest.port)) { if (openports.ContainsKey (ev.dest.port)) {
openports [ev.dest.port].eventqueue.Enqueue (ev); openports [ev.dest.port].eventqueue.Enqueue (ev);
} }
} //}
} }
System.Threading.Thread.Sleep (1); System.Threading.Thread.Sleep (1);
} }

View file

@ -62,68 +62,91 @@ namespace DMX2
AlsaSeqLib.MidiPort midiport; AlsaSeqLib.MidiPort midiport;
public uint CurrentPage { public uint CurrentPage
get { {
get
{
return page; return page;
} }
set { set
{
if (value < 1 || value > maxpage) if (value < 1 || value > maxpage)
return; return;
page = value; page = value;
Refresh(); Refresh();
} }
} }
public uint PageUpCC { public uint PageUpCC
get { {
get
{
return pageUpCC; return pageUpCC;
} }
set { set
{
pageUpCC = value; pageUpCC = value;
} }
} }
public uint PageDownCC { public uint PageDownCC
get { {
get
{
return pageDownCC; return pageDownCC;
} }
set { set
{
pageDownCC = value; pageDownCC = value;
} }
} }
public uint Maxpage { public uint Maxpage
get { {
get
{
return maxpage; return maxpage;
} }
set { set
{
maxpage = value; maxpage = value;
} }
} }
public List<byte> UnpaginatedChannels { public List<byte> UnpaginatedChannels
get { {
get
{
return unpaginatedchannels; return unpaginatedchannels;
} }
} }
public bool Use14bCC { public bool Use14bCC
get { {
get
{
return use14b; return use14b;
} }
set { set
{
use14b = value; use14b = value;
} }
} }
public int Max14bValue { public int Max14bValue
get { {
get
{
return max14bValue; return max14bValue;
} }
set { set
{
max14bValue = value; max14bValue = value;
} }
} }
public bool GuiRefreshFlag { public bool GuiRefreshFlag
get { {
if (guirefreshflag) { get
{
if (guirefreshflag)
{
guirefreshflag = false; guirefreshflag = false;
return true; return true;
} }
@ -139,11 +162,15 @@ namespace DMX2
public void RefreshFeedback(string name) public void RefreshFeedback(string name)
{ {
foreach (AlsaSeqLib.Port port in knowndevices[name].ConnectedPorts) { foreach (AlsaSeqLib.Port port in knowndevices[name].ConnectedPorts)
if (knowndevices [name].HasFeedback) { {
if (knowndevices[name].HasFeedback)
{
if (!feedbacksources.Contains(port)) if (!feedbacksources.Contains(port))
feedbacksources.Add(port); feedbacksources.Add(port);
} else { }
else
{
if (feedbacksources.Contains(port)) if (feedbacksources.Contains(port))
feedbacksources.Remove(port); feedbacksources.Remove(port);
} }
@ -156,7 +183,8 @@ namespace DMX2
return; return;
knowndevices.Remove(dev.Name); knowndevices.Remove(dev.Name);
foreach (AlsaSeqLib.Port connectedport in dev.ConnectedPorts) { foreach (AlsaSeqLib.Port connectedport in dev.ConnectedPorts)
{
midiport.Deconnecte(connectedport); midiport.Deconnecte(connectedport);
} }
} }
@ -166,8 +194,10 @@ namespace DMX2
return knowndevices.ContainsKey(name); return knowndevices.ContainsKey(name);
} }
public IEnumerable<MidiControler> KnownDevices { public IEnumerable<MidiControler> KnownDevices
get { {
get
{
return knowndevices.Values; return knowndevices.Values;
} }
} }
@ -186,14 +216,19 @@ namespace DMX2
//AlsaSeqLib.Init (); //AlsaSeqLib.Init ();
midiport = new AlsaSeqLib.MidiPort("event_prov_in_out"); midiport = new AlsaSeqLib.MidiPort("event_prov_in_out");
//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(); AutoConnect();
} }
void AutoConnect() void AutoConnect()
{ {
foreach (var cli in AlsaSeqLib.EnumClients()) { foreach (var cli in AlsaSeqLib.EnumClients())
foreach (var p in cli.Ports) { {
foreach (var p in cli.Ports)
{
PortDetected(cli, p); PortDetected(cli, p);
} }
} }
@ -208,7 +243,8 @@ namespace DMX2
guirefreshflag = true; guirefreshflag = true;
string fullportname = cli.Name + ':' + p.Name; string fullportname = cli.Name + ':' + p.Name;
if (knowndevices.ContainsKey (fullportname)) { if (knowndevices.ContainsKey(fullportname))
{
int srcid = p.ClientId << 8 + p.PortId; int srcid = p.ClientId << 8 + p.PortId;
if (knowndevices[fullportname].ConnectedPorts.Contains(p)) if (knowndevices[fullportname].ConnectedPorts.Contains(p))
return; return;
@ -221,17 +257,21 @@ namespace DMX2
void PortConnect(AlsaSeqLib.snd_seq_connect_t cn, bool connect) void PortConnect(AlsaSeqLib.snd_seq_connect_t cn, bool connect)
{ {
int clientId, portId; int clientId, portId;
if (cn.dest.client == AlsaSeqLib.ClientId) { if (cn.dest.client == AlsaSeqLib.ClientId)
{
clientId = cn.sender.client; clientId = cn.sender.client;
portId = cn.sender.port; portId = cn.sender.port;
} else { }
else
{
clientId = cn.dest.client; clientId = cn.dest.client;
portId = cn.dest.port; 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); AlsaSeqLib.Client c = AlsaSeqLib.GetClientByID(clientId);
string fpname = c.Name + ":" + p.Name; string fpname = c.Name + ":" + p.Name;
if (!knowndevices.ContainsKey(fpname)) if (!knowndevices.ContainsKey(fpname))
@ -248,8 +288,10 @@ namespace DMX2
return; return;
} }
foreach (var dev in knowndevices.Values) { foreach (var dev in knowndevices.Values)
if (dev.ConnectedPorts.Contains (p)) { {
if (dev.ConnectedPorts.Contains(p))
{
dev.ConnectedPorts.Remove(p); dev.ConnectedPorts.Remove(p);
guirefreshflag = true; guirefreshflag = true;
return; return;
@ -260,7 +302,8 @@ namespace DMX2
static int CombineHash(int hash1, int hash2) static int CombineHash(int hash1, int hash2)
{ {
unchecked { unchecked
{
return hash1 * 33 + hash2; return hash1 * 33 + hash2;
} }
} }
@ -277,10 +320,13 @@ namespace DMX2
public void Refresh() public void Refresh()
{ {
foreach (var ievent in eventlist.Values) { foreach (var ievent in eventlist.Values)
if (ievent.Page == page) { {
if (ievent.Page == page)
{
ievent.SendFeedback(); ievent.SendFeedback();
foreach (AlsaSeqLib.Port src in feedbacksources) { foreach (AlsaSeqLib.Port src in feedbacksources)
{
int lnvk = CombineHash(src.SrcId, ievent.MidiEvCode); int lnvk = CombineHash(src.SrcId, ievent.MidiEvCode);
if (ievent.LastKnownValue != -1) if (ievent.LastKnownValue != -1)
lastValueOfSrc[lnvk] = (byte)ievent.LastKnownValue; lastValueOfSrc[lnvk] = (byte)ievent.LastKnownValue;
@ -299,7 +345,8 @@ namespace DMX2
if (!eventId.StartsWith("MIDI-")) if (!eventId.StartsWith("MIDI-"))
return false; return false;
if (! eventlist.ContainsKey (eventId)) { if (!eventlist.ContainsKey(eventId))
{
Match res = regexEventID.Match(eventId); Match res = regexEventID.Match(eventId);
if (!res.Success) if (!res.Success)
return false; return false;
@ -308,11 +355,14 @@ namespace DMX2
midiFeedbackSender sender = null; midiFeedbackSender sender = null;
res = regexCtrlEventID.Match(eventId); res = regexCtrlEventID.Match(eventId);
if (res.Success) { if (res.Success)
{
byte chan = byte.Parse(res.Groups["chan"].Value); byte chan = byte.Parse(res.Groups["chan"].Value);
uint param = uint.Parse(res.Groups["param"].Value); uint param = uint.Parse(res.Groups["param"].Value);
sender = new midiCCFbSender(this, chan, param); sender = new midiCCFbSender(this, chan, param);
} else if ((res = regexPbEventID.Match (eventId)).Success){ }
else if ((res = regexPbEventID.Match(eventId)).Success)
{
byte chan = byte.Parse(res.Groups["chan"].Value); byte chan = byte.Parse(res.Groups["chan"].Value);
sender = new midiPBFbSender(this, chan); sender = new midiPBFbSender(this, chan);
} }
@ -335,7 +385,8 @@ namespace DMX2
{ {
Gtk.Menu retmenu = new Gtk.Menu(); Gtk.Menu retmenu = new Gtk.Menu();
if (levent != null) { // Creation du sous menu "Dernier" if (levent != null)
{ // Creation du sous menu "Dernier"
/*Gtk.MenuItem lmenuitem = new Gtk.MenuItem ("Dernier"); /*Gtk.MenuItem lmenuitem = new Gtk.MenuItem ("Dernier");
retmenu.Add (lmenuitem); retmenu.Add (lmenuitem);
Gtk.Menu lmenu = new Gtk.Menu (); Gtk.Menu lmenu = new Gtk.Menu ();
@ -355,7 +406,8 @@ namespace DMX2
List<string> sortedKeys = eventlist.Keys.ToList(); // On recupere des IDs List<string> sortedKeys = eventlist.Keys.ToList(); // On recupere des IDs
sortedKeys.Sort(); // et on les trie sortedKeys.Sort(); // et on les trie
foreach (string key in sortedKeys) { foreach (string key in sortedKeys)
{
internalEventDesc evt = eventlist[key]; internalEventDesc evt = eventlist[key];
Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(evt.InternalName)); Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(evt.InternalName));
item.Data[EventManager.EventIdKey] = evt.InternalName; item.Data[EventManager.EventIdKey] = evt.InternalName;
@ -374,13 +426,15 @@ namespace DMX2
uint evpage; uint evpage;
// Tant qu'il y des evenements midi en attente // Tant qu'il y des evenements midi en attente
while (midiport.GetEvent(out evS)) { while (midiport.GetEvent(out evS))
{
Console.WriteLine(string.Format("event {0}", evS.type)); Console.WriteLine(string.Format("event {0}", evS.type));
string id = null; string id = null;
int value = 0; int value = 0;
byte channel = 255; byte channel = 255;
switch (evS.type) { 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_SUBSCRIBED: // Connection d'un périph midi
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_UNSUBSCRIBED: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
PortConnect( PortConnect(
@ -389,21 +443,25 @@ namespace DMX2
); );
continue; continue;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER:
if (evS.data_ev_ctrl.param == pageUpCC && evS.data_ev_ctrl.value > 0) { if (evS.data_ev_ctrl.param == pageUpCC && evS.data_ev_ctrl.value > 0)
{
CurrentPage++; CurrentPage++;
continue; continue;
} }
if (evS.data_ev_ctrl.param == pageDownCC && evS.data_ev_ctrl.value > 0) { if (evS.data_ev_ctrl.param == pageDownCC && evS.data_ev_ctrl.value > 0)
{
CurrentPage--; CurrentPage--;
continue; continue;
} }
channel = evS.data_ev_ctrl.channel; channel = evS.data_ev_ctrl.channel;
if (use14b && evS.data_ev_ctrl.param < 64) { if (use14b && evS.data_ev_ctrl.param < 64)
{
long msbAddr; long msbAddr;
if (evS.data_ev_ctrl.param < 32) { if (evS.data_ev_ctrl.param < 32)
{
msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param; msbAddr = evS.data_ev_ctrl.channel * 32 + evS.data_ev_ctrl.param;
fbTmpData[msbAddr] = (byte)evS.data_ev_ctrl.value; fbTmpData[msbAddr] = (byte)evS.data_ev_ctrl.value;
continue; continue;
@ -413,7 +471,9 @@ namespace DMX2
value = ((fbTmpData[msbAddr] << 7) ^ evS.data_ev_ctrl.value); value = ((fbTmpData[msbAddr] << 7) ^ evS.data_ev_ctrl.value);
value = 255 * value / max14bValue; value = 255 * value / max14bValue;
if (value > 255) value = 255; if (value > 255) value = 255;
} else { }
else
{
value = 255 * evS.data_ev_ctrl.value / 127; // Conversion {0,127} => {0,255} 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); id = string.Format("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param);
@ -440,8 +500,12 @@ namespace DMX2
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PGMCHANGE: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PGMCHANGE:
CurrentPage = (uint)evS.data_ev_ctrl.value; CurrentPage = (uint)evS.data_ev_ctrl.value;
continue; 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_CLOCK:
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING:
continue;*/ continue;*/
@ -455,7 +519,8 @@ namespace DMX2
continue; continue;
} }
if (id != null) { if (id != null)
{
// Hashcode de l'ev Midi, non pagine // 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 srcid = evS.source.client << 8 + evS.source.port;
@ -470,8 +535,10 @@ namespace DMX2
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 // Creation de l'objet interne si innexistant
if (!eventlist.ContainsKey (id)) { if (!eventlist.ContainsKey(id))
switch (evS.type) { {
switch (evS.type)
{
// TODO : Pitchbend feedback // TODO : Pitchbend feedback
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER:
eventlist.Add(id, new internalEventDesc(id, evpage, evHC, eventlist.Add(id, new internalEventDesc(id, evpage, evHC,
@ -490,9 +557,11 @@ namespace DMX2
} }
levent = eventlist[id]; //Dernier Evenement recu conserve pour menu levent = eventlist[id]; //Dernier Evenement recu conserve pour menu
if (!lastValueOfSrc.ContainsKey (lnvk)) { if (!lastValueOfSrc.ContainsKey(lnvk))
{
lastValueOfSrc[lnvk] = (byte)value; lastValueOfSrc[lnvk] = (byte)value;
} else if (lastValueOfSrc [lnvk] == (byte)value) }
else if (lastValueOfSrc[lnvk] == (byte)value)
continue; continue;
EventData evData = new EventData(); EventData evData = new EventData();
@ -516,8 +585,10 @@ namespace DMX2
} }
} }
string IEventProvider.MenuName { string IEventProvider.MenuName
get { {
get
{
return "Midi"; return "Midi";
} }
} }
@ -542,20 +613,23 @@ namespace DMX2
return null; return null;
var res = regexCtrlEventID.Match(eventId); var res = regexCtrlEventID.Match(eventId);
if (res.Success) { if (res.Success)
{
uint page = uint.Parse(res.Groups["page"].Value); uint page = uint.Parse(res.Groups["page"].Value);
byte chan = byte.Parse(res.Groups["chan"].Value); byte chan = byte.Parse(res.Groups["chan"].Value);
uint param = uint.Parse(res.Groups["param"].Value); uint param = uint.Parse(res.Groups["param"].Value);
return string.Format("Page {2} => Control-Change C({0}) Param-{1}", chan + 1, param, page); return string.Format("Page {2} => Control-Change C({0}) Param-{1}", chan + 1, param, page);
} }
res = regexPbEventID.Match(eventId); res = regexPbEventID.Match(eventId);
if (res.Success) { if (res.Success)
{
uint page = uint.Parse(res.Groups["page"].Value); uint page = uint.Parse(res.Groups["page"].Value);
byte chan = byte.Parse(res.Groups["chan"].Value); byte chan = byte.Parse(res.Groups["chan"].Value);
return string.Format("Page {1} => PitchBend C({0})", chan + 1, page); return string.Format("Page {1} => PitchBend C({0})", chan + 1, page);
} }
res = regexNoteEventID.Match(eventId); res = regexNoteEventID.Match(eventId);
if (res.Success) { if (res.Success)
{
uint page = uint.Parse(res.Groups["page"].Value); uint page = uint.Parse(res.Groups["page"].Value);
byte chan = byte.Parse(res.Groups["chan"].Value); byte chan = byte.Parse(res.Groups["chan"].Value);
byte note = byte.Parse(res.Groups["note"].Value); byte note = byte.Parse(res.Groups["note"].Value);
@ -607,13 +681,15 @@ namespace DMX2
el.SetAttribute("max14b", max14bValue.ToString()); el.SetAttribute("max14b", max14bValue.ToString());
System.Xml.XmlElement xmlEl; System.Xml.XmlElement xmlEl;
foreach (MidiControler dev in knowndevices.Values) { foreach (MidiControler dev in knowndevices.Values)
{
el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement("MidiDev")); el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement("MidiDev"));
xmlEl.SetAttribute("name", dev.Name); xmlEl.SetAttribute("name", dev.Name);
xmlEl.SetAttribute("feedback", dev.HasFeedback.ToString()); xmlEl.SetAttribute("feedback", dev.HasFeedback.ToString());
} }
foreach (byte ch in unpaginatedchannels) { foreach (byte ch in unpaginatedchannels)
{
el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement("UPC")); el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement("UPC"));
xmlEl.SetAttribute("ch", ch.ToString()); xmlEl.SetAttribute("ch", ch.ToString());
} }
@ -630,7 +706,8 @@ namespace DMX2
use14b = el.TryGetAttribute("fourteenbits", string.Empty).Equals("true"); use14b = el.TryGetAttribute("fourteenbits", string.Empty).Equals("true");
max14bValue = int.Parse(el.TryGetAttribute("max14b", "255")); 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; System.Xml.XmlElement xdev = xd as System.Xml.XmlElement;
string name = xdev.GetAttribute("name"); string name = xdev.GetAttribute("name");
if (!knowndevices.ContainsKey(name)) if (!knowndevices.ContainsKey(name))
@ -638,7 +715,8 @@ namespace DMX2
knowndevices[name].HasFeedback = bool.Parse(xdev.TryGetAttribute("feedback", "false")); knowndevices[name].HasFeedback = bool.Parse(xdev.TryGetAttribute("feedback", "false"));
} }
unpaginatedchannels.Clear(); unpaginatedchannels.Clear();
foreach (var xu in el.GetElementsByTagName("UPC")) { foreach (var xu in el.GetElementsByTagName("UPC"))
{
System.Xml.XmlElement xupc = xu as System.Xml.XmlElement; System.Xml.XmlElement xupc = xu as System.Xml.XmlElement;
unpaginatedchannels.Add(byte.Parse(xupc.GetAttribute("ch"))); unpaginatedchannels.Add(byte.Parse(xupc.GetAttribute("ch")));
} }
@ -657,29 +735,38 @@ namespace DMX2
readonly midiFeedbackSender fbSender; readonly midiFeedbackSender fbSender;
public bool Bound { public bool Bound
get { {
get
{
return bound; return bound;
} }
set { set
{
bound = value; bound = value;
} }
} }
public string InternalName { public string InternalName
get { {
get
{
return internalName; return internalName;
} }
} }
public uint Page { public uint Page
get { {
get
{
return page; return page;
} }
} }
public int MidiEvCode { public int MidiEvCode
get { {
get
{
return midiEvCode; return midiEvCode;
} }
} }
@ -694,11 +781,14 @@ namespace DMX2
int lastknownvalue = -1; int lastknownvalue = -1;
public int LastKnownValue { public int LastKnownValue
get { {
get
{
return lastknownvalue; return lastknownvalue;
} }
set { set
{
lastknownvalue = value; lastknownvalue = value;
} }
} }
@ -719,17 +809,20 @@ namespace DMX2
} }
} }
abstract class midiFeedbackSender { abstract class midiFeedbackSender
{
public abstract void SendFeedback(int value); public abstract void SendFeedback(int value);
} }
class midiCCFbSender : midiFeedbackSender { class midiCCFbSender : midiFeedbackSender
{
readonly MidiEventProvider prov; readonly MidiEventProvider prov;
AlsaSeqLib.snd_seq_event_t ev; AlsaSeqLib.snd_seq_event_t ev;
AlsaSeqLib.snd_seq_event_t ev2; AlsaSeqLib.snd_seq_event_t ev2;
public midiCCFbSender (MidiEventProvider _prov, byte _chan, uint _param){ public midiCCFbSender(MidiEventProvider _prov, byte _chan, uint _param)
{
prov = _prov; prov = _prov;
ev = new AlsaSeqLib.snd_seq_event_t(); ev = new AlsaSeqLib.snd_seq_event_t();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER; ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
@ -740,13 +833,16 @@ namespace DMX2
} }
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; value = value * prov.max14bValue / 255;
ev.data_ev_ctrl.value = value >> 7; ev.data_ev_ctrl.value = value >> 7;
ev2.data_ev_ctrl.value = value & 0xFF; ev2.data_ev_ctrl.value = value & 0xFF;
prov.SendEvent(ev); prov.SendEvent(ev);
prov.SendEvent(ev2); prov.SendEvent(ev2);
} else { }
else
{
ev.data_ev_ctrl.value = value * 127 / 255; ev.data_ev_ctrl.value = value * 127 / 255;
prov.SendEvent(ev); prov.SendEvent(ev);
} }
@ -754,12 +850,14 @@ namespace DMX2
} }
} }
class midiPBFbSender : midiFeedbackSender { class midiPBFbSender : midiFeedbackSender
{
readonly MidiEventProvider prov; readonly MidiEventProvider prov;
AlsaSeqLib.snd_seq_event_t ev; AlsaSeqLib.snd_seq_event_t ev;
public midiPBFbSender (MidiEventProvider _prov, byte _chan){ public midiPBFbSender(MidiEventProvider _prov, byte _chan)
{
prov = _prov; prov = _prov;
ev = new AlsaSeqLib.snd_seq_event_t(); ev = new AlsaSeqLib.snd_seq_event_t();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND; ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND;
@ -791,9 +889,11 @@ namespace DMX2
iev.LastKnownValue = data; iev.LastKnownValue = data;
if (prov.CurrentPage == iev.Page || iev.Page == 0) { if (prov.CurrentPage == iev.Page || iev.Page == 0)
{
iev.SendFeedback(); iev.SendFeedback();
foreach (AlsaSeqLib.Port src in prov.feedbacksources) { foreach (AlsaSeqLib.Port src in prov.feedbacksources)
{
int lnvk = CombineHash(src.SrcId, iev.MidiEvCode); int lnvk = CombineHash(src.SrcId, iev.MidiEvCode);
if (iev.LastKnownValue != -1) if (iev.LastKnownValue != -1)
prov.lastValueOfSrc[lnvk] = (byte)iev.LastKnownValue; prov.lastValueOfSrc[lnvk] = (byte)iev.LastKnownValue;
@ -815,7 +915,8 @@ namespace DMX2
readonly List<AlsaSeqLib.Port> connected = new List<AlsaSeqLib.Port>(); readonly List<AlsaSeqLib.Port> connected = new List<AlsaSeqLib.Port>();
public List<AlsaSeqLib.Port> ConnectedPorts { public List<AlsaSeqLib.Port> ConnectedPorts
{
get { return connected; } get { return connected; }
} }