diff --git a/pd/src/d_array.c b/pd/src/d_array.c
index 175704b1d063d15bf97cb1fa1b4d9a1acfef7903..eb6d2031d60ffa99e6cb817527fbdbc196f58abd 100644
--- a/pd/src/d_array.c
+++ b/pd/src/d_array.c
@@ -8,6 +8,7 @@
 
 #include "m_pd.h"
 
+#define GOODINT(i) (!(i & 0xC0000000)) // used for integer overflow protection
 
 /* ------------------------- tabwrite~ -------------------------- */
 
@@ -494,76 +495,25 @@ static void tabread4_tilde_setup(void)
 
 /******************** tabosc4~ ***********************/
 
-/* this is all copied from d_osc.c... what include file could this go in? */
-#define UNITBIT32 1572864.  /* 3*2^19; bit 32 has place value 1 */
-
-    /* machine-dependent definitions.  These ifdefs really
-    should have been by CPU type and not by operating system! */
-#ifdef IRIX
-    /* big-endian.  Most significant byte is at low address in memory */
-#define HIOFFSET 0    /* word offset to find MSB */
-#define LOWOFFSET 1    /* word offset to find LSB */
-#define int32 long  /* a data type that has 32 bits */
-#endif /* IRIX */
-
-#ifdef MSW
-    /* little-endian; most significant byte is at highest address */
-#define HIOFFSET 1
-#define LOWOFFSET 0
-#define int32 long
-#endif
-
-#if defined(__FreeBSD__) || defined(__APPLE__)
-#include <machine/endian.h>
-#endif
-
-#ifdef __linux__
-#include <endian.h>
-#endif
-
-#if defined(__unix__) || defined(__APPLE__)
-#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN)                         
-#error No byte order defined                                                    
-#endif                                                                          
-
-#if BYTE_ORDER == LITTLE_ENDIAN                                             
-#define HIOFFSET 1                                                              
-#define LOWOFFSET 0                                                             
-#else                                                                           
-#define HIOFFSET 0    /* word offset to find MSB */                             
-#define LOWOFFSET 1    /* word offset to find LSB */                            
-#endif /* __BYTE_ORDER */                                                       
-#include <sys/types.h>
-#define int32 int32_t
-#endif /* __unix__ or __APPLE__*/
-
-union tabfudge
-{
-    double tf_d;
-    int32 tf_i[2];
-};
-
 static t_class *tabosc4_tilde_class;
 
 typedef struct _tabosc4_tilde
 {
     t_object x_obj;
-    t_float x_fnpoints;
-    t_float x_finvnpoints;
-    t_word *x_vec;
-    t_symbol *x_arrayname;
+    int looplength;
+    t_float oneoversamplerate;
+    double tabphase;
+    t_word *array;
+    t_symbol *arrayname;
     t_float x_f;
-    double x_phase;
-    t_float x_conv;
 } t_tabosc4_tilde;
 
 static void *tabosc4_tilde_new(t_symbol *s)
 {
     t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class);
-    x->x_arrayname = s;
-    x->x_vec = 0;
-    x->x_fnpoints = 512.;
-    x->x_finvnpoints = (1./512.);
+    x->arrayname = s;
+    x->array = 0;
+    x->looplength = 512.;
     outlet_new(&x->x_obj, gensym("signal"));
     inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
     x->x_f = 0;
