aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/udpreceive~.c87
-rw-r--r--net/udpsend~-help.pd278
-rw-r--r--net/udpsend~.c168
-rw-r--r--net/udpsend~.h2
4 files changed, 309 insertions, 226 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_");
diff --git a/net/udpsend~-help.pd b/net/udpsend~-help.pd
index 76b90a7..e97aad8 100644
--- a/net/udpsend~-help.pd
+++ b/net/udpsend~-help.pd
@@ -1,120 +1,158 @@
-#N canvas 579 96 701 749 10;
-#X obj 85 160 dac~ 1;
-#X obj 110 183 dac~ 2;
-#X obj 138 160 dac~ 3;
-#X obj 164 183 dac~ 4;
-#X obj 242 478 osc~ 440;
-#X obj 260 499 osc~ 880;
-#X obj 280 520 osc~ 990;
-#X obj 299 541 osc~ 220;
-#X text 313 563 sends 4 dsp-channels to localhost:8008;
-#X msg 47 351 disconnect;
-#X msg 68 372 format float;
-#X msg 89 393 format 16bit;
-#X msg 110 414 format 8bit;
-#X text 181 361 format defines the resolution of the sent signal;
-#X text 365 540 the signals to send;
-#X text 260 584 status: 1 = connected 0 = disconnected;
-#X msg 5 309 connect localhost 8008;
-#X text 244 21 written by Olaf Matthes <olaf.matthes@gmx.de>;
-#X text 204 123 receives 4 channels on port 8808;
-#X text 146 309 connect to <hostname> <port>;
-#X text 201 435 change number of channels;
-#X text 174 375 float is the most expensive with the best resolution
-(32bit) \, default is 16bit;
-#X msg 130 434 channels 2;
-#X msg 26 330 connect 255.255.255.255 8008;
-#X msg 60 81 buffer 0.25;
-#X msg 81 102 print;
-#X obj 85 123 udpreceive~ 8008 4;
-#X obj 242 563 udpsend~ 4;
-#X text 17 -2 udpreceive~/udpsend~;
-#X obj 535 183 print udpreceive~;
-#X obj 572 685 print udpsend~;
-#X obj 242 586 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 1 1
-;
-#X obj 299 605 route format channels framesize bitrate ipaddr;
-#X symbolatom 299 701 10 0 0 0 - - -;
-#X floatatom 353 635 5 0 0 0 - - -;
-#X floatatom 408 657 9 0 0 0 - - -;
-#X floatatom 462 686 9 0 0 0 - - -;
-#X symbolatom 517 656 10 0 0 0 - - -;
-#X obj 299 677 prepend set;
-#X obj 517 633 prepend set;
-#X text 294 634 channels:;
-#X text 253 700 format:;
-#X text 410 686 bitrate:;
-#X text 346 657 framesize:;
-#X text 496 655 to:;
-#X msg 152 456 info;
-#X symbolatom 190 253 10 0 0 0 - - -;
-#X floatatom 233 206 5 0 0 0 - - -;
-#X floatatom 276 183 9 0 0 0 - - -;
-#X floatatom 319 206 9 0 0 0 - - -;
-#X obj 190 229 prepend set;
-#X text 169 205 channels:;
-#X text 144 252 format:;
-#X text 267 205 bitrate:;
-#X text 214 186 framesize:;
-#X obj 190 146 route format channels framesize bitrate overflow underflow
-queuesize average;
-#X floatatom 362 229 9 0 0 0 - - -;
-#X floatatom 405 183 9 0 0 0 - - -;
-#X floatatom 448 206 9 0 0 0 - - -;
-#X floatatom 491 229 9 0 0 0 - - -;
-#X text 305 228 overflow:;
-#X text 343 186 underflow:;
-#X text 385 205 queuesize:;
-#X text 439 228 average:;
-#X msg 39 60 info;
-#X text 17 16 based on [netreceive~] and [netsend~];
-#X text 146 3 by Martin Peach 2010/01/10;
-#X text 208 325 broadcast to everybody on your local subnet listening
-on the specified port;
-#X msg 19 40 reset;
-#X text 72 59 status info to rightmost outlet;
-#X text 184 456 status info to rightmost outlet;
-#X text 57 39 reset underflow & overflow counters;
-#X text 136 81 set buffer to one-quarter of 16 frames;
-#X text 304 98 one frame is 1024 samples;
-#X connect 4 0 27 0;
-#X connect 5 0 27 1;
-#X connect 6 0 27 2;
-#X connect 7 0 27 3;
-#X connect 9 0 27 0;
-#X connect 10 0 27 0;
-#X connect 11 0 27 0;
-#X connect 12 0 27 0;
-#X connect 16 0 27 0;
-#X connect 22 0 27 0;
-#X connect 23 0 27 0;
-#X connect 24 0 26 0;
-#X connect 25 0 26 0;
-#X connect 26 0 0 0;
-#X connect 26 1 1 0;
-#X connect 26 2 2 0;
-#X connect 26 3 3 0;
-#X connect 26 4 55 0;
-#X connect 27 0 31 0;
-#X connect 27 1 32 0;
-#X connect 32 0 38 0;
-#X connect 32 1 34 0;
-#X connect 32 2 35 0;
-#X connect 32 3 36 0;
-#X connect 32 4 39 0;
-#X connect 32 5 30 0;
-#X connect 38 0 33 0;
-#X connect 39 0 37 0;
-#X connect 45 0 27 0;
-#X connect 50 0 46 0;
-#X connect 55 0 50 0;
-#X connect 55 1 47 0;
-#X connect 55 2 48 0;
-#X connect 55 3 49 0;
-#X connect 55 4 56 0;
-#X connect 55 5 57 0;
-#X connect 55 6 58 0;
-#X connect 55 7 59 0;
-#X connect 55 8 29 0;
-#X connect 64 0 26 0;
-#X connect 68 0 26 0;
+#N canvas 308 59 838 769 10;
+#X obj -178 225 osc~ 440;
+#X msg -398 60 disconnect;
+#X msg -353 105 format float;
+#X msg -332 126 format 16bit;
+#X msg -311 147 format 8bit;
+#X msg -440 18 connect localhost 8008;
+#X text -244 103 float is the most expensive with the best resolution
+(32bit) \, default is 16bit;
+#X msg -419 39 connect 255.255.255.255 8008;
+#X obj 34 650 print udpreceive~;
+#X obj 224 369 print udpsend~;
+#X obj -178 320 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 1
+1;
+#X symbolatom -97 435 10 0 0 0 - - -;
+#X floatatom -44 369 5 0 0 0 - - -;
+#X floatatom 10 391 9 0 0 0 - - -;
+#X floatatom 63 411 9 0 0 0 - - -;
+#X symbolatom 117 390 10 0 0 0 - - -;
+#X obj -97 411 prepend set;
+#X obj 117 367 prepend set;
+#X text -102 368 channels:;
+#X text -152 442 format:;
+#X text 13 411 bitrate:;
+#X text -51 391 framesize:;
+#X text 98 389 to:;
+#X msg -216 242 info;
+#X symbolatom -311 720 10 0 0 0 - - -;
+#X floatatom -273 673 5 0 0 0 - - -;
+#X floatatom -235 650 7 0 0 0 - - -;
+#X floatatom -196 720 9 0 0 0 - - -;
+#X obj -311 696 prepend set;
+#X text -337 672 channels:;
+#X text -357 719 format:;
+#X text -248 719 bitrate:;
+#X text -299 649 framesize:;
+#X floatatom -158 674 9 0 0 0 - - -;
+#X floatatom -120 650 9 0 0 0 - - -;
+#X floatatom -81 696 5 0 0 0 - - -;
+#X floatatom -43 674 5 0 0 0 - - -;
+#X text -215 673 overflow:;
+#X text -182 649 underflow:;
+#X text -144 695 queuesize:;
+#X text -95 673 average:;
+#X msg -443 478 info;
+#X text -237 34 broadcast to everybody on your local subnet listening
+on the specified port;
+#X msg -463 458 reset;
+#X text -410 477 status info to rightmost outlet;
+#X text -415 241 status info to rightmost outlet;
+#X text -425 457 reset underflow & overflow counters;
+#X floatatom -268 591 3 0 0 0 - - -;
+#X floatatom -245 591 3 0 0 0 - - -;
+#X floatatom -222 591 3 0 0 0 - - -;
+#X floatatom -199 591 3 0 0 0 - - -;
+#X floatatom -175 591 5 0 0 0 - - -;
+#X obj -268 565 unpack 0 0 0 0 0;
+#X text -305 590 from:;
+#X obj -179 268 *~;
+#X floatatom -164 150 5 0 0 0 - - -;
+#X text -19 178 Framesize = (blocksize) X (number of channels) X (bytes
+per sample);
+#X obj -97 339 route format channels framesize bitrate ipaddr vecsize
+;
+#X floatatom 170 430 9 0 0 0 - - -;
+#X text 70 430 dsp vector size:;
+#X msg -258 200 channels \$1;
+#X obj -412 185 hradio 15 1 0 8 empty empty empty 0 -8 0 10 -4034 -1
+-1 1;
+#X obj -178 297 udpsend~ 2 512;
+#X text -88 296 sends 2 dsp-channels using 512-sample blocks;
+#X obj -397 541 udpreceive~ 8008 2 512;
+#X text -258 542 receives 2 channels on port 8808;
+#X obj -398 602 dac~ 1 2;
+#X text 68 448 (blocksize must be a multiple of this);
+#X text -160 318 1 = transmitting;
+#X obj -97 246 noise~;
+#X obj -98 268 *~;
+#X obj -164 170 / 100;
+#X text -456 310 Author: Martin Peach 2010/01/10;
+#X text -455 338 Based on: [netreceive~] and [netsend~]by Olaf Matthes
+;
+#X obj -311 613 route format channels framesize bitrate overflow underflow
+queuesize average packets;
+#X floatatom -5 718 9 0 0 0 - - -;
+#X text -57 717 packets:;
+#X text -20 204 Default blocksize is 2048 The number of samples per
+block must be an integer multiple of the number of samples in one signal
+vector.;
+#X text -23 248 Arguments: (1st required \, 2nd optional) 1:number
+of channels to send. 2:blocksize = number of samples per channel per
+frame. (Blocksize of sender and receiver must be the same.);
+#X text -98 558 To communicate \, a [udpreceive~] and [udpsend~] pair
+must have the same number of channels and the same blocksize. Also
+[udpsend~] must [connect( to the port on which [udpreceive~] is listening.
+;
+#X text -329 59 stop transmitting;
+#X text -355 76 format defines the resolution of the sent signal and
+may be changed on-the-fly;
+#X text -450 200 number of channels to transmit;
+#X msg -422 499 buffer 2;
+#X text -360 498 set number of frames to buffer before playback;
+#X text -456 373 [udpsend~] transmits dsp vectors ("audio") via UDP.
+UDP is a connectionless protocol \, so [udpsend~] will transmit even
+if nothing is receiving.;
+#X text -299 18 connect to <hostname> <port> and begin transmitting
+;
+#X text -455 294 [udpreceive~] and [udpsend~];
+#X connect 0 0 54 0;
+#X connect 1 0 62 0;
+#X connect 2 0 62 0;
+#X connect 3 0 62 0;
+#X connect 4 0 62 0;
+#X connect 5 0 62 0;
+#X connect 7 0 62 0;
+#X connect 16 0 11 0;
+#X connect 17 0 15 0;
+#X connect 23 0 62 0;
+#X connect 28 0 24 0;
+#X connect 41 0 64 0;
+#X connect 43 0 64 0;
+#X connect 52 0 47 0;
+#X connect 52 1 48 0;
+#X connect 52 2 49 0;
+#X connect 52 3 50 0;
+#X connect 52 4 51 0;
+#X connect 54 0 62 0;
+#X connect 55 0 71 0;
+#X connect 57 0 16 0;
+#X connect 57 1 12 0;
+#X connect 57 2 13 0;
+#X connect 57 3 14 0;
+#X connect 57 4 17 0;
+#X connect 57 5 58 0;
+#X connect 57 6 9 0;
+#X connect 60 0 62 0;
+#X connect 61 0 60 0;
+#X connect 62 0 10 0;
+#X connect 62 1 57 0;
+#X connect 64 0 66 0;
+#X connect 64 1 66 1;
+#X connect 64 2 74 0;
+#X connect 64 3 52 0;
+#X connect 69 0 70 0;
+#X connect 70 0 62 1;
+#X connect 71 0 54 1;
+#X connect 71 0 70 1;
+#X connect 74 0 28 0;
+#X connect 74 1 25 0;
+#X connect 74 2 26 0;
+#X connect 74 3 27 0;
+#X connect 74 4 33 0;
+#X connect 74 5 34 0;
+#X connect 74 6 35 0;
+#X connect 74 7 36 0;
+#X connect 74 8 75 0;
+#X connect 74 9 8 0;
+#X connect 83 0 64 0;
diff --git a/net/udpsend~.c b/net/udpsend~.c
index 70a3a7b..2abf288 100644
--- a/net/udpsend~.c
+++ b/net/udpsend~.c
@@ -75,41 +75,41 @@
static t_class *udpsend_tilde_class;
-static t_symbol *ps_nothing, *ps_localhost;
+static t_symbol *ps_nothing, *ps_localhost, *ps_vecsize;
static t_symbol *ps_format, *ps_channels, *ps_framesize, *ps_overflow, *ps_underflow;
static t_symbol *ps_queuesize, *ps_average, *ps_sf_float, *ps_sf_16bit, *ps_sf_8bit;
static t_symbol *ps_sf_mp3, *ps_sf_aac, *ps_sf_unknown, *ps_bitrate, *ps_hostname;
typedef struct _udpsend_tilde
{
- t_object x_obj;
- t_outlet *x_outlet;
- t_outlet *x_outlet2;
- t_clock *x_clock;
- int x_fd;
- t_tag x_tag;
- t_symbol* x_hostname;
- int x_portno;
- int x_connectstate;
- char *x_cbuf;
- int x_cbufsize;
- int x_blocksize; /* set to DEFAULT_AUDIO_BUFFER_SIZE in udpsend_tilde_new() */
- int x_blockspersend; /* set to x->x_blocksize / x->x_vecsize in udpsend_tilde_perform() */
- int x_blockssincesend;
-
- long x_samplerate; /* samplerate we're running at */
- int x_vecsize; /* current DSP signal vector size */
- int x_ninlets; /* number of inlets */
- int x_channels; /* number of channels we want to stream */
- int x_format; /* format of streamed audio data */
- int x_bitrate; /* specifies bitrate for compressed formats */
- int x_count; /* total number of audio frames */
- t_int **x_myvec; /* vector we pass on in the DSP routine */
-
- pthread_mutex_t x_mutex;
- pthread_cond_t x_requestcondition;
- pthread_cond_t x_answercondition;
- pthread_t x_childthread;
+ t_object x_obj;
+ t_outlet *x_outlet;
+ t_outlet *x_outlet2;
+ t_clock *x_clock;
+ int x_fd;
+ t_tag x_tag;
+ t_symbol* x_hostname;
+ int x_portno;
+ int x_connectstate;
+ char *x_cbuf;
+ int x_cbufsize;
+ int x_blocksize; /* set to DEFAULT_AUDIO_BUFFER_SIZE in udpsend_tilde_new() */
+ int x_blockspersend; /* set to x->x_blocksize / x->x_vecsize in udpsend_tilde_perform() */
+ int x_blockssincesend;
+
+ long x_samplerate; /* samplerate we're running at */
+ int x_vecsize; /* current DSP signal vector size */
+ int x_ninlets; /* number of inlets */
+ int x_channels; /* number of channels we want to stream */
+ int x_format; /* format of streamed audio data */
+ int x_bitrate; /* specifies bitrate for compressed formats */
+ int x_count; /* total number of audio frames */
+ t_int **x_myvec; /* vector we pass on in the DSP routine */
+
+ pthread_mutex_t x_mutex;
+ pthread_cond_t x_requestcondition;
+ pthread_cond_t x_answercondition;
+ pthread_t x_childthread;
} t_udpsend_tilde;
/* function prototypes */
@@ -125,7 +125,7 @@ static void udpsend_tilde_channels(t_udpsend_tilde *x, t_floatarg channels);
static void udpsend_tilde_format(t_udpsend_tilde *x, t_symbol* form, t_floatarg bitrate);
static void udpsend_tilde_float(t_udpsend_tilde* x, t_floatarg arg);
static void udpsend_tilde_info(t_udpsend_tilde *x);
-static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg prot);
+static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg blocksize);
static void udpsend_tilde_free(t_udpsend_tilde* x);
void udpsend_tilde_setup(void);
@@ -323,7 +323,8 @@ static t_int *udpsend_tilde_perform(t_int *w)
pthread_mutex_unlock(&x->x_mutex);
udpsend_tilde_disconnect(x);
return (w + offset + x->x_ninlets);
- }
+ }
+ if (length != 0)
/* UDP: max. packet size is 64k (incl. headers) so we have to split */
{
#ifdef __APPLE__
@@ -355,10 +356,11 @@ static t_int *udpsend_tilde_perform(t_int *w)
}
}
#else
- /* send the buffer, the OS might segment it into smaller packets */
+ /* If there is any data, send the buffer, the OS might segment it into smaller packets */
int ret = send(x->x_fd, bp, length, SEND_FLAGS);
if (ret <= 0)
- {
+ {
+ post ("length %ld", length);
udpsend_tilde_sockerror("send data");
pthread_mutex_unlock(&x->x_mutex);
udpsend_tilde_disconnect(x);
@@ -417,14 +419,15 @@ static void udpsend_tilde_dsp(t_udpsend_tilde *x, t_signal **sp)
static void udpsend_tilde_channels(t_udpsend_tilde *x, t_floatarg channels)
{
pthread_mutex_lock(&x->x_mutex);
- if (channels >= 0 && channels <= DEFAULT_AUDIO_CHANNELS)
+ if (channels >= 0 && channels <= x->x_ninlets)
{
x->x_channels = (int)channels;
post("udpsend~: channels set to %d", (int)channels);
}
+ else post ("udpsend~ number of channels must be between 0 and %d", x->x_ninlets);
pthread_mutex_unlock(&x->x_mutex);
}
-
+
static void udpsend_tilde_format(t_udpsend_tilde *x, t_symbol* form, t_floatarg bitrate)
{
pthread_mutex_lock(&x->x_mutex);
@@ -496,6 +499,10 @@ static void udpsend_tilde_info(t_udpsend_tilde *x)
SETFLOAT(list, (t_float)x->x_tag.channels);
outlet_anything(x->x_outlet2, ps_channels, 1, list);
+ /* current signal vector size */
+ SETFLOAT(list, (t_float)x->x_vecsize);
+ outlet_anything(x->x_outlet2, ps_vecsize, 1, list);
+
/* framesize */
SETFLOAT(list, (t_float)x->x_tag.framesize);
outlet_anything(x->x_outlet2, ps_framesize, 1, list);
@@ -509,7 +516,7 @@ static void udpsend_tilde_info(t_udpsend_tilde *x)
outlet_anything(x->x_outlet2, ps_hostname, 1, list);
}
-static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg prot)
+static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg blocksize)
{
int i;
@@ -518,49 +525,60 @@ static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg prot)
{
for (i = sizeof(t_object); i < (int)sizeof(t_udpsend_tilde); i++)
((char *)x)[i] = 0;
- }
-
- x->x_ninlets = CLIP((int)inlets, 1, DEFAULT_AUDIO_CHANNELS);
- for (i = 1; i < x->x_ninlets; i++)
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
-
- x->x_outlet = outlet_new(&x->x_obj, &s_float);
- x->x_outlet2 = outlet_new(&x->x_obj, &s_list);
- x->x_clock = clock_new(x, (t_method)udpsend_tilde_notify);
+
+ if ((int)inlets < 1 || (int)inlets > DEFAULT_AUDIO_CHANNELS)
+ {
+ error("udpsend~: Number of channels must be between 1 and %d", DEFAULT_AUDIO_CHANNELS);
+ return NULL;
+ }
+ x->x_ninlets = (int)inlets;
+ for (i = 1; i < x->x_ninlets; i++)
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+
+ x->x_outlet = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_list);
+ x->x_clock = clock_new(x, (t_method)udpsend_tilde_notify);
+
+ x->x_myvec = (t_int **)t_getbytes(sizeof(t_int *) * (x->x_ninlets + 3));
+ if (!x->x_myvec)
+ {
+ error("udpsend~: out of memory");
+ return NULL;
+ }
- x->x_myvec = (t_int **)t_getbytes(sizeof(t_int *) * (x->x_ninlets + 3));
- if (!x->x_myvec)
- {
- error("udpsend~: out of memory");
- return NULL;
- }
+ pthread_mutex_init(&x->x_mutex, 0);
+ pthread_cond_init(&x->x_requestcondition, 0);
+ pthread_cond_init(&x->x_answercondition, 0);
- pthread_mutex_init(&x->x_mutex, 0);
- pthread_cond_init(&x->x_requestcondition, 0);
- pthread_cond_init(&x->x_answercondition, 0);
+ x->x_hostname = ps_localhost;
+ x->x_portno = DEFAULT_PORT;
+ x->x_connectstate = 0;
+ x->x_childthread = 0;
+ x->x_fd = -1;
- x->x_hostname = ps_localhost;
- x->x_portno = DEFAULT_PORT;
- x->x_connectstate = 0;
- x->x_childthread = 0;
- x->x_fd = -1;
-
- x->x_tag.format = x->x_format = SF_FLOAT;
- x->x_tag.channels = x->x_channels = x->x_ninlets;
- x->x_tag.version = SF_BYTE_NATIVE; /* native endianness */
- x->x_vecsize = 64; /* this is updated in the perform routine udpsend_tilde_perform */
- x->x_bitrate = 0; /* not specified, use default */
- x->x_cbuf = NULL;
- x->x_blocksize = DEFAULT_AUDIO_BUFFER_SIZE; /* <-- the only place blocksize is set */
- x->x_blockspersend = x->x_blocksize / x->x_vecsize; /* 1024/64 = 16 blocks */
- x->x_blockssincesend = 0;
- x->x_cbufsize = x->x_blocksize * sizeof(t_float) * x->x_ninlets;
- x->x_cbuf = (char *)t_getbytes(x->x_cbufsize);
+ x->x_tag.format = x->x_format = SF_FLOAT;
+ x->x_tag.channels = x->x_channels = x->x_ninlets;
+ x->x_tag.version = SF_BYTE_NATIVE; /* native endianness */
+ x->x_vecsize = 64; /* this is updated in the perform routine udpsend_tilde_perform */
+ x->x_bitrate = 0; /* not specified, use default */
+ x->x_cbuf = NULL;
+ if (blocksize == 0) x->x_blocksize = DEFAULT_AUDIO_BUFFER_SIZE;
+ else if (DEFAULT_AUDIO_BUFFER_SIZE%(int)blocksize)
+ {
+ error("udpsend~: 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_blockspersend = x->x_blocksize / x->x_vecsize; /* 1024/64 = 16 blocks */
+ x->x_blockssincesend = 0;
+ x->x_cbufsize = x->x_blocksize * sizeof(t_float) * x->x_ninlets;
+ x->x_cbuf = (char *)t_getbytes(x->x_cbufsize);
#if defined(UNIX) || defined(unix)
- /* we don't want to get signaled in case send() fails */
- signal(SIGPIPE, SIG_IGN);
+ /* we don't want to get signaled in case send() fails */
+ signal(SIGPIPE, SIG_IGN);
#endif
+ }
return (x);
}
@@ -594,12 +612,14 @@ void udpsend_tilde_setup(void)
class_addmethod(udpsend_tilde_class, (t_method)udpsend_tilde_format, gensym("format"), A_SYMBOL, A_DEFFLOAT, 0);
class_sethelpsymbol(udpsend_tilde_class, gensym("udpsend~"));
post("udpsend~ v%s, (c) 2004-2005 Olaf Matthes, 2010 Martin Peach", VERSION);
+ post("udpsend~ Default blocksize is %d", DEFAULT_AUDIO_BUFFER_SIZE);
ps_nothing = gensym("");
ps_localhost = gensym("localhost");
ps_hostname = gensym("ipaddr");
ps_format = gensym("format");
- ps_channels = gensym("channels");
+ ps_channels = gensym("channels");
+ ps_vecsize = gensym("vecsize");
ps_framesize = gensym("framesize");
ps_bitrate = gensym("bitrate");
ps_sf_float = gensym("_float_");
diff --git a/net/udpsend~.h b/net/udpsend~.h
index 6894e49..6a3fdd7 100644
--- a/net/udpsend~.h
+++ b/net/udpsend~.h
@@ -37,7 +37,7 @@
#define VERSION "0.1"
#define DEFAULT_AUDIO_CHANNELS 32 /* nax. number of audio channels we support */
-#define DEFAULT_AUDIO_BUFFER_SIZE 1024 /* number of samples in one audio block */
+#define DEFAULT_AUDIO_BUFFER_SIZE 2048 /*1024*/ /* number of samples in one audio block */
#define DEFAULT_UDP_PACKT_SIZE 8192 /* number of bytes we send in one UDP datagram (OS X only) */
#define DEFAULT_PORT 8000 /* default network port number */