Skip to content

Commit

Permalink
Update BabbleOSC.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
dfgHiatus committed Apr 24, 2024
1 parent a6150b6 commit c060e71
Showing 1 changed file with 89 additions and 161 deletions.
250 changes: 89 additions & 161 deletions BabbleOSC.cs
Original file line number Diff line number Diff line change
@@ -1,169 +1,97 @@
using Microsoft.Extensions.Logging;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.Extensions.Logging;
using VRCFaceTracking.Core.OSC;

namespace VRCFaceTracking.Babble;

public class BabbleOSC
{
private Socket _receiver;
private bool _loop = true;
private readonly Thread _thread;
private readonly ILogger _logger;
private readonly int _resolvedPort;
private const int DEFAULT_PORT = 8888;
private const int TIMEOUT_MS = 10_000;

public BabbleOSC(ILogger iLogger, int? port = null)
{
_logger = iLogger;

if (_receiver != null)
{
_logger.LogError("BabbleOSC connection already exists.");
return;
}

_receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_resolvedPort = port ?? DEFAULT_PORT;
_receiver.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _resolvedPort));
_receiver.ReceiveTimeout = TIMEOUT_MS;

_loop = true;
_thread = new Thread(new ThreadStart(ListenLoop));
_thread.Start();
}

struct Msg
{
public string address;
public float value;
public bool success;
}

// https://github.com/benaclejames/SimpleRustOSC/blob/master/src/lib.rs#L54
private Msg ParseOSC(byte[] buffer, int length)
{
Msg msg = new Msg();
msg.success = false;

if (length < 4)
return msg;

int bufferPosition = 0;
string address = ParseString(buffer, length, ref bufferPosition);
if (address == "")
return msg;

msg.address = address;

// checking for ',' char
if (buffer[bufferPosition] != 44)
return msg;
bufferPosition++; // skipping ',' character

char valueType = (char)buffer[bufferPosition]; // unused
bufferPosition++;

float value = ParesFloat(buffer, length, bufferPosition);

msg.value = value;
msg.success = true;

return msg;
}

private string ParseString(byte[] buffer, int length, ref int bufferPosition)
{
string address = "";

// first character must be '/'
if (buffer[0] != 47)
return address;

for (int i = 0; i < length; i++)
{
if (buffer[i] == 0)
{
bufferPosition = i + 1;

if (bufferPosition % 4 != 0)
{
bufferPosition += 4 - (bufferPosition % 4);
}

break;
}

address += (char)buffer[i];
}

return address;
}

private float ParesFloat(byte[] buffer, int length, int bufferPosition)
{
var valueBuffer = new byte[length - bufferPosition];

int j = 0;
for (int i = bufferPosition; i < length; i++)
{
valueBuffer[j] = buffer[i];

j++;
}

float value = bytesToFLoat(valueBuffer);
return value;
}

private float bytesToFLoat(byte[] bytes)
{
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes); // Convert big endian to little endian
}

float myFloat = BitConverter.ToSingle(bytes, 0);
return myFloat;
}

private void ListenLoop()
{
var buffer = new byte[4096];

while (_loop)
{
try
{
if (_receiver.IsBound)
{
var length = _receiver.Receive(buffer);

Msg msg = ParseOSC(buffer, length);
if (msg.success && BabbleExpressions.BabbleExpressionMap.ContainsKey2(msg.address))
{
BabbleExpressions.BabbleExpressionMap.SetByKey2(msg.address, msg.value);
}
}
else
{
_receiver.Close();
_receiver.Dispose();
_receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_receiver.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _resolvedPort));
_receiver.ReceiveTimeout = TIMEOUT_MS;
}
}
catch (Exception) { }
}
}

public void Teardown()
{
_loop = false;
_receiver.Close();
_receiver.Dispose();
_thread.Join();
}
private Socket _receiver;

private bool _loop = true;

private readonly Thread _thread;

private readonly ILogger _logger;

private readonly int _resolvedPort;

private const int DEFAULT_PORT = 8888;

private const int TIMEOUT_MS = 10000;

public BabbleOSC(ILogger iLogger, int? port = null)
{
_logger = iLogger;
if (_receiver != null)
{
_logger.LogError("BabbleOSC connection already exists.");
return;
}
_receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_resolvedPort = port ?? DEFAULT_PORT;
_receiver.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _resolvedPort));
_receiver.ReceiveTimeout = TIMEOUT_MS;
_loop = true;
_thread = new Thread(ListenLoop);
_thread.Start();
}

private void ListenLoop()
{
byte[] array = new byte[4096];
while (_loop)
{
try
{
if (_receiver.IsBound)
{
int num = _receiver.Receive(array);
int num2 = 0;
OscMessage val;
try
{
val = new OscMessage(array, num, ref num2);
}
catch (Exception)
{
continue;
}
if (val.Value is float)
{
if (val.Address == "/mouthFunnel" || val.Address == "/mouthPucker")
{
BabbleExpressions.BabbleExpressionMap.SetByKey2(val.Address, (float)val.Value * 4f);
}
else if (BabbleExpressions.BabbleExpressionMap.ContainsKey2(val.Address))
{
BabbleExpressions.BabbleExpressionMap.SetByKey2(val.Address, (float)val.Value);
}
}
}
else
{
_receiver.Close();
_receiver.Dispose();
_receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_receiver.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _resolvedPort));
_receiver.ReceiveTimeout = TIMEOUT_MS;
}
}
catch (Exception)
{
}
}
}

public void Teardown()
{
_loop = false;
_receiver.Close();
_receiver.Dispose();
_thread.Join();
}
}

0 comments on commit c060e71

Please sign in to comment.