From cee98b59f1adf987b6dcbc771299bb9d6d75b843 Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Thu, 8 Aug 2002 16:42:32 +0000 Subject: added missing tildes svn path=/trunk/; revision=81 --- pd/extra/expr~/vexp_if.c | 931 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 pd/extra/expr~/vexp_if.c (limited to 'pd/extra/expr~/vexp_if.c') diff --git a/pd/extra/expr~/vexp_if.c b/pd/extra/expr~/vexp_if.c new file mode 100644 index 00000000..6d86ff1c --- /dev/null +++ b/pd/extra/expr~/vexp_if.c @@ -0,0 +1,931 @@ +/* + * jMax + * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See file LICENSE for further informations on licensing terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Based on Max/ISPW by Miller Puckette. + * + * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell. + * + */ + +/* "expr" was written by Shahrokh Yadegari c. 1989. -msp */ +/* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */ + +#include +#include + + +#include "vexp.h" +#ifndef MSP +#ifndef MACOSX +/* + * the compiler on mac seems not to like this, perhaps we could get away with + * not having it at all. + */ +#include "stdlib.h" +#endif +#endif +#include "string.h" + +static char *exp_version = "0.3"; + +extern struct ex_ex *ex_eval(struct expr *exp, struct ex_ex *eptr, + struct ex_ex *optr, int n); + +#ifdef PD +static t_class *expr_class; +static t_class *expr_tilde_class; +static t_class *fexpr_tilde_class; +#else /* MSP */ +void *expr_tilde_class; +#endif + + +/*------------------------- expr class -------------------------------------*/ + +extern int expr_donew(struct expr *expr, int ac, t_atom *av); + +/*#define EXPR_DEBUG*/ + +static void expr_bang(t_expr *x); +t_int *expr_perform(t_int *w); + + +static void +expr_list(t_expr *x, t_symbol *s, int argc, const fts_atom_t *argv) +{ + int i; + + if (argc > MAX_VARS) argc = MAX_VARS; + + for (i = 0; i < argc; i++) + { + if (argv[i].a_type == A_FLOAT) + { + if (x->exp_var[i].ex_type == ET_FI) + x->exp_var[i].ex_flt = argv[i].a_w.w_float; + else if (x->exp_var[i].ex_type == ET_II) + x->exp_var[i].ex_int = argv[i].a_w.w_float; + else pd_error(x, "expr: type mismatch"); + } + else if (argv[i].a_type == A_SYMBOL) + { + if (x->exp_var[i].ex_type == ET_SI) + x->exp_var[i].ex_ptr = (char *)argv[i].a_w.w_symbol; + else pd_error(x, "expr: type mismatch"); + } + } + expr_bang(x); +} + +static void +expr_flt(t_expr *x, t_float f, int in) +{ + if (in > MAX_VARS) + return; + + if (x->exp_var[in].ex_type == ET_FI) + x->exp_var[in].ex_flt = f; + else if (x->exp_var[in].ex_type == ET_II) + x->exp_var[in].ex_int = f; +} + +static t_class *exprproxy_class; + +typedef struct _exprproxy { + t_pd p_pd; + int p_index; + t_expr *p_owner; + struct _exprproxy *p_next; +} t_exprproxy; + +t_exprproxy *exprproxy_new(t_expr *owner, int indx); +void exprproxy_float(t_exprproxy *p, t_floatarg f); + +t_exprproxy * +exprproxy_new(t_expr *owner, int indx) +{ + t_exprproxy *x = (t_exprproxy *)pd_new(exprproxy_class); + x->p_owner = owner; + x->p_index = indx; + x->p_next = owner->exp_proxy; + owner->exp_proxy = x; + return (x); +} + +void +exprproxy_float(t_exprproxy *p, t_floatarg f) +{ + t_expr *x = p->p_owner; + int in = p->p_index; + + if (in > MAX_VARS) + return; + + if (x->exp_var[in].ex_type == ET_FI) + x->exp_var[in].ex_flt = f; + else if (x->exp_var[in].ex_type == ET_II) + x->exp_var[in].ex_int = f; +} + +/* method definitions */ +static void +expr_ff(t_expr *x) +{ + t_exprproxy *y; + + y = x->exp_proxy; + while (y) + { + x->exp_proxy = y->p_next; +#ifdef PD + pd_free(&y->p_pd); +#else /*MSP */ + /* SDY find out what needs to be called for MSP */ + +#endif + y = x->exp_proxy; + } + if (x->exp_stack) + fts_free(x->exp_stack); +/* + * SDY free all the allocated buffers here for expr~ and fexpr~ + */ +} + +static void +expr_bang(t_expr *x) +{ + +#ifdef EXPR_DEBUG + { + int i; + struct ex_ex *eptr; + + for (i = 0, eptr = x->exp_var; ; eptr++, i++) + { + if (!eptr->ex_type) + break; + switch (eptr->ex_type) + { + case ET_II: + fprintf(stderr,"ET_II: %d \n", eptr->ex_int); + break; + + case ET_FI: + fprintf(stderr,"ET_FT: %f \n", eptr->ex_flt); + break; + + default: + fprintf(stderr,"oups\n"); + } + } + } +#endif + /* banging a signal or filter object means nothing */ + if (!IS_EXPR(x)) + return; + + if (!ex_eval(x, x->exp_stack, &x->exp_res, 0)) + { + /* fprintf(stderr,"expr_bang(error evaluation)\n"); */ + return; + } + + + switch(x->exp_res.ex_type) + { + case ET_INT: + outlet_float(x->exp_outlet, (t_float) x->exp_res.ex_int); + break; + + case ET_FLT: + outlet_float(x->exp_outlet, x->exp_res.ex_flt); + break; + + case ET_SYM: + /* CHANGE this will have to be taken care of */ + + default: + post("expr: bang: unrecognized result %ld\n", x->exp_res.ex_type); + } +} + +static t_expr * +#ifdef PD +expr_new(t_symbol *s, int ac, t_atom *av) +#else /* MSP */ +Nexpr_new(t_symbol *s, int ac, t_atom *av) +#endif +{ + struct expr *x; + int i, ninlet; + struct ex_ex *eptr; + t_atom fakearg; + int dsp_index; /* keeping track of the dsp inlets */ + + +/* + * SDY - we may need to call dsp_setup() in this function + */ + + if (!ac) + { + ac = 1; + av = &fakearg; + SETFLOAT(&fakearg, 0); + } + +#ifdef PD + /* + * figure out if we are expr, expr~, or fexpr~ + */ + if (!strcmp("expr", s->s_name)) { + x = (t_expr *)pd_new(expr_class); + SET_EXPR(x); + } else if (!strcmp("expr~", s->s_name)) { + x = (t_expr *)pd_new(expr_tilde_class); + SET_EXPR_TILDE(x); + } else if (!strcmp("fexpr~", s->s_name)) { + x = (t_expr *)pd_new(fexpr_tilde_class); + SET_FEXPR_TILDE(x); + } else { + post("expr_new: bad object name '%s'"); + /* assume expr */ + x = (t_expr *)pd_new(expr_class); + SET_EXPR(x); + } +#else /* MSP */ + /* for now assume an expr~ */ + x = (t_expr *)pd_new(expr_tilde_class); + SET_EXPR_TILDE(x); +#endif + + /* + * initialize the newly allocated object + */ + x->exp_stack = (struct ex_ex *)0; + x->exp_proxy = 0; + x->exp_nivec = 0; + x->exp_error = 0; + x->exp_outlet = (t_outlet *)0; + x->exp_res.ex_type = 0; + x->exp_res.ex_int = 0; + x->exp_p_res = (t_float *)0; + x->exp_tmpres = (t_float *)0; + for (i = 0; i < MAX_VARS; i++) { + x->exp_var[i].ex_type = 0; + x->exp_var[i].ex_int = 0; + x->exp_p_var[i] = (t_float *)0; + } + x->exp_f = 0; /* save the control value to be transformed to signal */ + + + if (expr_donew(x, ac, av)) + { + pd_error(x, "expr: syntax error"); +/* +SDY the following coredumps why? + pd_free(&x->exp_ob.ob_pd); +*/ + return (0); + } + + ninlet = 1; + for (i = 0, eptr = x->exp_var; i < MAX_VARS ; i++, eptr++) + if (eptr->ex_type) { + ninlet = i + 1; + } + + /* + * create the new inlets + */ + for (i = 1, eptr = x->exp_var + 1, dsp_index=1; iex_type) + { + case 0: + /* nothing is using this inlet */ + if (i < ninlet) +#ifdef PD + floatinlet_new(&x->exp_ob, &eptr->ex_flt); +#else /* MSP */ + inlet_new(&x->exp_ob, "float"); +#endif + break; + + case ET_II: + case ET_FI: + p = exprproxy_new(x, i); +#ifdef PD + inlet_new(&x->exp_ob, &p->p_pd, &s_float, &s_float); +#else /* MSP */ + inlet_new(&x->exp_ob, "float"); +#endif + break; + + case ET_SI: +#ifdef PD + symbolinlet_new(&x->exp_ob, (t_symbol **)&eptr->ex_ptr); +#else /* MSP */ + inlet_new(&x->exp_ob, "symbol"); +#endif + break; + + case ET_XI: + case ET_VI: + if (!IS_EXPR(x)) { + dsp_index++; +#ifdef PD + inlet_new(&x->exp_ob, &x->exp_ob.ob_pd, + &s_signal, &s_signal); +#else /* MSP */ + inlet_new(&x->exp_ob, "signal"); +#endif + break; + } else + post("expr: internal error expr_new"); + default: + pd_error(x, "expr: bad type (%lx) inlet = %d\n", + eptr->ex_type, i + 1, 0, 0, 0); + break; + } + } + if (IS_EXPR(x)) { + x->exp_outlet = outlet_new(&x->exp_ob, 0); + } else { +#ifdef PD + x->exp_outlet = outlet_new(&x->exp_ob, gensym("signal")); +#else /* MSP */ + x->exp_outlet = outlet_new(&x->exp_ob, "signal"); +#endif + x->exp_nivec = dsp_index; + } + + return (x); +} + +t_int * +expr_perform(t_int *w) +{ + int i; + t_expr *x = (t_expr *)w[1]; + struct ex_ex res; + int n; + + /* sanity check */ + if (IS_EXPR(x)) { + post("expr_perform: bad x->exp_flags = %d", x->exp_flags); + abort(); + } + + if (x->exp_flags & EF_STOP) { + memset(x->exp_res.ex_vec, 0, x->exp_vsize * sizeof (float)); + return (w + 2); + } + + if (IS_EXPR_TILDE(x)) { + ex_eval(x, x->exp_stack, &x->exp_res, 0); + return (w + 2); + } + + if (!IS_FEXPR_TILDE(x)) { + post("expr_perform: bad x->exp_flags = %d - expecting fexpr", + x->exp_flags); + abort(); + } + /* + * since the output buffer could be the same as one of the inputs + * we need to keep the output in a different buffer + */ + for (i = 0; i < x->exp_vsize; i++) { + res.ex_type = 0; + res.ex_int = 0; + ex_eval(x, x->exp_stack, &res, i); + switch (res.ex_type) { + case ET_INT: + x->exp_tmpres[i] = (t_float) res.ex_int; + break; + case ET_FLT: + x->exp_tmpres[i] = res.ex_flt; + break; + default: + post("expr_perform: bad result type %d", res.ex_type); + } + } + /* + * copy inputs and results to the save buffers + * inputs need to be copied first as the output buffer can be + * same as an input buffer + */ + n = x->exp_vsize * sizeof(t_float); + for (i = 0; i < MAX_VARS; i++) + if (x->exp_var[i].ex_type == ET_XI) + memcpy(x->exp_p_var[i], x->exp_var[i].ex_vec, n); + memcpy(x->exp_p_res, x->exp_tmpres, n); + memcpy(x->exp_res.ex_vec, x->exp_tmpres, n); + return (w + 2); +} + +static void +expr_dsp(t_expr *x, t_signal **sp) +{ + int i, nv; + int newsize; + + x->exp_error = 0; /* reset all errors */ + newsize = (x->exp_vsize != sp[0]->s_n); + x->exp_vsize = sp[0]->s_n; /* record the vector size */ + x->exp_res.ex_type = ET_VEC; + x->exp_res.ex_vec = sp[x->exp_nivec]->s_vec; + for (i = 0, nv = 0; i < MAX_VARS; i++) + /* + * the first inlet is always a signal + * + * SDY We are warning the user till this limitation + * is taken away from pd + */ + if (!i || x->exp_var[i].ex_type == ET_VI || + x->exp_var[i].ex_type == ET_XI) { + if (nv >= x->exp_nivec) { + post("expr_dsp int. err nv = %d, x->exp_nive = %d", + nv, x->exp_nivec); + abort(); + } + x->exp_var[i].ex_vec = sp[nv]->s_vec; + nv++; + } + /* we always have one inlet but we may not use it */ + if (nv != x->exp_nivec && (nv != 0 || x->exp_nivec != 1)) { + post("expr_dsp internal error 2 nv = %d, x->exp_nive = %d", + nv, x->exp_nivec); + abort(); + } + + dsp_add(expr_perform, 1, (t_int *) x); + + if (!IS_FEXPR_TILDE(x)) + return; + if (x->exp_p_res) { + if (!newsize) + return; + /* + * if new size, reallocate all the previous buffers for fexpr~ + */ + fts_free(x->exp_p_res); + fts_free(x->exp_tmpres); + for (i = 0; i < MAX_VARS; i++) + fts_free(x->exp_p_var[i]); + + } + x->exp_p_res = fts_calloc(x->exp_vsize, sizeof (t_float)); + x->exp_tmpres = fts_calloc(x->exp_vsize, sizeof (t_float)); + for (i = 0; i < MAX_VARS; i++) + x->exp_p_var[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); +} + +/* + * expr_start -- turn on expr processing for now only used for fexpr~ + */ +static void +expr_start(t_expr *x) +{ + x->exp_flags &= ~EF_STOP; +} + +/* + * expr_stop -- turn on expr processing for now only used for fexpr~ + */ +static void +expr_stop(t_expr *x) +{ + x->exp_flags |= EF_STOP; +} + +#ifdef PD + +void +expr_setup(void) +{ + /* + * expr initialization + */ + expr_class = class_new(gensym("expr"), (t_newmethod)expr_new, + (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0); + class_addlist(expr_class, expr_list); + exprproxy_class = class_new(gensym("exprproxy"), 0, + 0, sizeof(t_exprproxy), CLASS_PD, 0); + class_addfloat(exprproxy_class, exprproxy_float); + + /* + * expr~ initialization + */ + expr_tilde_class = class_new(gensym("expr~"), (t_newmethod)expr_new, + (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0); + class_addmethod(expr_tilde_class, nullfn, gensym("signal"), 0); + CLASS_MAINSIGNALIN(expr_tilde_class, t_expr, exp_f); + class_addmethod(expr_tilde_class,(t_method)expr_dsp, gensym("dsp"), 0); + + /* + * fexpr~ initialization + */ + fexpr_tilde_class = class_new(gensym("fexpr~"), (t_newmethod)expr_new, + (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0); + class_addmethod(fexpr_tilde_class, nullfn, gensym("signal"), 0); + class_addmethod(fexpr_tilde_class,(t_method)expr_start, + gensym("start"), 0); + class_addmethod(fexpr_tilde_class,(t_method)expr_stop, + gensym("stop"), 0); + + class_addmethod(fexpr_tilde_class,(t_method)expr_dsp,gensym("dsp"), 0); + + post("expr, expr~, fexpr~ version %s under GNU General Public License ", exp_version); + +} + +void +expr_tilde_setup(void) +{ + expr_setup(); +} + +void +fexpr_tilde_setup(void) +{ + expr_setup(); +} +#else /* MSP */ +void +main(void) +{ + setup((t_messlist **)&expr_tilde_class, (method)Nexpr_new, + (method)expr_ff, (short)sizeof(t_expr), 0L, A_GIMME, 0); + addmess((method)expr_dsp, "dsp", A_CANT, 0); // dsp method + dsp_initclass(); +} +#endif + + +/* -- the following functions use Pd internals and so are in the "if" file. */ + + +int ex_getsym(char *p, fts_symbol_t *s) +{ + *s = gensym(p); + return (0); +} + +const char * +ex_symname(fts_symbol_t s) +{ + return (fts_symbol_name(s)); +} + +/* + * max_ex_tab -- evaluate this table access + * eptr is the name of the table and arg is the index we + * have to put the result in optr + * return 1 on error and 0 otherwise + * + * Arguments: + * the expr object + * table + * the argument + * the result pointer + */ +int +max_ex_tab(struct expr *exp,fts_symbol_t s,struct ex_ex *arg,struct ex_ex *optr) +{ +#ifdef PD + t_garray *garray; + int size, indx; + t_float *vec; + + if (!s || !(garray = (t_garray *)pd_findbyclass(s, garray_class)) || + !garray_getfloatarray(garray, &size, &vec)) + { + optr->ex_type = ET_FLT; + optr->ex_int = 0; + pd_error(exp, "no such table '%s'", s->s_name); + return (1); + } + optr->ex_type = ET_FLT; + + switch (arg->ex_type) { + case ET_INT: + indx = arg->ex_int; + break; + case ET_FLT: + /* strange interpolation code deleted here -msp */ + indx = arg->ex_flt; + break; + + default: /* do something with strings */ + pd_error(exp, "expr: bad argument for table '%s'\n", fts_symbol_name(s)); + indx = 0; + } + if (indx < 0) indx = 0; + else if (indx >= size) indx = size - 1; + optr->ex_flt = vec[indx]; +#else /* MSP */ + /* + * table lookup not done for MSP yet + */ + post("max_ex_tab: not complete for MSP yet!"); + optr->ex_type = ET_FLT; + optr->ex_flt = 0; +#endif + return (0); +} + +#ifdef PD /* this goes to the end of this file as the following functions + * should be defined in the expr object in MSP + */ +#define ISTABLE(sym, garray, size, vec) \ +if (!sym || !(garray = (t_garray *)pd_findbyclass(sym, garray_class)) || \ + !garray_getfloatarray(garray, &size, &vec)) { \ + optr->ex_type = ET_FLT; \ + optr->ex_int = 0; \ + error("no such table '%s'", sym->s_name); \ + return; \ +} + +/* + * ex_size -- find the size of a table + */ +void +ex_size(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + t_symbol *s; + t_garray *garray; + int size; + t_float *vec; + + if (argv->ex_type != ET_SYM) + { + post("expr: size: need a table name\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + return; + } + + s = (fts_symbol_t ) argv->ex_ptr; + + ISTABLE(s, garray, size, vec); + + optr->ex_type = ET_INT; + optr->ex_int = size; +} + +/* + * ex_sum -- calculate the sum of all elements of a table + */ + +void +ex_sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + t_symbol *s; + t_garray *garray; + int size; + t_float *vec, sum; + int indx; + + if (argv->ex_type != ET_SYM) + { + post("expr: sum: need a table name\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + return; + } + + s = (fts_symbol_t ) argv->ex_ptr; + + ISTABLE(s, garray, size, vec); + + for (indx = 0, sum = 0; indx < size; indx++) + sum += vec[indx]; + + optr->ex_type = ET_FLT; + optr->ex_flt = sum; +} + + +/* + * ex_Sum -- calculate the sum of table with the given boundries + */ + +void +ex_Sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + t_symbol *s; + t_garray *garray; + int size; + t_float *vec, sum; + int indx, n1, n2; + + if (argv->ex_type != ET_SYM) + { + post("expr: sum: need a table name\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + return; + } + + s = (fts_symbol_t ) argv->ex_ptr; + + ISTABLE(s, garray, size, vec); + + if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT) + { + post("expr: Sum: boundries have to be fix values\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + return; + } + n1 = argv->ex_int; + n2 = argv[1].ex_int; + + for (indx = n1, sum = 0; indx < n2; indx++) + if (indx >= 0 && indx < size) + sum += vec[indx]; + + optr->ex_type = ET_FLT; + optr->ex_flt = sum; +} + +/* + * ex_avg -- calculate the avarage of a table + */ + +void +ex_avg(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ +/* SDY - look into this function */ +#if 0 + fts_symbol_t s; + fts_integer_vector_t *tw = 0; + + if (argv->ex_type != ET_SYM) + { + post("expr: avg: need a table name\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + } + + s = (fts_symbol_t ) argv->ex_ptr; + + tw = table_integer_vector_get_by_name(s); + + if (tw) + { + optr->ex_type = ET_INT; + + if (! fts_integer_vector_get_size(tw)) + optr->ex_int = 0; + else + optr->ex_int = fts_integer_vector_get_sum(tw) / fts_integer_vector_get_size(tw); + } + else + { + optr->ex_type = ET_INT; + optr->ex_int = 0; + post("expr: avg: no such table %s\n", fts_symbol_name(s)); + } +#endif +} + + +/* + * ex_Avg -- calculate the avarage of table with the given boundries + */ + +void +ex_Avg(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ +/* SDY - look into this function */ +#if 0 + fts_symbol_t s; + fts_integer_vector_t *tw = 0; + + if (argv->ex_type != ET_SYM) + { + post("expr: Avg: need a table name\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + } + + s = (fts_symbol_t ) (argv++)->ex_ptr; + + tw = table_integer_vector_get_by_name(s); + + if (! tw) + { + optr->ex_type = ET_INT; + optr->ex_int = 0; + post("expr: Avg: no such table %s\n", fts_symbol_name(s)); + return; + } + + if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT) + { + post("expr: Avg: boundries have to be fix values\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + return; + } + + optr->ex_type = ET_INT; + + if (argv[1].ex_int - argv->ex_int <= 0) + optr->ex_int = 0; + else + optr->ex_int = (fts_integer_vector_get_sub_sum(tw, argv->ex_int, argv[1].ex_int) / + (argv[1].ex_int - argv->ex_int)); +#endif +} + +/* + * ex_store -- store a value in a table + * if the index is greater the size of the table, + * we will make a modulo the size of the table + */ + +void +ex_store(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ +/* SDY - look into this function */ +#if 0 + fts_symbol_t s; + fts_integer_vector_t *tw = 0; + + if (argv->ex_type != ET_SYM) + { + post("expr: store: need a table name\n"); + } + + s = (fts_symbol_t ) (argv++)->ex_ptr; + + tw = table_integer_vector_get_by_name(s); + + if (! tw) + { + optr->ex_type = ET_INT; + optr->ex_int = 0; + post("expr: store: no such table %s\n", fts_symbol_name(s)); + return; + } + + if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT) + { + post("expr: store: arguments have to be integer\n"); + optr->ex_type = ET_INT; + optr->ex_int = 0; + } + + fts_integer_vector_set_element(tw, argv->ex_int < 0 ? 0 : argv->ex_int % fts_integer_vector_get_size(tw), argv[1].ex_int); + *optr = argv[1]; +#endif +} + +#else /* MSP */ + +void +pd_error(void *object, char *fmt, ...) +{ + va_list ap; + t_int arg[8]; + int i; + static int saidit = 0; + va_start(ap, fmt); +/* SDY + vsprintf(error_string, fmt, ap); + */ post(fmt, ap); + va_end(ap); +/* SDY + fprintf(stderr, "error: %s\n", error_string); + error_object = object; +*/ + if (!saidit) + { + post("... you might be able to track this down from the Find menu."); + saidit = 1; + } +} +#endif -- cgit v1.2.1