@@ -573,96 +523,85 @@ static void *tabosc4_tilde_new(t_symbol *s)
 static t_int *tabosc4_tilde_perform(t_int *w)
 {
     t_tabosc4_tilde *x = (t_tabosc4_tilde *)(w[1]);
-    t_sample *in = (t_sample *)(w[2]);
+    t_sample *freq = (t_sample *)(w[2]);
     t_sample *out = (t_sample *)(w[3]);
-    int n = (int)(w[4]);
-    int normhipart;
-    union tabfudge tf;
-    t_float fnpoints = x->x_fnpoints;
-    int mask = fnpoints - 1;
-    t_float conv = fnpoints * x->x_conv;
-    t_word *tab = x->x_vec, *addr;
-    double dphase = fnpoints * x->x_phase + UNITBIT32;
-
-    if (!tab) goto zero;
-    tf.tf_d = UNITBIT32;
-    normhipart = tf.tf_i[HIOFFSET];
-
-#if 1
-    while (n--)
+    int vecsize = (int)(w[4]);
+
+    int loopmask = x->looplength - 1;
+    int index = 0;
+    t_float baseincrement = x->oneoversamplerate * (t_float)x->looplength;
+    double tabphase = x->tabphase;
+    t_word *ptab = x->array;
+    t_float frac = 0.,  a,  b,  c,  d, cminusb;
+    t_float endfreq = freq[vecsize-1];
+
+    if (!ptab) goto zero;
+
+    while (vecsize--)
     {
-        t_sample frac,  a,  b,  c,  d, cminusb;
-        tf.tf_d = dphase;
-        dphase += *in++ * conv;
-        addr = tab + (tf.tf_i[HIOFFSET] & mask);
-        tf.tf_i[HIOFFSET] = normhipart;
-        frac = tf.tf_d - UNITBIT32;
-        a = addr[0].w_float;
-        b = addr[1].w_float;
-        c = addr[2].w_float;
-        d = addr[3].w_float;
+        index = (tabphase >= 0.? (int)tabphase : (int)tabphase - 1);
+        frac = (GOODINT(index)? tabphase - index : 0.);
+        index &= loopmask;
+        tabphase += *freq++ * baseincrement;
+
+        // interpolation
+        a = ptab[index].w_float;
+        b = ptab[index+1].w_float;
+        c = ptab[index+2].w_float;
+        d = ptab[index+3].w_float;
         cminusb = c-b;
-        *out++ = b + frac * (
-            cminusb - 0.1666667f * (1.-frac) * (
-                (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
-            )
-        );
+        *out++ = b + frac * (cminusb - 0.166666666666667 *
+            (1.-frac) * ((d - a - 3.0 * cminusb) * frac + (d + 2.0*a - 3.0*b)));
     }
-#endif
 
-    tf.tf_d = UNITBIT32 * fnpoints;
-    normhipart = tf.tf_i[HIOFFSET];
-    tf.tf_d = dphase + (UNITBIT32 * fnpoints - UNITBIT32);
-    tf.tf_i[HIOFFSET] = normhipart;
-    x->x_phase = (tf.tf_d - UNITBIT32 * fnpoints)  * x->x_finvnpoints;
+    x->tabphase = frac + index + (endfreq * baseincrement);     // wrap phase state
     return (w+5);
- zero:
-    while (n--) *out++ = 0;
 
+zero:
+    while (vecsize--) *out++ = 0;
     return (w+5);
 }
 
 void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s)
 {
     t_garray *a;
-    int npoints, pointsinarray;
+    int looplength, pointsinarray;
 
-    x->x_arrayname = s;
-    if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+    x->arrayname = s;
+    if (!(a = (t_garray *)pd_findbyclass(x->arrayname, garray_class)))
     {
         if (*s->s_name)
-            pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name);
-        x->x_vec = 0;
+            pd_error(x, "tabosc4~: %s: no such array", x->arrayname->s_name);
+        x->array = 0;
     }
-    else if (!garray_getfloatwords(a, &pointsinarray, &x->x_vec))
+    else if (!garray_getfloatwords(a, &pointsinarray, &x->array))
     {
-        pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name);
-        x->x_vec = 0;
+        pd_error(x, "%s: bad template for tabosc4~", x->arrayname->s_name);
+        x->array = 0;
     }
-    else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3)))
+    else if ((looplength = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3)))
     {
         pd_error(x, "%s: number of points (%d) not a power of 2 plus three",
-            x->x_arrayname->s_name, pointsinarray);
-        x->x_vec = 0;
+            x->arrayname->s_name, pointsinarray);
+        x->array = 0;
         garray_usedindsp(a);
     }
     else
     {
-        x->x_fnpoints = npoints;
-        x->x_finvnpoints = 1./npoints;
+        x->looplength = looplength;
         garray_usedindsp(a);
     }
 }
 
 static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f)
 {
-    x->x_phase = f;
+    x->tabphase = f * x->looplength;
 }
 
 static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp)
 {
-    x->x_conv = 1. / sp[0]->s_sr;
-    tabosc4_tilde_set(x, x->x_arrayname);
+    x->oneoversamplerate = 1. / sp[0]->s_sr;
+    tabosc4_tilde_set(x, x->arrayname);
 
     dsp_add(tabosc4_tilde_perform, 4, x,
         sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);