Grosses améliorations sur la gestion des evenements, notament sur l'accroche et la pagination midi

This commit is contained in:
tzim 2014-05-21 14:26:44 +00:00
parent d48ab853df
commit 5260f8f2be
7 changed files with 310 additions and 70 deletions

View file

@ -155,18 +155,23 @@ namespace DMX2
static PointerWrapper evOutPtr = new PointerWrapper(32); static PointerWrapper evOutPtr = new PointerWrapper(32);
public static void SendEvent (snd_seq_event_t ev)
{
if(seq_handle==null) throw new InvalidOperationException();
ev.queue = SND_SEQ_QUEUE_DIRECT;
ev.source.client = (byte)clientId;
ev.source.port = (byte) outport;
Marshal.StructureToPtr(ev,evOutPtr.Pointer,false);
Invoke.snd_seq_event_output(seq_handle.Handle,evOutPtr.Pointer);
Invoke.snd_seq_drain_output(seq_handle.Handle);
}
public static void SendEventToSubscribers (snd_seq_event_t ev) public static void SendEventToSubscribers (snd_seq_event_t ev)
{ {
if(seq_handle==null) throw new InvalidOperationException(); if(seq_handle==null) throw new InvalidOperationException();
ev.queue = SND_SEQ_QUEUE_DIRECT;
ev.source.port = (byte) outport;
ev.dest.client=SND_SEQ_ADDRESS_SUBSCRIBERS; ev.dest.client=SND_SEQ_ADDRESS_SUBSCRIBERS;
ev.dest.port= SND_SEQ_ADDRESS_UNKNOWN; ev.dest.port= SND_SEQ_ADDRESS_UNKNOWN;
Marshal.StructureToPtr(ev,evOutPtr.Pointer,false); SendEvent(ev);
Invoke.snd_seq_event_output(seq_handle.Handle,evOutPtr.Pointer);
Invoke.snd_seq_drain_output(seq_handle.Handle);
} }
public static IEnumerable<Client> EnumClients () public static IEnumerable<Client> EnumClients ()

View file

@ -216,7 +216,6 @@ namespace DMX2
loopthread.Join (); loopthread.Join ();
loopthread = null; loopthread = null;
} }
//TODO : Close Port
if(serial != null) if(serial != null)
serial.Dispose(); serial.Dispose();
@ -289,6 +288,7 @@ namespace DMX2
while (eventsPending.TryDequeue(out bt)) { while (eventsPending.TryDequeue(out bt)) {
evd.id= string.Format("BV1-B{0}",bt.button ); evd.id= string.Format("BV1-B{0}",bt.button );
evd.value = bt.pressed?(byte)0xFF:(byte)0x00; evd.value = bt.pressed?(byte)0xFF:(byte)0x00;
evd.prev_value = (!bt.pressed)?(byte)0xFF:(byte)0x00;
callback(evd); callback(evd);
} }
} }

View file

@ -28,11 +28,12 @@ namespace DMX2
{ {
struct dmxState { struct dmxState {
public dmxState(int _dmx, byte _value){ public dmxState(int _dmx, byte _value, byte _lastvalue){
value=_value; dmx=_dmx; value=_value; dmx=_dmx; lastvalue = _lastvalue;
} }
public int dmx; public int dmx;
public byte value; public byte value;
public byte lastvalue;
} }
enum etatAutomate { enum etatAutomate {
@ -409,8 +410,8 @@ namespace DMX2
lock(watchdmx) lock(watchdmx)
foreach (int dmx in watchdmx) { foreach (int dmx in watchdmx) {
if( inputbuffer[dmx-1]!= lastVal[dmx]){ if( inputbuffer[dmx-1]!= lastVal[dmx]){
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx-1],lastVal[dmx]));
lastVal[dmx] = inputbuffer[dmx-1]; lastVal[dmx] = inputbuffer[dmx-1];
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx-1]));
} }
} }
} }
@ -423,7 +424,6 @@ namespace DMX2
loopthread.Join (); loopthread.Join ();
loopthread = null; loopthread = null;
} }
//TODO : Close Port
if(serial != null) if(serial != null)
serial.Dispose(); serial.Dispose();
@ -524,6 +524,7 @@ namespace DMX2
while (eventsPending.TryDequeue(out dmxs)) { while (eventsPending.TryDequeue(out dmxs)) {
evd.id= string.Format("BV2-D{0}",dmxs.dmx ); evd.id= string.Format("BV2-D{0}",dmxs.dmx );
evd.value = dmxs.value; evd.value = dmxs.value;
evd.prev_value = dmxs.lastvalue;
callback(evd); callback(evd);
} }
} }

