Hello, I'm essentially a c++ novice, so bare with me. I'm currently learning OpenGL on linux and would like to stream data to and from Pd. I'm aware of GEM, but would like to have the possibility of collaborating with those OpenGL programmers whom have no intention of learning Pd. There's also the possibility of incorporating it into a 3D Cave project being conducted by the media studies department here.
I'm trying to utilize this class which I found (libtcp++) in order to provide tcp client capabilities to my GL code: http://www.sashanet.com/internet/download.html
For now, I'm mainly determined to get the OpenGL-to-Pd connection working. So far, I've succeeded in creating the libtcp build, importing and instantiating a tcp_client object, and establishing a connection with Pd (netreceive outputs "1" upon execution of the graphic app). But I haven't figured out how to format the data in order for it to be received.
The tcp_client send fuction is as follows:
int TcpClient::send(char* data, int num_bytes) { return write(socket_fd, data, num_bytes); }
My call to 'send' is:
net->send(data, sizeof(data)); //net is my instantiated tcp object
based on this, I had to convert number data from the GL code to string before passing it. I tried both passing the data string alone (e.g. "49") as well as concatenating it with a name to be recognized by a Pd receive object (e.g. "foo 49").
What has to be reformatted in order for this to work?
Thanks, Dan
DO IT!! this is exactly what I'm hoping the netsend~/netreceive~ objects will encourage!
So, make it "foo 49;" -- it's the semicolon that terminates a message. It would be good to put a "\n" character at the end so that it looks better when you print the stream out.
As to getting a return value, netsend~ doesn't wait for a response; you have to handle that by "netreceive~" -ing a return code.
cheers Miller
On Mon, Dec 04, 2000 at 07:02:23PM -0500, Dan Neveu wrote:
Hello, I'm essentially a c++ novice, so bare with me. I'm currently learning OpenGL on linux and would like to stream data to and from Pd. I'm aware of GEM, but would like to have the possibility of collaborating with those OpenGL programmers whom have no intention of learning Pd. There's also the possibility of incorporating it into a 3D Cave project being conducted by the media studies department here.
I'm trying to utilize this class which I found (libtcp++) in order to provide tcp client capabilities to my GL code: http://www.sashanet.com/internet/download.html
For now, I'm mainly determined to get the OpenGL-to-Pd connection working. So far, I've succeeded in creating the libtcp build, importing and instantiating a tcp_client object, and establishing a connection with Pd (netreceive outputs "1" upon execution of the graphic app). But I haven't figured out how to format the data in order for it to be received.
The tcp_client send fuction is as follows:
int TcpClient::send(char* data, int num_bytes) { return write(socket_fd, data, num_bytes); }
My call to 'send' is:
net->send(data, sizeof(data)); //net is my instantiated tcp object
based on this, I had to convert number data from the GL code to string before passing it. I tried both passing the data string alone (e.g. "49") as well as concatenating it with a name to be recognized by a Pd receive object (e.g. "foo 49").
What has to be reformatted in order for this to work?
Thanks, Dan
Dan Neveu wrote:
I'm trying to utilize this class which I found (libtcp++) in order to provide tcp client capabilities to my GL code: http://www.sashanet.com/internet/download.html
Then Miller Puckette wrote :
DO IT!! this is exactly what I'm hoping the netsend~/netreceive~ objects will encourage!
I did something similar a couple of weeks ago to drive my openGL app with PD. I only need udp communication from PD to my app, so I hacked the source code of u_pdreceive, which is one of Miller's sample applications that uses the FUDI protocol. I stripped everything not needed, so it's not as flexible as the original u_pdreceive (no tcp), but it's simple and it works very well, at least on the same machine.
Here's the source:
/* -- file "u_pd_in.c" -- (sorry, not commented) */
// Maybe some header files are not needed here... #include <sys/types.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <sys/time.h>
typedef struct _fdpoll { int fdp_fd; char *fdp_inbuf; int fdp_inhead; int fdp_intail; int fdp_udp; } t_fdpoll;
static int maxfd; static int sockfd;
static void sockerror(char *s);
#define BUFSIZE 1024
char *u_pd_in_argv[25]; int u_pd_in_argc = 0;
int init_u_pd_in() { int portno = 3001; struct sockaddr_in server;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
sockerror("socket()");
return(1);
}
maxfd = sockfd + 1;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
/* assign client port number */
server.sin_port = htons((unsigned short)portno);
/* name the socket */
if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
{
sockerror("bind");
close(sockfd);
return (0);
}
return(0);
}
char *check_u_pd_in(void)
{
fd_set readset;
struct timeval tv;
char *buf[BUFSIZE], *command;
int retval, ret;
FD_ZERO(&readset);
FD_SET(sockfd, &readset);
tv.tv_sec = 0; tv.tv_usec = 5;
retval = select(maxfd+1, &readset, NULL, NULL, &tv);
command = strdup("");
if (retval > 0) {
ret = recv(sockfd, &buf, BUFSIZE, 0);
if (ret < 0) {
sockerror("recv (udp)");
close(sockfd);
exit(1);
}
if (ret > 0)
command = strtok((char *)buf, ";");
}
return(command);
}
static void sockerror(char *s) { int err = errno; fprintf(stderr, "%s: %s (%d)\n", s, strerror(err), err); }
/* -- enf of file "u_pd_in.c -- */
In my application main loop, I check if there's new messages from PD, I split the incoming string in a argv style array, then I parse the arguments:
void check_u_pd_command(void) { int argc = 0; char *argv[25], *buffer, *token; const char *delims = " ";
// get a new list from PD buffer = strdup(check_u_pd_in()); // split the string token = strtok(buffer, delims); while(token != (char *)NULL) { argv[argc] = token; argc++; token = strtok(NULL, delims); } free(buffer); if (argc == 0) return;
// parse the arguments and do something if (!strcmp(argv[0],"test")) { printf("test: %s, %s\n", argv[1], argv[2]); } else .... }
Voilà !