[SCM] pd-vbap/master: New upstream version 1.1

umlaeute at users.alioth.debian.org umlaeute at users.alioth.debian.org
Tue Aug 22 17:01:32 UTC 2017


The following commit has been merged in the master branch:
commit 803adc70057ce5dac1dbef37f953b41aa441e5ba
Author: IOhannes m zmölnig <zmoelnig at umlautQ.umlaeute.mur.at>
Date:   Tue Aug 22 18:54:52 2017 +0200

    New upstream version 1.1

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000..9956b0f
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,5 @@
+14 Aug. 2014 update from version 1.0.3.2 to version  1.1
+
+- changed vbap to allocate memory dynamically, to eliminate crash-producing memory overwrites when larger speaker configurations were defined (e.g. on OSX for speakers >  13 in 3D)   z.settel
+- eliminated a post to the console reporting azimuth updates
+
diff --git a/Makefile b/Makefile
index 7a077b1..99be87b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-## Pd library template version 1.0.12
+## Pd library template version 1.0.14
 # For instructions on how to use this template, see:
 #  http://puredata.info/docs/developer/MakefileTemplate
 LIBRARY_NAME = vbap
@@ -13,10 +13,10 @@ SOURCES = vbap.c rvbap.c define_loudspeakers.c
 PDOBJECTS = 
 
 # example patches and related files, in the 'examples' subfolder
-EXAMPLES = graph-to-aziele.pd high.pd playsample~.pd recent.pd vbap-demo.pd vbap-level-config.pd vbapmodule.pd vbapsnd.pd rvbap-demo.pd vbap.main.pd
+EXAMPLES =  graph-to-aziele.pd high.pd playsample~.pd recent.pd vbap-demo.pd vbap-level-config.pd vbapmodule.pd vbapsnd.pd rvbap-demo.pd vbap.main.pd
 
 # manuals and related files, in the 'manual' subfolder
-MANUAL = 
+MANUAL =
 
 # if you want to include any other files in the source and binary tarballs,
 # list them here.  This can be anything from header files, test patches,
@@ -108,13 +108,19 @@ ifeq ($(UNAME),Darwin)
     ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
       FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
     else
-      FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
       SOURCES += $(SOURCES_iphoneos)
+# Starting with Xcode 4.0, the PowerPC compiler is not installed by default
+      ifeq ($(wildcard /usr/llvm-gcc-4.2/libexec/gcc/powerpc*), )
+        FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.5
+      else
+        FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
+      endif
     endif
     ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
     # if the 'pd' binary exists, check the linking against it to aid with stripping
     BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd)
-    ALL_LDFLAGS += $(FAT_FLAGS) -bundle $(BUNDLE_LOADER) -undefined dynamic_lookup -L/sw/lib
+    ALL_LDFLAGS += $(FAT_FLAGS) -headerpad_max_install_names -bundle $(BUNDLE_LOADER) \
+	-undefined dynamic_lookup -L/sw/lib
     SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \
 	-install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0
     ALL_LIBS += -lc $(LIBS_macosx)
@@ -129,22 +135,32 @@ endif
 ifeq ($(UNAME),ANDROID)
   CPU := arm
   SOURCES += $(SOURCES_android)
-  EXTENSION = pd_linux
+  EXTENSION = so
   SHARED_EXTENSION = so
   OS = android
   PD_PATH = /usr
-  NDK_BASE := /usr/local/android-ndk
-  NDK_PLATFORM_VERSION := 5
-  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm
-  NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
-  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86
-  CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT)
+  NDK_BASE := /opt/android-ndk
+  NDK_PLATFORM_LEVEL ?= 5
+  NDK_ABI=arm
+  NDK_COMPILER_VERSION = 4.6
+  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI)
+  NDK_UNAME:=$(shell uname -s | tr '[A-Z]' '[a-z]')
+  ifeq ($(NDK_ABI),x86)
+    HOST = i686-linux-android
+    NDK_TOOLCHAIN = $(NDK_ABI)-$(NDK_COMPILER_VERSION)
+  else
+    HOST = $(NDK_ABI)-linux-androideabi
+    NDK_TOOLCHAIN = $(HOST)-$(NDK_COMPILER_VERSION)
+  endif
+  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/$(NDK_TOOLCHAIN)/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR)
+  CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-gcc --sysroot=$(NDK_SYSROOT)
+  LD := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ld
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
   CFLAGS += 
   LDFLAGS += -rdynamic -shared
   SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
   LIBS += -lc $(LIBS_android)
