Grosses améliorations sur la gestion des evenements, notament sur l'accroche et la pagination midi
This commit is contained in:
parent
d48ab853df
commit
5260f8f2be
7 changed files with 310 additions and 70 deletions
|
|
@ -155,18 +155,23 @@ namespace DMX2
|
|||
|
||||
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)
|
||||
{
|
||||
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.port= SND_SEQ_ADDRESS_UNKNOWN;
|
||||
Marshal.StructureToPtr(ev,evOutPtr.Pointer,false);
|
||||
Invoke.snd_seq_event_output(seq_handle.Handle,evOutPtr.Pointer);
|
||||
Invoke.snd_seq_drain_output(seq_handle.Handle);
|
||||
SendEvent(ev);
|
||||
}
|
||||
|
||||
public static IEnumerable<Client> EnumClients ()
|
||||
|
|
|
|||
|
|
@ -216,7 +216,6 @@ namespace DMX2
|
|||
loopthread.Join ();
|
||||
loopthread = null;
|
||||
}
|
||||
//TODO : Close Port
|
||||
if(serial != null)
|
||||
serial.Dispose();
|
||||
|
||||
|
|
@ -289,6 +288,7 @@ namespace DMX2
|
|||
while (eventsPending.TryDequeue(out bt)) {
|
||||
evd.id= string.Format("BV1-B{0}",bt.button );
|
||||
evd.value = bt.pressed?(byte)0xFF:(byte)0x00;
|
||||
evd.prev_value = (!bt.pressed)?(byte)0xFF:(byte)0x00;
|
||||
callback(evd);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@ namespace DMX2
|
|||
{
|
||||
|
||||
struct dmxState {
|
||||
public dmxState(int _dmx, byte _value){
|
||||
value=_value; dmx=_dmx;
|
||||
public dmxState(int _dmx, byte _value, byte _lastvalue){
|
||||
value=_value; dmx=_dmx; lastvalue = _lastvalue;
|
||||
}
|
||||
public int dmx;
|
||||
public byte value;
|
||||
public byte lastvalue;
|
||||
}
|
||||
|
||||
enum etatAutomate {
|
||||
|
|
@ -409,8 +410,8 @@ namespace DMX2
|
|||
lock(watchdmx)
|
||||
foreach (int dmx in watchdmx) {
|
||||
if( inputbuffer[dmx-1]!= lastVal[dmx]){
|
||||
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx-1],lastVal[dmx]));
|
||||
lastVal[dmx] = inputbuffer[dmx-1];
|
||||
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx-1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -423,7 +424,6 @@ namespace DMX2
|
|||
loopthread.Join ();
|
||||
loopthread = null;
|
||||
}
|
||||
//TODO : Close Port
|
||||
if(serial != null)
|
||||
serial.Dispose();
|
||||
|
||||
|
|
@ -524,6 +524,7 @@ namespace DMX2
|
|||
while (eventsPending.TryDequeue(out dmxs)) {
|
||||
evd.id= string.Format("BV2-D{0}",dmxs.dmx );
|
||||
evd.value = dmxs.value;
|
||||
evd.prev_value = dmxs.lastvalue;
|
||||
callback(evd);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@ namespace DMX2
|
|||
{
|
||||
|
||||
struct dmxState {
|
||||
public dmxState(int _dmx, byte _value){
|
||||
value=_value; dmx=_dmx;
|
||||
public dmxState(int _dmx, byte _value, byte _lastvalue){
|
||||
value=_value; dmx=_dmx; lastvalue = _lastvalue;
|
||||
}
|
||||
public int dmx;
|
||||
public byte value;
|
||||
public byte lastvalue;
|
||||
}
|
||||
|
||||
enum etatAutomate {
|
||||
|
|
@ -466,8 +467,8 @@ namespace DMX2
|
|||
lock(watchdmx)
|
||||
foreach (int dmx in watchdmx) {
|
||||
if( inputbuffer[dmx]!= lastVal[dmx]){
|
||||
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx],lastVal[dmx]));
|
||||
lastVal[dmx] = inputbuffer[dmx];
|
||||
eventsPending.Enqueue(new dmxState(dmx,inputbuffer[dmx]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -480,7 +481,6 @@ namespace DMX2
|
|||
loopthread.Join ();
|
||||
loopthread = null;
|
||||
}
|
||||
//TODO : Close Port
|
||||
if(serial != null)
|
||||
serial.Dispose();
|
||||
|
||||
|
|
@ -581,6 +581,7 @@ namespace DMX2
|
|||
while (eventsPending.TryDequeue(out dmxs)) {
|
||||
evd.id= string.Format("BV3-D{0}",dmxs.dmx );
|
||||
evd.value = dmxs.value;
|
||||
evd.prev_value = dmxs.lastvalue;
|
||||
callback(evd);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace DMX2
|
|||
{
|
||||
public string id;
|
||||
public byte value;
|
||||
public byte prev_value ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -280,7 +281,7 @@ namespace DMX2
|
|||
///<summary> Fonction appelee sur evenement</summary>
|
||||
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)) {
|
||||
foreach (IEventTarget target in bindings[data.id].Targets) {
|
||||
target.FireEvent(data);
|
||||
|
|
|
|||
|
|
@ -27,58 +27,209 @@ namespace DMX2
|
|||
{
|
||||
|
||||
class internalEvent {
|
||||
public string internalName;
|
||||
public string description;
|
||||
public internalEvent(string _id, string _desc)
|
||||
|
||||
public string InternalName{ get; set; }
|
||||
bool bound=false;
|
||||
|
||||
public bool Bound {
|
||||
get {
|
||||
return bound;
|
||||
}
|
||||
set {
|
||||
bound = value;
|
||||
}
|
||||
}
|
||||
|
||||
public internalEvent(string _id)
|
||||
{
|
||||
internalName=_id;
|
||||
description=_desc;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class feedbackinfo : IFeedbackInfo {
|
||||
abstract class feedbackinfo : IFeedbackInfo {
|
||||
|
||||
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;
|
||||
ev.data_ev_ctrl.channel = channel;
|
||||
ev.data_ev_ctrl.param= param;
|
||||
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
|
||||
|
||||
public feedbackinfo(MidiEventProvider _prov, string _eventId, int _page){
|
||||
prov = _prov;
|
||||
eventId = _eventId;
|
||||
page = _page;
|
||||
}
|
||||
|
||||
protected abstract bool UpdateEvent(byte data);
|
||||
|
||||
#region IFeedbackInfo implementation
|
||||
bool IFeedbackInfo.FeedBack (byte data)
|
||||
{
|
||||
ev.data_ev_ctrl.value = (byte)((int)data * 127 / 255) ;
|
||||
prov.SendEvent(ev);
|
||||
if (!prov.eventlist.ContainsKey (eventId))
|
||||
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;
|
||||
}
|
||||
#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;
|
||||
internalEvent levent=null;
|
||||
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)
|
||||
{
|
||||
manager.RegisterProvider (this);
|
||||
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);
|
||||
|
||||
|
||||
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 p in cli.Ports){
|
||||
PortDetected(cli,p);
|
||||
}
|
||||
}
|
||||
|
||||
unpaginatedchannels.Add((byte)0);
|
||||
}
|
||||
|
||||
void PortDetected (AlsaSeqLib.Client cli, AlsaSeqLib.Port p)
|
||||
|
|
@ -89,25 +240,50 @@ namespace DMX2
|
|||
|
||||
string fullportname = cli.Name + ':' + p.Name;
|
||||
Console.WriteLine(fullportname);
|
||||
if(midiPortAutoConnect.Contains(fullportname))
|
||||
if(knowndevices.ContainsKey(fullportname)){
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
bool IEventProvider.Bind (string eventId)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
if(! eventlist.ContainsKey(eventId)) return;
|
||||
eventlist[eventId].Bound = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -121,8 +297,8 @@ namespace DMX2
|
|||
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;
|
||||
Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(levent.InternalName));
|
||||
item.Data[EventManager.EventIdKey] = levent.InternalName;
|
||||
item.Data[EventManager.StateKey] = state;
|
||||
item.ButtonPressEvent += handler;
|
||||
lmenu.Add (item);
|
||||
|
|
@ -138,8 +314,8 @@ namespace DMX2
|
|||
|
||||
foreach ( string key in sortedKeys ) {
|
||||
internalEvent evt= eventlist[key];
|
||||
Gtk.MenuItem item = new Gtk.MenuItem(evt.description);
|
||||
item.Data[EventManager.EventIdKey] = evt.internalName;
|
||||
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);
|
||||
|
|
@ -152,31 +328,48 @@ namespace DMX2
|
|||
void IEventProvider.ProcessEvents (EventManagerCallback callback)
|
||||
{
|
||||
AlsaSeqLib.snd_seq_event_t evS;
|
||||
int evpage;
|
||||
|
||||
// Tant qu'il y des evenements midi en attente
|
||||
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) {
|
||||
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED: // Connection d'un périph midi
|
||||
connected = true;
|
||||
continue;
|
||||
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);
|
||||
description = string.Format("Controller Ch {0} Param {1}",evS.data_ev_ctrl.channel,evS.data_ev_ctrl.param);
|
||||
if(evS.data_ev_ctrl.param==127 && value>0){
|
||||
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}
|
||||
break;
|
||||
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 );
|
||||
description = string.Format("Note {1} Ch {0}",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 );
|
||||
channel = evS.data_ev_note.channel;
|
||||
value = 255 ;
|
||||
break;
|
||||
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 );
|
||||
description = string.Format("Note {1} Ch {0}",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 );
|
||||
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 + 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_SENSING:
|
||||
continue;
|
||||
|
|
@ -199,19 +392,40 @@ namespace DMX2
|
|||
|
||||
connected=true;
|
||||
|
||||
|
||||
|
||||
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))
|
||||
eventlist.Add(id,new internalEvent(id,description));
|
||||
eventlist.Add(id,new internalEvent(id));
|
||||
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();
|
||||
evData.id = id;
|
||||
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;
|
||||
|
||||
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(
|
||||
@"MIDI-CTRL-C(?<chan>\d+)P(?<param>\d+)",
|
||||
@"MIDI-PAGE(?<page>\d+)-CTRL-C(?<chan>\d+)P(?<param>\d+)",
|
||||
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)
|
||||
{
|
||||
var res = regexCtrlEventID.Match (eventId);
|
||||
|
|
@ -233,7 +458,14 @@ namespace DMX2
|
|||
Console.WriteLine("Succes");
|
||||
byte chan = byte.Parse (res.Groups ["chan"].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;
|
||||
|
||||
|
|
|
|||
|
|
@ -126,8 +126,7 @@ namespace DMX2
|
|||
Circuit circuit;
|
||||
Dictionary<string,int> valeursrecues= new Dictionary<string, int>();
|
||||
SequenceurLineaire seq;
|
||||
int max=0, signe=-2;
|
||||
bool nofeedbackflag = false;
|
||||
int max=0;//, signe=-2;
|
||||
|
||||
bool attache;
|
||||
|
||||
|
|
@ -136,7 +135,7 @@ namespace DMX2
|
|||
return attache;
|
||||
}
|
||||
set {
|
||||
signe=-2;
|
||||
if(value==false)valeursrecues.Clear();
|
||||
attache = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -148,18 +147,21 @@ namespace DMX2
|
|||
|
||||
bool IEventTarget.FireEvent (EventData data)
|
||||
{
|
||||
valeursrecues[data.id]=data.value;
|
||||
max = valeursrecues.Values.Max();
|
||||
if (!Attache) {
|
||||
int val = seq.ValeurBruteCircuit (circuit);
|
||||
int cs = Math.Sign (val - max);
|
||||
if (signe == -2) signe=cs;
|
||||
if (cs==0 || cs!=signe) Attache=true;
|
||||
else return true ;
|
||||
valeursrecues [data.id] = data.value;
|
||||
max = valeursrecues.Values.Max ();
|
||||
/*if (max != data.value)
|
||||
return true;*/
|
||||
|
||||
int val = seq.ValeurBruteCircuit (circuit);
|
||||
|
||||
if ((data.prev_value != val)
|
||||
&& ((data.prev_value < val && data.value < val) ||
|
||||
(data.prev_value > val && data.value > val))) {
|
||||
return true;
|
||||
}
|
||||
nofeedbackflag = true;
|
||||
|
||||
seq.ChangeValeur(circuit,max);
|
||||
nofeedbackflag = false;
|
||||
attache = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +186,7 @@ namespace DMX2
|
|||
}
|
||||
|
||||
public void FeedBack(byte data){
|
||||
if(nofeedbackflag) return;
|
||||
Attache = false;
|
||||
foreach (var fb in feedbacks)
|
||||
fb.FeedBack(data);
|
||||
}
|
||||
|
|
@ -396,8 +398,6 @@ namespace DMX2
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void FinDeTransition ()
|
||||
{
|
||||
lock(this) {
|
||||
|
|
@ -439,7 +439,7 @@ namespace DMX2
|
|||
timeStamp = TimeSpan.Zero;
|
||||
if (ui != null)
|
||||
ui.EffetChange ();
|
||||
foreach(var t in targets.Values) t.Attache = false;
|
||||
//foreach(var t in targets.Values) t.Attache = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue