From fc3d3c0a4f110a23335398c327ac0a4fc949d5cb Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 17 Jun 2002 10:13:57 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r12, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/ggee/; revision=13 --- signal/pipewrite~.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100755 signal/pipewrite~.c (limited to 'signal/pipewrite~.c') diff --git a/signal/pipewrite~.c b/signal/pipewrite~.c new file mode 100755 index 0000000..fe332f8 --- /dev/null +++ b/signal/pipewrite~.c @@ -0,0 +1,216 @@ +/* (C) Guenter Geiger */ + + +#include "m_imp.h" +//#include +#include "g_canvas.h" +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* + * -------------------------- pipewrite~ ------------------------------- + */ + +#define MAX_CHANS 4 +#define BLOCKTIME 0.001 +#define uint32 unsigned int +#define uint16 unsigned short + +static t_class *pipewrite_class; + +typedef struct _pipewrite +{ + t_object x_obj; + t_symbol* filename; + int x_file; + t_int x_channels; + t_int size; + t_glist * x_glist; + t_int x_blocked; + t_int x_blockwarn; + short maxval; +} t_pipewrite; + +static void pipewrite_close(t_pipewrite *x) +{ + if (x->x_file > 0) { + close(x->x_file); + } + x->x_file = -1; + x->size=0; +} + + +static void pipewrite_open(t_pipewrite *x,t_symbol *filename) +{ + char fname[MAXPDSTRING]; + + if (filename == &s_) { + post("pipewrite: open without filename"); + return; + } + + canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name, + fname, MAXPDSTRING); + x->x_blocked = 0; + x->filename = filename; + x->maxval=0; + x->size=0; + post("pipewrite: filename = %s",x->filename->s_name); + + pipewrite_close(x); + + if ((x->x_file = open(fname,O_WRONLY | O_NONBLOCK)) < 0) + { + + error("can't open pipe %s: ",fname); + perror("system says"); + return; + } +} + +static void pipewrite_block(t_pipewrite *x, t_floatarg f) +{ + x->x_blockwarn = f; +} + + +static short out[4*64]; + +static t_int *pipewrite_perform(t_int *w) +{ + t_pipewrite* x = (t_pipewrite*)(w[1]); + t_float * in[4]; + int c = x->x_channels; + int i,num,n; + short* tout = out; + int ret; + double timebefore,timeafter; + double late; + struct sigaction action; + struct sigaction oldaction; + + + if (x->x_file < 0) { + pipewrite_open(x,x->filename); + } + + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, &oldaction); + + for (i=0;i < c;i++) { + in[i] = (t_float *)(w[2+i]); + } + + n = num = (int)(w[2+c]); + + /* loop */ + + if (x->x_file >= 0) { + + while (n--) { + for (i=0;i 1. ) { *(in[i]) = 1. ; } + if (*(in[i]) < -1. ) { *(in[i]) = -1. ; } + *tout++ = (*(in[i])++ * 32768.); + } + } + + timebefore = sys_getrealtime(); + if ((ret = write(x->x_file,out,sizeof(short)*num*c)) < sizeof(short)*num*c) { + post("pipewrite: short write %d",ret); + + } + + timeafter = sys_getrealtime(); + late = timeafter - timebefore; + x->size +=ret; + /* OK, we let only 10 ms block here */ + if (late > BLOCKTIME && x->x_blockwarn) { + x->x_blocked++; + if (x->x_blocked > x->x_blockwarn) { + x->x_blocked=0; +/* post("maximum blockcount %d reached",x->x_blockwarn); */ + } + } + } + + sigaction(SIGPIPE, &oldaction, NULL); + + return (w+3+c); +} + + + +static void pipewrite_dsp(t_pipewrite *x, t_signal **sp) +{ + switch (x->x_channels) { + case 1: + dsp_add(pipewrite_perform, 3, x, sp[0]->s_vec, + sp[0]->s_n); + break; + case 2: + dsp_add(pipewrite_perform, 4, x, sp[0]->s_vec, + sp[1]->s_vec, sp[0]->s_n); + break; + case 4: + dsp_add(pipewrite_perform, 6, x, sp[0]->s_vec, + sp[1]->s_vec, + sp[2]->s_vec, + sp[3]->s_vec, + sp[0]->s_n); + break; + } +} + +static void pipewrite_free(t_pipewrite* x) +{ + pipewrite_close(x); +} + + +static void *pipewrite_new(t_symbol* name,t_floatarg chan) +{ + t_pipewrite *x = (t_pipewrite *)pd_new(pipewrite_class); + t_int c = chan; + + if (c<1 || c > MAX_CHANS) c = 1; + + x->x_glist = (t_glist*) canvas_getcurrent(); + x->x_channels = c--; + post("channels:%d",x->x_channels); + x->x_file=0; + x->x_blocked = 0; + x->x_blockwarn = 10; + while (c--) { + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + } + + if (name && name != &s_) { /* start the pipe */ + pipewrite_open(x,name); + } + + return (x); +} + +void pipewrite_tilde_setup(void) +{ + pipewrite_class = class_new(gensym("pipewrite~"), (t_newmethod)pipewrite_new, (t_method)pipewrite_free, + sizeof(t_pipewrite), 0,A_DEFSYM,A_DEFFLOAT,A_NULL); + class_addmethod(pipewrite_class,nullfn,gensym("signal"), 0); + class_addmethod(pipewrite_class, (t_method) pipewrite_dsp, gensym("dsp"), 0); + class_addmethod(pipewrite_class, (t_method) pipewrite_open, gensym("open"), A_SYMBOL,A_NULL); + class_addmethod(pipewrite_class, (t_method) pipewrite_close, gensym("close"), 0); + class_addmethod(pipewrite_class, (t_method)pipewrite_block,gensym("block"),A_DEFFLOAT,0); + +} -- cgit v1.2.1