-  STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \
+  STRIP := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-strip) \
 	--strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -221,9 +237,10 @@ ifeq (MINGW,$(findstring MINGW,$(UNAME)))
   CC=gcc
   OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
   ALL_CFLAGS += -mms-bitfields
-  ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj"
+  ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import
   SHARED_LDFLAGS += -shared
-  ALL_LIBS += -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 $(LIBS_windows)
+  ALL_LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" \
+	-lpd -lwsock32 -lkernel32 -luser32 -lgdi32 -liberty $(LIBS_windows)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)
 endif
@@ -237,7 +254,7 @@ ALL_LIBS := $(LIBS) $(ALL_LIBS)
 
 SHARED_SOURCE ?= $(wildcard lib$(LIBRARY_NAME).c)
 SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h)
-SHARED_LIB = $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION))
+SHARED_LIB ?= $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION))
 SHARED_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl)
 
 .PHONY = install libdir_install single_install install-doc install-examples install-manual install-unittests clean distclean dist etags $(LIBRARY_NAME)
@@ -252,12 +269,13 @@ all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
 	chmod a-x "$*.$(EXTENSION)"
 
 # this links everything into a single binary file
-$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
-	$(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(ALL_LIBS)
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o lib$(LIBRARY_NAME).o
+	$(CC) $(ALL_LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) \
+		$(LIBRARY_NAME).o lib$(LIBRARY_NAME).o $(ALL_LIBS)
 	chmod a-x $(LIBRARY_NAME).$(EXTENSION)
 
 $(SHARED_LIB): $(SHARED_SOURCE:.c=.o)
-	$(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCE:.c=.o) $(LIBS)
+	$(CC) $(SHARED_LDFLAGS) -o $(SHARED_LIB) $(SHARED_SOURCE:.c=.o) $(ALL_LIBS)
 
 install: libdir_install
 
@@ -360,6 +378,8 @@ dist: $(DISTDIR)
 		$(INSTALL_DATA) $(ALLSOURCES)  $(DISTDIR)
 	test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \
 		$(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl))  $(DISTDIR)
+	test -z "$(strip $(wildcard $(LIBRARY_NAME).c))" || \
+		$(INSTALL_DATA) $(LIBRARY_NAME).c  $(DISTDIR)
 	test -z "$(strip $(SHARED_HEADER))" || \
 		$(INSTALL_DATA) $(SHARED_HEADER)  $(DISTDIR)
 	test -z "$(strip $(SHARED_SOURCE))" || \
@@ -399,9 +419,11 @@ dpkg-source:
 	rm -rf -- $(DISTDIR) $(ORIGDIR)
 	cd .. && dpkg-source -b $(LIBRARY_NAME)
 
