diff --git a/l2ork_addons/autotune/Makefile b/l2ork_addons/autotune/Makefile
index 18df98e8af96ba1e55c549a040f4c92d9f84601d..f8694edcee951e86019160098c8d0de963af1d1b 100644
--- a/l2ork_addons/autotune/Makefile
+++ b/l2ork_addons/autotune/Makefile
@@ -57,7 +57,7 @@ INSTALL = install
 INSTALL_FILE    = $(INSTALL) -p -m 644
 INSTALL_DIR     = $(INSTALL) -p -m 755 -d
 
-CFLAGS = -DPD -I ../../pd/src -Wall -W -g
+CFLAGS = -DPD -I ../../pd/src -Wall -W -g -fPIC
 LDFLAGS =  
 LIBS = 
 ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
diff --git a/l2ork_addons/autotune/autotune~.c b/l2ork_addons/autotune/autotune~.c
index 3bf5282c6c235eb6347679df750a9c1d74e2fef6..9f4c2db922778ab5c51faeed93870b2a27cbb781 100644
--- a/l2ork_addons/autotune/autotune~.c
+++ b/l2ork_addons/autotune/autotune~.c
@@ -9,10 +9,17 @@
  VERSION 0.2
 
  Ivica Ico Bukvic <ico.bukvic.net>
- VERSION 0.9
+ VERSION 0.9.1
+ changes:
+     *added ability to specify FFT size
+     *added ability to specify hop (window) size--requires further refinement
+      to allow for more nimble pitch readjustment
+     *added pull 2 value where pitch pull is relative to the closest pitch
+     *circumvented segfaults due to NANs--may require a better fix
 
+ VERSION 0.9
  changes:
-	*compatible with the latest version of autotalent
+     *compatible with the latest version of autotalent
  
  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        
@@ -264,7 +271,7 @@ typedef struct _autotune 	// Data structure for this object PD
 
 
 //prototypes for methods
-void *autotune_new();
+void *autotune_new(t_symbol *s, int argc, t_atom *argv);
 void autotune_free(t_autotune *x);	
 void autotune_init(t_autotune *x, unsigned long sr);
 t_int *autotune_perform(t_int *w);
@@ -286,6 +293,7 @@ void autotune_lfo_symmetry(t_autotune *x, t_floatarg f);
 void autotune_formant_correction(t_autotune *x, t_floatarg f);
 void autotune_formant_warp(t_autotune *x, t_floatarg f);
 void autotune_scale_warp(t_autotune *x, t_floatarg f);
+void autotune_confidence(t_autotune *x, t_floatarg f);
 void autotune_processclock(t_autotune *x);
 
 
@@ -294,10 +302,10 @@ void autotune_processclock(t_autotune *x);
 void autotune_tilde_setup(void)
 {
 	autotune_class = class_new(gensym("autotune~"), (t_newmethod)autotune_new, 
-							   (t_method)autotune_free ,sizeof(t_autotune), 0,A_GIMME,0);
+							   (t_method)autotune_free ,sizeof(t_autotune),0,A_GIMME,0);
 	CLASS_MAINSIGNALIN(autotune_class, t_autotune, x_f );
-	class_addmethod(autotune_class,(t_method)autotune_dsp, gensym("dsp"), 0);
-	class_addmethod(autotune_class,(t_method)autotune_assist, gensym("assist"), 0);
+	class_addmethod(autotune_class,(t_method)autotune_dsp, gensym("dsp"),0);
+	class_addmethod(autotune_class,(t_method)autotune_assist, gensym("assist"),0);
 	class_addmethod(autotune_class,(t_method)autotune_list,gensym("list"),A_GIMME,0);
 	class_addmethod(autotune_class,(t_method)autotune_mix,gensym("mix"),A_FLOAT,0);
 	class_addmethod(autotune_class,(t_method)autotune_shift,gensym("shift"),A_FLOAT,0);