View file

@ -28,11 +28,12 @@ namespace DMX2
{ {
struct dmxState { struct dmxState {
public dmxState(int _dmx, byte _value){ public dmxState(int _dmx, byte _value, byte _lastvalue){
value=_value; dmx=_dmx; value=_value; dmx=_dmx; lastvalue = _lastvalue;
} }
public int dmx; public int dmx;
public byte value; public byte value;
public byte lastvalue;
} }
enum etatAutomate { enum etatAutomate {
@ -466,8 +467,8 @@ namespace DMX2
lock(watchdmx) lock(watchdmx)
foreach (int dmx in watchdmx) { foreach (int dmx in watchdmx) {
if( inputbuffer[dmx]!= lastVal[dmx]){ if( inputbuffer[dmx]!= lastVal[dmx]){
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx],lastVal[dmx]));
lastVal[dmx] = inputbuffer[dmx]; lastVal[dmx] = inputbuffer[dmx];
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx]));
} }
} }
} }
@ -480,7 +481,6 @@ namespace DMX2
loopthread.Join (); loopthread.Join ();
loopthread = null; loopthread = null;
} }
//TODO : Close Port
if(serial != null) if(serial != null)
serial.Dispose(); serial.Dispose();
@ -581,6 +581,7 @@ namespace DMX2
while (eventsPending.TryDequeue(out dmxs)) { while (eventsPending.TryDequeue(out dmxs)) {
evd.id= string.Format("BV3-D{0}",dmxs.dmx ); evd.id= string.Format("BV3-D{0}",dmxs.dmx );
evd.value = dmxs.value; evd.value = dmxs.value;
evd.prev_value = dmxs.lastvalue;
callback(evd); callback(evd);
} }
} }

View file

