aboutsummaryrefslogtreecommitdiff
path: root/src/sort.c
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2005-04-04 12:23:48 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2005-04-04 12:23:48 +0000
commitb271428159f52db484b8077ea0b4fd2f4d7c8247 (patch)
tree546371913140182f69055134cec9a85536895ce4 /src/sort.c
parent2b60d55c919e7588f5aff15936e83c300b3660bb (diff)
added a 2nd outlet to get the indices for sorting
svn path=/trunk/externals/zexy/; revision=2674
Diffstat (limited to 'src/sort.c')
-rw-r--r--src/sort.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/sort.c b/src/sort.c
index 97a7dd3..578d2a3 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -36,8 +36,11 @@ typedef struct _sort
int bufsize;
t_float *buffer;
+ t_int *indices;
int ascending;
+
+ t_outlet*indexOut, *sortedOut;
} t_sort;
@@ -49,18 +52,23 @@ static void sort_dir(t_sort *x, t_float f)
static void sort_buffer(t_sort *x, int argc, t_atom *argv)
{
int n = argc;
- t_float *buf;
+ t_float *buf, *idx;
t_atom *atombuf = argv;
if (argc != x->bufsize) {
- if (x->buffer) freebytes(x->buffer, x->bufsize * sizeof(t_float));
+ if (x->buffer) freebytes(x->buffer, x->bufsize * sizeof(t_float));
+ if (x->indices)freebytes(x->indices, x->bufsize * sizeof(t_int));
+
x->bufsize = argc;
x->buffer = getbytes(x->bufsize * sizeof(t_float));
+ x->indices = getbytes(x->bufsize * sizeof(t_int));
}
buf = x->buffer;
- while (n--)
+ while (n--){
*buf++ = atom_getfloat(atombuf++);
+ x->indices[n] = n;
+ }
}
static void sort_list(t_sort *x, t_symbol *s, int argc, t_atom *argv)
@@ -68,11 +76,13 @@ 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;
+ t_int *idx;
int i, loops = 1;
sort_buffer(x, argc, argv);
buf = x->buffer;
+ idx = x->indices;
while (step > 1) {
step = (step % 2)?(step+1)/2:step/2;
@@ -84,20 +94,30 @@ static void sort_list(t_sort *x, t_symbol *s, int argc, t_atom *argv)
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];
+ t_int i_tmp = idx[n];
+ t_float f_tmp = buf[n];
buf[n] = buf[n+step];
- buf[n+step] = dummy;
+ buf[n+step] = f_tmp;
+ idx[n] = idx[n+step];
+ idx[n+step] = i_tmp;
}
}
}
}
if (x->ascending)
+ for (n = 0; n < argc; n++) SETFLOAT(&atombuf[n], idx[n]);
+ else
+ for (n = 0, i=argc-1; n < argc; n++, i--) SETFLOAT(&atombuf[n], idx[i]);
+
+ outlet_list(x->indexOut , &s_list, n, atombuf);
+
+ 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->sortedOut, &s_list, n, atombuf);
- outlet_list(x->x_obj.ob_outlet, &s_list, n, atombuf);
freebytes(atombuf, argc*sizeof(t_atom));
}
@@ -107,7 +127,8 @@ 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->sortedOut=outlet_new(&x->x_obj, &s_list);
+ x->indexOut=outlet_new(&x->x_obj, &s_list);
x->bufsize = 0;
x->buffer = NULL;