/* * valve takes a map like 0 1 3 4 7 and a route. if the route and the input are * non-zero in the map, then the route is output from the object * Copyright (c) 2007, Dr Edward Kelly * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * * provided with the distribution. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "m_pd.h" #include #include #define MAXENTRIES 512 #define LASTENTRY 511 static t_class *valve_class; typedef struct _valve { t_object x_obj; t_atom *map; int bufsize; t_float input, router, max; t_outlet *routed, *notrouted; int flush; } t_valve; static void valve_map(t_valve *x, t_symbol *s, int n, t_atom *map) { if (x->map) { freebytes(x->map, x->bufsize * sizeof(t_atom)); x->map = 0; x->bufsize = 0; } x->map = copybytes(map, n * sizeof(t_atom)); x->bufsize = n; } void valve_float(t_valve *x, t_floatarg fin) { if (x->map) { int arg, arga, argb; arga = argb = 0; float testa, testb; testa = testb = 0; x->input = fin; arg = (int)x->input; testa = fin < 0 ? 0 : atom_getfloatarg(arg, x->bufsize, x->map); testb = x->router < 0 ? 0 : atom_getfloatarg(x->router, x->bufsize, x->map); arga = (int)testa; argb = (int)testb; if(arga && argb) { outlet_float(x->routed, x->router); } else if (!argb) { outlet_float(x->notrouted, argb); } else if (!arga && argb) { outlet_float(x->notrouted, arga); } } } void valve_set(t_valve *x, t_floatarg fmap, t_floatarg fval) { if(fmap < x->bufsize && fmap >= 0) { int imap = (int)fmap; SETFLOAT(&x->map[imap], fval); x->max = fmap > x->max ? fmap : x->max; } } void valve_clear(t_valve *x) { if (x->map) { freebytes(x->map, x->bufsize * sizeof(t_atom)); x->map = 0; x->bufsize = 0; } } void valve_debug(t_valve *x) { int i; for(i=0;ibufsize;i++) { float element = atom_getfloatarg(i, x->bufsize, x->map); post("element %d = %d", i, element); } post("max = %d", x->max); } void *valve_new(t_floatarg f) { t_valve *x = (t_valve *)pd_new(valve_class); x->max = 0; int i; x->map = 0; x->bufsize = 0; floatinlet_new(&x->x_obj, &x->router); x->routed = outlet_new(&x->x_obj, &s_float); x->notrouted = outlet_new(&x->x_obj, &s_float); return (void *)x; } void valve_setup(void) { valve_class = class_new(gensym("valve"), (t_newmethod)valve_new, 0, sizeof(t_valve), 0, A_DEFFLOAT, 0); post("|¬~¬~¬~¬~¬~¬valve~¬~¬~¬~¬~¬~¬|"); post("|~>^^^integer map router^^^<¬|"); post("|¬~¬~¬Edward Kelly 2007~¬~¬~¬|"); class_addfloat(valve_class, valve_float); class_addmethod(valve_class, (t_method)valve_set, gensym("set"), A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(valve_class, (t_method)valve_map, gensym("map"), A_GIMME, 0); class_addmethod(valve_class, (t_method)valve_clear, gensym("clear"), A_DEFFLOAT, 0); class_addmethod(valve_class, (t_method)valve_debug, gensym("debug"), A_DEFFLOAT, 0); }