// Create an OSC message object for the specified binary buffer public OscMessage(byte[] buffer) { string address; List <object> arguments = new List <object>(); if (buffer == null) { throw new ArgumentNullException("buffer", "Buffer must not be null."); } using (MemoryStream stream = new MemoryStream(buffer)) { address = stream.ReadOscString(); if (address == null) { throw new ArgumentException("Missing address.", "buffer"); } if (address[0] != OscMessage.ADDRESS_PREFIX) { throw new ArgumentException("Invalid address.", "buffer"); } string typeTagString = stream.ReadOscString(); if (typeTagString.Length == 0 || typeTagString[0] != TYPE_PREFIX) { throw new ArgumentException("ERROR: This implementation requires the OSC type-tag string.", "buffer"); } typeTagString = typeTagString.Substring(1); // Remove prefix for (int i = 0; i < typeTagString.Length; i++) { switch (typeTagString[i]) { // OSC 1.0 types case OscMessage.TYPE_INT: arguments.Add(stream.ReadOscInt()); break; case OscMessage.TYPE_FLOAT: arguments.Add(stream.ReadOscFloat()); break; case OscMessage.TYPE_STRING: arguments.Add(stream.ReadOscString()); break; case OscMessage.TYPE_BLOB: arguments.Add(stream.ReadOscBlob()); break; // OSC 1.1 types case OscMessage.TYPE_TRUE: arguments.Add((Boolean)true); break; case OscMessage.TYPE_FALSE: arguments.Add((Boolean)false); break; case OscMessage.TYPE_NULL: arguments.Add(null); break; case OscMessage.TYPE_IMPULSE: arguments.Add(typeof(Object)); break; // Not really sure how to represent an 'impulse' object case OscMessage.TYPE_TIME: arguments.Add(OscData.DateTimeFromTimestamp((ulong)stream.ReadOscLong())); break; // Non-standard/optional types case OscMessage.TYPE_SYMBOL: arguments.Add(stream.ReadOscString()); break; case OscMessage.TYPE_LONG: arguments.Add(stream.ReadOscLong()); break; case OscMessage.TYPE_DOUBLE: arguments.Add(stream.ReadOscDouble()); break; case OscMessage.TYPE_CHAR: arguments.Add((char)stream.ReadOscInt()); break; case OscMessage.TYPE_RGBA: arguments.Add(stream.ReadOscInt()); break; case OscMessage.TYPE_MIDI: arguments.Add(stream.ReadOscInt()); break; case OscMessage.TYPE_ARRAY_OPEN: break; // ignore for now case OscMessage.TYPE_ARRAY_CLOSE: break; // ignore for now default: throw new ArgumentException("Unknown OSC type tag '" + typeTagString[i] + "'", "buffer"); } } } this.Buffer = buffer; this.Address = address; this.Arguments = arguments.ToArray(); }
// UDP listening thread private void Listener() { while (!quitReceiver) { try { // Receive UDP packet byte[] buffer = udpClient.Receive(ref endPoint); if (quitReceiver) { break; } // Create OscData object OscData messageOrBundle = null; try { messageOrBundle = OscData.FromByteArray(buffer); } catch (Exception ex) { Console.Error.WriteLine("ERROR: Problem creating OscData from message (" + ex.Message + ")."); } if (messageOrBundle != null) { if (messageOrBundle is OscMessage) { OscMessage message = (OscMessage)messageOrBundle; DateTime timestamp = DateTime.UtcNow; OnReceivedMessage(new OscMessageEventArgs(timestamp, message)); } else if (messageOrBundle is OscBundle) { OscBundle bundle = (OscBundle)messageOrBundle; DateTime timestamp = (bundle.Timestamp == OscData.TIMESTAMP_NOW) ? DateTime.UtcNow : OscData.DateTimeFromTimestamp(bundle.Timestamp); OnReceivedBundle(new OscBundleEventArgs(timestamp, bundle)); } } } catch (ThreadInterruptedException) { Console.Error.WriteLine("WARNING: ThreadInterruptedException in Listener..."); if (quitReceiver) { break; } } catch (SocketException) { Console.Error.WriteLine("WARNING: SocketException in Listener..."); if (quitReceiver) { break; } } } udpClient.Close(); }