diff options
Diffstat (limited to 'modules/generic/pdp_udp_receive.c')
-rw-r--r-- | modules/generic/pdp_udp_receive.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/modules/generic/pdp_udp_receive.c b/modules/generic/pdp_udp_receive.c new file mode 100644 index 0000000..3d42466 --- /dev/null +++ b/modules/generic/pdp_udp_receive.c @@ -0,0 +1,203 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +/* this module sends receives an udp packet stream and converts to pdp packet */ + +#include "pdp_net.h" +#include "pdp.h" +#include "pdp_resample.h" + +#define D if(0) + +typedef struct pdp_udp_receive_struct +{ + + t_object x_obj; + t_float x_f; + + /* receiver object */ + t_pdp_udp_receiver *x_receiver; + + + /* thread vars */ + pthread_attr_t x_attr; + pthread_t x_thread; + int x_exit_thread; + + /* packet queue */ + int x_index; + int x_packet[2]; + + /* polling clock */ + t_clock *x_clock; + /* outlet */ + t_outlet *x_outlet0; + +} t_pdp_udp_receive; + + +static void clock_tick(t_pdp_udp_receive *x) +{ + /* poll for new packet */ + + pdp_pass_if_valid(x->x_outlet0, &x->x_packet[!x->x_index]); + clock_delay(x->x_clock, 1.0f); +} + + + + +static void *receive_thread(void *threaddata) +{ + t_pdp_udp_receive *x = (t_pdp_udp_receive *)threaddata; + t_pdp *pdp_header = 0; + void *pdp_data = 0; + int tmp_packet = -1; + char *type = 0; + unsigned int size = 0; + + /* listen for packets */ + while (!x->x_exit_thread){ + + + switch(pdp_udp_receiver_receive(x->x_receiver, 100)){ + case -1: + /* error */ + goto exit; + case 0: + /* timeout */ + continue; + case 1: + /* data ready */ + break; + } + + /* create a new packet */ + type = pdp_udp_receiver_type(x->x_receiver); + tmp_packet = pdp_factory_newpacket(pdp_gensym(type)); + pdp_header = pdp_packet_header(tmp_packet); + pdp_data = pdp_packet_data(tmp_packet); + + /* check if we were able to create the pdp packet */ + if (!(pdp_header && pdp_data)){ + post("pdp_netreceive: can't create packet (type %s)", type); + pdp_udp_receiver_reset(x->x_receiver); + continue; + } + + /* check size */ + size = pdp_udp_receiver_size(x->x_receiver); + if ((pdp_header->size - PDP_HEADER_SIZE) != size){ + pdp_packet_mark_unused(tmp_packet); + tmp_packet = -1; + post("pdp_netreceive: invalid packet size %d (pdp packet size = %d)", + size, pdp_header->size - PDP_HEADER_SIZE); + continue; + } + + /* copy the data */ + memcpy(pdp_data, pdp_udp_receiver_data(x->x_receiver), size); + + /* copy the packet into queue */ + x->x_index ^= 1; + pdp_packet_mark_unused(x->x_packet[x->x_index]); + x->x_packet[x->x_index] = tmp_packet; + + + } + + exit: + post("thread exiting"); + return 0; +} + + +static void pdp_udp_receive_free(t_pdp_udp_receive *x) +{ + int i; + void* retval; + x->x_exit_thread = 1; // wait for thread to finish + pthread_join(x->x_thread, &retval); + + pdp_udp_receiver_free(x->x_receiver); + + pdp_packet_mark_unused(x->x_packet[0]); + pdp_packet_mark_unused(x->x_packet[1]); + +} + +t_class *pdp_udp_receive_class; + + + +void *pdp_udp_receive_new(t_floatarg fport) +{ + int i; + int port; + struct hostent *hp; + + t_pdp_udp_receive *x = (t_pdp_udp_receive *)pd_new(pdp_udp_receive_class); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + + x->x_packet[0] = -1; + x->x_packet[1] = -1; + x->x_index = 0; + + port = (fport == 0.0f) ? 7777 : fport; + x->x_receiver = pdp_udp_receiver_new(port); + + /* setup thread stuff & create thread */ + x->x_exit_thread = 0; + pthread_attr_init(&x->x_attr); + pthread_attr_setschedpolicy(&x->x_attr, SCHED_OTHER); + pthread_create(&x->x_thread, &x->x_attr, receive_thread, x); + + + /* setup the clock */ + x->x_clock = clock_new(x, (t_method)clock_tick); + clock_delay(x->x_clock, 0); + + post("pdp_netreceive: WARNING: experimental object"); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_udp_receive_setup(void) +{ + + + pdp_udp_receive_class = class_new(gensym("pdp_netreceive"), (t_newmethod)pdp_udp_receive_new, + (t_method)pdp_udp_receive_free, sizeof(t_pdp_udp_receive), 0, A_DEFFLOAT, A_NULL); + + +} + +#ifdef __cplusplus +} +#endif |