@ -29,6 +29,7 @@ namespace DMX2
{ {
public string id; public string id;
public byte value; public byte value;
public byte prev_value ;
} }
/// <summary> /// <summary>
@ -280,7 +281,7 @@ namespace DMX2
///<summary> Fonction appelee sur evenement</summary> ///<summary> Fonction appelee sur evenement</summary>
public void EventCallBack (EventData data) public void EventCallBack (EventData data)
{ {
Console.WriteLine("Event {0} => {1}",data.id,data.value); Console.WriteLine("Event {0} => {1} (last = {2})",data.id,data.value,data.prev_value);
if (bindings.ContainsKey (data.id)) { if (bindings.ContainsKey (data.id)) {
foreach (IEventTarget target in bindings[data.id].Targets) { foreach (IEventTarget target in bindings[data.id].Targets) {
target.FireEvent(data); target.FireEvent(data);

View file

@ -27,58 +27,209 @@ namespace DMX2
{ {
class internalEvent { class internalEvent {
public string internalName;
public string description; public string InternalName{ get; set; }
public internalEvent(string _id, string _desc) bool bound=false;
{
internalName=_id; public bool Bound {
description=_desc; get {
return bound;
}
set {
bound = value;
} }
} }
class feedbackinfo : IFeedbackInfo { public internalEvent(string _id)
{
InternalName=_id;
}
int[] sources=null;
public IEnumerable<int> Sources {
get {
if(sources == null || sources.Length!=lastknownvalues.Count) sources = lastknownvalues.Keys.ToArray();
return sources;
}
}
readonly Dictionary<int,byte> lastknownvalues = new Dictionary<int, byte>();
public Dictionary<int, byte> LastKnownValues {
get {
return lastknownvalues;
}
}
AlsaSeqLib.snd_seq_event_t storedevent;
public AlsaSeqLib.snd_seq_event_t StoredEvent {
get {
return storedevent;
}
set {
storedevent = value;
}
}
}
abstract class feedbackinfo : IFeedbackInfo {
MidiEventProvider prov; MidiEventProvider prov;
AlsaSeqLib.snd_seq_event_t ev; protected AlsaSeqLib.snd_seq_event_t ev;
string eventId;
int page;
public feedbackinfo(MidiEventProvider _prov, byte channel,uint param){
ev = new AlsaSeqLib.snd_seq_event_t(); prov=_prov; public feedbackinfo(MidiEventProvider _prov, string _eventId, int _page){
ev.data_ev_ctrl.channel = channel; prov = _prov;
ev.data_ev_ctrl.param= param; eventId = _eventId;
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER; page = _page;
} }
protected abstract bool UpdateEvent(byte data);
#region IFeedbackInfo implementation #region IFeedbackInfo implementation
bool IFeedbackInfo.FeedBack (byte data) bool IFeedbackInfo.FeedBack (byte data)
{ {
ev.data_ev_ctrl.value = (byte)((int)data * 127 / 255) ; if (!prov.eventlist.ContainsKey (eventId))
prov.SendEvent(ev); return false;
bool update = UpdateEvent (data);
prov.eventlist[eventId].StoredEvent = ev;
if(!update) return true;
foreach (var src in prov.eventlist[eventId].Sources) {
if(prov.HasFeedback(src))
{
prov.eventlist[eventId].LastKnownValues[src]=data;
}
}
if(prov.CurrentPage == page || page == 0)
prov.SendEvent (ev);
return true; return true;
} }
#endregion #endregion
} }
class ctrlfeedbackinfo : feedbackinfo {
public ctrlfeedbackinfo(MidiEventProvider _prov, string _eventId, int _page, byte channel,uint param)
:base(_prov,_eventId,_page)
{
ev = new AlsaSeqLib.snd_seq_event_t();
ev.data_ev_ctrl.channel = channel;
ev.data_ev_ctrl.param= param;
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
}
protected override bool UpdateEvent (byte data)
{
int newvalue= (int)data * 127 / 255;
if(newvalue==ev.data_ev_ctrl.value) return false;
ev.data_ev_ctrl.value = newvalue;
return true;
}
}
class pitchbendfeedbackinfo : feedbackinfo {
public pitchbendfeedbackinfo(MidiEventProvider _prov, string _eventId,int _page, byte channel)
:base(_prov,_eventId,_page)
{
ev = new AlsaSeqLib.snd_seq_event_t();
ev.data_ev_ctrl.channel = channel;
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND;
}
protected override bool UpdateEvent (byte data)
{
int newvalue = (int)data * 16000 / 255-8000;
if(newvalue==ev.data_ev_ctrl.value) return false;
ev.data_ev_ctrl.value = newvalue;
return true;
}
}
public class MidiDev{
string name;
public string Name {get{return name;} }
public bool HasFeedback { get; set; }
readonly List<int> connected = new List<int>();
public List<int> ConnectedPorts {
get{return connected;}
}
public MidiDev(string _name)
{
name=_name;
}
}
readonly Dictionary<string,internalEvent> eventlist = new Dictionary<string, internalEvent>();
readonly Dictionary<string,MidiDev> knowndevices = new Dictionary<string,MidiDev>();
readonly List<int> feedbacksources = new List<int>();
readonly List<byte> unpaginatedchannels = new List<byte>();
Dictionary<string,internalEvent> eventlist = new Dictionary<string, internalEvent>();
List<string> midiPortAutoConnect = new List<string>();
EventData last; EventData last;
internalEvent levent=null; internalEvent levent=null;
bool connected=false; bool connected=false;
int page=1;
public int CurrentPage {
get {
return page;
}
set {
if(value<1 || value > 255) return;
page = value;
Refresh();
Console.WriteLine(page);
}
}
public List<byte> UnpaginatedChannels {
get {
return unpaginatedchannels;
}
}
public Dictionary<string,MidiDev> KnownDevices {
get {
return knowndevices;
}
}
public MidiEventProvider (EventManager manager) public MidiEventProvider (EventManager manager)
{ {
manager.RegisterProvider (this); manager.RegisterProvider (this);
AlsaSeqLib.Init (); AlsaSeqLib.Init ();
// Connection au port d'annonce pour detection auto
midiPortAutoConnect.Add("BCF2000:BCF2000 MIDI 1");
AlsaSeqLib.ConnectFrom(AlsaSeqLib.SND_SEQ_CLIENT_SYSTEM, AlsaSeqLib.SND_SEQ_PORT_SYSTEM_ANNOUNCE); AlsaSeqLib.ConnectFrom(AlsaSeqLib.SND_SEQ_CLIENT_SYSTEM, AlsaSeqLib.SND_SEQ_PORT_SYSTEM_ANNOUNCE);
MidiDev dev = new MidiDev("VMPK Input:VMPK Input");
dev.HasFeedback = true;
knowndevices.Add(dev.Name,dev);
dev = new MidiDev("VMPK Output:VMPK Output");
dev.HasFeedback = true;
knowndevices.Add(dev.Name,dev);
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);
} }
} }
unpaginatedchannels.Add((byte)0);
} }
void PortDetected (AlsaSeqLib.Client cli, AlsaSeqLib.Port p) void PortDetected (AlsaSeqLib.Client cli, AlsaSeqLib.Port p)
@ -89,25 +240,50 @@ namespace DMX2
string fullportname = cli.Name + ':' + p.Name; string fullportname = cli.Name + ':' + p.Name;
Console.WriteLine(fullportname); Console.WriteLine(fullportname);
if(midiPortAutoConnect.Contains(fullportname)) if(knowndevices.ContainsKey(fullportname)){
AlsaSeqLib.Connect(p); AlsaSeqLib.Connect(p);
int srcid = p.ClientId <<8 + p.PortId;
knowndevices[fullportname].ConnectedPorts.Add(srcid);
if(knowndevices[fullportname].HasFeedback)
feedbacksources.Add(srcid);
}
} }
protected bool HasFeedback (int source)
{
return feedbacksources.Contains(source);
}
public void SendEvent (AlsaSeqLib.snd_seq_event_t ev) public void SendEvent (AlsaSeqLib.snd_seq_event_t ev)
{ {
AlsaSeqLib.SendEventToSubscribers(ev); AlsaSeqLib.SendEventToSubscribers(ev);
} }
public void Refresh ()
{
string pageStr = string.Format("PAGE{0}",page);
foreach (var ievent in eventlist.Values) {
if (ievent.InternalName.Contains(pageStr)){
SendEvent(ievent.StoredEvent);
}
}
}
#region IEventProvider implementation #region IEventProvider implementation
bool IEventProvider.Bind (string eventId) bool IEventProvider.Bind (string eventId)
{ {
// On indique a l'EventManager qu'on traite, si l'ID commence par 'MIDI-' // On indique a l'EventManager qu'on traite, si l'ID commence par 'MIDI-'
return eventId.StartsWith("MIDI-"); if(! eventId.StartsWith("MIDI-")) return false;
if(! eventlist.ContainsKey(eventId)) eventlist.Add(eventId, new internalEvent(eventId));
eventlist[eventId].Bound = true;
return true;
} }
void IEventProvider.Unbind (string eventId) void IEventProvider.Unbind (string eventId)
{ {
if(! eventlist.ContainsKey(eventId)) return;
eventlist[eventId].Bound = false;
return; return;
} }
@ -121,8 +297,8 @@ namespace DMX2
retmenu.Add (lmenuitem); retmenu.Add (lmenuitem);
Gtk.Menu lmenu = new Gtk.Menu (); Gtk.Menu lmenu = new Gtk.Menu ();
lmenuitem.Submenu = lmenu; lmenuitem.Submenu = lmenu;
Gtk.MenuItem item = new Gtk.MenuItem(levent.description); Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(levent.InternalName));
item.Data[EventManager.EventIdKey] = levent.internalName; item.Data[EventManager.EventIdKey] = levent.InternalName;
item.Data[EventManager.StateKey] = state; item.Data[EventManager.StateKey] = state;
item.ButtonPressEvent += handler; item.ButtonPressEvent += handler;
lmenu.Add (item); lmenu.Add (item);
@ -138,8 +314,8 @@ namespace DMX2
foreach ( string key in sortedKeys ) { foreach ( string key in sortedKeys ) {
internalEvent evt= eventlist[key]; internalEvent evt= eventlist[key];
Gtk.MenuItem item = new Gtk.MenuItem(evt.description); Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(evt.InternalName));
item.Data[EventManager.EventIdKey] = evt.internalName; item.Data[EventManager.EventIdKey] = evt.InternalName;
item.Data[EventManager.StateKey] = state; item.Data[EventManager.StateKey] = state;
item.ButtonPressEvent += handler; item.ButtonPressEvent += handler;
evmenu.Add (item); evmenu.Add (item);
@ -152,31 +328,48 @@ namespace DMX2
void IEventProvider.ProcessEvents (EventManagerCallback callback) void IEventProvider.ProcessEvents (EventManagerCallback callback)
{ {
AlsaSeqLib.snd_seq_event_t evS; AlsaSeqLib.snd_seq_event_t evS;
int evpage;
// Tant qu'il y des evenements midi en attente // Tant qu'il y des evenements midi en attente
while (AlsaSeqLib.GetEvent(out evS)) { while (AlsaSeqLib.GetEvent(out evS)) {
string id=null, description=null; int value=0; string id = null;
int value=0;
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
connected = true; connected = true;
continue; continue;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: case AlsaSeqLib.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); if(evS.data_ev_ctrl.param==127 && value>0){
description = string.Format("Controller Ch {0} Param {1}",evS.data_ev_ctrl.channel,evS.data_ev_ctrl.param); CurrentPage++; continue;
}
if(evS.data_ev_ctrl.param==126 && value>0){
CurrentPage--; continue;
}
id = string.Format("CTRL-C{0}P{1}",evS.data_ev_ctrl.channel,evS.data_ev_ctrl.param);
channel = evS.data_ev_ctrl.channel;
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}
break; break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON: case AlsaSeqLib.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 ); id = string.Format("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 ); channel = evS.data_ev_note.channel;
value = 255 ; value = 255 ;
break; break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF: case AlsaSeqLib.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 ); id = string.Format("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 ); channel = evS.data_ev_note.channel;
value = 0; value = 0;
break; 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 + 8000) *255 / 16000);
if(value<0) value =0; if(value>255) value = 255;
break;
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;
@ -199,19 +392,40 @@ namespace DMX2
connected=true; connected=true;
if(id!=null) if(id!=null)
{ {
if(channel == 255 || unpaginatedchannels.Contains(channel))
evpage= 0;
else
evpage= page;
id = string.Format("MIDI-PAGE{0}-{1}",evpage,id);
if(!eventlist.ContainsKey(id)) if(!eventlist.ContainsKey(id))
eventlist.Add(id,new internalEvent(id,description)); eventlist.Add(id,new internalEvent(id));
levent= eventlist[id]; //Dernier Evenement recu conserve pour menu levent= eventlist[id]; //Dernier Evenement recu conserve pour menu
int srcid = evS.source.client <<8 + evS.source.port;
if(!eventlist[id].LastKnownValues.ContainsKey(srcid))
eventlist[id].LastKnownValues[srcid] = (byte)value;
EventData evData = new EventData(); EventData evData = new EventData();
evData.id = id; evData.id = id;
evData.value = (byte)value; evData.value = (byte)value;
evData.prev_value = eventlist[id].LastKnownValues[srcid];
if(evData.Equals(last)) continue; // On ignore les evenements répétés à l'identique eventlist[id].LastKnownValues[srcid] = (byte)value;
callback(evData); if(evData.Equals(last)) continue;
last = evData; last = evData;
if(eventlist[id].Bound) {
callback(evData);
}
} }
} }
} }
@ -222,10 +436,21 @@ namespace DMX2
} }
} }
//TODO gerer pages et feeddback
static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex( static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex(
@"MIDI-CTRL-C(?<chan>\d+)P(?<param>\d+)", @"MIDI-PAGE(?<page>\d+)-CTRL-C(?<chan>\d+)P(?<param>\d+)",
System.Text.RegularExpressions.RegexOptions.Compiled); System.Text.RegularExpressions.RegexOptions.Compiled);
static System.Text.RegularExpressions.Regex regexPbEventID = new System.Text.RegularExpressions.Regex(
@"MIDI-PAGE(?<page>\d+)-PB-C(?<chan>\d+)",
System.Text.RegularExpressions.RegexOptions.Compiled);
string GetDescription (string eventId)
{
return eventId;
}
IFeedbackInfo IEventProvider.GetFeedbackInfo (string eventId) IFeedbackInfo IEventProvider.GetFeedbackInfo (string eventId)
{ {
var res = regexCtrlEventID.Match (eventId); var res = regexCtrlEventID.Match (eventId);
@ -233,7 +458,14 @@ namespace DMX2
Console.WriteLine("Succes"); Console.WriteLine("Succes");
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 new feedbackinfo (this, chan, param); return new ctrlfeedbackinfo (this, eventId, page, chan, param);
}
res = regexPbEventID.Match (eventId);
if (res.Success) {
Console.WriteLine("Succes");
byte chan = byte.Parse (res.Groups ["chan"].Value);
return new pitchbendfeedbackinfo (this, eventId,page, chan);
} }
return null; return null;

