diff options
author | Martin Peach <mrpeach@users.sourceforge.net> | 2010-01-12 18:58:31 +0000 |
---|---|---|
committer | Martin Peach <mrpeach@users.sourceforge.net> | 2010-01-12 18:58:31 +0000 |
commit | fcd21c7b86fa4f48db3b8273465861bfa73a2d1f (patch) | |
tree | 97600d6072c46c33013e447788e9a6a13fbe4d9d /net | |
parent | b7e8b9bc0bf7964833ddf0bc1513600df41f170c (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')
-rw-r--r-- | net/udpreceive~.c | 87 | ||||
-rw-r--r-- | net/udpsend~-help.pd | 278 | ||||
-rw-r--r-- | net/udpsend~.c | 168 | ||||
-rw-r--r-- | net/udpsend~.h | 2 |
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 */
|