summaryrefslogtreecommitdiffstats
path: root/libraries/oscP5/src/oscP5/OscMessage.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/oscP5/src/oscP5/OscMessage.java')
-rw-r--r--libraries/oscP5/src/oscP5/OscMessage.java764
1 files changed, 764 insertions, 0 deletions
diff --git a/libraries/oscP5/src/oscP5/OscMessage.java b/libraries/oscP5/src/oscP5/OscMessage.java
new file mode 100644
index 0000000..153cfba
--- /dev/null
+++ b/libraries/oscP5/src/oscP5/OscMessage.java
@@ -0,0 +1,764 @@
+/**
+ * An OSC (Open Sound Control) library for processing.
+ *
+ * (c) 2004-2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ * @author Andreas Schlegel http://www.sojamo.de
+ * @modified 12/23/2012
+ * @version 0.9.9
+ */
+
+package oscP5;
+
+
+import java.net.DatagramPacket;
+
+import java.net.InetAddress;
+import netP5.Bytes;
+import netP5.Logger;
+import netP5.TcpClient;
+import netP5.TcpPacket;
+
+
+/**
+ * An OSC message consists of an OSC Address Pattern, an OSC Type Tag String
+ * and the OSC arguments.
+ *
+ * @related OscBundle
+ * @example oscP5sendReceive
+ */
+public class OscMessage extends OscPacket {
+
+ protected final OscArgument _myOscArgument = new OscArgument();
+
+ protected boolean isPlugged = false;
+
+ protected OscMessage(final DatagramPacket theDatagramPacket) {
+ inetAddress = theDatagramPacket.getAddress();
+ port = theDatagramPacket.getPort();
+ hostAddress = inetAddress.toString();
+ parseMessage(theDatagramPacket.getData());
+ _myType = MESSAGE;
+ }
+
+
+ protected OscMessage(final TcpPacket thePacket) {
+ _myTcpClient = thePacket.getTcpConnection();
+ inetAddress = _myTcpClient.netAddress().inetaddress();
+ port = _myTcpClient.netAddress().port();
+ hostAddress = inetAddress.toString();
+ parseMessage(thePacket.getData());
+ _myType = MESSAGE;
+ }
+
+
+ /**
+ *
+ * @param theOscMessage OscMessage
+ * @invisible
+ */
+
+ public OscMessage(final OscMessage theOscMessage) {
+ inetAddress = theOscMessage.inetAddress;
+ port = theOscMessage.port;
+ hostAddress = theOscMessage.hostAddress;
+ _myTcpClient = theOscMessage.tcpConnection();
+ _myAddrPattern = theOscMessage._myAddrPattern;
+ _myTypetag = theOscMessage._myTypetag;
+ _myData = theOscMessage._myData;
+ _myArguments = theOscMessage._myArguments;
+ isValid = true;
+ }
+
+
+ /**
+ *
+ * @param theAddrPattern
+ * String
+ */
+ public OscMessage(final String theAddrPattern) {
+ this(theAddrPattern, new Object[0]);
+ }
+
+
+ /**
+ *
+ * @param theAddrInt
+ * int
+ */
+ public OscMessage(final int theAddrInt) {
+ this(theAddrInt, new Object[0]);
+ }
+
+
+ /**
+ *
+ * @param theAddrPattern String
+ * @param theArguments
+ * Object[]
+ */
+ public OscMessage(final String theAddrPattern,
+ final Object[] theArguments) {
+ init();
+ setAddrPattern(theAddrPattern);
+ setArguments(theArguments);
+ }
+
+
+ /**
+ *
+ * @param theAddrPattern int
+ * @param theArguments Object[]
+ */
+ public OscMessage(final int theAddrPattern,
+ final Object[] theArguments) {
+ init();
+ setAddrPattern(theAddrPattern);
+ setArguments(theArguments);
+ }
+
+
+ protected OscMessage(final byte[] theBytes,
+ final InetAddress theInetAddress,
+ final int thePort,
+ final TcpClient theClient
+ ) {
+ _myTcpClient = theClient;
+ inetAddress = theInetAddress;
+ port = thePort;
+ hostAddress = inetAddress.toString();
+ parseMessage(theBytes);
+ }
+
+ protected OscMessage(final byte[] theBytes,
+ final InetAddress theInetAddress,
+ final int thePort,
+ final long theTimetag,
+ final TcpClient theClient
+ ) {
+ this(theBytes,theInetAddress,thePort,theClient);
+ timetag = theTimetag;
+ }
+
+
+
+ protected void init() {
+ _myTypetag = new byte[0];
+ _myData = new byte[0];
+ }
+
+
+ /**
+ * clear and reset an OscMessage for reuse.
+ */
+ public void clear() {
+ init();
+ setAddrPattern("");
+ setArguments(new Object[0]);
+ }
+
+ /**
+ * clears the arguments in a message,
+ * but keeps the address the address pattern.
+ *
+ */
+ public void clearArguments() {
+ _myTypetag = new byte[0];
+ _myData = new byte[0];
+ _myArguments = new Object[0];
+ }
+
+
+ /**
+ * TODO
+ * set should enable the programmer to set values
+ * of an existing osc message.
+ */
+ public void set(final int theIndex, final Object theObject) {
+// byte[] myPreTypetag = new byte[theIndex];
+// byte[] myPostTypetag = new byte[_myTypetag.length - theIndex];
+ System.out.println("Typetag:\t" + _myTypetag.length);
+ System.out.println("Arguments:\t");
+ Bytes.printBytes(_myData);
+ System.out.println(_myArguments.length);
+ for(int i=0;i<_myArguments.length;i++) {
+ System.out.println(_myArguments[i]);
+ }
+ }
+
+
+ /**
+ *
+ * @param theTypeTag
+ * String
+ * @return boolean
+ * @example oscP5parsing
+ */
+ public boolean checkTypetag(final String theTypeTag) {
+ return theTypeTag.equals(typetag());
+ }
+
+
+ /**
+ * check if an address pattern equals a specific address pattern
+ * you are looking for. this is usually used when parsing an osc message.
+ * e.g. if(theOscMessage.checkAddrPattern("/test")==true) {...}
+ * @param theAddrPattern
+ * String
+ * @return boolean
+ * @example oscP5parsing
+ */
+ public boolean checkAddrPattern(final String theAddrPattern) {
+ return theAddrPattern.equals(addrPattern());
+ }
+
+
+ /**
+ * set the address pattern of an osc message. you can set
+ * a string or an int as address pattern.tnt might be useful for
+ * supercollider users. oscP5 does support ints and strings as
+ * address patterns when sending and receiving messages.
+ * @param theAddrPattern
+ * String
+ */
+ public void setAddrPattern(final String theAddrPattern) {
+ _myAddrPattern = theAddrPattern.getBytes();
+ }
+
+
+ /**
+ *
+ * @param theAddrPattern
+ * int
+ */
+ public void setAddrPattern(final int theAddrPattern) {
+ _myAddrPattern = Bytes.toBytes(theAddrPattern);
+ }
+
+
+ /**
+ * set the arguments of the osc message using an object array.
+ * with version 0.9.4 the existing arguments are overwritten,
+ * to add the arguments to the argument list, use addArguments(Object[])
+ * @param theArguments
+ * Object[]
+ */
+ public void setArguments(final Object[] theArguments) {
+ clearArguments();
+ addArguments(theArguments);
+ }
+
+ /**
+ * add a list of arguments to an exisiting set of arguments.
+ * to overwrite the existing argument list, use setArguments(Object[])
+ *
+ * @param theArguments
+ */
+ public OscMessage addArguments(final Object[] theArguments) {
+ return add(theArguments);
+ }
+
+
+ public String addrPattern() {
+ return Bytes.getAsString(_myAddrPattern);
+ }
+
+
+ /**
+ * returns the address pattern of the osc message as int.
+ * @return int
+ */
+ public int addrInt() {
+ return _myAddrInt;
+ }
+
+
+ /**
+ * returns the typetag of the osc message. e.g. the message contains
+ * 3 floats then the typetag would be "fff"
+ * @return String
+ */
+ public String typetag() {
+ return Bytes.getAsString(_myTypetag);
+ }
+
+ /**
+ * get the timetag of an osc message. timetags are only sent by
+ * osc bundles.
+ * @return long
+ */
+ public long timetag() {
+ return timetag;
+ }
+
+ /**
+ *
+ * @return Object[]
+ */
+ public Object[] arguments() {
+ return _myArguments;
+ }
+
+
+ /**
+ * supported arrays see OscPlug.getArgs
+ * @return Object[]
+ */
+ protected Object[] argsAsArray() {
+ switch (_myTypetag[0]) {
+ case (0X66): // float f
+ final float[] myFloatArray = new float[_myArguments.length];
+ for (int i = 0; i < myFloatArray.length; i++) {
+ myFloatArray[i] = ((Float) _myArguments[i]).floatValue();
+ }
+ return new Object[] {myFloatArray};
+ case (0x69): // int i
+ final int[] myIntArray = new int[_myArguments.length];
+ for (int i = 0; i < myIntArray.length; i++) {
+ myIntArray[i] = ((Integer) _myArguments[i]).intValue();
+ }
+ return new Object[] {myIntArray};
+ case (0x53): // Symbol S
+ case (0x73): // String s
+ final String[] myStringArray = new String[_myArguments.length];
+ for (int i = 0; i < myStringArray.length; i++) {
+ myStringArray[i] = ((String) _myArguments[i]);
+ }
+ return new Object[] {myStringArray};
+ default:
+ break;
+ }
+ return new Object[] {};
+ }
+
+ /**
+ *
+ * @return byte[]
+ * @invisible
+ */
+ public byte[] getAddrPatternAsBytes() {
+ return Bytes.append(_myAddrPattern,
+ new byte[align(_myAddrPattern.length)]);
+ }
+
+
+ /**
+ *
+ * @return byte[]
+ * @invisible
+ */
+ public byte[] getTypetagAsBytes() {
+ return _myTypetag;
+ }
+
+
+ /**
+ *
+ * @return byte[]
+ * @invisible
+ */
+ public byte[] getBytes() {
+ byte[] myBytes = new byte[0];
+ byte[] myTypeTag = Bytes.copy(_myTypetag, 0);
+ myBytes = Bytes.append(myBytes, _myAddrPattern,
+ new byte[align(_myAddrPattern.length)]);
+ if (myTypeTag.length == 0) {
+ myTypeTag = new byte[] {KOMMA};
+ } else if (myTypeTag[0] != KOMMA) {
+ myTypeTag = Bytes.append(new byte[] {KOMMA}, myTypeTag);
+ }
+ myBytes = Bytes.append(myBytes, myTypeTag,
+ new byte[align(myTypeTag.length)]);
+ myBytes = Bytes.append(myBytes, _myData,
+ new byte[align(_myData.length) % 4]);
+ return myBytes;
+ }
+
+
+ protected Object[] increase(int theAmount) {
+ if(_myArguments.length<1 || _myArguments == null) {
+ return new Object[1];
+ }
+ Object[] myArguments = new Object[_myArguments.length + theAmount];
+ System.arraycopy(_myArguments, 0, myArguments, 0, _myArguments.length);
+ return myArguments;
+ }
+ /**
+ * add values to an osc message. please check the
+ * add documentation for specific information.
+ * @example oscP5message
+ */
+ public OscMessage add() {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x4e});
+ return this;
+ }
+
+
+ /**
+ * @param theValue int
+ */
+ public OscMessage add(final int theValue) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x69});
+ _myData = Bytes.append(_myData, Bytes.toBytes(theValue));
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = new Integer(theValue);
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue String
+ */
+ public OscMessage add(final String theValue) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x73});
+ final byte[] myString = theValue.getBytes();
+ _myData = Bytes.append(_myData, myString,
+ new byte[align(myString.length)]);
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = theValue;
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue float
+ */
+ public OscMessage add(final float theValue) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x66});
+ _myData = Bytes.append(_myData, Bytes.toBytes(Float
+ .floatToIntBits(theValue)));
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = new Float(theValue);
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue double
+ */
+ public OscMessage add(final double theValue) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x64});
+ _myData = Bytes.append(_myData, Bytes.toBytes(Double
+ .doubleToLongBits(theValue)));
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = new Double(theValue);
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue boolean
+ */
+ public OscMessage add(final boolean theValue) {
+ if (theValue) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x54});
+ } else {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x46});
+ }
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue Boolean
+ */
+ public OscMessage add(final Boolean theValue) {
+ add((theValue).booleanValue());
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue Integer
+ */
+ public OscMessage add(final Integer theValue) {
+ add(theValue.intValue());
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue
+ * Float
+ */
+ public OscMessage add(final Float theValue) {
+ add(theValue.floatValue());
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue
+ * Double
+ */
+ public OscMessage add(final Double theValue) {
+ add(theValue.doubleValue());
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue
+ * Character
+ */
+ public OscMessage add(final Character theValue) {
+ add(theValue.charValue());
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theValue
+ * char
+ */
+ public OscMessage add(final char theValue) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x63});
+ _myData = Bytes.append(_myData, Bytes.toBytes(theValue));
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = new Character(theValue);
+ return this;
+ }
+
+
+ /**
+ *
+ * @param channel int
+ * @param status int
+ * @param value1 int
+ * @param value2 int
+ */
+
+ public OscMessage add(final int channel,
+ final int status,
+ final int value1,
+ final int value2) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x6d}); // m
+ final byte[] theBytes = new byte[4];
+ theBytes[0] = (byte) channel;
+ theBytes[1] = (byte) status;
+ theBytes[2] = (byte) value1;
+ theBytes[3] = (byte) value2;
+ _myData = Bytes.append(_myData, theBytes);
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = theBytes;
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theArray
+ * int[]
+ */
+ public OscMessage add(final int[] theArray) {
+ for (int i = 0; i < theArray.length; i++) {
+ add(theArray[i]);
+ }
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theArray
+ * char[]
+ */
+ public OscMessage add(final char[] theArray) {
+ for (int i = 0; i < theArray.length; i++) {
+ add(theArray[i]);
+ }
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theArray
+ * float[]
+ */
+ public OscMessage add(final float[] theArray) {
+ for (int i = 0; i < theArray.length; i++) {
+ add(theArray[i]);
+ }
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theArray
+ * String[]
+ */
+ public OscMessage add(final String[] theArray) {
+ for (int i = 0; i < theArray.length; i++) {
+ add(theArray[i]);
+ }
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theArray
+ * byte[]
+ */
+ public OscMessage add(final byte[] theArray) {
+ _myTypetag = Bytes.append(_myTypetag, new byte[] {0x62});
+ _myData = Bytes.append(_myData, makeBlob(theArray));
+ _myArguments = increase(1);
+ _myArguments[_myArguments.length-1] = theArray;
+ return this;
+ }
+
+
+ /**
+ *
+ * @param theArray
+ * Object[]
+ */
+ public OscMessage add(final Object[] theArray) {
+ for (int i = 0; i < theArray.length; i++) {
+ if (!add(theArray[i])) {
+ System.out.println("type of Argument not defined in osc specs.");
+ }
+ }
+ return this;
+ }
+
+
+ private boolean add(final Object theObject) {
+ if (theObject instanceof Number) {
+ if (theObject instanceof Integer) {
+ add((Integer) theObject);
+ } else if (theObject instanceof Float) {
+ add((Float) theObject);
+ } else if (theObject instanceof Double) {
+ add((Double) theObject);
+ } else if (theObject instanceof Long) {
+ add((Long) theObject);
+ }
+ } else if (theObject instanceof String) {
+ add((String) theObject);
+ } else if (theObject instanceof Boolean) {
+ add((Boolean) theObject);
+ } else if (theObject instanceof Character) {
+ add((Character) theObject);
+ }
+
+ else {
+ if (theObject instanceof int[]) {
+ add((int[]) theObject);
+ return true;
+ } else if (theObject instanceof float[]) {
+ add((float[]) theObject);
+ return true;
+ } else if (theObject instanceof byte[]) {
+ add((byte[]) theObject);
+ return true;
+ }
+
+ else if (theObject instanceof String[]) {
+ add((String[]) theObject);
+ return true;
+ } else if (theObject instanceof char[]) {
+ add((char[]) theObject);
+ return true;
+ } else if (theObject instanceof double[]) {
+ add((float[]) theObject);
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ *
+ * @param b byte[]
+ * @return byte[]
+ * @invisible
+ */
+ public static byte[] makeBlob(final byte[] b) {
+ final int tLength = b.length;
+ byte[] b1 = Bytes.toBytes(tLength);
+ b1 = Bytes.append(b1, b);
+ final int t = tLength % 4;
+ if (t != 0) {
+ b1 = Bytes.append(b1, new byte[4 - t]);
+ }
+ return b1;
+ }
+
+
+ /**
+ * get a value at a specific position in the osc message. the get method
+ * returns an OscArgument from which the value can be parsed into the right
+ * format. e.g. to parse an int from the first argument in the osc message,
+ * use theOscMessage.get(0).intValue();
+ * @param theIndex int
+ * @return OscArgument
+ */
+ public OscArgument get(final int theIndex) {
+ if (theIndex < arguments().length) {
+ _myOscArgument.value = arguments()[theIndex];
+ return _myOscArgument;
+ }
+ return null;
+ }
+
+
+ /**
+ *
+ * @return String
+ * @invisible
+ */
+ public final String toString() {
+ return hostAddress + ":" + port + " | " +
+ addrPattern() + " " + typetag();
+ }
+
+
+ public boolean isPlugged() {
+ return isPlugged;
+ }
+
+
+ public void print() {
+ Logger.println("-OscMessage----------");
+ Logger.println("received from\t" + hostAddress + ":" + port);
+ Logger.println("addrpattern\t" + Bytes.getAsString(_myAddrPattern));
+ Logger.println("typetag\t" + Bytes.getAsString(_myTypetag));
+ Logger.println(Bytes.getAsString(_myArguments));
+ Logger.println("---------------------");
+ }
+
+ public void printData() {
+ Bytes.printBytes(_myData);
+ }
+}