diff options
Diffstat (limited to 'audience~')
-rw-r--r-- | audience~/BUGS | 14 | ||||
-rw-r--r-- | audience~/CHANGES.LOG | 8 | ||||
-rw-r--r-- | audience~/INSTALL | 15 | ||||
-rw-r--r-- | audience~/Makefile | 85 | ||||
-rw-r--r-- | audience~/README | 20 | ||||
-rw-r--r-- | audience~/audience~.c | 1054 | ||||
-rw-r--r-- | audience~/audience~.h | 44 | ||||
-rw-r--r-- | audience~/audience~.tk | 90 | ||||
-rw-r--r-- | audience~/help-audience~.pd | 60 | ||||
-rw-r--r-- | audience~/speaker.gif | bin | 0 -> 83 bytes | |||
-rw-r--r-- | audience~/wanderer.gif | bin | 0 -> 962 bytes |
11 files changed, 1390 insertions, 0 deletions
diff --git a/audience~/BUGS b/audience~/BUGS new file mode 100644 index 0000000..53cddfe --- /dev/null +++ b/audience~/BUGS @@ -0,0 +1,14 @@ +0.3 + Dead connections remain drawn after you change the number of listeners + Can't change dynamically the number of inputs, code's there but it makes PD crash + Clicks when moving listeners around +0.1 + Dead connections remain drawn after you change the number of listeners + Can't change dynamically the number of inputs, code's there but it makes PD crash + A little bit buggy audio computation + Clicks when moving listeners around +0.1 + Dead connections remain drawn after you change the number of listeners + Can't change dynamically the number of inputs, code's there but it makes PD crash + Buggy audio computation + Clicks when moving listeners around diff --git a/audience~/CHANGES.LOG b/audience~/CHANGES.LOG new file mode 100644 index 0000000..9957a67 --- /dev/null +++ b/audience~/CHANGES.LOG @@ -0,0 +1,8 @@ +0.5 + Install images in /tmp +0.4 + Made delay optional and disabled by default +0.2 + Fixed audio computation +0.1 + First implementation diff --git a/audience~/INSTALL b/audience~/INSTALL new file mode 100644 index 0000000..a1a03e0 --- /dev/null +++ b/audience~/INSTALL @@ -0,0 +1,15 @@ +untar in /my/pd/dir/externs + +cd /my/pd/dir/externs/audience~ + +make clean + +make + +make install + +open help-audience~.pd + +Thanx for getting here. +Yves/ +comments and bugs @ ydegoyon@free.fr diff --git a/audience~/Makefile b/audience~/Makefile new file mode 100644 index 0000000..d60890d --- /dev/null +++ b/audience~/Makefile @@ -0,0 +1,85 @@ +NAME=audience~ +CSYM=audience~ + +current: pd_linux + +# ----------------------- NT ----------------------- + +pd_nt: $(NAME).dll + +.SUFFIXES: .dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo +VC="C:\Program Files\Microsoft Visual Studio\Vc98" + +PDNTINCLUDE = /I. /I\tcl\include /I\ftp\pd\src /I$(VC)\include + +PDNTLDIR = $(VC)\lib +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\kernel32.lib \ + \ftp\pd\bin\pd.lib + +.c.dll: + cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) + +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: $(NAME).pd_irix5 + +.SUFFIXES: .pd_irix5 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I../../src + +.c.pd_irix5: + cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o + rm $*.o + +# ----------------------- IRIX 6.x ----------------------- + +pd_irix6: $(NAME).pd_irix6 + +.SUFFIXES: .pd_irix6 + +SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ + -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ + -Ofast=ip32 + +.c.pd_irix6: + cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o + rm $*.o + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -DUNIX -DICECAST -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wno-shadow -Wstrict-prototypes -g \ + -Wno-unused -Wno-parentheses -Wno-switch -Werror + +LINUXINCLUDE = -I../../src + +.c.pd_linux: + ./tk2c.bash < $*.tk > $*.tk2c + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm + strip --strip-unneeded $*.pd_linux + rm -f $*.o ../$*.pd_linux + ln -s $*/$*.pd_linux .. + +# ---------------------------------------------------------- + +install: + cp help-*.pd ../../doc/5.reference + ln -sf `pwd`/speaker.gif /tmp + ln -sf `pwd`/wanderer.gif /tmp + +clean: + rm -f *.o *.pd_* *.tk2c core diff --git a/audience~/README b/audience~/README new file mode 100644 index 0000000..e0e6382 --- /dev/null +++ b/audience~/README @@ -0,0 +1,20 @@ +*****************************************************************************
+Version 0.01
+copyright 2002 Yves Degoyon
+tarballs and updates available @ http://ydegoyon.free.fr
+
+audience~ : 2-dimensional audience simulation ( also called 2 dollars spatialization !!! )
+
+To install audience~, follow the steps from INSTALL
+
+This software is published under GPL terms.
+
+This is software with ABSOLUTELY NO WARRANTY.
+Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing
+due to a bug or for other reasons.
+We do not warrant that the program is free of infringement of any third-party
+patents.
+
+*****************************************************************************
+
+
diff --git a/audience~/audience~.c b/audience~/audience~.c new file mode 100644 index 0000000..2d74bbb --- /dev/null +++ b/audience~/audience~.c @@ -0,0 +1,1054 @@ +/* Copyright (c) 2002 Yves Degoyon. */ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL */ +/* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ +/* */ +/* audience.c written by Yves Degoyon 2002 */ +/* 2-dimensional audience simulation */ +/* ( simulates spatialization and interferences ) */ +/* */ +/* 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. */ +/* */ +/* Made while listening to : */ +/* */ +/* Shalaby Effect -- Instrumentals */ +/* Honey Bane -- I Wish I Could Be Me */ +/* ---------------------------------------------------------------------------- */ + + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <ctype.h> +#include "m_imp.h" +#include "g_canvas.h" +#include "t_tk.h" +#include "audience~.h" + +#ifdef NT +#include <io.h> +#else +#include <unistd.h> +#endif + +#define DEFAULT_AUDIENCE_WIDTH 200 +#define DEFAULT_AUDIENCE_HEIGHT 200 +#define DEFAULT_AUDIENCE_NBINPUTS 4 +#define DEFAULT_AUDIENCE_NBOUTPUTS 2 +#define DEFAULT_AUDIENCE_ATTENUATION 0.01 + +#define LISTENER_WIDTH 15 +#define LISTENER_HEIGHT 20 +#define SPEAKER_WIDTH 15 +#define SPEAKER_HEIGHT 20 + +// sound propagates at the speed of 340 m/s, isn't it ?? +#define SOUNDSPEED 340.0 + +// a pixel is 0.1 meter +#define PIXELSIZE 0.1 + +static char *audience_version = "audience : 2d audience simulation, version 0.5 (ydegoyon@free.fr)"; + +t_widgetbehavior audience_widgetbehavior; +static t_class *audience_class_tilde; + +static int guidebug=0; + +#define SYS_VGUI2(a,b) if (guidebug) \ + post(a,b);\ + sys_vgui(a,b) + +#define SYS_VGUI3(a,b,c) if (guidebug) \ + post(a,b,c);\ + sys_vgui(a,b,c) + +#define SYS_VGUI4(a,b,c,d) if (guidebug) \ + post(a,b,c,d);\ + sys_vgui(a,b,c,d) + +#define SYS_VGUI5(a,b,c,d,e) if (guidebug) \ + post(a,b,c,d,e);\ + sys_vgui(a,b,c,d,e) + +#define SYS_VGUI6(a,b,c,d,e,f) if (guidebug) \ + post(a,b,c,d,e,f);\ + sys_vgui(a,b,c,d,e,f) + +#define SYS_VGUI7(a,b,c,d,e,f,g) if (guidebug) \ + post(a,b,c,d,e,f,g );\ + sys_vgui(a,b,c,d,e,f,g) + +#define SYS_VGUI8(a,b,c,d,e,f,g,h) if (guidebug) \ + post(a,b,c,d,e,f,g,h );\ + sys_vgui(a,b,c,d,e,f,g,h) + +#define SYS_VGUI9(a,b,c,d,e,f,g,h,i) if (guidebug) \ + post(a,b,c,d,e,f,g,h,i );\ + sys_vgui(a,b,c,d,e,f,g,h,i) + +/* drawing functions */ +static void audience_draw_update(t_audience_tilde *x, t_glist *glist) +{ + t_canvas *canvas=glist_getcanvas(glist); + t_int ei; + + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + SYS_VGUI6(".x%x.c coords %xISPEAKER%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_inputs_x[ei], + x->x_obj.te_ypix + x->x_inputs_y[ei] + ); + SYS_VGUI6(".x%x.c coords %xSPEAKERNUM%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_inputs_x[ei] - SPEAKER_WIDTH/2, + x->x_obj.te_ypix + x->x_inputs_y[ei] - SPEAKER_HEIGHT/2 + ); + } + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + SYS_VGUI6(".x%x.c coords %xILISTENER%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_outputs_x[ei], + x->x_obj.te_ypix + x->x_outputs_y[ei] + ); + SYS_VGUI6(".x%x.c coords %xLISTENERNUM%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_outputs_x[ei] + LISTENER_WIDTH/2, + x->x_obj.te_ypix + x->x_outputs_y[ei] + LISTENER_HEIGHT/2 + ); + } +} + +static void audience_draw_new(t_audience_tilde *x, t_glist *glist) +{ + t_canvas *canvas=glist_getcanvas(glist); + int ei; + + SYS_VGUI7(".x%x.c create rectangle %d %d %d %d -fill #EAF1E2 -tags %xAAUDIENCE\n", + canvas, x->x_obj.te_xpix, x->x_obj.te_ypix, + x->x_obj.te_xpix + x->x_width, x->x_obj.te_ypix + x->x_height, + x); + // create captions + SYS_VGUI5(".x%x.c create text %d %d -font -*-courier-bold--normal--10-* -text \"0m\" -tags %xBLCAPTION\n", + canvas, x->x_obj.te_xpix - 10 , x->x_obj.te_ypix + x->x_height + 10, x ); + SYS_VGUI6(".x%x.c create text %d %d -font -*-courier-bold--normal--10-* -text \"%dm\" -tags %xBRCAPTION\n", + canvas, x->x_obj.te_xpix + x->x_width + 10 , x->x_obj.te_ypix + x->x_height + 10, x->x_width, x ); + SYS_VGUI6(".x%x.c create text %d %d -font -*-courier-bold--normal--10-* -text \"%dm\" -tags %xULCAPTION\n", + canvas, x->x_obj.te_xpix - 10 , x->x_obj.te_ypix, x->x_height, x ); + + // draw all outlets + if ( x->x_nboutputs > 1 ) + { + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + SYS_VGUI8(".x%x.c create rectangle %d %d %d %d -outline #000000 -fill #000000 -tags %xOUT%d\n", + canvas, x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nboutputs-1), + x->x_obj.te_ypix + x->x_height, + x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nboutputs-1) + 5, + x->x_obj.te_ypix + x->x_height + 2, + x, ei); + } + } + else + { + SYS_VGUI8(".x%x.c create rectangle %d %d %d %d -outline #000000 -fill #000000 -tags %xOUT%d\n", + canvas, x->x_obj.te_xpix, + x->x_obj.te_ypix + x->x_height, + x->x_obj.te_xpix + 5, + x->x_obj.te_ypix + x->x_height + 2, + x, 0); + } + // draw all inlets + for ( ei=0; ei<x->x_nbinputs+1; ei++ ) + { + SYS_VGUI8(".x%x.c create rectangle %d %d %d %d -outline #000000 -fill #000000 -tags %xIN%d\n", + canvas, x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nbinputs), + x->x_obj.te_ypix - 2, + x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nbinputs) + 5, + x->x_obj.te_ypix, + x, ei); + } + // create speaker images + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + SYS_VGUI5("image create photo %xSPEAKER%d -file /tmp/speaker.gif -format gif -width %d -height %d\n", + x, ei, SPEAKER_WIDTH, SPEAKER_HEIGHT ); + SYS_VGUI8(".x%x.c create image %d %d -image %xSPEAKER%d -tags %xISPEAKER%d\n", + canvas, + x->x_obj.te_xpix + x->x_inputs_x[ei], + x->x_obj.te_ypix + x->x_inputs_y[ei], + x, ei, x, ei ); + SYS_VGUI7(".x%x.c create text %d %d -font -*-courier-bold--normal--10-* -text \"s%d\" -tags %xSPEAKERNUM%d\n", + canvas, x->x_obj.te_xpix + x->x_inputs_x[ei] - SPEAKER_WIDTH/2, + x->x_obj.te_ypix + x->x_inputs_y[ei] - SPEAKER_HEIGHT/2, ei+1, x, ei ); + } + // create listener images + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + SYS_VGUI5("image create photo %xLISTENER%d -file /tmp/wanderer.gif -format gif -width %d -height %d\n", + x, ei, LISTENER_WIDTH, LISTENER_HEIGHT ); + SYS_VGUI8(".x%x.c create image %d %d -image %xLISTENER%d -tags %xILISTENER%d\n", + canvas, + x->x_obj.te_xpix + x->x_outputs_x[ei], + x->x_obj.te_ypix + x->x_outputs_y[ei], + x, ei, x, ei ); + SYS_VGUI7(".x%x.c create text %d %d -font -*-courier-bold--normal--10-* -text \"l%d\" -tags %xLISTENERNUM%d\n", + canvas, x->x_obj.te_xpix + x->x_outputs_x[ei] + LISTENER_WIDTH/2, + x->x_obj.te_ypix + x->x_outputs_y[ei] + LISTENER_HEIGHT/2, ei+1, x, ei ); + } + canvas_fixlinesfor( canvas, (t_text*)x ); +} + +static void audience_draw_move(t_audience_tilde *x, t_glist *glist) +{ + t_canvas *canvas=glist_getcanvas(glist); + t_int ei; + + SYS_VGUI7(".x%x.c coords %xAAUDIENCE %d %d %d %d\n", + canvas, x, + x->x_obj.te_xpix, x->x_obj.te_ypix, + x->x_obj.te_xpix+x->x_width, x->x_obj.te_ypix+x->x_height); + SYS_VGUI5(".x%x.c coords %xBLCAPTION %d %d\n", + canvas, x, + x->x_obj.te_xpix - 10 , x->x_obj.te_ypix + x->x_height + 10); + SYS_VGUI5(".x%x.c coords %xBRCAPTION %d %d\n", + canvas, x, + x->x_obj.te_xpix + x->x_width + 10 , x->x_obj.te_ypix + x->x_height + 10 ); + SYS_VGUI5(".x%x.c coords %xULCAPTION %d %d\n", + canvas, x, + x->x_obj.te_xpix - 10 , x->x_obj.te_ypix ); + + for ( ei=0; ei<x->x_nbinputs+1; ei++ ) + { + SYS_VGUI8(".x%x.c coords %xIN%d %d %d %d %d\n", + canvas, x, ei, x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nbinputs), + x->x_obj.te_ypix - 2, + x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nbinputs) + 5, + x->x_obj.te_ypix + ); + } + for ( ei=0; ei<x->x_nbinputs+1; ei++ ) + { + SYS_VGUI6(".x%x.c coords %xISPEAKER%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_inputs_x[ei], + x->x_obj.te_ypix + x->x_inputs_y[ei] + ); + SYS_VGUI6(".x%x.c coords %xSPEAKERNUM%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_inputs_x[ei] - SPEAKER_WIDTH/2, + x->x_obj.te_ypix + x->x_inputs_y[ei] - SPEAKER_HEIGHT/2 + ); + } + if ( x->x_nboutputs > 1 ) + { + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + SYS_VGUI8(".x%x.c coords %xOUT%d %d %d %d %d\n", + canvas, x, ei, x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nboutputs-1), + x->x_obj.te_ypix + x->x_height, + x->x_obj.te_xpix + ( ei * (x->x_width - 5) )/ (x->x_nboutputs-1) + 5, + x->x_obj.te_ypix + x->x_height + 2 + ); + SYS_VGUI6(".x%x.c coords %xILISTENER%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_outputs_x[ei], + x->x_obj.te_ypix + x->x_outputs_y[ei] + ); + SYS_VGUI6(".x%x.c coords %xLISTENERNUM%d %d %d\n", + canvas, x, ei, + x->x_obj.te_xpix + x->x_outputs_x[ei] + LISTENER_WIDTH/2, + x->x_obj.te_ypix + x->x_outputs_y[ei] + LISTENER_HEIGHT/2 + ); + } + } + else + { + SYS_VGUI8(".x%x.c coords %xOUT%d %d %d %d %d\n", + canvas, x, 0, x->x_obj.te_xpix, + x->x_obj.te_ypix + x->x_height, + x->x_obj.te_xpix + 5, + x->x_obj.te_ypix + x->x_height + 2 + ); + SYS_VGUI6(".x%x.c coords %xILISTENER%d %d %d\n", + canvas, x, 0, + x->x_obj.te_xpix + x->x_outputs_x[0], + x->x_obj.te_ypix + x->x_outputs_y[0] + ); + SYS_VGUI6(".x%x.c coords %xLISTENERNUM%d %d %d\n", + canvas, x, 0, + x->x_obj.te_xpix + x->x_outputs_x[0] + LISTENER_WIDTH/2, + x->x_obj.te_ypix + x->x_outputs_y[0] + LISTENER_HEIGHT/2 + ); + } + canvas_fixlinesfor( canvas, (t_text*)x ); +} + +static void audience_draw_erase(t_audience_tilde* x,t_glist* glist) +{ + t_canvas *canvas=glist_getcanvas(glist); + int ei; + + SYS_VGUI3(".x%x.c delete %xAAUDIENCE\n", canvas, x); + SYS_VGUI3(".x%x.c delete %xBLCAPTION\n", canvas, x); + SYS_VGUI3(".x%x.c delete %xBRCAPTION\n", canvas, x); + SYS_VGUI3(".x%x.c delete %xULCAPTION\n", canvas, x); + for ( ei=0; ei<x->x_nbinputs+1; ei++ ) + { + SYS_VGUI4(".x%x.c delete %xIN%d\n", canvas, x, ei ); + } + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + SYS_VGUI4(".x%x.c delete %xISPEAKER%d\n", canvas, x, ei ); + SYS_VGUI4(".x%x.c delete %xSPEAKERNUM%d\n", canvas, x, ei ); + // SYS_VGUI3("image delete %xSPEAKER%d\n", x, ei ); + } + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + SYS_VGUI4(".x%x.c delete %xOUT%d\n", canvas, x, ei ); + SYS_VGUI4(".x%x.c delete %xILISTENER%d\n", canvas, x, ei ); + SYS_VGUI4(".x%x.c delete %xLISTENERNUM%d\n", canvas, x, ei ); + // SYS_VGUI3("image delete %xLISTENER%d\n", x, ei ); + } +} + +static void audience_draw_select(t_audience_tilde* x,t_glist* glist) +{ + t_canvas *canvas=glist_getcanvas(glist); + + if(x->x_selected) + { + /* sets the item in blue */ + SYS_VGUI3(".x%x.c itemconfigure %xAAUDIENCE -outline #0000FF\n", canvas, x); + } + else + { + SYS_VGUI3(".x%x.c itemconfigure %xAAUDIENCE -outline #000000\n", canvas, x); + } +} + +/* ------------------------ audience widgetbehaviour----------------------------- */ + + +static void audience_getrect(t_gobj *z, t_glist *owner, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + t_audience_tilde* x = (t_audience_tilde*)z; + + *xp1 = x->x_obj.te_xpix; + *yp1 = x->x_obj.te_ypix; + *xp2 = x->x_obj.te_xpix+x->x_width; + *yp2 = x->x_obj.te_ypix+x->x_height; +} + +static void audience_save(t_gobj *z, t_binbuf *b) +{ + t_audience_tilde *x = (t_audience_tilde *)z; + t_int ii; + + binbuf_addv(b, "ssiisiiiifi", gensym("#X"),gensym("obj"), + (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix, + gensym("audience~"), x->x_width, x->x_height, + x->x_nbinputs, x->x_nboutputs, x->x_attenuation, x->x_applydelay ); + for ( ii=0; ii<x->x_nbinputs; ii++ ) + { + binbuf_addv(b, "ii", x->x_inputs_x[ii], x->x_inputs_y[ii] ); + } + for ( ii=0; ii<x->x_nboutputs; ii++ ) + { + binbuf_addv(b, "ii", x->x_outputs_x[ii], x->x_outputs_y[ii] ); + } + binbuf_addv(b, ";"); +} + +static void audience_properties(t_gobj *z, t_glist *owner) +{ + char buf[800]; + t_audience_tilde *x=(t_audience_tilde *)z; + + sprintf(buf, "pdtk_audience_dialog %%s %d %d %d\n", + x->x_width, x->x_height, x->x_nboutputs + ); + // post("audience_properties : %s", buf ); + gfxstub_new(&x->x_obj.ob_pd, x, buf); +} + +static void audience_select(t_gobj *z, t_glist *glist, int selected) +{ + t_audience_tilde *x = (t_audience_tilde *)z; + + x->x_selected = selected; + audience_draw_select( x, glist ); +} + +static void audience_vis(t_gobj *z, t_glist *glist, int vis) +{ + t_audience_tilde *x = (t_audience_tilde *)z; + + // post( "audience~ : vis : %d", vis ); + if (vis) + { + audience_draw_new( x, glist ); + } + else + { + audience_draw_erase( x, glist ); + } +} + +static void audience_dialog(t_audience_tilde *x, t_symbol *s, int argc, t_atom *argv) +{ + t_int onbinputs = x->x_nbinputs; + t_int onboutputs = x->x_nboutputs; + t_int owidth = x->x_width; + t_int oheight = x->x_height; + t_int bi, ei; + t_int dspstate; + t_canvas *canvas=glist_getcanvas(x->x_glist); + + if ( !x ) { + post( "audience~ : error :tried to set properties on an unexisting object" ); + } + if ( argc != 3 ) + { + post( "audience : error in the number of arguments ( %d instead of 3 )", argc ); + return; + } + if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT || + argv[2].a_type != A_FLOAT ) { + post( "audience~ : wrong arguments" ); + return; + } + + dspstate = canvas_suspend_dsp(); + audience_draw_erase(x, x->x_glist); + + x->x_width = (int)argv[0].a_w.w_float; + if ( x->x_width < 10 ) x->x_width = 10; + x->x_height = (int)argv[1].a_w.w_float; + if ( x->x_height < 10 ) x->x_height = 10; + x->x_nboutputs = (int)argv[2].a_w.w_float; + if ( x->x_nboutputs < 1 ) x->x_nboutputs = 1; + + // re-allocate audio buffers if needed + if ( ( owidth != x->x_width ) || ( oheight != x->x_height ) ) + { + if ( x->x_audiobuffer ) + { + for ( ei=0; ei<onbinputs; ei++ ) + { + freebytes( x->x_audiobuffer[ei], x->x_audiobuffersize*sizeof(t_float) ); + } + freebytes( x->x_audiobuffer, onbinputs*sizeof(t_float*) ); + } + // allocate audio buffer + x->x_audiobuffer = (t_float **) getbytes( x->x_nbinputs*sizeof(t_float *) ); + if ( !x->x_audiobuffer ) + { + post( "audience~ : could not allocate audio buffer" ); + return; + } + x->x_audiobuffersize = ( t_int ) ( ( ( ( t_float ) sqrt( pow( x->x_width, 2 ) + + pow( x->x_height, 2 ) ) ) / SOUNDSPEED ) + * ( (float ) sys_getsr() ) ); + post( "audience~ : audio buffer size : %d samples", x->x_audiobuffersize ); + for ( bi=0; bi<x->x_nbinputs; bi++ ) + { + x->x_audiobuffer[bi] = (t_float *) getbytes( x->x_audiobuffersize*sizeof(t_float) ); + if ( !x->x_audiobuffer[bi] ) + { + post( "audience~ : could not allocate audio buffer" ); + return; + } + } + x->x_audiowritepos = 0; + } + + // re-allocate inlets : CRASHES PD,I GUESS IT'S NOT SUPPORTED + if ( onbinputs != x->x_nbinputs ) + { + // post( "audience~ : cleaning up old inlets" ); + if ( x->x_inputs ) + { + for ( ei=0; ei<onbinputs; ei++ ) + { + // post( "audience~ : freeing input ! %d", ei ); + inlet_free( x->x_inputs[ei] ); + } + freebytes( x->x_inputs, onbinputs*sizeof(t_inlet*) ); + } + if ( x->x_inputs_x ) + { + freebytes( x->x_inputs_x, onbinputs*sizeof(t_int) ); + } + if ( x->x_inputs_y ) + { + freebytes( x->x_inputs_y, onbinputs*sizeof(t_int) ); + } + // post( "audience~ : creating new ones" ); + x->x_inputs = (t_inlet **) getbytes( x->x_nbinputs*sizeof(t_inlet *) ); + x->x_inputs_x = (t_int *) getbytes( x->x_nbinputs*sizeof(t_int) ); + x->x_inputs_y = (t_int *) getbytes( x->x_nbinputs*sizeof(t_int) ); + if ( !x->x_inputs || !x->x_inputs_x || !x->x_inputs_y ) + { + error( "audience~ : fatal : could not create new object" ); + return; + } + for ( bi=0; bi<x->x_nbinputs; bi++ ) + { + // post( "audience~ : allocating input ! %d", bi ); + x->x_inputs[bi] = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + } + } + + // re-allocate outlets + if ( onboutputs != x->x_nboutputs ) + { + // post( "audience~ : cleaning up old outlets" ); + if ( x->x_outputs ) + { + for ( ei=0; ei<onboutputs; ei++ ) + { + canvas_rmoutlet(canvas, x->x_outputs[ei] ); + // outlet_free( x->x_outputs[ei] ); + } + freebytes( x->x_outputs, onboutputs*sizeof(t_outlet*) ); + } + if ( x->x_outputs_x ) + { + freebytes( x->x_outputs_x, onboutputs*sizeof(t_int) ); + } + if ( x->x_outputs_y ) + { + freebytes( x->x_outputs_y, onboutputs*sizeof(t_int) ); + } + // post( "audience~ : creating new ones" ); + x->x_outputs = (t_outlet **) getbytes( x->x_nboutputs*sizeof(t_outlet *) ); + x->x_outputs_x = (t_int *) getbytes( x->x_nboutputs*sizeof(t_int) ); + x->x_outputs_y = (t_int *) getbytes( x->x_nboutputs*sizeof(t_int) ); + if ( !x->x_outputs || !x->x_outputs_x || !x->x_outputs_y ) + { + // error( "audience~ : fatal : could not create new object" ); + return; + } + for ( bi=0; bi<x->x_nboutputs; bi++ ) + { + x->x_outputs[bi] = outlet_new( &x->x_obj, &s_signal ); + } + // set default coordinates + if ( x->x_nboutputs > 1 ) + { + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + x->x_outputs_x[ei] = ei * (x->x_width - 5) / ( x->x_nboutputs - 1 ); + x->x_outputs_y[ei] = x->x_height - LISTENER_HEIGHT/2; + } + } + else + { + x->x_outputs_x[0] = x->x_width; + x->x_outputs_y[0] = x->x_height - LISTENER_HEIGHT/2; + } + } + + canvas_fixlinesfor( canvas, (t_text*)x ); + audience_draw_new(x, x->x_glist); + canvas_resume_dsp(dspstate); +} + +static void audience_delete(t_gobj *z, t_glist *glist) +{ + t_audience_tilde *x = (t_audience_tilde *)z; + + // post( "audience~ : delete" ); + audience_draw_erase( x, glist ); + canvas_deletelinesfor( glist_getcanvas(glist), (t_text *)z); +} + +static void audience_displace(t_gobj *z, t_glist *glist, int dx, int dy) +{ + t_audience_tilde *x = (t_audience_tilde *)z; + int xold = x->x_obj.te_xpix; + int yold = x->x_obj.te_ypix; + + // post( "audience_displace dx=%d dy=%d", dx, dy ); + + x->x_obj.te_xpix += dx; + x->x_obj.te_ypix += dy; + if(xold != x->x_obj.te_xpix || yold != x->x_obj.te_ypix) + { + audience_draw_move(x, x->x_glist); + } +} + +static void audience_motion(t_audience_tilde *x, t_floatarg dx, t_floatarg dy) +{ + // post( "audience_motion dx=%f dy=%f", dx, dy ); + + switch( x->x_type_selected ) + { + case AUDIENCE_INPUT: + x->x_inputs_x[ x->x_nselected ] += dx; + if ( x->x_inputs_x[ x->x_nselected ] < 0 ) x->x_inputs_x[ x->x_nselected ] = 0; + if ( x->x_inputs_x[ x->x_nselected ] > x->x_width ) x->x_inputs_x[ x->x_nselected ] = x->x_width; + x->x_inputs_y[ x->x_nselected ] += dy; + if ( x->x_inputs_y[ x->x_nselected ] < 0 ) x->x_inputs_y[ x->x_nselected ] = 0; + if ( x->x_inputs_y[ x->x_nselected ] > x->x_height ) x->x_inputs_y[ x->x_nselected ] = x->x_height; + break; + case AUDIENCE_OUTPUT: + x->x_outputs_x[ x->x_nselected ] += dx; + if ( x->x_outputs_x[ x->x_nselected ] < 0 ) x->x_outputs_x[ x->x_nselected ] = 0; + if ( x->x_outputs_x[ x->x_nselected ] > x->x_width ) x->x_outputs_x[ x->x_nselected ] = x->x_width; + x->x_outputs_y[ x->x_nselected ] += dy; + if ( x->x_outputs_y[ x->x_nselected ] < 0 ) x->x_outputs_y[ x->x_nselected ] = 0; + if ( x->x_outputs_y[ x->x_nselected ] > x->x_height ) x->x_outputs_y[ x->x_nselected ] = x->x_height; + break; + } + + audience_draw_update(x, x->x_glist); +} + +static int audience_click(t_gobj *z, struct _glist *glist, + int xpix, int ypix, int shift, int alt, int dbl, int doit) +{ + t_audience_tilde* x = (t_audience_tilde *)z; + t_int bi; + + // post( "audience_click doit=%d x=%d y=%d", doit, xpix, ypix ); + if ( doit) + { + t_int relx = xpix-x->x_obj.te_xpix; + t_int rely = ypix-x->x_obj.te_ypix; + + // post( "audience~ : relx : %d : rely : %d", relx, rely ); + x->x_type_selected = AUDIENCE_NONE; + x->x_nselected = -1; + for ( bi=0; bi<x->x_nbinputs; bi++ ) + { + if ( ( abs( relx - x->x_inputs_x[bi] ) < SPEAKER_WIDTH ) && + ( abs( rely - x->x_inputs_y[bi] ) < SPEAKER_HEIGHT ) ) { + x->x_type_selected = AUDIENCE_INPUT; + x->x_nselected = bi; + break; + } + } + if ( x->x_type_selected == AUDIENCE_NONE ) + { + for ( bi=0; bi<x->x_nboutputs; bi++ ) + { + if ( ( abs( relx - x->x_outputs_x[bi] ) < LISTENER_WIDTH ) && + ( abs( rely - x->x_outputs_y[bi] ) < LISTENER_HEIGHT ) ) { + x->x_type_selected = AUDIENCE_OUTPUT; + x->x_nselected = bi; + break; + } + } + } + audience_draw_update(x, glist); + glist_grab(glist, &x->x_obj.te_g, (t_glistmotionfn)audience_motion, + 0, xpix, ypix); + } + return (1); +} + +static t_audience_tilde *audience_new(t_symbol *s, int argc, t_atom *argv) +{ + t_int bi, ei; + t_audience_tilde *x; + t_pd *x2; + char *str; + + // post( "audience_new : create : %s argc =%d", s->s_name, argc ); + + x = (t_audience_tilde *)pd_new(audience_class_tilde); + // new audience created from the gui + if ( argc != 0 ) + { + if ( argc < 5 ) + { + post( "audience~ : error in the number of arguments ( %d )", argc ); + return NULL; + } + if ( argv[0].a_type != A_FLOAT || argv[1].a_type != A_FLOAT || + argv[2].a_type != A_FLOAT || argv[3].a_type != A_FLOAT || + argv[4].a_type != A_FLOAT || argv[5].a_type != A_FLOAT ) { + post( "audience~ : wrong arguments" ); + return NULL; + } + + x->x_width = (int)argv[0].a_w.w_float; + if ( x->x_width < 10 ) x->x_width = 10; + x->x_height = (int)argv[1].a_w.w_float; + if ( x->x_height < 10 ) x->x_height = 10; + x->x_nbinputs = (int)argv[2].a_w.w_float; + if ( x->x_nbinputs < 1 ) x->x_nbinputs = 1; + x->x_nboutputs = (int)argv[3].a_w.w_float; + if ( x->x_nboutputs < 1 ) x->x_nboutputs = 1; + x->x_attenuation = argv[4].a_w.w_float; + if ( x->x_attenuation < 0 ) x->x_attenuation = 0; + x->x_applydelay = argv[5].a_w.w_float; + } + else + { + x->x_width = DEFAULT_AUDIENCE_WIDTH; + x->x_height = DEFAULT_AUDIENCE_HEIGHT; + x->x_nbinputs = DEFAULT_AUDIENCE_NBINPUTS; + x->x_nboutputs = DEFAULT_AUDIENCE_NBOUTPUTS; + x->x_attenuation = DEFAULT_AUDIENCE_ATTENUATION; + x->x_applydelay = 0; + } + + // create inlets and outlets + x->x_outputs = (t_outlet **) getbytes( x->x_nboutputs*sizeof(t_outlet *) ); + x->x_outputs_x = (t_int *) getbytes( x->x_nboutputs*sizeof(t_int) ); + x->x_outputs_y = (t_int *) getbytes( x->x_nboutputs*sizeof(t_int) ); + if ( !x->x_outputs || !x->x_outputs_x || !x->x_outputs_y ) + { + post( "audience~ : could not allocate outputs" ); + return NULL; + } + for ( bi=0; bi<x->x_nboutputs; bi++ ) + { + x->x_outputs[bi] = outlet_new( &x->x_obj, &s_signal ); + } + x->x_inputs = (t_inlet **) getbytes( x->x_nbinputs*sizeof(t_inlet *) ); + x->x_inputs_x = (t_int *) getbytes( x->x_nbinputs*sizeof(t_int) ); + x->x_inputs_y = (t_int *) getbytes( x->x_nbinputs*sizeof(t_int) ); + if ( !x->x_inputs || !x->x_inputs_x || !x->x_inputs_y ) + { + post( "audience~ : could not allocate inputs" ); + return NULL; + } + for ( bi=0; bi<x->x_nbinputs; bi++ ) + { + x->x_inputs[bi] = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + } + + // allocate audio buffer + x->x_audiowritepos = 0; + x->x_audiobuffer = (t_float **) getbytes( x->x_nbinputs*sizeof(t_float *) ); + if ( !x->x_audiobuffer ) + { + post( "audience~ : could not allocate audio buffer" ); + return NULL; + } + x->x_audiobuffersize = ( t_int ) ( ( ( ( t_float ) sqrt( pow( x->x_width, 2 ) + + pow( x->x_height, 2 ) ) ) / SOUNDSPEED ) + * ( (float ) sys_getsr() ) ); + post( "audience~ : audio buffer size : %d samples", x->x_audiobuffersize ); + for ( bi=0; bi<x->x_nbinputs; bi++ ) + { + x->x_audiobuffer[bi] = (t_float *) getbytes( x->x_audiobuffersize*sizeof(t_float) ); + if ( !x->x_audiobuffer[bi] ) + { + post( "audience~ : could not allocate audio buffer" ); + return NULL; + } + } + + if ( argc == 0 ) + { + // set default coordinates + if ( x->x_nbinputs > 1 ) + { + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + x->x_inputs_x[ei] = (ei+1) * (x->x_width - 5) / x->x_nbinputs; + x->x_inputs_y[ei] = SPEAKER_HEIGHT/2; + } + } + else + { + x->x_inputs_x[0] = x->x_width; + x->x_inputs_y[0] = SPEAKER_HEIGHT/2; + } + + if ( x->x_nboutputs > 1 ) + { + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + x->x_outputs_x[ei] = ei * (x->x_width - 5) / ( x->x_nboutputs - 1 ); + x->x_outputs_y[ei] = x->x_height - LISTENER_HEIGHT/2; + } + } + else + { + x->x_outputs_x[0] = x->x_width; + x->x_outputs_y[0] = x->x_height - LISTENER_HEIGHT/2; + } + } + else + { + t_int ai = 6; + + // restore coordinates from arguments + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + x->x_inputs_x[ei] = argv[ai++].a_w.w_float; + x->x_inputs_y[ei] = argv[ai++].a_w.w_float; + } + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + x->x_outputs_x[ei] = argv[ai++].a_w.w_float; + x->x_outputs_y[ei] = argv[ai++].a_w.w_float; + } + } + + x->x_glist = (t_glist *) canvas_getcurrent(); + x->x_type_selected = AUDIENCE_NONE; + x->x_nselected = -1; + + // post( "audience~ : new object : inlets : %d : outlets : %d : attenuation : %f", x->x_nbinputs, x->x_nboutputs, x->x_attenuation ); + return (x); +} + +static void audience_free(t_audience_tilde *x) +{ + t_int ei; + + if ( x->x_outputs ) + { + for ( ei=0; ei<x->x_nboutputs; ei++ ) + { + outlet_free( x->x_outputs[ei] ); + } + freebytes( x->x_outputs, x->x_nboutputs*sizeof(t_outlet*) ); + } + if ( x->x_inputs ) + { + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + inlet_free( x->x_inputs[ei] ); + } + freebytes( x->x_inputs, x->x_nbinputs*sizeof(t_outlet*) ); + } + if ( x->x_audiobuffer ) + { + for ( ei=0; ei<x->x_nbinputs; ei++ ) + { + freebytes( x->x_audiobuffer[ei], x->x_audiobuffersize*sizeof(t_float) ); + } + freebytes( x->x_audiobuffer, x->x_nbinputs*sizeof(t_float*) ); + } +} + +static t_int *audience_perform(t_int *w) +{ + t_int ii, oi, op; + t_audience_tilde *x = (t_audience_tilde*)(w[1]); + t_int bsize = w[2]; + + { + // save input sounds in the audio buffer + for ( ii=0; ii<x->x_nbinputs; ii++ ) + { + t_float* isound = (t_float*)w[ii+3]; + + if ( x->x_audiobuffer[ii] ) + { + op = 0; + while ( op < bsize ) + { + *(x->x_audiobuffer[ii] + x->x_audiowritepos + op ) = *(isound + op); + op++; + } + } + } + + // set outputs + for ( oi=0; oi<x->x_nboutputs; oi++ ) + { + t_float* osound = (t_float*)w[oi+3+x->x_nbinputs]; + + // zeroing output + memset( osound, 0x00, bsize*sizeof( t_float ) ); + + for ( ii=0; ii<x->x_nbinputs; ii++ ) + { + t_int delay; + t_int dist; + t_int readpos; + t_int maxwritepos; + + maxwritepos = ( x->x_audiobuffersize / bsize ) * bsize; + dist = sqrt( pow( (x->x_outputs_x[oi] - x->x_inputs_x[ii]), 2 ) + + pow( (x->x_outputs_y[oi] - x->x_inputs_y[ii]), 2 ) ); + delay = ( t_int ) ( ( ( ( t_float ) dist ) * ( (float ) sys_getsr() ) ) / SOUNDSPEED ); + delay = ( delay / bsize ) * bsize; // set a block frontier + if ( x->x_applydelay ) + { + if ( x->x_audiowritepos >= delay ) + { + readpos = x->x_audiowritepos - delay; + } + else + { + readpos = maxwritepos - delay + x->x_audiowritepos; + } + } + else + { + readpos = x->x_audiowritepos; + } + // if ( ii == 0 ) + // { + // post( "audience~ : dist : %d : delay : %d : readpos : %d : writepos : %d", + // dist, delay, readpos, x->x_audiowritepos ); + // } + + op = 0; + while ( op < bsize ) + { + if ( ( readpos < x->x_audiobuffersize ) && ( readpos >= 0 ) ) + { + if ( 1.0-x->x_attenuation*dist < 0 ) + { + *(osound+op) += 0.0; + } + else + { + *(osound+op) += *(x->x_audiobuffer[ii] + readpos + op)*(1.0-x->x_attenuation*dist); + } + } + else + { + error( "audience~ : delay : %d : wrong readpos !!! : %d >= %d or < 0", delay, readpos, x->x_audiobuffersize ); + } + op++; + } + } + } + + // update write position + if ( x->x_audiowritepos + bsize > x->x_audiobuffersize - bsize ) + { + // post( "audience~ : write back to zero @ %d", x->x_audiowritepos ); + x->x_audiowritepos = 0; + } + else + { + x->x_audiowritepos += bsize; + } + + } + + return (w+x->x_nbinputs+x->x_nboutputs+3); +} + +static void audience_dsp(t_audience_tilde *x, t_signal **sp) +{ + switch ( x->x_nbinputs+x->x_nboutputs ) + { + case 2 : + dsp_add(audience_perform, 4, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec ); + break; + + case 3 : + dsp_add(audience_perform, 5, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec ); + break; + + case 4 : + dsp_add(audience_perform, 6, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec ); + break; + + case 5 : + dsp_add(audience_perform, 7, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, sp[5]->s_vec ); + break; + + case 6 : + dsp_add(audience_perform, 8, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, + sp[5]->s_vec, sp[6]->s_vec ); + break; + + case 7 : + dsp_add(audience_perform, 9, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, + sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec ); + break; + + case 8 : + dsp_add(audience_perform, 10, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, + sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec, sp[8]->s_vec ); + break; + + case 9 : + dsp_add(audience_perform, 11, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, + sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec, sp[8]->s_vec, sp[9]->s_vec ); + break; + + case 10 : + dsp_add(audience_perform, 12, x, sp[1]->s_n, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec, + sp[5]->s_vec, sp[6]->s_vec, sp[7]->s_vec, sp[8]->s_vec, + sp[9]->s_vec, sp[10]->s_vec ); + break; + + default : + post( "audience~ : number of inlets/outlets not supported" ); + break; + } +} + +// set attenuation +static void audience_attenuation(t_audience_tilde *x, t_floatarg fattenuation ) +{ + if ( fattenuation < 0 ) + { + post( "audience~ : error : wrong attenuation : %f", fattenuation ); + return; + } + x->x_attenuation = fattenuation; +} + +// set delay +static void audience_delay(t_audience_tilde *x, t_floatarg fdelay ) +{ + if ( fdelay == 0. ) + { + x->x_applydelay = 0; + } + else + { + x->x_applydelay = 1; + } +} + +void audience_tilde_setup(void) +{ + post( audience_version ); +#include "audience~.tk2c" + audience_class_tilde = class_new(gensym("audience~"), (t_newmethod)audience_new, + (t_method)audience_free, sizeof(t_audience_tilde), 0, A_GIMME, 0); + CLASS_MAINSIGNALIN( audience_class_tilde, t_audience_tilde, x_f ); + class_addmethod(audience_class_tilde, (t_method)audience_dsp, gensym("dsp"), 0); + class_addmethod(audience_class_tilde, (t_method)audience_dialog, gensym("dialog"), A_GIMME, 0); + class_addmethod(audience_class_tilde, (t_method)audience_attenuation, gensym("attenuation"), A_DEFFLOAT, 0); + class_addmethod(audience_class_tilde, (t_method)audience_delay, gensym("delay"), A_DEFFLOAT, 0); + audience_widgetbehavior.w_getrectfn = audience_getrect; + audience_widgetbehavior.w_displacefn = audience_displace; + audience_widgetbehavior.w_selectfn = audience_select; + audience_widgetbehavior.w_activatefn = NULL; + audience_widgetbehavior.w_deletefn = audience_delete; + audience_widgetbehavior.w_visfn = audience_vis; + audience_widgetbehavior.w_clickfn = audience_click; + audience_widgetbehavior.w_propertiesfn = audience_properties; + audience_widgetbehavior.w_savefn = audience_save; + class_setwidget(audience_class_tilde, &audience_widgetbehavior); + class_sethelpsymbol(audience_class_tilde, gensym("help-audience~.pd")); +} diff --git a/audience~/audience~.h b/audience~/audience~.h new file mode 100644 index 0000000..b02d1b2 --- /dev/null +++ b/audience~/audience~.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2002 Yves Degoyon +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* a header for 2d_space which enables to spatialize +* several sound inputs with the mouse +*/ + +#ifndef __G_2D_SPACE_H +#define __G_2D_SPACE_H + +#define AUDIENCE_NONE 0 +#define AUDIENCE_INPUT 1 +#define AUDIENCE_OUTPUT 2 + +typedef struct _audience_tilde +{ + t_object x_obj; + t_glist *x_glist; + t_int x_nbinputs; + t_int x_nboutputs; + t_int *x_inputs_x; + t_int *x_inputs_y; + t_int *x_outputs_x; + t_int *x_outputs_y; + t_inlet **x_inputs; + t_outlet **x_outputs; + t_int x_allocate; /* indicates that audio buffer is */ + /* beeing reallocated */ + t_int x_audiobuffersize; /* audio buffer size */ + t_int x_audiowritepos; /* audio writing position */ + t_float **x_audiobuffer; /* audio buffer */ + t_int x_type_selected; /* type of selected object */ + /* e.g. inpout or output or none */ + t_int x_nselected; /* index of item selected */ + t_int x_height; /* height of the 2d_space object */ + t_int x_width; /* width of the 2d_space object */ + t_int x_selected; /* stores selected state */ + t_float x_attenuation; /* sound attenuation per meter */ + t_int x_applydelay; /* optional delay due to the distance */ + t_float x_f; /* classical float for signal input */ +} t_audience_tilde; + +#endif diff --git a/audience~/audience~.tk b/audience~/audience~.tk new file mode 100644 index 0000000..fcf7458 --- /dev/null +++ b/audience~/audience~.tk @@ -0,0 +1,90 @@ +############ audience procedures -- ydegoyon@free.fr ######### + +proc audience_apply {id} { +# strip "." from the TK id to make a variable name suffix + set vid [string trimleft $id .] +# for each variable, make a local variable to hold its name... + set var_graph_width [concat graph_width_$vid] + global $var_graph_width + set var_graph_height [concat graph_height_$vid] + global $var_graph_height + set var_graph_nboutputs [concat graph_nboutputs_$vid] + global $var_graph_nboutputs + + set cmd [concat $id dialog \ + [eval concat $$var_graph_width] \ + [eval concat $$var_graph_height] \ + [eval concat $$var_graph_nboutputs] \ + \;] + #puts stderr $cmd + pd $cmd +} + +proc audience_cancel {id} { + set cmd [concat $id cancel \;] + #puts stderr $cmd + pd $cmd +} + +proc audience_ok {id} { + audience_apply $id + audience_cancel $id +} + +proc pdtk_audience_dialog {id width height nboutputs} { + set vid [string trimleft $id .] + set var_graph_width [concat graph_width_$vid] + global $var_graph_width + set var_graph_height [concat graph_height_$vid] + global $var_graph_height + set var_graph_nboutputs [concat graph_nboutputs_$vid] + global $var_graph_nboutputs + + set $var_graph_width $width + set $var_graph_height $height + set $var_graph_nboutputs $nboutputs + + toplevel $id + wm title $id {audience} + wm protocol $id WM_DELETE_WINDOW [concat audience_cancel $id] + + label $id.label -text {2$ SPACE PROPERTIES} + pack $id.label -side top + + frame $id.buttonframe + pack $id.buttonframe -side bottom -fill x -pady 2m + button $id.buttonframe.cancel -text {Cancel}\ + -command "audience_cancel $id" + button $id.buttonframe.apply -text {Apply}\ + -command "audience_apply $id" + button $id.buttonframe.ok -text {OK}\ + -command "audience_ok $id" + pack $id.buttonframe.cancel -side left -expand 1 + pack $id.buttonframe.apply -side left -expand 1 + pack $id.buttonframe.ok -side left -expand 1 + + frame $id.1rangef + pack $id.1rangef -side top + label $id.1rangef.lwidth -text "Width :" + entry $id.1rangef.width -textvariable $var_graph_width -width 7 + pack $id.1rangef.lwidth $id.1rangef.width -side left + + frame $id.2rangef + pack $id.2rangef -side top + label $id.2rangef.lheight -text "Height :" + entry $id.2rangef.height -textvariable $var_graph_height -width 7 + pack $id.2rangef.lheight $id.2rangef.height -side left + + frame $id.3rangef + pack $id.3rangef -side top + label $id.3rangef.lnboutputs -text "Nb Listeners :" + entry $id.3rangef.nboutputs -textvariable $var_graph_nboutputs -width 7 + pack $id.3rangef.lnboutputs $id.3rangef.nboutputs -side left + + bind $id.1rangef.width <KeyPress-Return> [concat audience_ok $id] + bind $id.2rangef.height <KeyPress-Return> [concat audience_ok $id] + bind $id.3rangef.nboutputs <KeyPress-Return> [concat audience_ok $id] + focus $id.1rangef.width +} + +############ audience procedures END -- ydegoyon@free.fr ######### diff --git a/audience~/help-audience~.pd b/audience~/help-audience~.pd new file mode 100644 index 0000000..ee90caf --- /dev/null +++ b/audience~/help-audience~.pd @@ -0,0 +1,60 @@ +#N canvas 207 7 763 647 10; +#X text 370 378 * Width : graphical x size; +#X text 371 393 * Height : graphical y size; +#X text 358 456 bugs and comments @ ydegoyon@free.fr [-_-]; +#X obj 91 492 *~ 1; +#X obj 177 491 *~ 1; +#X obj 134 458 / 100; +#X floatatom 134 428 5 0 0; +#X floatatom 174 129 5 0 0; +#X floatatom 254 128 5 0 0; +#X floatatom 332 128 5 0 0; +#X floatatom 405 128 5 0 0; +#X text 332 210 audience~ is a moving audience simulation; +#X text 334 236 within a 2d space; +#X text 332 223 Each sound input and each listener can be moved; +#X text 371 407 * Nb Listeners : number of listeners; +#X obj 129 523 dac~; +#X msg 42 89 attenuation 0; +#X msg 42 64 attenuation 0.1; +#X msg 42 40 attenuation 1; +#X obj 406 153 osc~ 10000; +#X text 8 14 Sound attenuation per meter ( default = 0.01 ); +#X text 338 306 Example : audience~ 200 200 4 1 0.01 0; +#X text 339 349 (invoke with <right mouse>Properties ); +#X text 342 339 You can set the following properties :; +#X text 341 527 Note : the number of inputs + outputs is limited to +10; +#X text 341 540 ( can be easily changed in the code ); +#X obj 254 154 osc~ 500; +#X obj 331 154 osc~ 3000; +#X text 337 278 Constructor : audience~ <width> <height> <nbinputs> +<nblisteners> <attenuation> <apply delay flag> | audience~; +#X obj 175 155 osc~ 50; +#X obj 70 196 audience~ 200 200 4 2 0.01 0 0 0 193 188 126 118 145 +72 20 182 10 0; +#X msg 165 66 delay 0; +#X msg 165 91 delay 1; +#X text 296 41 ( due to the distance between speaker and listener ) +; +#X text 163 40 Apply delay option; +#X connect 3 0 15 0; +#X connect 4 0 15 1; +#X connect 5 0 3 1; +#X connect 5 0 4 1; +#X connect 6 0 5 0; +#X connect 7 0 29 0; +#X connect 8 0 26 0; +#X connect 9 0 27 0; +#X connect 10 0 19 0; +#X connect 16 0 30 0; +#X connect 17 0 30 0; +#X connect 18 0 30 0; +#X connect 19 0 30 4; +#X connect 26 0 30 2; +#X connect 27 0 30 3; +#X connect 29 0 30 1; +#X connect 30 0 3 0; +#X connect 30 1 4 0; +#X connect 31 0 30 0; +#X connect 32 0 30 0; diff --git a/audience~/speaker.gif b/audience~/speaker.gif Binary files differnew file mode 100644 index 0000000..6dd9fd4 --- /dev/null +++ b/audience~/speaker.gif diff --git a/audience~/wanderer.gif b/audience~/wanderer.gif Binary files differnew file mode 100644 index 0000000..b2a9f8c --- /dev/null +++ b/audience~/wanderer.gif |