Max 5 API Reference

Jitter Networking Specification

This appendix describes the format of the data sent by a object.

The object attempts to form a TCP connection with a host at the IP and port specified by the object's attributes. Any program wishing to receive data will therefore have to set itself up as a host and listen for incoming TCP connections.

Once a connection is formed, data can be sent. Data is sent as a stream of chunks. The first thing received will be a chunk header. It consists of a 32-bit chunk ID and a 32-bit int representing the size of the next chunk to come. The chunk ID can be one of the following 4-char symbols, depending on what kind of packet it is:


This chunk header could be represented in C by the following struct:

typedef struct _jit_net_packet_header
   long id;
   long size; //size of packet to come
} t_jit_net_packet_header;

If the chunk is a matrix packet, the next data received will be a header of 288 bytes with the following contents:




288 (32-bit int, size of this header)


32-bit int


32-bit int, 0 for char, 1 for long, 2 for float32, 3 for float64


32-bit int


Array of 32 32-bit ints


Array of 32 32-bit ints


32-bit int, size of the data buffer to come


64-bit double precision float

This chunk could be represented with the following C struct:

typedef struct _jit_net_packet_matrix 
   long   id;
   long   size;
   long   planecount;
   long   type;         //0=char,1=long,2=float32,3=float64
   long   dimcount;
   long   dimstride[JIT_MATRIX_MAX_DIMCOUNT];
   long   datasize;
   double   time;

} t_jit_net_packet_matrix;

Following this header the next data received will be the matrix data, the size of which was passed in the above header. When using the data, please note the dimstrides transmitted in the header.

The time field in the above header will be set to the time of transmission from the sending computer. expects the server to respond by sending back timing data of its own – it uses this data to estimate the transmission latency. The exact data in the latency chunk that expects to receive is the following:




64-bit double, the time value received in the matrix header packet


64-bit double, the time on the server when the packet header is received


64-bit double, the time on the server after the packet has been processed and is in use

This chunk can be represnted by the following C struct:

typedef struct _jit_net_packet_latency
   long id;
   double client_time_original;
   double server_time_before_data; 
   double server_time_after_data;
} t_jit_net_packet_latency;

The difference between the server time before and server time after processing the data represents the time it takes the server to mobilize the data after it has been received. will send and expects to receive time in milliseconds. When this timing information is received by the transmitting computer, it notes its current time, calculates the round trip time and then estimates the latency as half the round trip time plus half of the server processing time. This estimate is accurate if the time of flight from A to B is the same as the time of flight from B to A, but network topology can be very complicated, and often the route from A to B is not the reverse of the route from B to A. In simple situations, such as a direct connection between two computers or a small LAN, the estimate should be reasonably accurate.

Finally, the last type of packet that can be sent is the message packet. The size of the message packet is sent in the initial header packet. Standard A_GIMME messages (t_symbol *s, long ac, t_atom *av) are serialized starting with a 32-bit integer that contains the size of the serialized message in bytes. Following that another 32-bit integer gives the argument count for the atoms. Following that comes the message atoms themselves, starting with the leading symbol if it exists. Each atom is represented in memory first with a char that indicates what type of atom it is: 's' for symbol, 'l' for long, and 'f' for float. For long and float atoms, the next 4 bytes contain the value of the atom; for symbol atoms a null terminated character string follows. Below is a C function that will deserialize a message passed in as a data pointer.

void gimme_deserialize(char *data, t_symbol **s, long *ac, t_atom **av)
   char *curr = data;
   float *currf;
   long *currl,i;
   long datasize = BE_I32(*((long *)curr));
   curr += sizeof(long);   
   *ac = BE_I32(*(long *)(curr));
   curr += sizeof(long);
   *av = (t_atom *)sysmem_newptr(sizeof(t_atom)*(*ac));

      *s = gensym(curr);
      while (*(++curr) != '\0') ;
      *s = 0L;
   for (i=0;i<*ac;i++)
      switch (*curr++)
            (*av)[i].a_type = A_SYM;
            (*av)[i].a_w.w_sym = gensym(curr);
            while (*(++curr) != '\0') ;
            (*av)[i].a_type = A_FLOAT;
            (*av)[i].a_w.w_float = BE_F32(*((float *)curr));
            curr += sizeof(float);
            (*av)[i].a_type = A_LONG;
            (*av)[i].a_w.w_long = BE_I32(*((long *)curr));
            curr += sizeof(long);

Copyright © 2008, Cycling '74