-etags:
+etags: TAGS
+
+TAGS: $(wildcard $(PD_INCLUDE)/*.h) $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
 	etags $(wildcard $(PD_INCLUDE)/*.h)
-	etags -a *.h $(SOURCES)
+	etags -a *.h $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
 	etags -a --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl
 
 showsetup:
@@ -430,3 +452,6 @@ showsetup:
 	@echo "pkglibdir: $(pkglibdir)"
 	@echo "DISTDIR: $(DISTDIR)"
 	@echo "ORIGDIR: $(ORIGDIR)"
+	@echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)"
+	@echo "NDK_BASE: $(NDK_BASE)"
+	@echo "NDK_SYSROOT: $(NDK_SYSROOT)"
diff --git a/define_loudspeakers.c b/define_loudspeakers.c
index 5c7e478..16c5b62 100644
--- a/define_loudspeakers.c
+++ b/define_loudspeakers.c
@@ -14,14 +14,14 @@ See copyright in file with name LICENSE.txt  */
 // If we are within VBAP (which includes define_loudspeakers), then don't create a main for define_loudspeakres
 void define_loudspeakers_setup(void)
 {
-	def_ls_class = class_new(gensym("define_loudspeakers"), (t_newmethod)def_ls_new, 0, (short)sizeof(t_def_ls), 0, A_GIMME, 0); 
+	def_ls_class = class_new(gensym("define_loudspeakers"), (t_newmethod)def_ls_new, 0, (short)sizeof(t_def_ls), 0, A_GIMME, 0);
 	/* def_ls_new = creation function, A_DEFLONG = its (optional) arguement is a long (32-bit) int */
 	
 	class_addbang(def_ls_class, (t_method)def_ls_bang);			/* the procedure it uses when it gets a bang in the left inlet */
 	class_addmethod(def_ls_class, (t_method)def_ls_read_directions, gensym("ls-directions"), A_GIMME, 0);	
 	class_addmethod(def_ls_class, (t_method)def_ls_read_triplets, gensym("ls-triplets"), A_GIMME, 0);
 
-	post(DFLS_VERSION);
+	logpost(NULL,1, DFLS_VERSION);
 }
 # else /* Max */
 void main(void)
@@ -177,6 +177,11 @@ static void ls_angles_to_cart(t_ls *ls)
 /* create new instance of object... MUST send it an int even if you do nothing with this int!! */
 static void *def_ls_new(t_symbol *s, int ac, Atom *av)	
 {
+    
+    
+    //post("def_ls_new: AC = %d", ac);
+    
+    
 	// s is object name (we ignore it)
 	t_def_ls *x = (t_def_ls *)newobject(def_ls_class);
 
@@ -195,6 +200,9 @@ static void *def_ls_new(t_symbol *s, int ac, Atom *av)
 void vbap_def_ls(t_def_ls *x, t_symbol *s, int ac, Atom *av)	
 {
 	initContent_ls_directions(x,ac,av); // Initialize object internal data from a ls-directions list
+
+    logpost(NULL,3, "vbap_def_ls:   %ld-D configuration with %ld speakers", x->x_def_ls_dimension, x->x_def_ls_amount );
+    
 	def_ls_bang(x); // calculate and send matrix to vbap
 }
 
@@ -205,7 +213,9 @@ static void initContent_ls_directions(t_def_ls *x,int ac,Atom*av)
 	
 	long d = 0;
 /*	if (av[0].a_type == A_LONG) d = av[0].a_w.w_long;
-	else */ if(av[0].a_type == A_FLOAT) d = (long)av[0].a_w.w_float;
+	else */
+    
+    if(av[0].a_type == A_FLOAT) d = (long)av[0].a_w.w_float;
 	else { error("define-loudspeakers: dimension NaN"); return; }
 
 	if (d==2 || d==3)
@@ -463,6 +473,9 @@ static void add_ldsp_triplet(int i, int j, int k, t_def_ls *x)
     trip_ptr = trip_ptr->next;
   }
   trip_ptr = (struct t_ls_set*) getbytes (sizeof (struct t_ls_set));
+
+    //post("add_ldsp_triplet getbytes:  %ld", sizeof (struct t_ls_set));
+    
   if(prev == NULL)
     x->x_ls_set = trip_ptr;
   else 
@@ -594,7 +607,10 @@ static void  calculate_3x3_matrixes(t_def_ls *x)
   t_float *invmx;
   //t_float *ptr;
   struct t_ls_set *tr_ptr = x->x_ls_set;
-  int triplet_amount = 0, /*ftable_size,*/i,pointer,list_length=0;
+  
+  unsigned long triplet_amount = 0, /*ftable_size,*/i,pointer,list_length=0; 
+   
+    
   Atom *at;
   t_ls *lss = x->x_ls;
   
@@ -613,7 +629,8 @@ static void  calculate_3x3_matrixes(t_def_ls *x)
   tr_ptr = x->x_ls_set;
   list_length= triplet_amount * 21 + 3;
   at= (Atom *) getbytes(list_length*sizeof(Atom));
-  
+
+
   SETLONG(&at[0], x->x_def_ls_dimension);
   SETLONG(&at[1], x->x_def_ls_amount);
   pointer=2;
@@ -656,11 +673,14 @@ static void  calculate_3x3_matrixes(t_def_ls *x)
     SETFLOAT(&at[pointer], lp2->z); pointer++;
     SETFLOAT(&at[pointer], lp3->z); pointer++;
  
+     
+      
     tr_ptr = tr_ptr->next;
   }
