aboutsummaryrefslogtreecommitdiff
path: root/src/z_sort.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/z_sort.c')
-rw-r--r--src/z_sort.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/z_sort.c b/src/z_sort.c
new file mode 100644
index 0000000..e0c656a
--- /dev/null
+++ b/src/z_sort.c
@@ -0,0 +1,114 @@
+
+/* 1309:forum::für::umläute:2000 */
+
+/*
+ sort : sort a package of floats
+*/
+
+#include "zexy.h"
+
+/* ------------------------- sort ------------------------------- */
+
+/*
+SHELL SORT: simple and easy
+*/
+
+static t_class *sort_class;
+
+typedef struct _sort
+{
+ t_object x_obj;
+
+ int bufsize;
+ t_float *buffer;
+
+ int ascending;
+} t_sort;
+
+
+static void sort_dir(t_sort *x, t_float f)
+{
+ x->ascending = (f < 0.f)?0:1;
+}
+
+static void sort_buffer(t_sort *x, int argc, t_atom *argv)
+{
+ int n = argc;
+ t_float *buf;
+ t_atom *atombuf = argv;
+
+ if (argc != x->bufsize) {
+ if (x->buffer) freebytes(x->buffer, x->bufsize * sizeof(t_float));
+ x->bufsize = argc;
+ x->buffer = getbytes(x->bufsize * sizeof(t_float));
+ }
+
+ buf = x->buffer;
+ while (n--)
+ *buf++ = atom_getfloat(atombuf++);
+}
+
+static void sort_list(t_sort *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int step = argc, n;
+ t_atom *atombuf = (t_atom *)getbytes(sizeof(t_atom) * argc);
+ t_float *buf;
+
+ int i, loops = 1;
+
+ sort_buffer(x, argc, argv);
+ buf = x->buffer;
+
+ while (step > 1) {
+ step = (step % 2)?(step+1)/2:step/2;
+
+ // i = loops++;
+ i = loops;
+ loops += 2;
+
+ while(i--) { /* there might be some optimization in here */
+ for (n=0; n<(argc-step); n++) {
+ if (buf[n] > buf[n+step]) {
+ t_float dummy = buf[n];
+ buf[n] = buf[n+step];
+ buf[n+step] = dummy;
+ }
+ }
+ }
+ }
+
+ if (x->ascending)
+ for (n = 0; n < argc; n++) SETFLOAT(&atombuf[n], buf[n]);
+ else
+ for (n = 0, i=argc-1; n < argc; n++, i--) SETFLOAT(&atombuf[n], buf[i]);
+
+ outlet_list(x->x_obj.ob_outlet, &s_list, n, atombuf);
+
+ freebytes(atombuf, sizeof(atombuf));
+}
+
+static void *sort_new(t_floatarg f)
+{
+ t_sort *x = (t_sort *)pd_new(sort_class);
+ x->ascending = (f < 0.f)?0:1;
+
+ outlet_new(&x->x_obj, &s_list);
+
+ x->bufsize = 0;
+ x->buffer = NULL;
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("direction"));
+
+ return (x);
+}
+
+void z_sort_setup(void)
+{
+ sort_class = class_new(gensym("sort"), (t_newmethod)sort_new,
+ 0, sizeof(t_sort), 0, A_DEFFLOAT, 0);
+
+ class_addlist (sort_class, sort_list);
+ class_addmethod (sort_class, (t_method)sort_dir, gensym("direction"), A_DEFFLOAT, 0);
+
+ class_sethelpsymbol(sort_class, gensym("zexy/sort"));
+}