[PD] pd -> php

Max Neupert abonnements at revolwear.com
Sat Oct 7 14:19:04 CEST 2006


merci patco,

i have a hard time to spot your modifications in the semi-human- 
readable php code without line breaks. could you paste it formatted  
or just the changes?

thank you.

Am 07.10.2006 um 03:27 schrieb Patco:

> Patco a écrit :
>> Max Neupert a écrit :
>>> hi list,
>>>
>>> i am trying to send a value from pd to a php page.
>>> i am using an udp connection vie netsend to fsockopen().
>> Hello, there is a php class for that:
>> http://www.a2hd.com/software/OSC.phps
>> The end of the file have to be modified, I've tested it once it's  
>> more stable than netsend.
> attached is the modified php file
> Patco.
> * Copyright 2003 * * Version 0.1 * * Requirements: PHP 4.1.0 or  
> later. * For information about Open Sound Control, * see http:// 
> cnmat.berkeley.edu/OSC * * This is free software. * It may contain  
> bugs, design flaws or other unforseeable problems. * Please feel  
> free to report problems (or success stories) to the author. * *  
> License: LGPL version 2.1 or later. * * 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 * * For  
> questions regarding this library contact * Andy W. Schmeder */ //  
> Test if this machine is a little endian architecture function  
> test_little_endian() { $cpu_int = pack("L", 1); // Machine  
> dependent $be_int = pack("N", 1); // Machine independent if($cpu_int 
> [0] == $be_int[0]) { return FALSE; } else { return TRUE; } } //  
> Test if this machine uses twos complement representation function  
> test_twos_complement() { $cpu_int = pack("i", -1); // Machine  
> dependent if(ord($cpu_int[0]) == 255) { return TRUE; } else  
> { return FALSE; } } // Take note of the configuration for this  
> machine. $_arch_little_endian = test_little_endian();  
> $_arch_twos_complement = test_twos_complement(); if(!  
> $_arch_twos_complement) { trigger_error("WARNING: This machine does  
> not use twos-complement integers. " . "Negative numbers may not be  
> represented correctly.", E_USER_NOTICE); } /** This is a utility  
> function to convert from CPU byte order to network order (big  
> endian). * * It is necessary to use this function because PHP's pack 
> () function does not support * big endian encoding for most data  
> types. (It only does big endian for unsigned ints). */ function  
> host_to_network_order($str) { global $_arch_little_endian; if 
> ($_arch_little_endian) { $swstr = ""; for($i = 0; $i < strlen 
> ($str); $i++) { $swstr .= $str[(strlen($str)-1)-$i]; } return  
> $swstr; } else { // No conversion necessary for big-endian arch  
> return $str; } } /** OSCDatagram is a virtual base class for  
> OSCMessage and OSCBundle. */ class OSCDatagram { // Virtual private  
> data var $bin = NULL; var $data = NULL; // Virtual functions  
> function get_binary() {} function clear() {} // Shared functions / 
> ** Returns a semi-human readable representation of the binary data.  
> * Printable bytes will appear as "_C" where C is the printable  
> character. * Non-printable bytes will appear in hex, e.g. '20' for  
> a space (\s) character * Bytes are clustered in groups of 4 to show  
> the alignment. */ function get_human_readable() { $bin = $this- 
> >get_binary(); $hex = ""; for($i = 0; $i < strlen($bin); $i++) { if 
> (ord($bin[$i]) >= 33 && ord($bin[$i]) <= 126) { // Printable  
> characters $hex .= "_" . chr(ord($bin[$i])); } else { $hex .=  
> sprintf("%02x", ord($bin[$i])); } if($i != 0 && $i < strlen($bin)  
> && ($i+1) % 4 == 0) { $hex .= " "; } } return $hex . "\n"; } /**  
> Pack data into $this->bin as 4-byte aligned, network-byte order. */  
> function pack_data($data, $type_hint) { $bin = ""; switch 
> ($type_hint) { case "T": case "F": case "N": case "I": return; //  
> These types have no allocated space case "A": foreach($data as  
> $arg) { $this->pack_data($arg[0], $arg[1]); } break; case "s":  
> $data .= "\0"; // The builtin \0 terminator is ignored... we must  
> explicitly request one. $bin = pack("a*" . $this->get_strpad 
> ($data), $data); break; case "b": $this->pack_data(strlen($data- 
> >bin), "i"); $bin = pack("a*" . $this->get_strpad($data->bin),  
> $data->bin); break; case "i": $bin = host_to_network_order(pack 
> ("i", $data)); // Machine-independent size (4-bytes) break; case  
> "f": $bin = host_to_network_order(pack("f", $data)); // Machine- 
> dependent size if(strlen($bin) != 4) { $this->error("Sorry, your  
> machine uses an unsupported single-precision floating point  
> size."); } break; case "d": $bin = host_to_network_order(pack("d",  
> $data)); // Machine-dependent size if(strlen($bin) != 8) { $this- 
> >error("Sorry, your machine uses an unsupported double-precision  
> floating point size."); } break; case "t": if(is_null($data))  
> { $data = array(0, 1); } $bin = host_to_network_order(pack("L",  
> $data->sec)) . host_to_network_order(pack("L", $data->frac_sec));  
> break; } if(strlen($bin) % 4 != 0) { $this->error("$data failed to  
> align properly, size is " . strlen($bin) . " bytes."); } $this- 
> >bin .= $bin; } /** Utility to generate padding for strings      */  
> function get_strpad($str) { $x = (strlen($str)) % 4; if($x == 0)  
> { return ''; } else { $x = 4 - $x; } switch($x) { case 1: return  
> 'x'; case 2: return 'xx'; case 3: return 'xxx'; default: $this- 
> >error("Pad calculation is screwy, x = $x"); } } /** Report an  
> error */ function error($message) { trigger_error("OSCDatagram  
> Error: $message", E_USER_ERROR); } } /** OSCMessage type */ class  
> OSCMessage extends OSCDatagram { var $address = "/";    var  
> $typetags = ","; var $data = array(); /** Make a new message -  
> Optionally specify address and arguements. * * e.g. $a = new  
> OSCMessage("/foo", array(1, 2.94, "bar")) * It is not possible to  
> provide type-hinting using this initialization method. */ function  
> OSCMessage($address = NULL, $args = NULL) { if(! is_null($address))  
> { $this->address = $address; } if(is_array($args)) { foreach($args  
> as $arg) { $this->add_arg($arg); } } } /** Reset internal data  
> structures */ function clear() { $this->address = "/"; $this- 
> >typetags = ","; $this->data = array(); $this->bin = NULL; } /**  
> Set packet address * e.g. "/test". * See OSC spec for details on  
> allowed characters in an OSC address. */ function set_address 
> ($addr) { $this->bin = NULL; $this->address = $addr; } /** Add an  
> arg to the OSC message. * $data can be an integer, float, string,  
> boolean, NULL, or an array of those types. * $type-hint is  
> optional. */ function add_arg($data, $type_hint = NULL) { $this- 
> >bin = NULL; if($type_hint == NULL) { $type_hint = $this->get_type 
> ($data); } $data = $this->set_type($data, $type_hint); array_push 
> ($this->data, array($data, $type_hint)); } /** Try to guess the  
> type of data. * If this does not work for you, try using a type- 
> hint. */ function get_type($data) { switch(gettype($data)) { case  
> "integer": return "i"; case "double": case "float": return "f";  
> case "string": return "s"; case "boolean": if($data) { return  
> "T"; } else { return "F"; } case "array": // Array type will be  
> handled later... 'A' is not actually an OSC type. return "A"; case  
> "object": switch(strtolower(get_class($data))) { case "infinitum":  
> return "I"; case "timetag": return "t"; case "blob": return "b";  
> default: $this->error("Unknown or unsupported object type."); }  
> case "NULL": return "N"; default: $this->error("Unknown or  
> unsupported data type."); } } /** Cast data to type, and add type  
> info to typetags. */ function set_type($data, $type_tag) { switch 
> ($type_tag) { case "i": $this->typetags .= "i"; return (int)$data;  
> case "f"; $this->typetags .= "f"; return (double)$data; case "d";  
> $this->typetags .= "d"; return (double)$data; case "s": case "c":  
> $this->typetags .= "s"; return (string)$data; case "T": $this- 
> >typetags .= "T"; return TRUE; case "F": $this->typetags .= "F";  
> return FALSE; case "N": $this->typetags .= "N"; return NULL; case  
> "I": $this->typetags .= "I"; return $data; case "t": $this- 
> >typetags .= "t"; return $data; case "b": $this->typetags .= "b";  
> return $data; case "A": // Array is now expanded... $this- 
> >typetags .= "["; $data = (array)$data; for($i = 0; $i < count 
> ($data); $i++) { $type_tag = $this->get_type($data[$i]); $data[$i]  
> = array($this->set_type($data[$i], $type_tag), $type_tag); } $this- 
> >typetags .= "]"; return $data; default: trigger_error 
> ("Unrecognized type tag, '$type_tag'", E_USER_ERROR); } } function  
> get_binary() { // Check for cached binary representation and reuse  
> if found. if(! is_null($this->bin)) { return $this->bin; } // Pack  
> address... $this->pack_data($this->address, "s"); // Pack  
> typetags... $this->pack_data($this->typetags, "s"); // Pack args...  
> foreach($this->data as $arg) { $this->pack_data($arg[0], $arg 
> [1]); } return $this->bin; } } /** OSCBundle datagram type * This  
> object can contain any number of other OSCDatagram objects. */  
> class OSCBundle extends OSCDatagram { var $data = array(); var  
> $timetag = NULL; /** Create a new OSCBundle datagram * * $init may  
> be an array of OSCDatagram objects, * e.g. $b = new OSCBundle(new  
> OSCMessage(...), new OSCBundle(...)) * * Otherwise, add messages at  
> runtime using OSCBundle::add_datagram. */ function OSCBundle($init  
> = NULL) { if(is_array($init)) { foreach($init as $d) { $this- 
> >add_datagram($d); } } } /** Set time tag as whole seconds since  
> July 1, 1970, and fraction of a second. * This feature is not  
> tested, but it should work if you need it. * * If timetag is not  
> set, it will default to "Immediate". */ function set_timetag 
> ($timetag_obj) { $this->timetag = $timetag_obj; } /** Add an  
> OSCDatagram object to a bundle. * This can be either an OSCMessage  
> or an OSCBundle. * However, you cannot reasonably add a bundle to  
> itself. */ function add_datagram($osc_datagram) { $this->bin =  
> NULL; array_push($this->data, $osc_datagram); } function clear()  
> { $this->bin = NULL; $this->data = NULL; } function get_binary()  
> { if($this->bin != NULL) { return $this->bin; } $this->bin = "";  
> $this->pack_data("#bundle", "s"); $this->pack_data(NULL, "t");  
> foreach($this->data as $datagram) { $bin = $datagram->get_binary();  
> $this->pack_data((int)strlen($bin), "i"); $this->bin .= $bin; }  
> return $this->bin; } } /** OSCClient uses a connectionless UDP  
> socket to transmit binary to its destination. * * Example of use: *  
> * $c = new OSCClient(); * $c->set_destination("192.168.1.5", 3890);  
> * $c->send(new OSCMessage("/foo", array(1,2,3))); * ... etc. * *  
> Since it is connectionless, you can change the destination address/ 
> port at any time. * If you are having problems establishing  
> communication, it may be due to a bad address, * improper setup of  
> the IP routing table, or a problem on the other end. When in doubt,  
> * use tcpdump or ethereal to check that packets are indeed being  
> transmitted. */ class OSCClient { var $sock = NULL;    var $address  
> = NULL; var $port = NULL; function OSCClient($address = NULL, $port  
> = NULL) { $this->address = $address; $this->port = $port; if(($this- 
> >sock = socket_create(AF_INET, SOCK_DGRAM, 0)) < 0) { $this->error 
> ("Could not create datagram socket."); } } /** Destructor function,  
> usually not needed, provided in case you want to free the socket.  
> */ function destroy() { socket_close($this->sock); } /* // You can  
> enable this part if you have PHP 4.3.0 or later... function  
> enable_broadcast() { if(($ret = socket_set_option($this->sock,  
> SOL_SOCKET, SO_BROADCAST, 1)) < 0) {            $this->error 
> ("Failed to enable broadcast option."); } } function  
> disable_broadcast() { if(($ret = socket_set_option($this->sock,  
> SOL_SOCKET, SO_BROADCAST, 0)) < 0) { $this->error("Failed to  
> disable broadcast option."); } } */ /** Address is an IP address,  
> given as a string. * To convert a hostname to IP, use gethostbyname 
> ('www.example.com') * You must also specify a port as an integer,  
> typically $port is larger than 1024. */ function set_destination 
> ($address, $port) { $this->address = $address; $this->port =  
> $port; } /** send() accepts either an OSCDatagram object or a  
> binary string */ function send($message) { if(is_null($this- 
> >address) || is_null($this->port)) { $this->error("Destination is  
> not well-defined. Please use OSCClient::set_destination()."); } if 
> (is_object($message)) { $message = $message->get_binary(); } if 
> (($ret = socket_sendto($this->sock, $message, strlen($message), 0,  
> $this->address, $this->port)) < 0) { $this->error("Transmission  
> failure."); } if($ret != strlen($message)) { $mlen = strlen 
> ($message); $this->error("Could not send the entire message, only  
> $ret bytes were sent, of $mlen total"); } return $ret; } /** Report  
> a fatal error. */ function error($message) { trigger_error 
> ("OSCClient Error: $message", E_USER_ERROR); } } /** Object to  
> represent the OSC Infinitum type ("I") */ class Infinitum { } /**  
> 64-bit OSC timetag type, Refer to NTP format for details. */ / 
> **class Timetag { function Timetag($sec = 0, $frac_sec = 1) { $this- 
> >sec = $sec; $this->frac_sec = $frac_sec; } }*/ /** Binary Blob  
> datatype * Blob is basically a non-null-terminated string prefixed  
> by a size indicator. */ class Blob { function Blob($bin) { $this- 
> >bin = $bin; } } /** Run some tests to make sure the library  
> behaves in a sane way. the modifications begins here replace  
> localhost with server's adress and put the correct port */ function  
> test_osc_lib() { $c = new OSCClient(); $c->set_destination 
> ("localhost", 3333); /** $m1 = new OSCMessage("/test", array(new  
> Timetag(3294967295, 5), new Infinitum(), new Blob("aoeuaoeu!")));  
> $m1->add_arg(28658.93, "d"); */ $m2 = new OSCMessage("/bar", array 
> (test, one, two)); $b = new OSCBundle(); $b->add_datagram($m1); $b- 
> >add_datagram($m2); $b2 = new OSCBundle(array($m1, $b)); //echo $b2- 
> >get_human_readable(); //echo $m1->get_human_readable();     $c- 
> >send($m2); } // Uncomment to run the test test_osc_lib(); ?>





More information about the Pd-list mailing list