diff options
author | Pablo Martín <caedesv@users.sourceforge.net> | 2003-09-07 21:45:05 +0000 |
---|---|---|
committer | Pablo Martín <caedesv@users.sourceforge.net> | 2003-09-07 21:45:05 +0000 |
commit | 213978fa8a868661dda88e6b4e7cacec1c90677a (patch) | |
tree | ada4aa53b2e25926c93bc1d4f2d19cbd018d1493 /modules/generic/pdp_forthproc.c | |
parent | 599a8e20c02fa48bab5102d15fab79dd6b631c95 (diff) |
Updating pdp to current version 0.12.2
svn path=/trunk/externals/pdp/; revision=941
Diffstat (limited to 'modules/generic/pdp_forthproc.c')
-rw-r--r-- | modules/generic/pdp_forthproc.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/modules/generic/pdp_forthproc.c b/modules/generic/pdp_forthproc.c new file mode 100644 index 0000000..011396f --- /dev/null +++ b/modules/generic/pdp_forthproc.c @@ -0,0 +1,244 @@ +/* + * Pure Data Packet module. + * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org> + * + * 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. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +/* + +example object definitions: + +; stack: (mix_float in_packet state_packet) + +(motion-blur + ((in 1) (feedback 0)) + ((out 0)) + (ip ip 0.0) + (dup down mix dup down down)) + + +; stack: (ouput_packet packet_type) + +(noise-gen + ((bang -1) (type 1)) + ((out 0)) + (image/YCrCb/320x240 ip) + (dup noise)) + +; constraints: +; if a processor accepts more than one atom message (float, list, pdp) +; of the same type they MUST be remapped to other inlets + +(pd-mappings + (motion-blur ((in 0) (feedback 1) (out 0))) + (noise ((out 0)))) + + +*/ + + +#include "pdp.h" +#include "pdp_forth.h" + +#define MAXINLETS 4 + +/* this object instantiates a forth processor */ + +typedef struct pdp_forthproc_struct +{ + t_object x_obj; + t_pdp_list *x_processor; // the processor definition + + + t_pdp_list *x_passive_stack; // we're still into thread processing + t_pdp_list *x_stack; + t_pdp_list *x_program; + +} t_pdp_forthproc; + + + +static int _check_portlist(t_pdp_list *l) +{ + t_pdp_atom *a; + post ("number of ports = %d", l->elements); + for (a = l->first; a; a=a->next){ + t_pdp_atom *b; + if (a->t != a_list) goto error; + if (a->w.w_list->elements != 2) goto error; + b = a->w.w_list->first; + if ((b->t != a_symbol) && (b->t != a_int)) goto error; + b = b->next; + if (b->t != a_int) goto error; + } + post ("port mappings:"); + for (a = l->first; a; a=a->next) pdp_list_print(a->w.w_list); + return 1; + error: + return 0; +} + +static int _check_processor(t_pdp_list *p) +{ + t_pdp_atom *a; + t_pdp_list *l; + + post ("list elements = %d", p->elements); + if (p->elements != 4) goto error; + for (a=p->first; a; a=a->next) if (a->t != a_list) goto error; + post ("all elements are lists: OK"); + + a = p->first; + post ("checking inlets"); + if (!_check_portlist(a->w.w_list)) goto error; + + a = a->next; + post ("checking outlets"); + if (!_check_portlist(a->w.w_list)) goto error; + + a = a->next; post ("init program:"); pdp_list_print(a->w.w_list); + a = a->next; post ("loop program:"); pdp_list_print(a->w.w_list); + + + return 1; + + error: + post("not a valid processor"); + return 0; +} + +/* this function maps an input symbol to a type (how to interpret the + anything message) and a stack index */ +static inline void pdp_forthproc_map_symbol(t_pdp_forthproc *x, t_symbol *s, + t_pdp_word_type *t, int *i) +{ +} + +/* this function stores a new item in an index on the stack + and executes the forth process if this is an active location */ +static inline void pdp_forthproc_write_stack(t_pdp_forthproc *x, int i, t_pdp_word w) +{ +} + +static void pdp_forthproc_anything(t_pdp_forthproc *x, t_symbol *s, int argc, t_atom *argv) +{ + /* if the symbol's length is one character, it's a remapped input. + this instance contains a mapping from symbol->(type, stack entry) */ + + t_pdp_word_type type = a_undef; + t_pdp_word word = (t_pdp_word)0; + int index = -1; + + /* determine what we got and where we need to put it */ + pdp_forthproc_map_symbol(x, s, &type, &index); + + /* interprete the anything message according to expected type. + and put the result in w */ + + /* TODO: put pd list <-> pdp list code in core (also in pdp_guile) */ + switch(type){ + case a_float: + case a_int: + case a_symbol: + case a_list: + case a_packet: + default: + post("got %s, and dunno what to do with it", s->s_name); + return; + + } + + /* write the word to the stack + and run the word if this was an active location */ + pdp_forthproc_write_stack(x, index, word); + +} + +static void pdp_forthproc_free(t_pdp_forthproc *x) +{ + pdp_tree_strip_packets(x->x_stack); + pdp_tree_free(x->x_stack); +} + +t_class *pdp_forthproc_class; + + +void *pdp_forthproc_new(t_symbol *s) +{ + t_pdp_forthproc *x; + + /* get processor */ + t_pdp_symbol *procname = pdp_gensym(s->s_name); + if (!procname->s_processor) return 0; + + /* allocate */ + x = (t_pdp_forthproc *)pd_new(pdp_forthproc_class); + x->x_processor = procname->s_processor; + post("pdp_forthproc %s", s->s_name); + pdp_list_print(x->x_processor); + + + if (_check_processor(x->x_processor)) post ("processor OK"); + + /* create state stack */ + x->x_stack = pdp_stack_new(); + x->x_passive_stack = pdp_stack_new(); + pdp_forth_execute_def(x->x_stack, x->x_processor->first->next->next->w.w_list); + pdp_forth_execute_def(x->x_passive_stack, x->x_processor->first->next->next->w.w_list); + post("initial stack:"); + pdp_list_print(x->x_stack); + + + /* create inlets from description */ + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_bang, gensym("A")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_bang, gensym("B")); + + + + return (void *)x; +} + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_forthproc_setup(void) +{ + int i; + char iname[] = "i1"; + char def[] = "(((0 1) (1 0)) ((0 0)) (ip ip 0.0) (dup down mix dup down down))"; + + /* create a test processor */ + pdp_gensym("testproc")->s_processor = pdp_forth_compile_def(def); + + /* create a standard pd class */ + pdp_forthproc_class = class_new(gensym("pdp_forthproc"), (t_newmethod)pdp_forthproc_new, + (t_method)pdp_forthproc_free, sizeof(t_pdp_forthproc), 0, A_SYMBOL, A_NULL); + + /* add global message handler */ + class_addanything(pdp_forthproc_class, (t_method)pdp_forthproc_anything); + +} + +#ifdef __cplusplus +} +#endif |