@@ -313,17 +321,53 @@ void autotune_tilde_setup(void)
 	class_addmethod(autotune_class,(t_method)autotune_formant_correction,gensym("fcorr"),A_FLOAT,0);
 	class_addmethod(autotune_class,(t_method)autotune_formant_warp,gensym("warp"),A_FLOAT,0);
 	class_addmethod(autotune_class,(t_method)autotune_scale_warp,gensym("scwarp"),A_FLOAT,0);
-	post("autotune~ v.0.9");
-	post("Ivica Ico Bukvic 2015");
+	class_addmethod(autotune_class,(t_method)autotune_confidence,gensym("confidence"),A_FLOAT,0);
+	post("autotune~ v.0.9.2");
+	post("Ivica Ico Bukvic 2016");
 }
 
 
+int autotune_power_of_two (int x)
+{
+	 while (((x % 2) == 0) && x > 1) /* While x is even and > 1 */
+	 	x /= 2;
+	 return (x == 1);
+}
+
 
 // Create - Contruction of signal inlets and outlets
-void *autotune_new()
+void *autotune_new(t_symbol *s, int argc, t_atom *argv)
 {
     unsigned long sr;
+    int fft_window = 0;
+    int fft_hop = 0;
+
     t_autotune *x = (t_autotune *)pd_new(autotune_class);
+
+    if (argc && argv->a_type == A_FLOAT) // got FFT window
+    {
+        fft_window = (int)atom_getint(argv);
+
+        if (fft_window < 0) fft_window = 0;
+        if (!autotune_power_of_two(fft_window)) fft_window = 0;
+        argv++;
+        argc--;
+    }
+
+    if (argc && argv->a_type == A_FLOAT) // got hop number
+    {
+        fft_hop = (int)atom_getint(argv);
+
+        if (fft_hop < 2 || fft_hop > 32) fft_hop = 0;
+        argv++;
+        argc--;
+    }
+
+    if (fft_window != 0)
+    	x->cbsize = fft_window;
+
+    if (fft_hop != 0)
+    	x->noverlap = fft_hop;
 	
 	if(sys_getsr()) sr = sys_getsr();
 	else sr = 44100;
@@ -408,11 +452,14 @@ void autotune_init(t_autotune *x,unsigned long sr)
 	x->aref = 440;
 	x->fTune = x->aref;
 	
-	if (x->fs >=88200) {
-		x->cbsize = 4096;
-	}
-	else {
-		x->cbsize = 2048;
+	if (x->cbsize == 0)
+	{
+		if (x->fs >=88200) {
+			x->cbsize = 4096;
+		}
+		else {
+			x->cbsize = 2048;
+		}
 	}
 	x->corrsize = x->cbsize / 2 + 1;
 	
@@ -471,7 +518,10 @@ void autotune_init(t_autotune *x,unsigned long sr)
 		x->cbwindow[ti+x->cbsize/4] = -0.5*cos(4*PI*ti/(x->cbsize - 1)) + 0.5;
 	}
 	
-	x->noverlap = 4;
+	if (x->noverlap == 0)
+		x->noverlap = 4;
+
+	//fprintf(stderr,"%d %d\n", x->cbsize, x->noverlap);
 	
 	x->fx = fft_con(x->cbsize);
 	
@@ -617,47 +667,47 @@ t_int *autotune_perform(t_int *w)
 	
 		//
 	
-	long int ti;
-	long int ti2;
-	long int ti3;
-	long int ti4;
-	float tf;
-	float tf2;
-	float tf3;
+	volatile long int ti;
+	volatile long int ti2;
+	volatile long int ti3;
+	volatile long int ti4;
+	volatile float tf;
+	volatile float tf2;
+	volatile float tf3;
 
 	// Variables for cubic spline interpolator
-	float indd;
-	int ind0;
-	int ind1;
-	int ind2;
-	int ind3;
-	float vald;
-	float val0;
-	float val1;
-	float val2;
-	float val3;
-
-	int lowersnap;
-	int uppersnap;
-	float lfoval;
-
-	float pperiod;
-	float inpitch;
-	float conf;
-	float outpitch;
-	float aref;
-	float fa;
-	float fb;
-	float fc;
-	float fk;
-	float flamb;
-	float frlamb;
-	float falph;
-	float foma;
-	float f1resp;
-	float f0resp;
-	float flpa;
-	int ford;
+	volatile float indd;
+	volatile int ind0;
+	volatile int ind1;
+	volatile int ind2;
+	volatile int ind3;
+	volatile float vald;
+	volatile float val0;
+	volatile float val1;
+	volatile float val2;
+	volatile float val3;
+
+	volatile int lowersnap;
+	volatile int uppersnap;
+	volatile float lfoval;
+
+	volatile float pperiod;
+	volatile float inpitch;
+	volatile float conf;
+	volatile float outpitch;
+	volatile float aref;
+	volatile float fa;
+	volatile float fb;
+	volatile float fc;
+	volatile float fk;
+	volatile float flamb;
+	volatile float frlamb;
+	volatile float falph;
+	volatile float foma;
+	volatile float f1resp;
+	volatile float f0resp;
+	volatile float flpa;
+	volatile int ford;
 
 	// Some logic for the semitone->scale and scale->semitone conversion
 	// If no notes are selected as being in the scale, instead snap to all notes
@@ -670,7 +720,7 @@ t_int *autotune_perform(t_int *w)
 		}
 		else {
 			iPitch2Note[ti] = -1;
-			}
+		}
 	}
 	numNotes = ti2;
 	while (ti2<12) {
@@ -773,6 +823,7 @@ t_int *autotune_perform(t_int *w)
 		// ********************//
 
 		//fprintf(stderr,"overlap=%d outpitch=%f inpitch=%f\n", (x->cbiwr)%(N/x->noverlap), outpitch, inpitch);
+		//fprintf(stderr,"outpitch=%f inpitch=%f\n", outpitch, inpitch);
 		
 		// Every N/noverlap samples, run pitch estimation / correction code
 		if ((x->cbiwr)%(N/x->noverlap) == 0) {
@@ -855,9 +906,16 @@ t_int *autotune_perform(t_int *w)
 			// Convert to semitones
 			tf = (float) -12*log10((float)aref*pperiod)*L2SC;
 			//fprintf(stderr,"tf=%f aref=%f pperiod=%f\n", tf, aref, pperiod);
-			if (conf>=x->vthresh) {
+			post("pperiod=%f conf=%f\n", pperiod, conf);
+			float pp_test = x->pperiod/(x->pperiod - pperiod);
+			if (pp_test < 0.5 || pp_test > 2)
+				pp_test = 1;
+			else
+				pp_test = 0;
+			if (conf>=x->vthresh && tf == tf) { // second check is for NANs
 				inpitch = tf;
 				x->inpitch = tf; // update pitch only if voiced
+				x->pperiod = pperiod;
 			}
 			x->conf = conf;
 
@@ -865,7 +923,7 @@ t_int *autotune_perform(t_int *w)
 			x->fConf = conf;
 
 			//x->pitch = pitch;
-			x->pperiod = pperiod;
+			//x->pperiod = pperiod;
 			//x->conf = conf;
 			
 			//  ---- END Calculate pitch and confidence ----
@@ -997,7 +1055,47 @@ t_int *autotune_perform(t_int *w)
 			//fprintf(stderr,"outpitch=%f\n", outpitch);
 
 			// Pull to fixed pitch
-			outpitch = (1-fPull)*outpitch + fPull*fFixed;
+
+			// when fPull is 1 (legacy behavior which picks absolute pitch in respect to A intonation)
+			if (fPull <= 1)
+			{
+				outpitch = (1-fPull)*outpitch + fPull*fFixed;
+			}
+			else
+			{
+				// Special pull case when fPull is 2
+				/*if (fFixed < 0)
+					while (fFixed < 0)
+						fFixed += 12;
+				else if (fFixed > 12)
+					while (fFixed > 12)
+						fFixed -= 12;*/
+
+				float inpitch_norm = inpitch;
+				if (inpitch_norm < 6)
+					while (inpitch_norm < 6)
+						inpitch_norm += 12;
+				else if (inpitch_norm > 6)
+					while (inpitch_norm > 6)
+						inpitch_norm -= 12;
+				/*float a = fFixed - inpitch_norm;
+				float b = fFixed - 12 - inpitch_norm;
+				float c = fFixed + 12 - inpitch_norm;
+				float result = a;
+				if (abs(b) < abs(result)) result = b;
+				if (abs(c) < abs(result)) result = c;
+				outpitch = inpitch + result;*/
+				float a = inpitch - inpitch_norm;
+				float b = inpitch - 12 - inpitch_norm;
+				float c = inpitch + 12 - inpitch_norm;
+				//post("a=%f b=%f c=%f in_norm=%f\n", a, b, c, inpitch_norm);
+				float result = a;
+				if (abs(b) < abs(result)) result = b;
+				if (abs(c) < abs(result)) result = c;
+				outpitch = result + fFixed;
+				//fprintf(stderr,"outpitch=%f inpitch=%f in_norm=%f\n", outpitch, inpitch, inpitch_norm);
+
+			}
 
 			// -- Convert from semitones to scale notes --
 			ti = (int)(outpitch/12 + 32) - 32; // octave
@@ -1326,13 +1424,13 @@ void autotune_shift(t_autotune *x, t_floatarg f)
 
 void autotune_pull(t_autotune *x, t_floatarg f)
 {
-	x->fPull   = CLIP(f,0.,1.);
+	x->fPull   = CLIP(f,0.,2.);
 	//post("pull=%f", x->fPull);
 }
 
 void autotune_pull_pitch(t_autotune *x, t_floatarg f)
 {
-	x->fFixed  = CLIP(f,-36.,12.);
+	x->fFixed  = CLIP(f,-36.,36.);
 	//post("pullpitch=%f", x->fFixed);
 }
 
@@ -1397,6 +1495,12 @@ void autotune_scale_warp(t_autotune *x, t_floatarg f)
 	//post("scwarp=%f", x->fScwarp);
 }
 
+void autotune_confidence(t_autotune *x, t_floatarg f)
+{
+	x->vthresh   = CLIP(f,0.,1.);
+	//post("vthresh=%f", x->vthresh);
+}
+
 void autotune_list(t_autotune *x, t_symbol *m, short argc, t_atom *argv)
 {
 	if(argc== 12)
diff --git a/l2ork_addons/raspberry_pi/disis_gpio/disis_gpio.c b/l2ork_addons/raspberry_pi/disis_gpio/disis_gpio.c
index 4930ab3c03c4d0fa5a8a02e17e3008f025afa50a..77e90456dc8afbaef644ee00ee6a0f254a05a045 100644
--- a/l2ork_addons/raspberry_pi/disis_gpio/disis_gpio.c
+++ b/l2ork_addons/raspberry_pi/disis_gpio/disis_gpio.c
@@ -33,6 +33,8 @@ typedef struct _params
     int *p_thread;
 } t_params;
 
+static int wiringPiAlreadyCalled = 0;
+
 /*
  * softPwmThread:
  *  Thread to do the actual PWM output
@@ -422,7 +424,11 @@ static void *disis_gpio_new(t_floatarg f)
     x->x_params.p_val = &(x->x_softpwmval);
     x->x_params.p_thread = &(x->x_softpwm_thread);
 
-    wiringPiSetupGpio();
+    if (!wiringPiAlreadyCalled)
+    {
+        wiringPiSetupGpio();
+        wiringPiAlreadyCalled = 1;
+    }
     //x->x_pwmrange = 0;
     //x->x_chown = gensym(buf);
     return (x);