using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Collections.Generic; namespace DMX2 { public class OSCServer : IDisposable { UdpClient udpCli=null; Thread pollThread = null; bool running=true; public OSCServer () { pollThread = new Thread(new ThreadStart(Loop)); pollThread.Start(); } void Loop () { udpCli = new UdpClient (7772); byte[] recv; IPEndPoint remep = new IPEndPoint (IPAddress.Any, 0); try { while (running) { recv = udpCli.Receive (ref remep); //Console.WriteLine(remep); OSCMessage msg = new OSCMessage(recv); #if DEBUG Console.Write(msg.Address); Console.Write(" "); foreach(var arg in msg.Args) Console.WriteLine(arg.GetString()); #endif try{ ProcessMessage(msg,remep); }catch{} } } catch (SocketException ex) { } finally { } } /// /// /master void ProcessMessage (OSCMessage msg,IPEndPoint remep) { if(Conduite.Courante == null) return; string[] toks = msg.Address.Split (new char[]{'/'},StringSplitOptions.RemoveEmptyEntries); int arg; switch (toks [0]) { case "refresh": IPEndPoint ep = new IPEndPoint(remep.Address,msg.Args[0].GetInt()); SendRefresh(ep); break; case "master": arg = msg.Args[0].GetInt(); if (arg<0) arg=0; if (arg>100)arg=100; Conduite.Courante.Master = arg; break; case "masterseq": switch(toks[1]){ case "go": if( msg.Args[0].GetInt() !=0) Conduite.Courante.SequenceurMaitre.EffetSuivant(); break; case "goback": if( msg.Args[0].GetInt() !=0) Conduite.Courante.SequenceurMaitre.EffetPrecedent(); break; case "next": arg = msg.Args[0].GetInt(); Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre = arg; break; case "goto": arg = msg.Args[0].GetInt(); Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre = arg; Conduite.Courante.SequenceurMaitre.EffetSuivant(); break; } break; case "seq": ProcessMessageSeq(msg,toks); break; case "universe": ProcessMessageUniv(msg,toks); break; case "circuitTel": ProcessMessageCircuit(msg,toks); break; } } void ProcessMessageSeq (OSCMessage msg, string[] toks) { int seqId; Sequenceur seq = null; if (int.TryParse (toks [1], out seqId)) { if (seqId < 0 || seqId > Conduite.Courante.Sequenceurs.Count) return; seq = Conduite.Courante.Sequenceurs [seqId-1]; } if (seq is SequenceurLineaire) { SequenceurLineaire seql = seq as SequenceurLineaire; switch(toks[2]){ case "go": if( msg.Args[0].GetInt() !=0) seql.IndexEffetCourrant++; break; case "goback": if( msg.Args[0].GetInt() !=0) seql.IndexEffetCourrant--; break; case "goto": int arg = msg.Args[0].GetInt(); seql.IndexEffetCourrant = arg; break; case "master": arg = msg.Args[0].GetInt(); if (arg<0) arg=0; if (arg>100)arg=100; seql.Master = arg; break; case "circuit": int cirId; arg = msg.Args[0].GetInt(); arg = Math.Max(0,arg); arg = Math.Min(255,arg); if(!int.TryParse(toks[3],out cirId)) return; Circuit c = Conduite.Courante.GetCircuitByID (cirId); if(seql.Circuits.Contains(c)) seql.ChangeValeur(c,arg); break; } } if (seq is SequenceurMacro) { SequenceurMacro seqm = seq as SequenceurMacro; switch(toks[2]){ case "go": if( msg.Args[0].GetInt() !=0) seqm.LigneSuivante(); break; case "goto": int arg = msg.Args[0].GetInt(); seqm.IndexLigneaSuivre = arg; seqm.LigneSuivante(); break; case "next": arg = msg.Args[0].GetInt(); seqm.IndexLigneaSuivre = arg; break; case "master": arg = msg.Args[0].GetInt(); if (arg<0) arg=0; if (arg>100)arg=100; seqm.Master = arg; break; } } if (seq is SequenceurSon) { SequenceurSon seqs = seq as SequenceurSon; switch(toks[2]){ case "master": int arg = msg.Args[0].GetInt(); if (arg<0) arg=0; if (arg>100)arg=100; seqs.Volume = (uint)arg; break; } } } void ProcessMessageUniv (OSCMessage msg, string[] toks) { int univId; if (!int.TryParse (toks [1], out univId)) return; if (univId <= 0 || univId > Conduite.Courante.Patches.Count) return; UniversDMX univ = Conduite.Courante.Patches [univId-1]; switch (toks [2]) { case "on": int dimId; if(!int.TryParse(toks[3],out dimId))return; if( msg.Args[0].GetInt() !=0) if(!univ.AllumageForce.Contains(dimId)) univ.AllumageForce.Add(dimId); break; case "off": if(!int.TryParse(toks[3],out dimId))return; if( msg.Args[0].GetInt() !=0) if(univ.AllumageForce.Contains(dimId)) univ.AllumageForce.Remove(dimId); break; case "alloff": univ.AllumageForce.Clear(); break; case "onval": int val = msg.Args[0].GetInt(); if(val<0) val=0; if(val>255) val=255; univ.AllumageForceVal = val; break; } } void ProcessMessageCircuit (OSCMessage msg, string[] toks) { switch (toks [1]) { case "on": { int cirId; if (!int.TryParse (toks [2], out cirId)) return; if (msg.Args [0].GetInt () != 0) { if (cirId > 0 && cirId <= Conduite.Courante.Circuits.Count) { Circuit c = Conduite.Courante.Circuits [cirId - 1]; if (!Conduite.Courante.CircuitTelecomande.Contains (c)) Conduite.Courante.CircuitTelecomande.Add (c); } } } break; case "off": { int cirId; if (!int.TryParse (toks [2], out cirId)) return; if (msg.Args [0].GetInt () != 0) { if (cirId > 0 && cirId <= Conduite.Courante.Circuits.Count) { Circuit c = Conduite.Courante.Circuits [cirId - 1]; if (Conduite.Courante.CircuitTelecomande.Contains (c)) Conduite.Courante.CircuitTelecomande.Remove (c); } } } break; case "alloff": Conduite.Courante.CircuitTelecomande.Clear(); break; case "onval": int val = msg.Args[0].GetInt(); if(val<0) val=0; if(val>255) val=255; Conduite.Courante.CircuitTelecomandeVal = val; break; } } void SendRefresh (IPEndPoint ep) { OSCMessage msg = new OSCMessage ("/master"); msg.AddFloat (Conduite.Courante.Master); byte[] buff = msg.Encode (); udpCli.Send (buff, buff.Length, ep); var id = Conduite.Courante.SequenceurMaitre.IndexLigneEnCours - 1; msg = new OSCMessage ("/masterseq/prevstep"); if (id >= 0) { msg.AddString ( string.Format ("{0}. {1}", id + 1, Conduite.Courante.SequenceurMaitre.Lignes [id].Nom) ); } else { msg.AddString ("---"); } buff = msg.Encode (); udpCli.Send (buff, buff.Length, ep); id = Conduite.Courante.SequenceurMaitre.IndexLigneEnCours; string auto = string.Empty; msg = new OSCMessage ("/masterseq/curstep"); if (id >= 0) { msg.AddString ( string.Format ("{0}. {1}", id + 1, Conduite.Courante.SequenceurMaitre.Lignes [id].Nom) ); if(Conduite.Courante.SequenceurMaitre.Lignes[id].Duree!= TimeSpan.Zero) auto = string.Format(" (AUTO {0})",Conduite.Courante.SequenceurMaitre.Lignes[id].Duree.TotalMilliseconds/100); } else { msg.AddString ("---"); } buff = msg.Encode(); udpCli.Send (buff, buff.Length, ep); id = Conduite.Courante.SequenceurMaitre.IndexLigneaSuivre; if (id == -1) id = Conduite.Courante.SequenceurMaitre.IndexLigneEnCours + 1; msg = new OSCMessage ("/masterseq/nextstep"); if (id >= 0 && id < Conduite.Courante.SequenceurMaitre.Lignes.Count) { msg.AddString ( string.Format ("{0}. {1}{2}", id + 1, Conduite.Courante.SequenceurMaitre.Lignes [id].Nom,auto) ); } else { msg.AddString ("---"); } buff = msg.Encode (); udpCli.Send (buff, buff.Length, ep); msg = new OSCMessage("/masterseq/time"); msg.AddFloat(((float) Conduite.Courante.SequenceurMaitre.TimeStamp.TotalMilliseconds/1000 )); buff = msg.Encode(); udpCli.Send (buff, buff.Length, ep); } #region IDisposable implementation public void Dispose () { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose (bool disposing) { if (disposing) { running=false; if(udpCli!=null) udpCli.Close(); if(pollThread!=null) { if(!pollThread.Join(100)) pollThread.Abort(); pollThread=null; } } } #endregion } }