View file

@ -126,8 +126,7 @@ namespace DMX2
Circuit circuit; Circuit circuit;
Dictionary<string,int> valeursrecues= new Dictionary<string, int>(); Dictionary<string,int> valeursrecues= new Dictionary<string, int>();
SequenceurLineaire seq; SequenceurLineaire seq;
int max=0, signe=-2; int max=0;//, signe=-2;
bool nofeedbackflag = false;
bool attache; bool attache;
@ -136,7 +135,7 @@ namespace DMX2
return attache; return attache;
} }
set { set {
signe=-2; if(value==false)valeursrecues.Clear();
attache = value; attache = value;
} }
} }
@ -148,18 +147,21 @@ namespace DMX2
bool IEventTarget.FireEvent (EventData data) bool IEventTarget.FireEvent (EventData data)
{ {
valeursrecues[data.id]=data.value; valeursrecues [data.id] = data.value;
max = valeursrecues.Values.Max(); max = valeursrecues.Values.Max ();
if (!Attache) { /*if (max != data.value)
return true;*/
int val = seq.ValeurBruteCircuit (circuit); int val = seq.ValeurBruteCircuit (circuit);
int cs = Math.Sign (val - max);
if (signe == -2) signe=cs; if ((data.prev_value != val)
if (cs==0 || cs!=signe) Attache=true; && ((data.prev_value < val && data.value < val) ||
else return true ; (data.prev_value > val && data.value > val))) {
return true;
} }
nofeedbackflag = true;
seq.ChangeValeur(circuit,max); seq.ChangeValeur(circuit,max);
nofeedbackflag = false; attache = true;
return true; return true;
} }
@ -184,7 +186,7 @@ namespace DMX2
} }
public void FeedBack(byte data){ public void FeedBack(byte data){
if(nofeedbackflag) return; Attache = false;
foreach (var fb in feedbacks) foreach (var fb in feedbacks)
fb.FeedBack(data); fb.FeedBack(data);
} }
@ -396,8 +398,6 @@ namespace DMX2
} }
} }
public void FinDeTransition () public void FinDeTransition ()
{ {
lock(this) { lock(this) {
@ -439,7 +439,7 @@ namespace DMX2
timeStamp = TimeSpan.Zero; timeStamp = TimeSpan.Zero;
if (ui != null) if (ui != null)
ui.EffetChange (); ui.EffetChange ();
foreach(var t in targets.Values) t.Attache = false; //foreach(var t in targets.Values) t.Attache = false;
} }
} }