+    
 	sendLoudspeakerMatrices(x,list_length, at);
-//  outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
-  freebytes(at, list_length*sizeof(Atom));
+    
+   freebytes(at, list_length*sizeof(Atom));
 }
 
 
@@ -720,7 +740,8 @@ static void choose_ls_tuplets(t_def_ls *x)
   // Output
   list_length= amount * 10  + 2;
   at= (Atom *) getbytes(list_length*sizeof(Atom));
-  
+    //post("choose_ls_tuplets getbytes:  %ld", list_length*sizeof(Atom));
+
   SETLONG(&at[0], x->x_def_ls_dimension);
   SETLONG(&at[1], x->x_def_ls_amount);
   pointer=2;
@@ -755,7 +776,9 @@ static void choose_ls_tuplets(t_def_ls *x)
     	pointer++;
     }
   }
-	sendLoudspeakerMatrices(x,list_length, at);
+    //post("choose_ls_tuplets:  before call to sendLoudspeakerMatrices");
+
+    sendLoudspeakerMatrices(x,list_length, at);
   //outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
   freebytes(at, list_length*sizeof(Atom));
 }
diff --git a/vbap-meta.pd b/vbap-meta.pd
index d95168b..8077fd7 100644
--- a/vbap-meta.pd
+++ b/vbap-meta.pd
@@ -1,7 +1,8 @@
-#N canvas 10 10 200 200 10;
-#N canvas 20 20 420 300 META 0;
+#N canvas 140 22 200 200 10;
+#N canvas 20 22 420 300 META 0;
 #X text 10 30 NAME vbap;
 #X text 10 50 AUTHOR Ville Pulkki;
-#X text 10 70 DESCRIPTION spatialization using Vector Based Amplitude Panning;
-#X text 10 90 VERSION 1.0.3.2;
+#X text 10 70 DESCRIPTION spatialization using Vector Based Amplitude
+Panning;
+#X text 10 107 VERSION 1.1;
 #X restore 10 10 pd META;
diff --git a/vbap.c b/vbap.c
index b92bf83..f1e4052 100644
--- a/vbap.c
+++ b/vbap.c
@@ -20,6 +20,8 @@ static void *vbap_class;
 static void vect_cross_prod(t_float v1[3], t_float v2[3],t_float v3[3]);
 static void additive_vbap(t_float *final_gs, t_float cartdir[3], t_vbap *x);
 static void vbap_bang(t_vbap *x);
+static int vbap_getmem(t_vbap *x, int lsSetCount );
+static void vbap_free(t_vbap *x);
 static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av);
 #ifndef PD /* Max */
 /* these are for getting data from a cold inlet on Max/MSP, in Pd you use t_floatinlet_new() in new() */
