From 5af7081222ef801b23857fb904c78d0798f5d0df Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 10 Jan 2011 06:03:02 +0000 Subject: build Pd's extra as a libdir svn path=/trunk/; revision=14694 --- externals/extra/choice/choice-help.pd | 58 +++++++++++++++ externals/extra/choice/choice.c | 128 ++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 externals/extra/choice/choice-help.pd create mode 100644 externals/extra/choice/choice.c (limited to 'externals/extra/choice') diff --git a/externals/extra/choice/choice-help.pd b/externals/extra/choice/choice-help.pd new file mode 100644 index 00000000..0677db87 --- /dev/null +++ b/externals/extra/choice/choice-help.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; diff --git a/externals/extra/choice/choice.c b/externals/extra/choice/choice.c new file mode 100644 index 00000000..b7bf23ab --- /dev/null +++ b/externals/extra/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 +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); +} -- cgit v1.2.1