367 lines
8.8 KiB
C#
367 lines
8.8 KiB
C#
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 {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// /master <X---
|
|
/// /masterseq/
|
|
/// go
|
|
/// goback
|
|
/// next <X---
|
|
/// goto
|
|
///
|
|
/// /seq/X/
|
|
/// go
|
|
/// goback
|
|
/// goto
|
|
/// master <X---
|
|
/// circuit/X <X---
|
|
///
|
|
/// /universe/X/
|
|
/// on/D
|
|
/// off
|
|
/// onval
|
|
///
|
|
///
|
|
/// </summary>
|
|
|
|
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
|
|
|
|
}
|
|
}
|
|
|