@@ -77,7 +79,7 @@ void vbap_assist(t_vbap *x, void *b, long m, long a, char *s)
 #ifdef PD
 void vbap_setup(void)
 {
-	vbap_class = class_new(gensym("vbap"), (t_newmethod)vbap_new, 0, (short)sizeof(t_vbap), 0, 
+	vbap_class = class_new(gensym("vbap"), (t_newmethod)vbap_new, (t_method) vbap_free, (short)sizeof(t_vbap), 0,
                            A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); 
 
 	class_addbang(vbap_class, (t_method)vbap_bang);	
@@ -95,7 +97,9 @@ void vbap_setup(void)
     class_addmethod(vbap_class, (t_method)def_ls_read_directions, gensym("ls-directions"), A_GIMME, 0);	
     class_addmethod(vbap_class, (t_method)def_ls_read_triplets, gensym("ls-triplets"), A_GIMME, 0);
 
-	logpost(NULL, 4, VBAP_VERSION);
+	logpost(NULL, 1, VBAP_VERSION);
+    //post(VBAP_VERSION);
+
 }
 #else /* MAX */
 void main(void)
@@ -152,6 +156,14 @@ static void *vbap_new(t_float azi, t_float ele, t_float spread)
 	x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
 	x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
 	x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
+    
+    
+    
+    // allocate space for the runtime matricies
+//    if (!vbap_getmem(x, MAX_LS_SETS))
+//        return( NULL );
+//    
+    
 #else /* Max */
 	t_vbap *x = (t_vbap *)newobject(vbap_class);
 
@@ -167,7 +179,9 @@ static void *vbap_new(t_float azi, t_float ele, t_float spread)
 	x->x_outlet0 = listout(x);
 #endif /* PD */
 	
-	x->x_spread_base[0] = 0.0;
+    x->x_ls_setCount = 0;       // refers to memory dynamically allocated when a define_loudspeakers config is received
+
+    x->x_spread_base[0] = 0.0;
 	x->x_spread_base[1] = 1.0;
 	x->x_spread_base[2] = 0.0;
 	x->x_lsset_available =0;
@@ -180,6 +194,89 @@ static void *vbap_new(t_float azi, t_float ele, t_float spread)
 }
 
 
+// currently can allocate upto 256K to support up to 44 channels in 3D
+// note:  to save memory, the required memory for a given configuration could instead,  be dynamically allocated by calling this method from the vbap_matrix() method
+static int vbap_getmem(t_vbap *x, int lsSetCount )
+{
+
+#ifdef PD
+
+    int i;
+    
+    if ( x->x_ls_setCount ) vbap_free(x);
+    
+    //was t_float x_set_inv_matx[MAX_LS_SETS][9];
+    x->x_set_inv_matx = getbytes( sizeof( t_float* ) * lsSetCount);
+    
+    if(!x->x_set_inv_matx) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof( t_float* ) * lsSetCount); return(0);}
+    
+    for (i = 0; i < lsSetCount; i++)
+    {
+        x->x_set_inv_matx[i] = getbytes( sizeof(t_float) * MATRIX_DIM );
+        if(!x->x_set_inv_matx[i]) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof(t_float) * MATRIX_DIM ); return(0);}
+    }
+    
+    
+    //was t_float x_set_matx[MAX_LS_SETS][9];
+    x->x_set_matx = getbytes( sizeof( t_float* ) * lsSetCount);
+
+    if(!x->x_set_matx) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof( t_float* ) * lsSetCount); return(0);}
+
+    for (i = 0; i < lsSetCount; i++)
+    {
+        x->x_set_matx[i] = getbytes( sizeof(t_float) * MATRIX_DIM );
+        if(!x->x_set_matx[i]) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof(t_float) * MATRIX_DIM ); return(0);}
+  }
+    
+    
+    //was long x_lsset[MAX_LS_SETS][3];
+    x->x_lsset = getbytes( sizeof( long * ) * lsSetCount);
+    
+    if(!x->x_lsset) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof( long * ) * lsSetCount); return(0);}
+    
+    for (i = 0; i < lsSetCount; i++)
+    {
+        x->x_lsset[i] = getbytes( sizeof( long ) * SPEAKER_SET_DIM );
+        if(!x->x_lsset[i]) {error("vbap_getmem: can't allocate additional %ld bytes", sizeof(long) * SPEAKER_SET_DIM ); return(0);}
+   }
+    
+    unsigned long memallocd = 2 * ( sizeof(t_float *) * lsSetCount  *  sizeof(t_float) * MATRIX_DIM) + ( sizeof(long *) * lsSetCount *  sizeof(long) * SPEAKER_SET_DIM);
+    
+    logpost(NULL, 3, "vbap_new:  %ldK bytes allocated for instance", memallocd /1000);
+    
+    x->x_ls_setCount = lsSetCount;
+
+#endif
+    return(1);
+    
+}
+
+
+// free any allocated memory for instance
+static void vbap_free(t_vbap *x)
+{
+    int i;
+
+    if (! x->x_ls_setCount) return;
+    
+    for (i = 0; i <  x->x_ls_setCount; i++)
+    {
+        freebytes( x->x_set_inv_matx[i], (sizeof(t_float) * MATRIX_DIM ));    // = getbytes( sizeof(t_float) * MATRIX_DIM );
+        freebytes( x->x_set_matx[i],  sizeof(t_float) * MATRIX_DIM);
+   }
+  
+    freebytes(x->x_set_inv_matx, (sizeof( t_float* ) *  x->x_ls_setCount));
+    freebytes(x->x_set_matx, sizeof( t_float* ) *  x->x_ls_setCount);
+
+
+    for (i = 0; i <   x->x_ls_setCount; i++)
+    {
+        freebytes(x->x_lsset[i], sizeof( long ) * SPEAKER_SET_DIM );
+    }
+ 
+    freebytes( x->x_lsset, sizeof( long * ) *  x->x_ls_setCount);
+}
+
 static void angle_to_cart(t_float azi, t_float ele, t_float res[3])
 // converts angular coordinates to cartesian
 { 
@@ -327,7 +424,7 @@ static void vbap(t_float g[3], long ls[3], t_vbap *x)
  	 	} else new_cartdir[2] = 0;
  	 	cart_to_angle(new_cartdir,new_angle_dir);
  	 	x->x_azi = (new_angle_dir[0] );
