aboutsummaryrefslogtreecommitdiff
path: root/externals/control
diff options
context:
space:
mode:
authorcarmen rocco <ix9@users.sourceforge.net>2004-09-16 18:01:09 +0000
committercarmen rocco <ix9@users.sourceforge.net>2004-09-16 18:01:09 +0000
commit1d427b8655e26e99906ac253f8e4a0bde468093f (patch)
tree0765cff32e2e8af489d4a5a0742ae42b09b39266 /externals/control
parent63c5c02b7270d1344557dcb8408770ee4302652e (diff)
dropped in goodie bag
svn path=/trunk/; revision=2041
Diffstat (limited to 'externals/control')
-rw-r--r--externals/control/choice/choice.c128
-rw-r--r--externals/control/choice/help-choice.pd58
2 files changed, 186 insertions, 0 deletions
diff --git a/externals/control/choice/choice.c b/externals/control/choice/choice.c
new file mode 100644
index 00000000..e70df6b2
--- /dev/null
+++ b/externals/control/choice/choice.c
@@ -0,0 +1,128 @@
+/* choice -- match incoming list against a collection of stored templates. */
+
+/* Copyright 1999 Miller Puckette.
+Permission is granted to use this software for any purpose provided you
+keep this copyright notice intact.
+
+THE AUTHOR AND HIS EMPLOYERS MAKE NO WARRANTY, EXPRESS OR IMPLIED,
+IN CONNECTION WITH THIS SOFTWARE.
+
+This file is downloadable from http://www.crca.ucsd.edu/~msp .
+*/
+
+#include "m_pd.h"
+#include <math.h>
+static t_class *choice_class;
+#define DIMENSION 10
+
+typedef struct _elem
+{
+ float e_age;
+ float e_weight[DIMENSION];
+} t_elem;
+
+typedef struct _choice
+{
+ t_object x_obj;
+ t_elem *x_vec;
+ int x_n;
+ int x_nonrepeat;
+} t_choice;
+
+static void *choice_new(t_float fnonrepeat)
+{
+ t_choice *x = (t_choice *)pd_new(choice_class);
+ outlet_new(&x->x_obj, gensym("float"));
+ x->x_vec = (t_elem *)getbytes(0);
+ x->x_n = 0;
+ x->x_nonrepeat = (fnonrepeat != 0);
+ return (x);
+}
+
+static void choice_clear(t_choice *x)
+{
+ x->x_vec = (t_elem *)resizebytes(x->x_vec, x->x_n * sizeof(t_elem), 0);
+ x->x_n = 0;
+}
+
+static void choice_print(t_choice *x)
+{
+ int j;
+ for (j = 0; j < x->x_n; j++)
+ {
+ t_elem *e = x->x_vec + j;
+ t_float *w = e->e_weight;
+ post("%2d age %2d \
+w %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f",
+ j, (int)(e->e_age), w[0], w[1], w[2], w[3], w[4], w[5],
+ w[6], w[7], w[8], w[9]);
+ }
+}
+
+static void choice_add(t_choice *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int oldn = x->x_n, newn = oldn + 1, i;
+ t_elem *e;
+ float sum, normal;
+ x->x_vec = (t_elem *)resizebytes(x->x_vec, oldn * sizeof(t_elem),
+ newn * sizeof(t_elem));
+ x->x_n = newn;
+ e = x->x_vec + oldn;
+ e->e_age = 2;
+
+ for (i = 0, sum = 0; i < DIMENSION; i++)
+ {
+ float f = atom_getfloatarg(i, argc, argv);
+ e->e_weight[i] = f;
+ sum += f*f;
+ }
+ normal = (float)(sum > 0 ? 1./sqrt(sum) : 1);
+ for (i = 0; i < DIMENSION; i++)
+ e->e_weight[i] *= normal;
+}
+
+static void choice_list(t_choice *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i, j;
+ float bestsum = 0;
+ int bestindex = -1;
+ t_float invec[DIMENSION];
+ for (i = 0; i < DIMENSION; i++)
+ invec[i] = atom_getfloatarg(i, argc, argv);
+ for (j = 0; j < x->x_n; j++)
+ {
+ t_elem *e = x->x_vec + j;
+ float sum;
+ for (i = 0, sum = 0; i < DIMENSION; i++)
+ sum += e->e_weight[i] * invec[i];
+ if (x->x_nonrepeat) sum *= (float)(log(e->e_age));
+ if (sum > bestsum)
+ {
+ bestsum = sum;
+ sum = 1;
+ bestindex = j;
+ }
+ }
+ if (bestindex >= 0)
+ {
+ for (j = 0; j < x->x_n; j++)
+ x->x_vec[j].e_age += 1.;
+ x->x_vec[bestindex].e_age = 1;
+ }
+ outlet_float(x->x_obj.ob_outlet, (float)bestindex);
+}
+
+static void choice_free(t_choice *x)
+{
+ freebytes(x->x_vec, x->x_n * sizeof(t_elem));
+}
+
+void choice_setup(void)
+{
+ choice_class = class_new(gensym("choice"), (t_newmethod)choice_new,
+ (t_method)choice_free, sizeof(t_choice), 0, A_DEFFLOAT, 0);
+ class_addmethod(choice_class, (t_method)choice_add, gensym("add"), A_GIMME, 0);
+ class_addmethod(choice_class, (t_method)choice_clear, gensym("clear"), 0);
+ class_addmethod(choice_class, (t_method)choice_print, gensym("print"), 0);
+ class_addlist(choice_class, choice_list);
+}
diff --git a/externals/control/choice/help-choice.pd b/externals/control/choice/help-choice.pd
new file mode 100644
index 00000000..3b75f932
--- /dev/null
+++ b/externals/control/choice/help-choice.pd
@@ -0,0 +1,58 @@
+#N canvas 16 5 609 600 12;
+#X obj 8 195 choice;
+#X msg 41 86 print;
+#X msg 29 63 clear;
+#X msg 8 34 add 1 0 0 \, add 0 1 0 \, add 0 0 1 \, add 1 1 1 \, add
+1 1 0;
+#X obj 77 171 pack 0 0 0;
+#X floatatom 182 125 0 0 0 0 - - -;
+#X floatatom 148 125 0 0 0 0 - - -;
+#X floatatom 115 125 0 0 0 0 - - -;
+#X obj 77 147 f;
+#X msg 77 125 bang;
+#X floatatom 8 216 0 0 0 0 - - -;
+#X obj 71 196 choice 1;
+#X floatatom 71 217 0 0 0 0 - - -;
+#X obj 76 4 choice;
+#X text 135 3 - search for a best match to an incoming list;
+#X text 19 243 The choice object holds a list of vectors \, each having
+up to ten elements. When sent a list of numbers \, it outputs the index
+of the known vector that matches most closely. The quality of the match
+is the dot product of the two vectors after normalizing them \, i.e.
+\, the vector whose direction is closest to that of the input wins.
+;
+#X text 19 340 If given a nonzero creation argument \, choice tries
+to avoid repetitious outputs by weighting less recently output vectors
+preferentially.;
+#X text 20 389 You can use this to choose interactively between a number
+of behaviors depending on their attributes. For example \, you might
+have stored a number of melodies \, of which some are syncopated \,
+some chromatic \, some are more than 100 years old \, some are bugle
+calls \, and some are Christmas carols. You could then ask to find
+a syncopated bugle call (1 \, 0 \, 0 \, 1 \, 0) and you'll get the
+thing most closely matching the request.;
+#X text 19 514 You can use numbers other than 0 and 1 to indicate relative
+strengths of the attributes \, or even use negative numbers to indicate
+opposites \, either in the incoming lists or in the stored ones.;
+#X text 320 572 updated for Pd version-0.30;
+#X text 79 62 delete all stored vectors;
+#X text 498 34 add vectors;
+#X text 94 84 debugging printout;
+#X text 69 104 tweak the numbers and hit "bang" to input a list;
+#X text 151 197 creation argument to avoid repeated outout;
+#X text 108 219 output is the index of best match \, counting from
+zero;
+#X connect 0 0 10 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 2 0 11 0;
+#X connect 3 0 0 0;
+#X connect 3 0 11 0;
+#X connect 4 0 0 0;
+#X connect 4 0 11 0;
+#X connect 5 0 4 2;
+#X connect 6 0 4 1;
+#X connect 7 0 8 1;
+#X connect 8 0 4 0;
+#X connect 9 0 8 0;
+#X connect 11 0 12 0;