aboutsummaryrefslogtreecommitdiff
path: root/net/udpreceive~.c
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2010-01-12 18:58:31 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2010-01-12 18:58:31 +0000
commitfcd21c7b86fa4f48db3b8273465861bfa73a2d1f (patch)
tree97600d6072c46c33013e447788e9a6a13fbe4d9d /net/udpreceive~.c
parentb7e8b9bc0bf7964833ddf0bc1513600df41f170c (diff)
Block size is settable by creation argument. Buffer size message is specified in frames. Info message gives some more info. Channels
transmitted can be set to zero. Cleaned up help patch. svn path=/trunk/externals/mrpeach/; revision=12968
Diffstat (limited to 'net/udpreceive~.c')
-rw-r--r--net/udpreceive~.c87
1 files changed, 56 insertions, 31 deletions
diff --git a/net/udpreceive~.c b/net/udpreceive~.c
index 3e8a419..353f1a6 100644
--- a/net/udpreceive~.c
+++ b/net/udpreceive~.c
@@ -76,6 +76,8 @@ typedef struct _udpreceive_tilde
t_object x_obj;
t_outlet *x_outlet1;
t_outlet *x_outlet2;
+ t_outlet *x_addrout;
+ t_atom x_addrbytes[5];
int x_socket;
int x_connectsocket;
int x_nconnections;
@@ -115,8 +117,7 @@ static int udpreceive_tilde_createsocket(t_udpreceive_tilde* x, int portno);
static t_int *udpreceive_tilde_perform(t_int *w);
static void udpreceive_tilde_dsp(t_udpreceive_tilde *x, t_signal **sp);
static void udpreceive_tilde_info(t_udpreceive_tilde *x);
-static void udpreceive_tilde_print(t_udpreceive_tilde* x);
-static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets);
+static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets, t_floatarg blocksize);
static void udpreceive_tilde_free(t_udpreceive_tilde *x);
void udpreceive_tilde_setup(void);
static int udpreceive_tilde_sockerror(char *s);
@@ -127,7 +128,7 @@ EXTERN void sys_rmpollfn(int fd);
EXTERN void sys_addpollfn(int fd, void* fn, void *ptr);
static t_class *udpreceive_tilde_class;
-static t_symbol *ps_format, *ps_channels, *ps_framesize, *ps_overflow, *ps_underflow,
+static t_symbol *ps_format, *ps_channels, *ps_framesize, *ps_overflow, *ps_underflow, *ps_packets,
*ps_queuesize, *ps_average, *ps_sf_float, *ps_sf_16bit, *ps_sf_8bit,
*ps_sf_mp3, *ps_sf_aac, *ps_sf_unknown, *ps_bitrate, *ps_hostname, *ps_nothing;
@@ -155,14 +156,15 @@ static void udpreceive_tilde_reset(t_udpreceive_tilde* x, t_floatarg buffer)
x->x_average[i] = x->x_maxframes;
x->x_averagecur = 0;
- if (buffer == 0.0) /* set default */
- x->x_maxframes = DEFAULT_QUEUE_LENGTH;
- else
- {
- buffer = (float)CLIP((float)buffer, 0., 1.);
- x->x_maxframes = (int)(DEFAULT_AUDIO_BUFFER_FRAMES * buffer);
- x->x_maxframes = CLIP(x->x_maxframes, 1, DEFAULT_AUDIO_BUFFER_FRAMES - 1);
- post("udpreceive~: set buffer to %g (%d frames)", buffer, x->x_maxframes);
+ i = (int)buffer;
+ if ((i > 0)&&(i < DEFAULT_AUDIO_BUFFER_FRAMES))
+ {
+ x->x_maxframes = i;
+ post("udpreceive~: set buffer to %d frames)", x->x_maxframes);
+ }
+ else if (i != 0) /* special case of 0 leaves buffer size unchanged */
+ {
+ post("udpreceive~: buffer must be between 1 and %d frames)", DEFAULT_AUDIO_BUFFER_FRAMES-1);
}
x->x_underflow = 0;
x->x_overflow = 0;
@@ -170,16 +172,32 @@ static void udpreceive_tilde_reset(t_udpreceive_tilde* x, t_floatarg buffer)
static void udpreceive_tilde_datapoll(t_udpreceive_tilde *x)
{
- int ret;
- int n;
+ int ret;
+ int n;
+ struct sockaddr_in from;
+ socklen_t fromlen = sizeof(from);
+ long addr;
+ unsigned short port;
n = x->x_nbytes;
if (x->x_nbytes == 0) /* we ate all the samples and need a new header tag */
{
/* receive header tag */
- ret = recv(x->x_socket, (char*)&x->x_frames[x->x_framein].tag, sizeof(t_tag), 0);
- if (ret <= 0) /* error */
+ ret = recvfrom(x->x_socket, (char*)&x->x_frames[x->x_framein].tag, sizeof(t_tag), 0,
+ (struct sockaddr *)&from, &fromlen);
+ /* get the sender's ip */
+ addr = ntohl(from.sin_addr.s_addr);
+ port = ntohs(from.sin_port);
+
+ x->x_addrbytes[0].a_w.w_float = (addr & 0xFF000000)>>24;
+ x->x_addrbytes[1].a_w.w_float = (addr & 0x0FF0000)>>16;
+ x->x_addrbytes[2].a_w.w_float = (addr & 0x0FF00)>>8;
+ x->x_addrbytes[3].a_w.w_float = (addr & 0x0FF);
+ x->x_addrbytes[4].a_w.w_float = port;
+ outlet_list(x->x_addrout, &s_list, 5L, x->x_addrbytes);
+
+ if (ret <= 0) /* error */
{
if (udpreceive_tilde_sockerror("recv tag"))
goto bail;
@@ -211,7 +229,8 @@ static void udpreceive_tilde_datapoll(t_udpreceive_tilde *x)
}
else /* we already have header tag or some data and need more */
{
- ret = recv(x->x_socket, (char*)x->x_frames[x->x_framein].data + x->x_frames[x->x_framein].tag.framesize - n, n, 0);
+ ret = recvfrom(x->x_socket, (char*)x->x_frames[x->x_framein].data + x->x_frames[x->x_framein].tag.framesize - n,
+ n, 0, (struct sockaddr *)&from, &fromlen);
if (ret > 0)
{
n -= ret;
@@ -493,9 +512,9 @@ static void udpreceive_tilde_dsp(t_udpreceive_tilde *x, t_signal **sp)
x->x_samplerate = (long)sp[0]->s_sr;
- if (DEFAULT_AUDIO_BUFFER_SIZE % sp[0]->s_n)
+ if (x->x_blocksize % sp[0]->s_n)
{
- error("netsend~: signal vector size too large (needs to be even divisor of %d)", DEFAULT_AUDIO_BUFFER_SIZE);
+ error("netsend~: signal vector size too large (needs to be even divisor of %d)", x->x_blocksize);
}
else
{
@@ -587,19 +606,13 @@ static void udpreceive_tilde_info(t_udpreceive_tilde *x)
/* average queuesize */
SETFLOAT(list, (t_float)((t_float)avg / (t_float)DEFAULT_AVERAGE_NUMBER));
outlet_anything(x->x_outlet2, ps_average, 1, list);
+
+ /* total packets */
+ SETFLOAT(list, (t_float)x->x_counter);
+ outlet_anything(x->x_outlet2, ps_packets, 1, list);
}
-static void udpreceive_tilde_print(t_udpreceive_tilde* x)
-{
- int i, avg = 0;
-
- for (i = 0; i < DEFAULT_AVERAGE_NUMBER; i++)
- avg += x->x_average[i];
- post("udpreceive~: last size = %d, avg size = %g, %d underflows, %d overflows", QUEUESIZE, (float)((float)avg / (float)DEFAULT_AVERAGE_NUMBER), x->x_underflow, x->x_overflow);
- post("udpreceive~: channels = %d, framesize = %d, packets = %d", x->x_frames[x->x_framein].tag.channels, x->x_frames[x->x_framein].tag.framesize, x->x_counter);
-}
-
-static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets)
+static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets, t_floatarg blocksize)
{
t_udpreceive_tilde *x;
int i;
@@ -616,6 +629,12 @@ static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets)
for (i = 0; i < x->x_noutlets; i++)
outlet_new(&x->x_obj, &s_signal);
x->x_outlet2 = outlet_new(&x->x_obj, &s_anything);
+ x->x_addrout = outlet_new(&x->x_obj, &s_list);
+ for (i = 0; i < 5; ++i)
+ {
+ x->x_addrbytes[i].a_type = A_FLOAT;
+ x->x_addrbytes[i].a_w.w_float = 0;
+ }
x->x_myvec = (t_int **)t_getbytes(sizeof(t_int *) * (x->x_noutlets + 3));
if (!x->x_myvec)
{
@@ -639,7 +658,13 @@ static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets)
x->x_frameout = 0;
x->x_maxframes = DEFAULT_QUEUE_LENGTH;
x->x_vecsize = 64; /* we'll update this later */
- x->x_blocksize = DEFAULT_AUDIO_BUFFER_SIZE; /* LATER make this dynamic */
+ if (blocksize == 0) x->x_blocksize = DEFAULT_AUDIO_BUFFER_SIZE;
+ else if (DEFAULT_AUDIO_BUFFER_SIZE%(int)blocksize)
+ {
+ error("udpreceive~: blocksize must fit snugly in %d", DEFAULT_AUDIO_BUFFER_SIZE);
+ return NULL;
+ }
+ else x->x_blocksize = (int)blocksize; //DEFAULT_AUDIO_BUFFER_SIZE; /* <-- the only place blocksize is set */
x->x_blockssincerecv = 0;
x->x_blocksperrecv = x->x_blocksize / x->x_vecsize;
@@ -684,7 +709,6 @@ void udpreceive_tilde_setup(void)
class_addmethod(udpreceive_tilde_class, nullfn, gensym("signal"), 0);
class_addmethod(udpreceive_tilde_class, (t_method)udpreceive_tilde_info, gensym("info"), 0);
class_addmethod(udpreceive_tilde_class, (t_method)udpreceive_tilde_dsp, gensym("dsp"), 0);
- class_addmethod(udpreceive_tilde_class, (t_method)udpreceive_tilde_print, gensym("print"), 0);
class_addmethod(udpreceive_tilde_class, (t_method)udpreceive_tilde_reset, gensym("reset"), A_DEFFLOAT, 0);
class_addmethod(udpreceive_tilde_class, (t_method)udpreceive_tilde_reset, gensym("buffer"), A_DEFFLOAT, 0);
post("udpreceive~ v%s, (c) 2004 Olaf Matthes, 2010 Martin Peach", VERSION);
@@ -697,6 +721,7 @@ void udpreceive_tilde_setup(void)
ps_underflow = gensym("underflow");
ps_queuesize = gensym("queuesize");
ps_average = gensym("average");
+ ps_packets = gensym("packets");
ps_hostname = gensym("ipaddr");
ps_sf_float = gensym("_float_");
ps_sf_16bit = gensym("_16bit_");