-		post("[vbap] use azimuth %g",x->x_azi );
+		//post("[vbap] use azimuth %g",x->x_azi );
  	 	x->x_ele = (new_angle_dir[1]);
  	 }
   //}
@@ -550,6 +647,7 @@ static void vbap_bang(t_vbap *x)
 	t_float g[3];
 	long ls[3];
 	long i;
+ 
 	t_float *final_gs = (t_float *) getbytes(x->x_ls_amount * sizeof(t_float));
 
 	if(x->x_lsset_available ==1)
@@ -559,7 +657,8 @@ static void vbap_bang(t_vbap *x)
 			final_gs[i]=0.0; 			
 		for(i=0;i<x->x_dimension;i++)
 		{
-			final_gs[ls[i]-1]=g[i];  
+			final_gs[ls[i]-1]=g[i];
+            //post("VBAP: PRE_SPREAD: %f", (t_float)final_gs[i]);
 		}
 		if(x->x_spread != 0)
 		{
@@ -568,7 +667,9 @@ static void vbap_bang(t_vbap *x)
 		for(i=0;i<x->x_ls_amount;i++) 
 		{
 #ifdef PD
-			SETFLOAT(&at[0], (t_float)i);	
+            
+
+            SETFLOAT(&at[0], (t_float)i);
 			SETFLOAT(&at[1], (t_float)final_gs[i]);
 			outlet_list(x->x_obj.ob_outlet, &s_list, 2, at);
 #else /* Max */
@@ -598,8 +699,14 @@ static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av)
 	{
 		int d = 0;
  		/*if(av[datapointer].a_type == A_LONG) d = av[datapointer++].a_w.w_long;
-		else*/ if(av[datapointer].a_type == A_FLOAT) d = (long)av[datapointer++].a_w.w_float;
-		else { error("vbap: Dimension NaN"); x->x_lsset_available=0; return; }
+		else*/
+        if (av[datapointer].a_type == A_FLOAT)
+            d = (long)av[datapointer++].a_w.w_float;
+		else
+        {
+            error("vbap: Dimension NaN"); x->x_lsset_available=0;
+            return;
+        }
 
 		if (d!=2 && d!=3) { error("vbap %s: Dimension can be only 2 or 3",s->s_name); x->x_lsset_available=0; return; }
 
@@ -617,25 +724,40 @@ static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av)
 
 		x->x_ls_amount = a;
 	}
- 	
+
 	long counter = (ac - 2) / ((x->x_dimension * x->x_dimension*2) + x->x_dimension);
- 	x->x_lsset_amount=counter;
+    
+    
+ 
+    if (counter-1 > MAX_LS_SETS) { error("vbap %s: loudspeaker definitions exceed maximum number of speakers",s->s_name); x->x_lsset_available=0; return; }
+
+    vbap_getmem(x, counter);        // PD only:  allocate memory (frees any previously allocated memory automatically)
+    
+    x->x_lsset_amount=counter;
+    
 
  	if(counter==0) { error("vbap %s: not enough parameters",s->s_name); x->x_lsset_available=0; return; }
  	
 	long setpointer=0;
 	long i;
