diff --git a/.gitmodules b/.gitmodules
index 10994eb818e5f49e9c4c3eccd000465bf8eb451e..ac8cc4aaac5fef3ca765fcf4853f961483da4dd2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -16,3 +16,6 @@
 [submodule "externals/lyonpotpourri"]
 	path = externals/lyonpotpourri
 	url = https://github.com/ericlyon/lyonpotpourri3.0.git
+[submodule "externals/cyclone"]
+	path = externals/cyclone
+	url = https://git.purrdata.net/jwilkes/pd-cyclone.git
diff --git a/externals/Makefile b/externals/Makefile
index 4669ef869eb56c821f2803a15778b9810042f240..c6f08df10ec7a43df15adc795d5b534493e0d4ee 100644
--- a/externals/Makefile
+++ b/externals/Makefile
@@ -431,16 +431,26 @@ cxc_clean:
 #------------------------------------------------------------------------------#
 # CYCLONE
 cyclone:
-	make -C $(externals_src)/miXed/cyclone -f Makefile.libdir \
-		PD_PATH=$(pd_src) PD_INCLUDE=$(DESTDIR)$(includedir)
+ifeq ($(OS_NAME),windows)
+	make -C $(externals_src)/cyclone \
+		pdbinpath=$(pd_src)/src PDINCLUDEDIR=$(DESTDIR)$(includedir)
+else
+	make -C $(externals_src)/cyclone \
+		PDDIR=$(pd_src)
+endif
 
 cyclone_install:
-	make -C $(externals_src)/miXed/cyclone -f Makefile.libdir \
+	make -C $(externals_src)/cyclone \
 		DESTDIR="$(DESTDIR)" objectsdir="$(objectsdir)" \
 		install
+	install -p $(externals_src)/cyclone/documentation/purr_help/*.pd \
+		$(DESTDIR)$(objectsdir)/cyclone
+	install -p \
+		$(externals_src)/cyclone/documentation/purr_help/abs_GUI/*.pd \
+		$(DESTDIR)$(objectsdir)/cyclone
 
 cyclone_clean:
-	make -C $(externals_src)/miXed/cyclone -f Makefile.libdir \
+	make -C $(externals_src)/cyclone \
 		clean
 
 #------------------------------------------------------------------------------#
diff --git a/externals/cyclone b/externals/cyclone
new file mode 160000
index 0000000000000000000000000000000000000000..d22585a21bf88246298e0ae0cd80c45b803e3fd5
--- /dev/null
+++ b/externals/cyclone
@@ -0,0 +1 @@
+Subproject commit d22585a21bf88246298e0ae0cd80c45b803e3fd5
diff --git a/externals/unauthorized/grid.c b/externals/unauthorized/grid.c
index da3c56ab1ea165cef34ecd6829ef457ef494156e..8ead72f69b5785b408cc180b6a8aab219922bb67 100644
--- a/externals/unauthorized/grid.c
+++ b/externals/unauthorized/grid.c
@@ -350,18 +350,18 @@ static void grid_properties(t_gobj *z, t_glist *owner)
     gui_start_vmess("gui_external_dialog", "ss", gfx_tag, "grid");
     gui_start_array();
 
-    gui_s("receive_symbol"); gui_s(x->x_name->s_name);
-    gui_s("width"); gui_i(x->x_width);
-    gui_s("min"); gui_f(x->x_min);
-    gui_s("max"); gui_f(x->x_max);
-    gui_s("height"); gui_i(x->x_height);
-    gui_s("y-min"); gui_f(x->y_min);
-    gui_s("y-max"); gui_f(x->y_max);
-    gui_s("grid_toggle"); gui_i(x->x_grid);
-    gui_s("x-steps"); gui_f(x->x_xstep);
-    gui_s("y-steps"); gui_f(x->x_ystep);
-    gui_s("x-lines"); gui_i(x->x_xlines);
-    gui_s("y-lines"); gui_i(x->x_ylines);
+    gui_s("symbol"); gui_s("receive_symbol"); gui_s(x->x_name->s_name);
+    gui_s("int");    gui_s("width"); gui_i(x->x_width);
+    gui_s("int");    gui_s("min"); gui_f(x->x_min);
+    gui_s("float");  gui_s("max"); gui_f(x->x_max);
+    gui_s("int");    gui_s("height"); gui_i(x->x_height);
+    gui_s("float");  gui_s("y-min"); gui_f(x->y_min);
+    gui_s("float");  gui_s("y-max"); gui_f(x->y_max);
+    gui_s("toggle"); gui_s("show_grid"); gui_i(x->x_grid);
+    gui_s("float");  gui_s("x-steps"); gui_f(x->x_xstep);
+    gui_s("float");  gui_s("y-steps"); gui_f(x->x_ystep);
+    gui_s("int");    gui_s("x-lines"); gui_i(x->x_xlines);
+    gui_s("int");    gui_s("y-lines"); gui_i(x->x_ylines);
 
     gui_end_array();
     gui_end_vmess();
@@ -450,6 +450,11 @@ static void grid_displace(t_gobj *z, t_glist *glist, int dx, int dy)
     x->y_current += dy;
     if (xold != text_xpix(&x->x_obj, glist) || yold != text_ypix(&x->x_obj, glist))
     {
+        gui_vmess("gui_text_displace", "xxii",
+            glist,
+            x,
+            dx,
+            dy);
 	//grid_draw_move(x, x->x_glist);
         canvas_fixlinesfor(glist, (t_text *)z);
     }
@@ -882,10 +887,10 @@ void grid_setup(void)
     /* Big hack for receiving edit-mode resize anchor clicks from
        g_editor.c. */
     class_addmethod(grid_class, (t_method)grid_click_for_resizing,
-                    gensym("_click_for_resizing"),
+                    gensym("_click"),
                     A_FLOAT, A_FLOAT, A_FLOAT, 0);
     class_addmethod(grid_class, (t_method)grid_motion_for_resizing,
-                    gensym("_motion_for_resizing"),
+                    gensym("_motion"),
                     A_FLOAT, A_FLOAT, 0);
     grid_widgetbehavior.w_getrectfn =    grid_getrect;
     grid_widgetbehavior.w_displacefn =   grid_displace;
