275 lines
4.9 KiB
C#
275 lines
4.9 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;
|
|
|
|
|
|
enum OSCType {
|
|
Int32,
|
|
Float32,
|
|
String,
|
|
Blob
|
|
}
|
|
|
|
class OSCMessage {
|
|
|
|
public abstract class OSCArg{
|
|
protected OSCArg(){}
|
|
public abstract OSCType Type{ get; }
|
|
public virtual string GetString(){ throw new System.NotImplementedException (); }
|
|
public virtual float GetFloat (){throw new System.NotImplementedException (); }
|
|
public virtual int GetInt(){throw new System.NotImplementedException (); }
|
|
public virtual byte[] GetBlob(){throw new System.NotImplementedException (); }
|
|
}
|
|
|
|
private class OSCStringArg : OSCArg{
|
|
string _s;
|
|
public override OSCType Type {
|
|
get {
|
|
return OSCType.String;
|
|
}
|
|
}
|
|
public OSCStringArg(string s){
|
|
_s=s;
|
|
}
|
|
public override string GetString ()
|
|
{
|
|
return _s;
|
|
}
|
|
}
|
|
private class OSCIntArg : OSCArg{
|
|
int _i;
|
|
public override OSCType Type {
|
|
get {
|
|
return OSCType.Int32;
|
|
}
|
|
}
|
|
public OSCIntArg(int i){
|
|
_i=i;
|
|
}
|
|
public override int GetInt ()
|
|
{
|
|
return _i;
|
|
}
|
|
public override float GetFloat ()
|
|
{
|
|
return (float)_i;
|
|
}
|
|
public override string GetString ()
|
|
{
|
|
return _i.ToString();
|
|
}
|
|
|
|
}
|
|
private class OSCFloatArg : OSCArg{
|
|
float _f;
|
|
public override OSCType Type {
|
|
get {
|
|
return OSCType.Float32;
|
|
}
|
|
}
|
|
public OSCFloatArg(float f){
|
|
_f=f;
|
|
}
|
|
public override int GetInt ()
|
|
{
|
|
return (int)(_f);
|
|
}
|
|
public override float GetFloat ()
|
|
{
|
|
return _f;
|
|
}
|
|
public override string GetString ()
|
|
{
|
|
return _f.ToString();
|
|
}
|
|
|
|
}
|
|
private class OSCBlobArg : OSCArg{
|
|
byte[] _b;
|
|
public override OSCType Type {
|
|
get {
|
|
return OSCType.Blob;
|
|
}
|
|
}
|
|
public OSCBlobArg(byte[] b){
|
|
_b=b;
|
|
}
|
|
public override byte[] GetBlob ()
|
|
{
|
|
return _b;
|
|
}
|
|
|
|
}
|
|
|
|
static string DecodeString (byte[] b, ref int pos)
|
|
{
|
|
int end = Array.IndexOf<byte>(b,0,pos);
|
|
if(end==-1) end = b.Length;
|
|
string ret = System.Text.Encoding.ASCII.GetString(b,pos,end-pos);
|
|
pos = (end/4+1)*4;
|
|
return ret;
|
|
}
|
|
|
|
static float DecodeFloat (byte[] b, ref int pos)
|
|
{
|
|
if(BitConverter.IsLittleEndian)
|
|
Array.Reverse(b,pos,4);
|
|
float ret = BitConverter.ToSingle(b,pos);
|
|
pos+=4;
|
|
return ret;
|
|
}
|
|
|
|
static int DecodeInt (byte[] b, ref int pos)
|
|
{
|
|
if(BitConverter.IsLittleEndian)
|
|
Array.Reverse(b,pos,4);
|
|
int ret = BitConverter.ToInt32(b, pos);
|
|
pos+=4;
|
|
return ret;
|
|
}
|
|
|
|
public OSCMessage(byte[] bmsg){
|
|
int pos = 0;
|
|
Address = DecodeString(bmsg,ref pos);
|
|
string typestring = DecodeString(bmsg,ref pos);
|
|
|
|
args = new OSCArg[typestring.Length-1];
|
|
|
|
int idx=0;
|
|
foreach(char c in typestring){
|
|
switch(c){
|
|
case 'f':
|
|
args[idx++] = new OSCFloatArg(DecodeFloat(bmsg,ref pos));
|
|
break;
|
|
case 's':
|
|
args[idx++] = new OSCStringArg(DecodeString(bmsg,ref pos));
|
|
break;
|
|
case 'i':
|
|
args[idx++] = new OSCIntArg(DecodeInt(bmsg,ref pos));
|
|
break;
|
|
case 'b':
|
|
int len=DecodeInt(bmsg,ref pos)*4;
|
|
byte[] b = new byte[len];
|
|
bmsg.CopyTo(b,0);
|
|
pos+=len;
|
|
args[idx++] = new OSCBlobArg(b);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
public string Address{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
OSCArg[] args;
|
|
|
|
public OSCArg[] Args {
|
|
get {
|
|
return args;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
Console.WriteLine(msg.Address);
|
|
foreach(var arg in msg.Args)
|
|
Console.WriteLine(arg.GetString());
|
|
ProcessMessage(msg);
|
|
}
|
|
} catch (SocketException ex) {
|
|
}
|
|
finally {
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// /master
|
|
/// /masterseq/
|
|
/// go
|
|
/// goback
|
|
/// goto
|
|
///
|
|
/// /seq/X/
|
|
/// go
|
|
/// goback
|
|
/// goto
|
|
/// master
|
|
/// circuit
|
|
///
|
|
/// /universe/X/
|
|
/// D/on
|
|
/// reset
|
|
///
|
|
///
|
|
///
|
|
/// </summary>
|
|
|
|
void ProcessMessage (OSCMessage msg)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
#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
|
|
|
|
}
|
|
}
|
|
|