- 
- 	while(counter-- > 0)
+    
+    long db_dim = x->x_dimension;
+    
+    while(counter-- > 0)
 	{
- 		for(i=0; i < x->x_dimension; i++)
+ 
+        for(i=0; i < x->x_dimension; i++)
 		{
 # ifdef PD
- 			if(av[datapointer].a_type == A_FLOAT)
+            
+            if(av[datapointer].a_type == A_FLOAT)
 			{
                 x->x_lsset[setpointer][i]=(long)av[datapointer++].a_w.w_float;
- 			}
- 			else { error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+  			}
+ 			else { error("vbap AA %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+
+            
+            
 # else /* Max */
  			if(av[datapointer].a_type == A_LONG)
 			{
@@ -644,26 +766,35 @@ static void vbap_matrix(t_vbap *x, Symbol *s, int ac, Atom *av)
  			else { error("vbap %s: param %d is not an in",s->s_name,datapointer); x->x_lsset_available=0; return; }
 # endif /* PD */
  		}	
- 		for(i=0; i < x->x_dimension*x->x_dimension; i++)
+
+ 		
+        for(i=0; i < x->x_dimension*x->x_dimension; i++)
 		{
- 			if(av[datapointer].a_type == A_FLOAT)
+
+            if(av[datapointer].a_type == A_FLOAT)
 			{
  				x->x_set_inv_matx[setpointer][i]=av[datapointer++].a_w.w_float;
  			}
- 			else { error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+ 			else { error("vbap BB %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
  		}
  		
+
  		for(i=0; i < x->x_dimension*x->x_dimension; i++)
 		{
+            
+            
  			if(av[datapointer].a_type == A_FLOAT)
 			{
  				x->x_set_matx[setpointer][i]=av[datapointer++].a_w.w_float;
  			}
- 			else { error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0; return; }
+ 			else {
+                error("vbap %s: param %d is not a float",s->s_name,datapointer); x->x_lsset_available=0;
+                 return;
+            }
  			
  		}
- 	
+	
  		setpointer++;
 	}
 	if (_enable_trace) post("vbap: Loudspeaker setup configured!");
-}
+ }
diff --git a/vbap.h b/vbap.h
index 0429b0d..ecd388c 100644
--- a/vbap.h
+++ b/vbap.h
@@ -10,21 +10,38 @@
 	#define M_PI        3.14159265358979323846264338327950288   /* pi */
 #endif
 
-#define MAX_LS_SETS 100			// maximum number of loudspeaker sets (triplets or pairs) allowed
-#define MAX_LS_AMOUNT 55    // maximum amount of loudspeakers, can be increased
+#ifdef PD
+//                              Revised by Z. Settel to dynamically allocate memory
+    #define MAX_LS_SETS 745     // maximum number of loudspeaker sets (triplets or pairs) allowed -- allows for up to 44 speakers in 3D config
+//#define MAX_LS_SETS 100	// former maximum value crashed for 3D speaker configurations with more than 13 speakers
+//#define MAX_LS_SETS 571	// example: for up to 32 speakers in 3D config
+
+#else   // Max
+
+#define MAX_LS_SETS 100	 // maximum number of loudspeaker sets (triplets or pairs) allowed - This can crash when too many speakers are defined
+
+#endif
+
+#define MATRIX_DIM 9   // hard-coded matrx dimension for the algorithm
+#define SPEAKER_SET_DIM 3  // hard-coded speaker set dimension for the algorithm
+
+#define MAX_LS_AMOUNT 55    // maximum amount of loudspeakers, can be increased, but see comments next to MAX_LS_SETS above
 #define MIN_VOL_P_SIDE_LGTH 0.01  
 
-#define VBAP_VERSION "vbap - v1.0.3.2 - 20 Nov 2010 - (c) Ville Pulkki 1999-2006 (Pd port by HCS)"
+#define VBAP_VERSION "vbap - v1.1 - 14 Aug. 2014 - (c) Ville Pulkki 1999-2006 (Pd port by HCS)"
 #define DFLS_VERSION "define_loudspeakers - v1.0.3.2 - 20 Nov 2010 - (c) Ville Pulkki 1999-2006"
 
 static t_float rad2ang = 360.0 / ( 2.0f * M_PI );
 static t_float atorad = (2.0f * M_PI) / 360.0f ;
 
 #ifdef VBAP_OBJECT
-	// We are inside vbap object, so sending matrix from define_loudspeakers is a simple call to the vbap receiver...
-	#define sendLoudspeakerMatrices(x,list_length, at) \
-					vbap_matrix(x, gensym("loudspeaker-matrices"),list_length, at); \
-					vbap_bang(x)
+
+//We are inside vbap object, so sending matrix from define_loudspeakers is a simple call to the vbap receiver...
+
+#define sendLoudspeakerMatrices(x,list_length, at) \
+ 					vbap_matrix(x, gensym("loudspeaker-matrices"),list_length, at); \
+ 					vbap_bang(x)
+
 #else
 	// We are inside define_loudspeaker object, send matrix to outlet
 	#define sendLoudspeakerMatrices(x,list_length, at) \
@@ -61,18 +78,31 @@ typedef struct t_ls_set
 		void *x_outlet1;				
 		void *x_outlet2;				
 		void *x_outlet3;				
-		void *x_outlet4;				
-		t_float x_set_inv_matx[MAX_LS_SETS][9];  // inverse matrice for each loudspeaker set
-		t_float x_set_matx[MAX_LS_SETS][9];      // matrice for each loudspeaker set
-		long x_lsset[MAX_LS_SETS][3];          // channel numbers of loudspeakers in each LS set 
+		void *x_outlet4;
+
 		long x_lsset_available;                // have loudspeaker sets been defined with define_loudspeakers
 		long x_lsset_amount;								   // amount of loudspeaker sets
-		long x_ls_amount;                      // amount of loudspeakers
+        long x_ls_amount;                      // amount of loudspeakers
 		long x_dimension;                      // 2 or 3
+        
 # ifdef PD
+        // memory for data sets is now allocated dynamically in each instance
+                        // WAS t_float x_set_inv_matx[MAX_LS_SETS][9];
+		t_float **x_set_inv_matx;  // inverse matrice for each loudspeaker set
+                          // WAS t_float x_set_matx[MAX_LS_SETS][9];
+        t_float **x_set_matx;     // matrice for each loudspeaker set
+		                // WAS long x_lsset[MAX_LS_SETS][3];
+ 		long **x_lsset;          // channel numbers of loudspeakers in each LS set
+
 		t_float x_spread;                      // speading amount of virtual source (0-100)
-# else /* Max */
-		long x_spread;                         // speading amount of virtual source (0-100)
+
+# else /* Max */        // memory allocation not tested for max, so it is allocated in the struct, as it was before
+
+        t_float x_set_inv_matx[MAX_LS_SETS][9];  // inverse matrice for each loudspeaker set
+        t_float x_set_matx[MAX_LS_SETS][9];      // matrice for each loudspeaker set
+		long x_lsset[MAX_LS_SETS][3];          // channel numbers of loudspeakers in each LS set
+        
+        long x_spread;                         // speading amount of virtual source (0-100)
 		double x_gain;                         // general gain control (0-2)
 # endif /* PD */
 		t_float x_spread_base[3];                // used to create uniform spreading
@@ -84,6 +114,7 @@ typedef struct t_ls_set
 		t_ls_set *x_ls_set;					// loudspeaker sets
 		long x_def_ls_amount;				// number of loudspeakers
 		long x_def_ls_dimension;		// 2 (horizontal arrays) or 3 (3d setups)
+        long x_ls_setCount;       // the number of Loudspeaker sets used for an instance's current loudspeaker configuration
 	} t_vbap;
 
 	// define loudspeaker data type...

-- 
pd-vbap packaging



More information about the pkg-multimedia-commits mailing list