diff --git a/pd/nw/dialog_external.html b/pd/nw/dialog_external.html
index 63b31d643d8e713b56802b9a5f53548e48f4c92c..503dcd52c3c09286b6fc82eb84e427b6a3e226ef 100644
--- a/pd/nw/dialog_external.html
+++ b/pd/nw/dialog_external.html
@@ -86,30 +86,31 @@ function ok() {
 // value: a value for the input
 function parse_attrs(attrs) {
     var ret = [],
-        elem;
-    attrs.forEach(function(token, i) {
-        if (i % 2 === 0) {
-            elem = {};
-            token = token.split("_");
-            if (token.length > 1) {
-                elem.type = token[token.length - 1];
-                if (elem.type !== "symbol" &&
-                    elem.type !== "toggle") {
-                    // no suffix defaults to "number"
-                    elem.type = "number";
+        elem,
+        gate = false;
+    attrs.forEach(function(attr, i) {
+        if (i % 3 === 0) {
+            elem = gate ? elem : {};
+            gate = attr === "enum";
+            elem.type = attr;
+        } else if (i % 3 === 1) {
+            elem.name = attr;
+            elem.label = attr.replace("_", " ");
+        } else {
+            if (elem.type === "enum") {
+                if (elem.options) {
+                    elem.options.push(attr);
                 } else {
-                    // remove the type suffix
-                    token = token.slice(0, -1);
+                    elem.options = [attr];
                 }
             } else {
-                elem.type = "number";
+                elem.value = attr;
             }
-            elem.name = token.join("_");
-            elem.label = token.join(" ");
-        } else {
-            elem.value = token;
             // now push the object onto the array
-            ret.push(elem);
+            if (elem.type !== "enum") {
+                elem.type = elem.type === "enum_index" ? "enum" : elem.type;
+                ret.push(elem);
+            }
         }
     });
     return ret;
@@ -134,7 +135,6 @@ function register_window_id(gfxstub, args) {
     translate_form();
 
     build_form(external_name, array_of_objects);
-
     // We don't turn on rendering of the "container" div until
     // We've finished displaying all the spans and populating the
     // labels and form elements.  That makes it more efficient and
@@ -160,7 +160,10 @@ function translate_form() {
 
 function get_input_type(t) {
     return t === "symbol" ? "text" :
-           t === "number" ? "text" : 
+           t === "int" ? "text" :
+           t === "float" ? "text" :
+           t === "color" ? "color" :
+           t === "enum" ? "select" :
            t === "toggle" ? "checkbox":
                             "text";
 }
@@ -168,23 +171,39 @@ function get_input_type(t) {
 function build_form(external_name, array_of_objects) {
     var fieldset = document.querySelector("fieldset");
     document.querySelector("legend").textContent = external_name;
-    array_of_objects.forEach(function(elem) {
-        var input_elem = document.createElement("input"),
-            label = document.createElement("label");
-        input_elem.type = get_input_type(elem.type);
-        if (input_elem.type === "checkbox") {
-            input_elem.checked = elem.value !== 0;
-            input_elem.onchange = function() {
-                elem.value = input_elem.checked ? 1 : 0;
+    array_of_objects.forEach(function(ob) {
+        var elem,
+            label,
+            type = get_input_type(ob.type);
+        if (type === "select") {
+            elem = document.createElement("select");
+            ob.options.forEach(function(e) {
+                var option = document.createElement("option");
+                option.textContent = e;
+                elem.appendChild(option);
+            });
+            elem.selectedIndex = ob.value;
+            elem.onchange = function() {
+                ob.value = elem.selectedIndex;
+            }
+        } else if (type === "checkbox") {
+            elem = document.createElement("input");
+            elem.type = "checkbox";
+            elem.checked = ob.value !== 0;
+            elem.onchange = function() {
+                ob.value = elem.checked ? 1 : 0;
             };
         } else {
-            input_elem.value = elem.value;
-            input_elem.onchange = function() {
-                elem.value = input_elem.value;
+            elem = document.createElement("input");
+            elem.type = type;
+            elem.value = ob.value;
+            elem.onchange = function() {
+                ob.value = elem.value;
             }
         }
-        label.textContent = elem.label;
-        label.appendChild(input_elem);
+        label = document.createElement("label");
+        label.textContent = ob.label;
+        label.appendChild(elem);
         fieldset.appendChild(label);
         // stop-gap until we make this prettier through css: insert a break
         fieldset.appendChild(document.createElement("br"));
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index aa9c5161b6fb40069bd3decf021dfb02da9b1ce8..4a685c02c77b6e2214d67e654c32cdf3debe692d 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -3751,6 +3751,7 @@ function gui_scope_draw_bg(cid, tag, fg_color, bg_color, w, h, grid_width, dx, d
         path_string = "",
         fg_xy_path, // to be used for the foreground lines
         fg_mono_path,
+        border,
         i, x, y, align_x, align_y;
     // Path strings for the grid lines
     // vertical lines...
@@ -3767,6 +3768,7 @@ function gui_scope_draw_bg(cid, tag, fg_color, bg_color, w, h, grid_width, dx, d
         d: path_string,
         fill: "none",
         stroke: "black",
+        class: "grid",
         "stroke-width": grid_width,
     });
     // We go ahead and create a path to be used in the foreground. We'll
@@ -3783,10 +3785,18 @@ function gui_scope_draw_bg(cid, tag, fg_color, bg_color, w, h, grid_width, dx, d
         stroke: fg_color,
         class: "fgmono"
     });
+    border = create_item(cid, "rect", {
+        style: "fill: none;",
+        width: w,
+        height: h,
+        class: "border",
+        "stroke-width": grid_width
+    });
     g.appendChild(bg);
     g.appendChild(path);
     g.appendChild(fg_xy_path);
     g.appendChild(fg_mono_path);
+    g.appendChild(border);
 }
 
 function scope_configure_fg(cid, tag, type, data_array) {
@@ -3805,13 +3815,13 @@ function gui_scope_configure_fg_mono(cid, tag, data_array) {
     scope_configure_fg(cid, tag, ".fgmono", data_array);
 }
 
-function gui_scope_configure_bg_color(cid, tag, color) {
+function scope_configure_bg_color(cid, tag, color) {
     var g = get_gobj(cid, tag),
         elem = g.querySelector(".bg");
     configure_item(elem, { fill: color });
 }
 
-function gui_scope_configure_fg_color(cid, tag, color) {
+function scope_configure_fg_color(cid, tag, color) {
      var g = get_gobj(cid, tag),
         xy = g.querySelector(".fgxy"),
         mono = g.querySelector(".fgmono");
@@ -3819,11 +3829,33 @@ function gui_scope_configure_fg_color(cid, tag, color) {
     configure_item(mono, { stroke: color });
 }
 
+function scope_configure_grid_color(cid, tag, color) {
+    var g = get_gobj(cid, tag),
+        grid = g.querySelector(".grid");
+    configure_item(grid, { stroke: color });
+}
+
+function gui_scope_configure_color(cid, tag, layer, color) {
+    if (layer === "fg") {
+        scope_configure_fg_color(cid, tag, color);
+    } else if (layer === "bg") {
+        scope_configure_bg_color(cid, tag, color);
+    } else if (layer === "grid") {
+        scope_configure_grid_color(cid, tag, color);
+    }
+}
+
 function gui_scope_clear_fg(cid, tag) {
     scope_configure_fg(cid, tag, ".fgxy", []);
     scope_configure_fg(cid, tag, ".fgmono", []);
 }
 
+function gui_scope_erase_innards(cid, tag) {
+    var g = get_gobj(cid, tag);
+    // Nuke it
+    g.innerHTML = '';
+}
+
 // unauthorized/grid
 
 function get_grid_data(w, h, x_l, y_l) {
diff --git a/pd/src/d_array.c b/pd/src/d_array.c
index 838a2ecb2dd7c9ffb4a4012cccac5efd75e9922b..175704b1d063d15bf97cb1fa1b4d9a1acfef7903 100644
--- a/pd/src/d_array.c
+++ b/pd/src/d_array.c
@@ -298,6 +298,7 @@ static t_int *tabread_tilde_perform(t_int *w)
     int i;
     
     maxindex = x->x_npoints - 1;
+    if (maxindex < 0) goto zero;
     if (!buf) goto zero;
 
     for (i = 0; i < n; i++)
@@ -398,6 +399,7 @@ static t_int *tabread4_tilde_perform(t_int *w)
     int i;
     
     maxindex = x->x_npoints - 3;
+    if (maxindex < 0) goto zero;
 
     if (!buf) goto zero;
 
diff --git a/pd/src/d_soundfile.c b/pd/src/d_soundfile.c
index 285720ea94cdc4d1cef3fca90a3514bbec1ccef5..85d6c573996e036014feea741717fafcb278dcd4 100644
--- a/pd/src/d_soundfile.c
+++ b/pd/src/d_soundfile.c
@@ -29,6 +29,7 @@ objects use Posix-like threads.  */
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <math.h>
 
 #include "m_pd.h"
 
@@ -200,6 +201,21 @@ static void swapstring(char *foo, int doit)
     }
 }
 
+    /* write a sample rate as an 80-bit AIFF-compatible number */
+static void makeaiffsamprate(double sr, unsigned char *shit)
+{
+    int exponent;
+    double mantissa = frexp(sr, &exponent);
+    unsigned long fixmantissa = ldexp(mantissa, 32);
+    shit[0] = (exponent+16382)>>8;
+    shit[1] = exponent+16382;
+    shit[2] = fixmantissa >> 24;
+    shit[3] = fixmantissa >> 16;
+    shit[4] = fixmantissa >> 8;
+    shit[5] = fixmantissa;
+    shit[6] = shit[7] = shit[8] = shit[9] = 0;
+}
+
 /******************** soundfile access routines **********************/
 
 /* This routine opens a file, looks for either a nextstep or "wave" header,
@@ -292,7 +308,8 @@ int open_soundfile_via_fd(int fd, int headersize,
             {
                 long chunksize = swap4(((t_wavechunk *)buf)->wc_size,
                     swap), seekto = headersize + chunksize + 8, seekout;
-                
+                if (seekto & 1)     /* pad up to even number of bytes */
+                    seekto++;
                 if (!strncmp(((t_wavechunk *)buf)->wc_id, "fmt ", 4))
                 {
                     long commblockonset = headersize + 8;
@@ -344,6 +361,8 @@ int open_soundfile_via_fd(int fd, int headersize,
             {
                 long chunksize = swap4(((t_datachunk *)buf)->dc_size,
                     swap), seekto = headersize + chunksize + 8, seekout;
+                if (seekto & 1)     /* pad up to even number of bytes */
+                    seekto++;
                 /* post("chunk %c %c %c %c seek %d",
                     ((t_datachunk *)buf)->dc_id[0],
                     ((t_datachunk *)buf)->dc_id[1],
@@ -374,8 +393,8 @@ int open_soundfile_via_fd(int fd, int headersize,
                         goto badheader;
                 headersize = seekto;
             }
-            bytelimit = swap4(((t_datachunk *)buf)->dc_size, swap);
-            headersize += 8;
+            bytelimit = swap4(((t_datachunk *)buf)->dc_size, swap) - 8;
+            headersize += sizeof(t_datachunk);
         }
     }
         /* seek past header and any sample frames to skip */
@@ -781,8 +800,6 @@ static int create_soundfile(t_canvas *canvas, const char *filename,
     {
         long datasize = nframes * nchannels * bytespersamp;
         long longtmp;
-        static unsigned char dogdoo[] =
-            {0x40, 0x0e, 0xac, 0x44, 0, 0, 0, 0, 0, 0, 'S', 'S', 'N', 'D'};
         if (strcmp(filenamebuf + strlen(filenamebuf)-4, ".aif") &&
             strcmp(filenamebuf + strlen(filenamebuf)-5, ".aiff"))
                 strcat(filenamebuf, ".aif");
@@ -795,10 +812,11 @@ static int create_soundfile(t_canvas *canvas, const char *filename,
         longtmp = swap4(nframes, swap);
         memcpy(&aiffhdr->a_nframeshi, &longtmp, 4);
         aiffhdr->a_bitspersamp = swap2(8 * bytespersamp, swap);
-        memcpy(aiffhdr->a_samprate, dogdoo, sizeof(dogdoo));
-        longtmp = swap4(datasize, swap);
-        memcpy(aiffhdr->a_samprate + sizeof(dogdoo), &longtmp, 4);
-        memset(aiffhdr->a_samprate + sizeof(dogdoo) + 4, 0, 8);
+        makeaiffsamprate(samplerate, aiffhdr->a_samprate);
+        strncpy(((char *)(&aiffhdr->a_samprate))+10, "SSND", 4);
+        longtmp = swap4(datasize + 8, swap);
+        memcpy(((char *)(&aiffhdr->a_samprate))+14, &longtmp, 4);
+        memset(((char *)(&aiffhdr->a_samprate))+18, 0, 8);
         headersize = AIFFPLUS;
     }
     else    /* WAVE format */
@@ -1264,9 +1282,9 @@ static void soundfiler_read(t_soundfiler *x, t_symbol *s,
         
         poswas = lseek(fd, 0, SEEK_CUR);
         eofis = lseek(fd, 0, SEEK_END);
-        if (poswas < 0 || eofis < 0)
+        if (poswas < 0 || eofis < 0 || eofis < poswas)
         {
-            pd_error(x, "lseek failed");
+            pd_error(x, "lseek failed: %ld..%ld", poswas, eofis);
             goto done;
         }
         lseek(fd, poswas, SEEK_SET);
@@ -1283,14 +1301,13 @@ static void soundfiler_read(t_soundfiler *x, t_symbol *s,
         {
             int vecsize;
 
-            garray_resize(garrays[i], finalsize);
+            garray_resize_long(garrays[i], finalsize);
                 /* for sanity's sake let's clear the save-in-patch flag here */
             garray_setsaveit(garrays[i], 0);
-            garray_getfloatwords(garrays[i], &vecsize, 
-                &vecs[i]);
-                /* if the resize failed, garray_resize reported the error */
-            if (vecsize != framesinfile)
+            if (!garray_getfloatwords(garrays[i], &vecsize, &vecs[i])
+                || (vecsize != framesinfile))
             {
+                /* if the resize failed, garray_resize reported the error */
                 pd_error(x, "resize failed");
                 goto done;
             }
@@ -1318,18 +1335,18 @@ static void soundfiler_read(t_soundfiler *x, t_symbol *s,
     for (i = 0; i < argc; i++)
     {
         int vecsize;
-        garray_getfloatwords(garrays[i], &vecsize, &vecs[i]);
-        for (j = itemsread; j < vecsize; j++)
-            vecs[i][j].w_float = 0;
+        if (garray_getfloatwords(garrays[i], &vecsize, &vecs[i]))
+            for (j = itemsread; j < vecsize; j++)
+                vecs[i][j].w_float = 0;
     }
         /* zero out vectors in excess of number of channels */
     for (i = channels; i < argc; i++)
     {
         int vecsize;
         t_word *foo;
-        garray_getfloatwords(garrays[i], &vecsize, &foo);
-        for (j = 0; j < vecsize; j++)
-            foo[j].w_float = 0;
+        if (garray_getfloatwords(garrays[i], &vecsize, &foo))
+            for (j = 0; j < vecsize; j++)
+                foo[j].w_float = 0;
     }
         /* do all graphics updates */
     for (i = 0; i < argc; i++)
@@ -1339,7 +1356,7 @@ static void soundfiler_read(t_soundfiler *x, t_symbol *s,
     goto done;
 usage:
     pd_error(x, "usage: read [flags] filename tablename...");
-    post("flags: -skip <n> -nframes <n> -resize -maxsize <n> ...");
+    post("flags: -skip <n> -resize -maxsize <n> ...");
     post("-raw <headerbytes> <channels> <bytespersamp> <endian (b, l, or n)>.");
 done:
     if (fd >= 0)
@@ -1799,13 +1816,13 @@ static void *readsf_child_main(void *zz)
                 {
                     x->x_fifohead += sysrtn;
                     x->x_bytelimit -= sysrtn;
+                    if (x->x_fifohead == fifosize)
+                        x->x_fifohead = 0;
                     if (x->x_bytelimit <= 0)
                     {
                         x->x_eof = 1;
                         break;
                     }
-                    if (x->x_fifohead == fifosize)
-                        x->x_fifohead = 0;
                 }
 #ifdef DEBUG_SOUNDFILE
                 sprintf(boo, "after: head %d, tail %d\n", 
@@ -2432,20 +2449,23 @@ static t_int *writesf_perform(t_int *w)
         bigendian = x->x_bigendian;
     if (x->x_state == STATE_STREAM)
     {
-        int wantbytes;
+        int wantbytes, roominfifo;
         pthread_mutex_lock(&x->x_mutex);
         wantbytes = sfchannels * vecsize * bytespersample;
-        while (x->x_fifotail > x->x_fifohead &&
-            x->x_fifotail < x->x_fifohead + wantbytes + 1)
+        roominfifo = x->x_fifotail - x->x_fifohead;
+        if (roominfifo <= 0)
+            roominfifo += x->x_fifosize;
+        while (roominfifo < wantbytes + 1)
         {
-#ifdef DEBUG_SOUNDFILE
-            pute("wait...\n");
-#endif
+            fprintf(stderr, "writesf waiting for disk write..\n");
+            fprintf(stderr, "(head %d, tail %d, room %d, want %d)\n",
+                x->x_fifohead, x->x_fifotail, roominfifo, wantbytes);
             sfread_cond_signal(&x->x_requestcondition);
             sfread_cond_wait(&x->x_answercondition, &x->x_mutex);
-#ifdef DEBUG_SOUNDFILE
-            pute("done\n");
-#endif
+            fprintf(stderr, "... done waiting.\n");
+            roominfifo = x->x_fifotail - x->x_fifohead;
+            if (roominfifo <= 0)
+                roominfifo += x->x_fifosize;
         }
 
         soundfile_xferout_sample(sfchannels, x->x_outvec,
@@ -2550,10 +2570,8 @@ static void writesf_open(t_writesf *x, t_symbol *s, int argc, t_atom *argv)
         (x->x_bytespersample * x->x_sfchannels * MAXVECSIZE));
             /* arrange for the "request" condition to be signalled 16
             times per buffer */
-    x->x_sigcountdown = x->x_sigperiod =
-        (x->x_fifosize /
-            (16 * x->x_bytespersample * x->x_sfchannels *
-                x->x_vecsize));
+    x->x_sigcountdown = x->x_sigperiod = (x->x_fifosize /
+            (16 * x->x_bytespersample * x->x_sfchannels * x->x_vecsize));
     sfread_cond_signal(&x->x_requestcondition);
     pthread_mutex_unlock(&x->x_mutex);
 }
@@ -2563,9 +2581,8 @@ static void writesf_dsp(t_writesf *x, t_signal **sp)
     int i, ninlets = x->x_sfchannels;
     pthread_mutex_lock(&x->x_mutex);
     x->x_vecsize = sp[0]->s_n;
-    
     x->x_sigperiod = (x->x_fifosize /
-        (x->x_bytespersample * ninlets * x->x_vecsize));
+            (16 * x->x_bytespersample * x->x_sfchannels * x->x_vecsize));
     for (i = 0; i < ninlets; i++)
         x->x_outvec[i] = sp[i]->s_vec;
     x->x_insamplerate = sp[0]->s_sr;
diff --git a/pd/src/g_array.c b/pd/src/g_array.c
index 91fb0e902de418a0bfb68ac04bc55f77e0941b45..ab50218e6a9a7d228f05272f137c1c390e20338f 100644
--- a/pd/src/g_array.c
+++ b/pd/src/g_array.c
@@ -698,7 +698,7 @@ void garray_arraydialog(t_garray *x, t_symbol *s, int argc, t_atom *argv)
         template_findbyname(x->x_scalar->sc_template),
         gensym("style"), x->x_scalar->sc_vec, 1);*/
 
-        int size;
+        long size;
         t_symbol *argname = sharptodollar(name);
         t_array *a = garray_getarray(x);
         t_template *scalartemplate;
@@ -757,7 +757,7 @@ void garray_arraydialog(t_garray *x, t_symbol *s, int argc, t_atom *argv)
         x->x_style = style;
         if (size != a->a_n)
         {
-            garray_resize(x, size);
+            garray_resize_long(x, size);
         }
         else
         {
@@ -1680,7 +1680,7 @@ static void garray_const(t_garray *x, t_floatarg g)
 }
 
     /* sum of Fourier components; called from routines below */
-static void garray_dofo(t_garray *x, int npoints, t_float dcval,
+static void garray_dofo(t_garray *x, long npoints, t_float dcval,
     int nsin, t_float *vsin, int sineflag)
 {
     double phase, phaseincr, fj;
@@ -1696,7 +1696,7 @@ static void garray_dofo(t_garray *x, int npoints, t_float dcval,
     if (npoints != (1 << ilog2(npoints)))
         post("%s: rounding to %d points", array->a_templatesym->s_name,
             (npoints = (1<<ilog2(npoints))));
-    garray_resize(x, npoints + 3);
+    garray_resize_long(x, npoints + 3);
     phaseincr = 2. * 3.14159 / npoints;
     for (i = 0, phase = -phaseincr; i < array->a_n; i++, phase += phaseincr)
     {
@@ -1716,7 +1716,8 @@ static void garray_dofo(t_garray *x, int npoints, t_float dcval,
 static void garray_sinesum(t_garray *x, t_symbol *s, int argc, t_atom *argv)
 {    
     t_float *svec;
-    int npoints, i;
+    long npoints;
+    int i;
     if (argc < 2)
     {
         error("sinesum: %s: need number of points and partial strengths",
@@ -1739,7 +1740,8 @@ static void garray_sinesum(t_garray *x, t_symbol *s, int argc, t_atom *argv)
 static void garray_cosinesum(t_garray *x, t_symbol *s, int argc, t_atom *argv)
 {
     t_float *svec;
-    int npoints, i;
+    long npoints;
+    int i;
     if (argc < 2)
     {
         error("sinesum: %s: need number of points and partial strengths",
@@ -1956,10 +1958,11 @@ int garray_ambigendian(void)
     return (c==0);
 }
 
-void garray_resize(t_garray *x, t_floatarg f)
+void garray_resize_long(t_garray *x, long n)
 {
     t_array *array = garray_getarray(x);
-    int n = (f < 1 ? 1 : f);
+    if (n < 1)
+        n = 1;
     //fprintf(stderr,"garray_resize %d\n", n);
     array_resize(array, n);
     garray_fittograph(x, n, 1);/*template_getfloat(
@@ -1970,6 +1973,12 @@ void garray_resize(t_garray *x, t_floatarg f)
         canvas_update_dsp();
 }
 
+    /* float version to use as Pd method */
+void garray_resize(t_garray *x, t_floatarg f)
+{
+    garray_resize_long(x, f);
+}
+
 static void garray_print(t_garray *x)
 {
     t_array *array = garray_getarray(x);
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index 3fdf9473bd2e780e284cd2b546ecf450bcc238a9..6986a69524fb81d04a7783e07e83bda2de4a2380 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -3307,7 +3307,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
             int noutlet;
             int ninlet;
                 /* resize?  only for "true" text boxes, canvases, iemguis,
-                   and -- using an awful hack-- for the Scope~ and grid
+                   and -- using an awful hack-- for the scope~ and grid
                    objects by checking for the class name below.
 
                    One exception-- my_canvas. It has a weirdo interface
@@ -3320,7 +3320,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
                 */
             if (ob && (ob->te_iemgui
                  && pd_class((t_pd *)ob) != my_canvas_class
-                 || pd_class(&ob->te_pd)->c_name == gensym("Scope~")
+                 || pd_class(&ob->te_pd)->c_name == gensym("scope~")
                  || pd_class(&ob->te_pd)->c_name == gensym("grid"))
                 && xpos >= x2-4 && ypos > y2-6)
             {
@@ -3339,7 +3339,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
                     }
                     else
                     {
-                        pd_vmess((t_pd *)ob, gensym("_click_for_resizing"),
+                        pd_vmess((t_pd *)ob, gensym("_click"),
                            "fff", (t_float)1, (t_float)xpos, (t_float)ypos);
                     }
                 }
@@ -5277,10 +5277,10 @@ void canvas_motion(t_canvas *x, t_floatarg xpos, t_floatarg ypos,
                 pd_vmess(sh, gensym("_motion"), "ff", (t_float)xpos, (t_float)ypos);
                 //pd_vmess(sh, gensym("_click"), "fff", 0, xpos, ypos);
             }
-            else if (ob && (pd_class(&ob->te_pd)->c_name == gensym("Scope~")
+            else if (ob && (pd_class(&ob->te_pd)->c_name == gensym("scope~")
                             || pd_class(&ob->te_pd)->c_name == gensym("grid")))
             {
-                pd_vmess((t_pd *)ob, gensym("_motion_for_resizing"),
+                pd_vmess((t_pd *)ob, gensym("_motion"),
                     "ff", (t_float)xpos, (t_float)ypos);
             }
             else post("not resizable");
diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h
index cf3a09982cd14a484daec87311b95065794c940d..36f19c65e255f728a66c93da6f91c522dddf2e8c 100644
--- a/pd/src/m_pd.h
+++ b/pd/src/m_pd.h
@@ -673,7 +673,8 @@ EXTERN t_float garray_get(t_garray *x, t_symbol *s, t_int indx);
 EXTERN void garray_redraw(t_garray *x);
 EXTERN int garray_npoints(t_garray *x);
 EXTERN char *garray_vec(t_garray *x);
-EXTERN void garray_resize(t_garray *x, t_floatarg f);
+EXTERN void garray_resize(t_garray *x, t_floatarg f);  /* avoid; use this: */
+EXTERN void garray_resize_long(t_garray *x, long n);   /* better version */
 EXTERN void garray_usedindsp(t_garray *x);
 EXTERN void garray_setsaveit(t_garray *x, int saveit);
 EXTERN t_glist *garray_getglist(t_garray *x);