From ccbb6e79117dcb3e872ec6edc89386f3d1e21140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Fri, 26 Mar 2010 14:33:47 +0000 Subject: no more audio-over-net objects use AOO (Audio Over OSC) or the like for such things... svn path=/trunk/externals/iem/iemnet/; revision=13281 --- udpreceive~.c | 805 ---------------------------------------------------------- 1 file changed, 805 deletions(-) delete mode 100644 udpreceive~.c (limited to 'udpreceive~.c') diff --git a/udpreceive~.c b/udpreceive~.c deleted file mode 100644 index 42bf7c7..0000000 --- a/udpreceive~.c +++ /dev/null @@ -1,805 +0,0 @@ -/* udpreceive~ started 20100110 by Martin Peach based on netreceive~: */ -/* ------------------------ netreceive~ --------------------------------------- */ -/* */ -/* Tilde object to receive uncompressed audio data from netsend~. */ -/* Written by Olaf Matthes . */ -/* Based on streamin~ by Guenter Geiger. */ -/* Get source at http://www.akustische-kunst.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. */ -/* */ -/* See file LICENSE for further informations on licensing terms. */ -/* */ -/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* */ -/* Based on PureData by Miller Puckette and others. */ -/* */ -/* This project was commissioned by the Society for Arts and Technology [SAT], */ -/* Montreal, Quebec, Canada, http://www.sat.qc.ca/. */ -/* */ -/* ---------------------------------------------------------------------------- */ - - -#include "m_pd.h" - -#include "udpsend~.h" - -#include -#include -#if defined(UNIX) || defined(unix) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define SOCKET_ERROR -1 -#endif -#ifdef _WIN32 -#include -#include /* for socklen_t */ -#endif - -#ifndef SOL_IP -#define SOL_IP IPPROTO_IP -#endif - -#define DEFAULT_AUDIO_BUFFER_FRAMES 16 /* a small circ. buffer for 16 frames */ -#define DEFAULT_AVERAGE_NUMBER 10 /* number of values we store for average history */ -#define DEFAULT_NETWORK_POLLTIME 1 /* interval in ms for polling for input data (Max/MSP only) */ -#define DEFAULT_QUEUE_LENGTH 3 /* min. number of buffers that can be used reliably on your hardware */ - -#if defined(UNIX) || defined(unix) -#define CLOSESOCKET(fd) close(fd) -#endif -#ifdef _WIN32 -#define CLOSESOCKET(fd) closesocket(fd) -#endif - -/* ------------------------ udpreceive~ ----------------------------- */ - -typedef struct _udpreceive_tilde -{ - t_object x_obj; - t_outlet *x_outlet1; - t_outlet *x_outlet2; - t_outlet *x_addrout; - t_clock *x_clock; - t_atom x_addrbytes[5]; - int x_socket; - int x_connectsocket; - int x_nconnections; - long x_addr; - unsigned short x_port; - t_symbol *x_hostname; - int x_error; - int x_buffering; - char x_msg[256]; - - /* buffering */ - int x_framein;// index of next empty frame in x_frames[] - int x_frameout;// index of next frame to play back from x_frames[] - t_frame x_frames[DEFAULT_AUDIO_BUFFER_FRAMES]; - int x_maxframes; - long x_tag_errors; - int x_sync;// zero if we didn't receive a tag when we expected one - int x_blocksize; - int x_blocksperrecv; - int x_blockssincerecv; - - int x_nbytes; - int x_counter;// count of received frames - int x_average[DEFAULT_AVERAGE_NUMBER]; - int x_averagecur; - int x_underflow; - int x_overflow; - int x_valid; - long x_samplerate; - int x_noutlets; - int x_vecsize; - t_int **x_myvec; /* vector we pass on to the DSP routine */ -} t_udpreceive_tilde; - -/* function prototypes */ -static void udpreceive_tilde_closesocket(t_udpreceive_tilde* x); -static void udpreceive_tilde_reset(t_udpreceive_tilde* x, t_floatarg buffer); -static void udpreceive_tilde_datapoll(t_udpreceive_tilde *x); -static void udpreceive_tilde_connectpoll(t_udpreceive_tilde *x); -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_tick(t_udpreceive_tilde *x); -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); -static int udpreceive_tilde_setsocketoptions(int sockfd); -/* these would require to include some headers that are different - between pd 0.36 and later, so it's easier to do it like this! */ -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, *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, - *ps_tag_errors; - -/* remove all pollfunctions and close socket */ -static void udpreceive_tilde_closesocket(t_udpreceive_tilde* x) -{ - sys_rmpollfn(x->x_socket); - outlet_float(x->x_outlet1, 0); - CLOSESOCKET(x->x_socket); - x->x_socket = -1; -} - -static void udpreceive_tilde_reset(t_udpreceive_tilde* x, t_floatarg buffer) -{ - int i; - - x->x_counter = 0; - x->x_nbytes = 0; - x->x_framein = 0; - x->x_frameout = 0; - x->x_blockssincerecv = 0; - x->x_blocksperrecv = x->x_blocksize / x->x_vecsize; - x->x_tag_errors = 0; - - for (i = 0; i < DEFAULT_AVERAGE_NUMBER; i++) - x->x_average[i] = x->x_maxframes; - x->x_averagecur = 0; - - 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; - x->x_buffering = 1; -} - -static void udpreceive_tilde_datapoll(t_udpreceive_tilde *x) -{ - int ret; - int n; - long addr; - unsigned short port; - struct sockaddr_in from; - socklen_t fromlen = sizeof(from); - t_tag *tag_ptr; - - n = x->x_nbytes; - - if (x->x_nbytes == 0) /* we ate all the samples and need a new header tag */ - { - tag_ptr = &x->x_frames[x->x_framein].tag; - /* receive header tag */ - ret = recvfrom(x->x_socket, (char*)tag_ptr, 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); - /* output addr/port only if changed */ - if (!((addr == x->x_addr)&&(port == x->x_port))) - { - x->x_addr = addr; - x->x_port = port; - x->x_addrbytes[0].a_w.w_float = (x->x_addr & 0xFF000000)>>24; - x->x_addrbytes[1].a_w.w_float = (x->x_addr & 0x0FF0000)>>16; - x->x_addrbytes[2].a_w.w_float = (x->x_addr & 0x0FF00)>>8; - x->x_addrbytes[3].a_w.w_float = (x->x_addr & 0x0FF); - x->x_addrbytes[4].a_w.w_float = x->x_port; - outlet_list(x->x_addrout, &s_list, 5L, x->x_addrbytes); - } - if (ret <= 0) /* error */ - { - if (0 == udpreceive_tilde_sockerror("recv tag")) return; - udpreceive_tilde_reset(x, 0); - return; - } - else if (ret != sizeof(t_tag)) - { - /* incomplete header tag: return and try again later */ - /* in the hope that more data will be available */ - error("udpreceive~: got incomplete header tag"); - return; - } - /* make sure this is really a tag */ - if (!((tag_ptr->tag[0] == 'T')&&(tag_ptr->tag[1] == 'A')&&(tag_ptr->tag[2] == 'G')&&(tag_ptr->tag[3] == '!'))) - { - ++x->x_tag_errors; - if (x->x_sync) error("udpreceive~: bad header tag (%d)", x->x_tag_errors); - x->x_sync = 0; - /* tag length is 16 bytes, a multiple of the data frame size, so eventually we should resync on a tag */ - return; - } - /* adjust byte order if necessary */ - tag_ptr->count = ntohl(tag_ptr->count); - tag_ptr->framesize = ntohl(tag_ptr->framesize); - - /* get info from header tag */ - if (tag_ptr->channels > (x->x_noutlets-1)) - { - error("udpreceive~: incoming stream has too many channels (%d)", tag_ptr->channels); - x->x_counter = 0; - return; - } - x->x_nbytes = n = tag_ptr->framesize; - x->x_sync = 1; - } - else /* we already have header tag or some data and need more */ - { - 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; - } - else if (ret < 0) /* error */ - { - if ( 0 == (ret = udpreceive_tilde_sockerror("recv data"))) return; -#ifdef _WIN32 - if ( ret == WSAEFAULT) -#else - if ( ret == EFAULT) -#endif - { - post ("udpreceive~: EFAULT: %p %lu %d", x->x_frames[x->x_framein].data, x->x_frames[x->x_framein].tag.framesize, n); - return; - } - udpreceive_tilde_reset(x, 0); - return; - } - - x->x_nbytes = n; - if (n == 0) /* a complete packet is received */ - { - if (x->x_frames[x->x_framein].tag.format == SF_AAC) - { - error("udpreceive~: don't know how to decode AAC format"); - return; - } - x->x_counter++; - x->x_framein++; - x->x_framein %= DEFAULT_AUDIO_BUFFER_FRAMES; - - /* check for buffer overflow */ - if (x->x_framein == x->x_frameout) - { - x->x_overflow++; - } - } - } -} - -static void udpreceive_tilde_connectpoll(t_udpreceive_tilde *x) -{ - socklen_t sockaddrlen = sizeof(struct sockaddr); - struct sockaddr_in incomer_address; - int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrlen); - - if (fd < 0) - { - post("udpreceive~: accept failed"); - return; - } - if (x->x_socket != -1) - { - post("udpreceive~: new connection"); - udpreceive_tilde_closesocket(x); - } - - udpreceive_tilde_reset(x, 0); - x->x_socket = fd; - x->x_nbytes = 0; - x->x_hostname = gensym(inet_ntoa(incomer_address.sin_addr)); - sys_addpollfn(fd, udpreceive_tilde_datapoll, x); - outlet_float(x->x_outlet1, 1); -} - -static int udpreceive_tilde_createsocket(t_udpreceive_tilde* x, int portno) -{ - struct sockaddr_in server; - int sockfd; - - /* create a socket */ - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - - if (sockfd < 0) - { - udpreceive_tilde_sockerror("socket"); - return 0; - } - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; - - /* assign server port number */ - - server.sin_port = htons((u_short)portno); - post("udpreceive~: listening to port number %d", portno); - - udpreceive_tilde_setsocketoptions(sockfd); - - /* name the socket */ - if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) - { - udpreceive_tilde_sockerror("bind"); - CLOSESOCKET(sockfd); - return 0; - } - - x->x_socket = sockfd; - x->x_nbytes = 0; - sys_addpollfn(sockfd, udpreceive_tilde_datapoll, x); - return 1; -} - -/* Queue is 1 to 16 frames long */ -#define QUEUESIZE (int)((x->x_framein + DEFAULT_AUDIO_BUFFER_FRAMES - x->x_frameout) % DEFAULT_AUDIO_BUFFER_FRAMES) -/* Block is a set of sample vectors inside a frame, one vector per channel */ -#define BLOCKOFFSET (x->x_blockssincerecv * x->x_vecsize * x->x_frames[x->x_frameout].tag.channels) - -static t_int *udpreceive_tilde_perform(t_int *w) -{ - t_udpreceive_tilde *x = (t_udpreceive_tilde*) (w[1]); - int n = (int)(w[2]); - t_float *out[DEFAULT_AUDIO_CHANNELS]; - const int offset = 3; - const int channels = x->x_frames[x->x_frameout].tag.channels; - int i = 0; - - x->x_valid = 0; - for (i = 0; i < x->x_noutlets; i++) - { - out[i] = (t_float *)(w[offset + i]); - } - - /* set our vector size to the local vector size */ - if (n != x->x_vecsize) - { - x->x_vecsize = n; - x->x_blocksperrecv = x->x_blocksize / x->x_vecsize; - x->x_blockssincerecv = 0; - } - - /* check whether there is enough data in buffer */ - if (x->x_buffering && (x->x_counter < x->x_maxframes)) - { - goto bail; - } - x->x_buffering = 0; - - /* check for buffer underflow */ - if (x->x_framein == x->x_frameout) - { - x->x_underflow++; - goto bail; - } - - x->x_valid = 1; - /* queue balancing */ - x->x_average[x->x_averagecur] = QUEUESIZE; - if (++x->x_averagecur >= DEFAULT_AVERAGE_NUMBER) - x->x_averagecur = 0; - - switch (x->x_frames[x->x_frameout].tag.format) - { - case SF_FLOAT: - { - int32_t* buf = (int32_t *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; - flint fl; - - /* swap bytes if necessary */ - while (n--) - { - for (i = 0; i < channels; i++) - { - fl.i32 = ntohl(*buf++); - *out[i]++ = fl.f32; - } - for (i = channels; i < (x->x_noutlets-1); i++) - { - *out[i]++ = 0.; - } - *out[i]++ = x->x_valid; - } - x->x_error = 0; - break; - } - case SF_16BIT: - { - short* buf = (short *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; - /* swap bytes if necessary */ - while (n--) - { - for (i = 0; i < channels; i++) - { - *out[i]++ = (t_float)((short)(ntohs(*buf++)) * 3.051850e-05); - } - for (i = channels; i < (x->x_noutlets-1); i++) - { - *out[i]++ = 0.; - } - *out[i]++ = x->x_valid; - } - x->x_error = 0; - break; - } - case SF_8BIT: - { - unsigned char* buf = (unsigned char *)x->x_frames[x->x_frameout].data + BLOCKOFFSET; - - while (n--) - { - for (i = 0; i < channels; i++) - { - *out[i]++ = (t_float)((0.0078125 * (*buf++)) - 1.0); - } - for (i = channels; i < (x->x_noutlets-1); i++) - { - *out[i]++ = 0.; - } - *out[i]++ = x->x_valid; - } - x->x_error = 0; - break; - } - case SF_MP3: - { - if (x->x_error != 1) - { - x->x_error = 1; - sprintf(x->x_msg, "udpreceive~: mp3 format not supported"); - clock_delay(x->x_clock, 0); - } - break; - } - case SF_AAC: - { - if (x->x_error != 2) - { - x->x_error = 2; - sprintf(x->x_msg, "udpreceive~: aac format not supported"); - clock_delay(x->x_clock, 0); - } - break; - } - default: - if (x->x_error != 3) - { - x->x_error = 3; - sprintf(x->x_msg, "udpreceive~: unknown format (%d)",x->x_frames[x->x_frameout].tag.format); - clock_delay(x->x_clock, 0); - } - break; - } - - if (!(x->x_blockssincerecv < x->x_blocksperrecv - 1)) - { - x->x_blockssincerecv = 0; - x->x_frameout++; - x->x_frameout %= DEFAULT_AUDIO_BUFFER_FRAMES; - } - else x->x_blockssincerecv++; - - return (w + offset + x->x_noutlets); - -bail: - /* set output to zero */ - while (n--) for (i = 0; i < x->x_noutlets; i++) *(out[i]++) = 0.; - return (w + offset + x->x_noutlets); -} - -static void udpreceive_tilde_dsp(t_udpreceive_tilde *x, t_signal **sp) -{ - int i; - - x->x_myvec[0] = (t_int*)x; - x->x_myvec[1] = (t_int*)sp[0]->s_n; - - x->x_samplerate = (long)sp[0]->s_sr; - - if (x->x_blocksize % sp[0]->s_n) - { - error("udpreceive~: signal vector size too large (needs to be even divisor of %d)", x->x_blocksize); - } - else - { - for (i = 0; i < x->x_noutlets; i++) - { - x->x_myvec[2 + i] = (t_int*)sp[i + 1]->s_vec; - } - dsp_addv(udpreceive_tilde_perform, x->x_noutlets + 2, (t_int*)x->x_myvec); - } -} - -/* send stream info */ -static void udpreceive_tilde_info(t_udpreceive_tilde *x) -{ - t_atom list[2]; - t_symbol *sf_format; - t_float bitrate; - int i, avg = 0; - - for (i = 0; i < DEFAULT_AVERAGE_NUMBER; i++) - avg += x->x_average[i]; - - bitrate = (t_float)((SF_SIZEOF(x->x_frames[x->x_frameout].tag.format) * x->x_samplerate * 8 * x->x_frames[x->x_frameout].tag.channels) / 1000.); - - switch (x->x_frames[x->x_frameout].tag.format) - { - case SF_FLOAT: - { - sf_format = ps_sf_float; - break; - } - case SF_16BIT: - { - sf_format = ps_sf_16bit; - break; - } - case SF_8BIT: - { - sf_format = ps_sf_8bit; - break; - } - case SF_MP3: - { - sf_format = ps_sf_mp3; - break; - } - case SF_AAC: - { - sf_format = ps_sf_aac; - break; - } - default: - { - sf_format = ps_sf_unknown; - break; - } - } - - /* --- stream information (t_tag) --- */ - /* audio format */ - SETSYMBOL(list, (t_symbol *)sf_format); - outlet_anything(x->x_outlet2, ps_format, 1, list); - - /* channels */ - SETFLOAT(list, (t_float)x->x_frames[x->x_frameout].tag.channels); - outlet_anything(x->x_outlet2, ps_channels, 1, list); - - /* framesize */ - SETFLOAT(list, (t_float)x->x_frames[x->x_frameout].tag.framesize); - outlet_anything(x->x_outlet2, ps_framesize, 1, list); - - /* bitrate */ - SETFLOAT(list, (t_float)bitrate); - outlet_anything(x->x_outlet2, ps_bitrate, 1, list); - - /* --- internal info (buffer and network) --- */ - /* overflow */ - SETFLOAT(list, (t_float)x->x_overflow); - outlet_anything(x->x_outlet2, ps_overflow, 1, list); - - /* underflow */ - SETFLOAT(list, (t_float)x->x_underflow); - outlet_anything(x->x_outlet2, ps_underflow, 1, list); - - /* queuesize */ - SETFLOAT(list, (t_float)QUEUESIZE); - outlet_anything(x->x_outlet2, ps_queuesize, 1, list); - - /* 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); - - /* total tag errors */ - SETFLOAT(list, (t_float)x->x_tag_errors); - outlet_anything(x->x_outlet2, ps_tag_errors, 1, list); - - outlet_list(x->x_addrout, &s_list, 5L, x->x_addrbytes); -} - -static void udpreceive_tilde_tick(t_udpreceive_tilde *x) -{ -/* post a message once, outside of perform routine */ - post("%s", x->x_msg); -} - -static void *udpreceive_tilde_new(t_floatarg fportno, t_floatarg outlets, t_floatarg blocksize) -{ - t_udpreceive_tilde *x; - int i; - - if (fportno == 0) fportno = DEFAULT_PORT; - - x = (t_udpreceive_tilde *)pd_new(udpreceive_tilde_class); - if (x) - { - for (i = sizeof(t_object); i < (int)sizeof(t_udpreceive_tilde); i++) - ((char *)x)[i] = 0; - - 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 + 1; // extra outlet for valid flag - 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_addr = 0; - x->x_port = 0; - x->x_myvec = (t_int **)t_getbytes(sizeof(t_int *) * (x->x_noutlets + 3)); - if (!x->x_myvec) - { - error("udpreceive~: out of memory"); - return NULL; - } - - x->x_connectsocket = x->x_socket = -1; - x->x_nconnections = x->x_underflow = x->x_overflow = 0; - x->x_hostname = ps_nothing; -/* allocate space for 16 frames of 1024 X numchannels floats*/ - for (i = 0; i < DEFAULT_AUDIO_BUFFER_FRAMES; i++) - { - x->x_frames[i].data = (char *)t_getbytes(DEFAULT_AUDIO_BUFFER_SIZE * (x->x_noutlets-1) * sizeof(t_float)); - } - x->x_clock = clock_new(&x->x_obj.ob_pd, (t_method)udpreceive_tilde_tick); - - x->x_sync = 1; - x->x_tag_errors = x->x_framein = x->x_frameout = x->x_valid = 0; - x->x_maxframes = DEFAULT_QUEUE_LENGTH; - x->x_vecsize = 64; /* we'll update this later */ - 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; - x->x_buffering = 1; - - if (!udpreceive_tilde_createsocket(x, (int)fportno)) - { - error("udpreceive~: failed to create listening socket"); - return (NULL); - } - } - return (x); -} - -static void udpreceive_tilde_free(t_udpreceive_tilde *x) -{ - int i; - - if (x->x_connectsocket != -1) - { - sys_rmpollfn(x->x_connectsocket); - CLOSESOCKET(x->x_connectsocket); - } - if (x->x_socket != -1) - { - sys_rmpollfn(x->x_socket); - CLOSESOCKET(x->x_socket); - } - - /* free memory */ - t_freebytes(x->x_myvec, sizeof(t_int *) * (x->x_noutlets + 3)); - for (i = 0; i < DEFAULT_AUDIO_BUFFER_FRAMES; i++) - { - t_freebytes(x->x_frames[i].data, DEFAULT_AUDIO_BUFFER_SIZE * (x->x_noutlets-1) * sizeof(t_float)); - } - clock_free(x->x_clock); -} - -void udpreceive_tilde_setup(void) -{ - udpreceive_tilde_class = class_new(gensym("udpreceive~"), - (t_newmethod) udpreceive_tilde_new, (t_method) udpreceive_tilde_free, - sizeof(t_udpreceive_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_NULL); - - 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_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); - - ps_format = gensym("format"); - ps_tag_errors = gensym("tag_errors"); - ps_channels = gensym("channels"); - ps_framesize = gensym("framesize"); - ps_bitrate = gensym("bitrate"); - ps_overflow = gensym("overflow"); - 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_"); - ps_sf_8bit = gensym("_8bit_"); - ps_sf_mp3 = gensym("_mp3_"); - ps_sf_aac = gensym("_aac_"); - ps_sf_unknown = gensym("_unknown_"); - ps_nothing = gensym(""); -} - -/* error handlers */ -static int udpreceive_tilde_sockerror(char *s) -{ -#ifdef _WIN32 - int err = WSAGetLastError(); - if (err == 10054) return 1; - else if (err == 10040) post("udpreceive~: %s: message too long (%d)", s, err); - else if (err == 10053) post("udpreceive~: %s: software caused connection abort (%d)", s, err); - else if (err == 10055) post("udpreceive~: %s: no buffer space available (%d)", s, err); - else if (err == 10060) post("udpreceive~: %s: connection timed out (%d)", s, err); - else if (err == 10061) post("udpreceive~: %s: connection refused (%d)", s, err); - else post("udpreceive~: %s: %s (%d)", s, strerror(err), err); -#else - int err = errno; - post("udpreceive~: %s: %s (%d)", s, strerror(err), err); -#endif -#ifdef _WIN32 - if (err == WSAEWOULDBLOCK) -#endif -#if defined(UNIX) || defined(unix) - if (err == EAGAIN) -#endif - { - return 0; /* recoverable error */ - } - return err; /* indicate non-recoverable error */ -} - -static int udpreceive_tilde_setsocketoptions(int sockfd) -{ - int sockopt = 1; - if (setsockopt(sockfd, SOL_IP, TCP_NODELAY, (const char*)&sockopt, sizeof(int)) < 0) - post("udpreceive~: setsockopt NODELAY failed"); - - sockopt = 1; - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&sockopt, sizeof(int)) < 0) - post("udpreceive~: setsockopt REUSEADDR failed"); - return 0; -} - -/* fin udpreceive~.c */ -- cgit v1.2.1