aboutsummaryrefslogtreecommitdiff
path: root/audience~
diff options
context:
space:
mode:
Diffstat (limited to 'audience~')
-rw-r--r--audience~/BUGS14
-rw-r--r--audience~/CHANGES.LOG8
-rw-r--r--audience~/INSTALL15
-rw-r--r--audience~/Makefile85
-rw-r--r--audience~/README20
-rw-r--r--audience~/audience~.c1054
-rw-r--r--audience~/audience~.h44
-rw-r--r--audience~/audience~.tk90
-rw-r--r--audience~/help-audience~.pd60
-rw-r--r--audience~/speaker.gifbin0 -> 83 bytes
-rw-r--r--audience~/wanderer.gifbin0 -> 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
new file mode 100644
index 0000000..6dd9fd4
--- /dev/null
+++ b/audience~/speaker.gif
Binary files differ
diff --git a/audience~/wanderer.gif b/audience~/wanderer.gif
new file mode 100644
index 0000000..b2a9f8c
--- /dev/null
+++ b/audience~/wanderer.gif
Binary files differ