diff options
author | Martin Peach <mrpeach@users.sourceforge.net> | 2010-01-14 20:24:32 +0000 |
---|---|---|
committer | Martin Peach <mrpeach@users.sourceforge.net> | 2010-01-14 20:24:32 +0000 |
commit | 353e70855e34a7da9800782048268bc6a52d10e4 (patch) | |
tree | f9f71136fd74ee0a89dee55b9fda805578f2325a | |
parent | 8281e1d171fa73f344c67b8a899144bc6390d593 (diff) |
Always send in network byte order for all architectures. UDP receiving socket doesn't need to be
non-blocking (I think...). Cleaned up help patch.
svn path=/trunk/externals/mrpeach/; revision=12998
-rw-r--r-- | net/udpreceive~.c | 86 | ||||
-rw-r--r-- | net/udpsend~-help.pd | 51 | ||||
-rw-r--r-- | net/udpsend~.c | 46 | ||||
-rw-r--r-- | net/udpsend~.h | 72 |
4 files changed, 89 insertions, 166 deletions
diff --git a/net/udpreceive~.c b/net/udpreceive~.c index 85f9bf1..263ac05 100644 --- a/net/udpreceive~.c +++ b/net/udpreceive~.c @@ -214,11 +214,8 @@ static void udpreceive_tilde_datapoll(t_udpreceive_tilde *x) return; } /* adjust byte order if neccessarry */ - if (x->x_frames[x->x_framein].tag.version != SF_BYTE_NATIVE) - { - x->x_frames[x->x_framein].tag.count = netsend_long(x->x_frames[x->x_framein].tag.count); - x->x_frames[x->x_framein].tag.framesize = netsend_long(x->x_frames[x->x_framein].tag.framesize); - } + x->x_frames[x->x_framein].tag.count = ntohl(x->x_frames[x->x_framein].tag.count); + x->x_frames[x->x_framein].tag.framesize = ntohl(x->x_frames[x->x_framein].tag.framesize); /* get info from header tag */ if (x->x_frames[x->x_framein].tag.channels > x->x_noutlets) { @@ -270,18 +267,15 @@ bail: static void udpreceive_tilde_connectpoll(t_udpreceive_tilde *x) { - int sockaddrl = (int)sizeof(struct sockaddr); + socklen_t sockaddrlen = sizeof(struct sockaddr); struct sockaddr_in incomer_address; - int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl); + int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrlen); if (fd < 0) { post("udpreceive~: accept failed"); return; } -#ifdef O_NONBLOCK - fcntl(fd, F_SETFL, O_NONBLOCK); -#endif if (x->x_socket != -1) { post("udpreceive~: new connection"); @@ -382,34 +376,20 @@ static t_int *udpreceive_tilde_perform(t_int *w) { case SF_FLOAT: { - t_float* buf = (t_float *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; + int32_t* buf = (int32_t *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; + flint fl; - if (x->x_frames[x->x_frameout].tag.version == SF_BYTE_NATIVE) + /* swap bytes if necessary */ + while (n--) { - while (n--) + for (i = 0; i < channels; i++) { - for (i = 0; i < channels; i++) - { - *out[i]++ = *buf++; - } - for (i = channels; i < x->x_noutlets; i++) - { - *out[i]++ = 0.; - } + fl.i32 = ntohl(*buf++); + *out[i]++ = fl.f32; } - } - else /* swap bytes */ - { - while (n--) + for (i = channels; i < x->x_noutlets; i++) { - for (i = 0; i < channels; i++) - { - *out[i]++ = netsend_float(*buf++); - } - for (i = channels; i < x->x_noutlets; i++) - { - *out[i]++ = 0.; - } + *out[i]++ = 0.; } } break; @@ -417,40 +397,23 @@ static t_int *udpreceive_tilde_perform(t_int *w) case SF_16BIT: { short* buf = (short *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; - - if (x->x_frames[x->x_frameout].tag.version == SF_BYTE_NATIVE) + /* swap bytes if necessary */ + while (n--) { - while (n--) + for (i = 0; i < channels; i++) { - for (i = 0; i < channels; i++) - { - *out[i]++ = (t_float)(*buf++ * 3.051850e-05); - } - for (i = channels; i < x->x_noutlets; i++) - { - *out[i]++ = 0.; - } + *out[i]++ = (t_float)((short)(ntohs(*buf++)) * 3.051850e-05); } - } - else /* swap bytes */ - { - while (n--) + for (i = channels; i < x->x_noutlets; i++) { - for (i = 0; i < channels; i++) - { - *out[i]++ = (t_float)(netsend_short(*buf++) * 3.051850e-05); - } - for (i = channels; i < x->x_noutlets; i++) - { - *out[i]++ = 0.; - } + *out[i]++ = 0.; } } break; } case SF_8BIT: { - unsigned char* buf = (char *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; + unsigned char* buf = (unsigned char *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; while (n--) { @@ -468,6 +431,7 @@ static t_int *udpreceive_tilde_perform(t_int *w) case SF_MP3: { post("udpreceive~: mp3 format not supported"); + break; } case SF_AAC: { @@ -626,7 +590,13 @@ static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets, t_floa for (i = sizeof(t_object); i < (int)sizeof(t_udpreceive_tilde); i++) ((char *)x)[i] = 0; - x->x_noutlets = CLIP((int)outlets, 1, DEFAULT_AUDIO_CHANNELS); + if ((int)outlets < 1 || (int)outlets > DEFAULT_AUDIO_CHANNELS) + { + error("udpreceive~: Number of channels must be between 1 and %d", DEFAULT_AUDIO_CHANNELS); + return NULL; + } + + x->x_noutlets = (int)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); diff --git a/net/udpsend~-help.pd b/net/udpsend~-help.pd index e97aad8..f8bc684 100644 --- a/net/udpsend~-help.pd +++ b/net/udpsend~-help.pd @@ -1,4 +1,4 @@ -#N canvas 308 59 838 769 10; +#N canvas 415 49 838 769 10; #X obj -178 225 osc~ 440; #X msg -398 60 disconnect; #X msg -353 105 format float; @@ -10,7 +10,7 @@ #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 +#X obj -178 320 tgl 15 0 empty empty empty 17 7 0 10 -4034 -1 -1 0 1; #X symbolatom -97 435 10 0 0 0 - - -; #X floatatom -44 369 5 0 0 0 - - -; @@ -65,12 +65,11 @@ per sample); #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 -412 185 hradio 15 1 0 4 empty empty empty 0 -8 0 10 -4034 -1 +-1 2; #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; @@ -106,6 +105,9 @@ if nothing is receiving.; #X text -299 18 connect to <hostname> <port> and begin transmitting ; #X text -455 294 [udpreceive~] and [udpsend~]; +#X text -256 540 receives 2 channels on port 8008 Same blocksize as +udpsend~; +#X floatatom -412 216 5 0 0 0 - - -; #X connect 0 0 54 0; #X connect 1 0 62 0; #X connect 2 0 62 0; @@ -125,7 +127,7 @@ if nothing is receiving.; #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 55 0 70 0; #X connect 57 0 16 0; #X connect 57 1 12 0; #X connect 57 2 13 0; @@ -135,24 +137,25 @@ if nothing is receiving.; #X connect 57 6 9 0; #X connect 60 0 62 0; #X connect 61 0 60 0; +#X connect 61 0 88 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 0 65 0; +#X connect 64 1 65 1; +#X connect 64 2 73 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; +#X connect 68 0 69 0; +#X connect 69 0 62 1; +#X connect 70 0 54 1; +#X connect 70 0 69 1; +#X connect 73 0 28 0; +#X connect 73 1 25 0; +#X connect 73 2 26 0; +#X connect 73 3 27 0; +#X connect 73 4 33 0; +#X connect 73 5 34 0; +#X connect 73 6 35 0; +#X connect 73 7 36 0; +#X connect 73 8 74 0; +#X connect 73 9 8 0; +#X connect 82 0 64 0; diff --git a/net/udpsend~.c b/net/udpsend~.c index 291891e..d209837 100644 --- a/net/udpsend~.c +++ b/net/udpsend~.c @@ -34,11 +34,11 @@ #include "m_pd.h" #include "udpsend~.h" -#include "float_cast.h" /* tools for fast conversion from float to int */ #include <sys/types.h> #include <string.h> #include <stdlib.h> +#include <math.h> #if defined(UNIX) || defined(unix) #include <sys/socket.h> #include <errno.h> @@ -52,7 +52,6 @@ #include <fcntl.h> #include <stdio.h> #include <pthread.h> -#include <math.h> #define SOCKET_ERROR -1 #endif #ifdef _WIN32 @@ -93,18 +92,18 @@ typedef struct _udpsend_tilde int x_connectstate; char *x_cbuf; int x_cbufsize; - int x_blocksize; /* set to DEFAULT_AUDIO_BUFFER_SIZE in udpsend_tilde_new() */ + int x_blocksize; /* set to DEFAULT_AUDIO_BUFFER_SIZE or user-supplied argument 3 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 */ + 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; @@ -279,26 +278,33 @@ static t_int *udpsend_tilde_perform(t_int *w) { case SF_FLOAT: { - t_float* fbuf = (t_float *)x->x_cbuf + (x->x_blockssincesend * x->x_vecsize * x->x_tag.channels); + int32_t* fbuf = (int32_t *)x->x_cbuf + (x->x_blockssincesend * x->x_vecsize * x->x_tag.channels); + flint fl; + while (n--) for (i = 0; i < x->x_tag.channels; i++) - *fbuf++ = *(in[i]++); + { + fl.f32 = *(in[i]++); + *fbuf++ = htonl(fl.i32); + } break; } case SF_16BIT: { short* cibuf = (short *)x->x_cbuf + (x->x_blockssincesend * x->x_vecsize * x->x_tag.channels); + while (n--) for (i = 0; i < x->x_tag.channels; i++) - *cibuf++ = (short)lrint(32767.0 * *(in[i]++)); + *cibuf++ = htons((short)floor(32767.5 * *(in[i]++)));/* signed binary */ break; } case SF_8BIT: { - unsigned char* cbuf = (unsigned char*)x->x_cbuf + (x->x_blockssincesend * x->x_vecsize * x->x_tag.channels); + unsigned char* cbuf = (unsigned char*)x->x_cbuf + (x->x_blockssincesend * x->x_vecsize * x->x_tag.channels); + while (n--) for (i = 0; i < x->x_tag.channels; i++) - *cbuf++ = (unsigned char)(128. * (1.0 + *(in[i]++))); + *cbuf++ = (unsigned char)floor(128. * (1.0 + *(in[i]++))); /* offset binary */ break; } default: @@ -314,8 +320,8 @@ static t_int *udpsend_tilde_perform(t_int *w) { bp = (char *)x->x_cbuf; /* fill in the header tag */ - x->x_tag.framesize = length; - x->x_tag.count = x->x_count; + x->x_tag.framesize = htonl(length); + x->x_tag.count = htonl(x->x_count); /* send the format tag */ if (send(x->x_fd, (char*)&x->x_tag, sizeof(t_tag), SEND_FLAGS) < 0) { @@ -504,7 +510,7 @@ static void udpsend_tilde_info(t_udpsend_tilde *x) outlet_anything(x->x_outlet2, ps_vecsize, 1, list); /* framesize */ - SETFLOAT(list, (t_float)x->x_tag.framesize); + SETFLOAT(list, (t_float)(ntohl(x->x_tag.framesize))); outlet_anything(x->x_outlet2, ps_framesize, 1, list); /* bitrate */ @@ -558,9 +564,7 @@ static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg blocksize) 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) diff --git a/net/udpsend~.h b/net/udpsend~.h index 6a3fdd7..af1e07e 100644 --- a/net/udpsend~.h +++ b/net/udpsend~.h @@ -1,4 +1,4 @@ -/* udpsend~.h based on netsend~.h */
+/* udpsend~.h modified by Martin Peach from netsend~.h: */
/* ------------------------ netsend~ ------------------------------------------ */
/* */
/* Tilde object to send uncompressed audio data to netreceive~. */
@@ -34,7 +34,7 @@ /* Some enhancements have been made with the goal of keeping compatibility */
/* between the stream formats of streamout~/in~ and netsend~/receive~. */
-#define VERSION "0.1"
+#define VERSION "0.2"
#define DEFAULT_AUDIO_CHANNELS 32 /* nax. number of audio channels we support */
#define DEFAULT_AUDIO_BUFFER_SIZE 2048 /*1024*/ /* number of samples in one audio block */
@@ -59,54 +59,12 @@ typedef unsigned short u_int16_t; #define HAVE_U_INT16_T
#endif
#endif
-
-#ifndef CLIP
-#define CLIP(a, lo, hi) ( (a)>(lo)?( (a)<(hi)?(a):(hi) ):(lo) )
-#endif
-
-
-/* swap 32bit t_float. Is there a better way to do that???? */
-#ifdef _WIN32
-__inline static float netsend_float(float f)
-#else
-inline static float netsend_float(float f)
-#endif
-{
- union
- {
- float f;
- unsigned char b[4];
- } dat1, dat2;
-
- dat1.f = f;
- dat2.b[0] = dat1.b[3];
- dat2.b[1] = dat1.b[2];
- dat2.b[2] = dat1.b[1];
- dat2.b[3] = dat1.b[0];
- return dat2.f;
-}
-
-/* swap 32bit long int */
-#ifdef _WIN32
-__inline static long netsend_long(long n)
-#else
-inline static long netsend_long(long n)
-#endif
-{
- return (((n & 0xff) << 24) | ((n & 0xff00) << 8) |
- ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24));
-}
-
-/* swap 16bit short int */
-#ifdef _WIN32
-__inline static long netsend_short(long n)
-#else
-inline static short netsend_short(short n)
-#endif
-{
- return (((n & 0xff) << 8) | ((n & 0xff00) >> 8));
-}
-
+ +typedef union _flint +{ + int i32; + t_float f32; +} flint; /* format specific stuff */
@@ -124,21 +82,9 @@ inline static short netsend_short(short n) #define SF_SIZEOF(a) (a == SF_FLOAT ? sizeof(t_float) : \
a == SF_16BIT ? sizeof(short) : 1)
-
-/* version / byte-endian specific stuff */
-
-#define SF_BYTE_LE 1 /* little endian */
-#define SF_BYTE_BE 2 /* big endian */
-
-#if defined(_WIN32) || defined(__linux__) || defined(IRIX)
-#define SF_BYTE_NATIVE SF_BYTE_LE
-#else /* must be __APPLE__ */
-#define SF_BYTE_NATIVE SF_BYTE_BE
-#endif
-
typedef struct _tag
{ /* size (bytes) */
- char version; /* 1 */
+// char version; /* 1 */
char format; /* 1 */
long count; /* 4 */
char channels; /* 1 */
|