diff options
Diffstat (limited to 'puredata')
-rw-r--r-- | puredata/CONTENTS | 10 | ||||
-rw-r--r-- | puredata/Makefile | 12 | ||||
-rw-r--r-- | puredata/pdp_base.c | 415 | ||||
-rw-r--r-- | puredata/pdp_comm.c | 367 | ||||
-rw-r--r-- | puredata/pdp_compat.c | 57 | ||||
-rw-r--r-- | puredata/pdp_control.c | 186 | ||||
-rw-r--r-- | puredata/pdp_dpd_base.c | 270 | ||||
-rw-r--r-- | puredata/pdp_forthproc.c_bak | 807 | ||||
-rw-r--r-- | puredata/pdp_imagebase.c | 79 | ||||
-rw-r--r-- | puredata/pdp_queue.c | 386 | ||||
-rw-r--r-- | puredata/pdp_ut.c | 262 |
11 files changed, 0 insertions, 2851 deletions
diff --git a/puredata/CONTENTS b/puredata/CONTENTS deleted file mode 100644 index 19eeaaa..0000000 --- a/puredata/CONTENTS +++ /dev/null @@ -1,10 +0,0 @@ -base pdp base pd object -image_base image processing base pd object -dpd_base bucket base pd object -comm pdp communication protocol in pd -compat legacy pdp stuff -control control pdp from within pd -fp object interface to the forth system -forthconsole console interface to the forth system -queue processing queue and synchro stuff -ut some utility pd objects diff --git a/puredata/Makefile b/puredata/Makefile deleted file mode 100644 index 11c78ec..0000000 --- a/puredata/Makefile +++ /dev/null @@ -1,12 +0,0 @@ - -OBJECTS = pdp_base.o pdp_imagebase.o pdp_dpd_base.o pdp_ut.o pdp_queue.o pdp_comm.o \ - pdp_control.o pdp_compat.o $(PDP_PDMOD) - - -include ../Makefile.config - -all: $(OBJECTS) - -clean: - rm -f *~ - rm -f *.o diff --git a/puredata/pdp_base.c b/puredata/pdp_base.c deleted file mode 100644 index 194134e..0000000 --- a/puredata/pdp_base.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Pure Data Packet base class implementation. - * 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. - * - */ - - -/* - - This file contains the pdp base class object. - This is really nothing more than an attempt to stay away from c++ - as far as possible, while having some kind of base class functionality - for pdp (tucking away the communication & thread protocol). - -*/ - -#include "pdp_base.h" -#include <stdarg.h> - - -static void pdp_base_debug(t_pdp_base *b, t_floatarg f) -{ - int i; - post("debug"); - post("inlets: %d", b->b_inlets); - post("\tpacket\tnext_packet"); - for (i=0; i<b->b_inlets; i++) - post("\t%d\t%d", b->b_packet[i], b->b_packet_next[i]); - //post("outlets: %d", b->b_inlets); -} - -static void pdp_base_thread(t_pdp_base *b, t_floatarg f) -{ - int i = (int)f; - if ((i == 0) || (i == 1)) b->b_thread_enabled = i; -} - -static void pdp_base_process(t_pdp_base *b) -{ - - if (b->b_process_method) - (*b->b_process_method)(b); -} - -/* this method is called after the thread has finished processing */ -static void pdp_base_postprocess(t_pdp_base *b) -{ - /* call the derived class postproc callback if there is any */ - if (b->b_postproc_method) - (*b->b_postproc_method)(b); - - /* unregister (mark unused) packet and propagate if packet is valid */ - if (b->b_outlet[0]) - pdp_pass_if_valid(b->b_outlet[0], &b->b_packet[0]); -} - - -/* move the passive packets in place */ -void pdp_base_movepassive(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - int i; - - /* if a cold packet was received in the meantime - swap it in, else keep the old one */ - for (i=1; i<b->b_inlets; i++){ - pdp_replace_if_valid(&b->b_packet[i], &b->b_packet_next[i]); - } - - -} - -/* the standard bang method */ -void pdp_base_bang(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - int i; - - /* if pdp thread is still processing, do nothing */ - if (-1 != b->b_queue_id) return; - - /* move packets in place */ - pdp_base_movepassive(x); - - - /* if there is a preproc method defined, call it inside - the pd thread. (mainly for allocations) */ - if (b->b_preproc_method) - (*b->b_preproc_method)(b); - - /* check if we need to use pdp queue */ - if (b->b_thread_enabled){ - - /* add the process method and callback to the process queue */ - pdp_procqueue_add(b->b_q, b, pdp_base_process, pdp_base_postprocess, &b->b_queue_id); - } - else{ - /* call both methods directly */ - pdp_base_process(b); - pdp_base_postprocess(b); - } -} - -/* hot packet input handler */ -void pdp_base_input_hot(t_pdp_base *b, t_symbol *s, t_floatarg f) -{ - - int p = (int)f; - - /* dont register if active inlet is disabled */ - if (!b->b_active_inlet_enabled) return; - - /* register the packet (readonly or read/write) - or drop it if we have an active packet - if type template is not null, packet will be converted */ - - - if (b->b_active_inlet_readonly){ - if (s == S_REGISTER_RO){ - if (b->b_type_template[0]){ - pdp_packet_convert_ro_or_drop(&b->b_packet[0], p, b->b_type_template[0]); - } - else{ - pdp_packet_copy_ro_or_drop(&b->b_packet[0], p); - } - } - } - else{ - if (s == S_REGISTER_RW) { - if (b->b_type_template[0]){ - pdp_packet_convert_rw_or_drop(&b->b_packet[0], p, b->b_type_template[0]); - } - else{ - pdp_packet_copy_rw_or_drop(&b->b_packet[0], p); - } - } - } - - /* start processing if there is an active packet to process - and the processing method is not active */ - - if ((s == S_PROCESS) && (-1 != b->b_packet[0]) && (-1 == b->b_queue_id)){ - pdp_base_bang(b); - } - //if ((pdp_sym_prc() == s) && (-1 != b->b_packet[0]) && (!b->b_dropped)) pdp_base_bang(b); - -} - -/* cold packet input handlers */ -void pdp_base_input_cold(t_pdp_base *b, t_symbol *s, int ac, t_atom *av) -{ - - int p; - int i; - char msg[] = "pdp1"; - char *c; - - int inlet; - - //post("pdp_base_input_cold: got packet"); - - /* do cheap tests first */ - if (ac != 2) return; - if (av[0].a_type != A_SYMBOL) return; - if (av[0].a_w.w_symbol != S_REGISTER_RO) return; - if (av[1].a_type != A_FLOAT) return; - p = (int)av[1].a_w.w_float; - - - /* check if it's a pdp message - and determine inlet */ - for (i=1; i<MAX_NB_PDP_BASE_INLETS; i++){ - if (s == gensym(msg)){ - inlet = i; - goto found; - } - else{ - msg[3]++; - } - } - return; - - - found: - - /* store the packet and trow away - the old one, if there is any */ - - pdp_packet_copy_ro_or_drop(&b->b_packet_next[inlet], p); -} - - -void pdp_base_set_process_method(void *x, t_pdp_method m) -{ - t_pdp_base *b = (t_pdp_base *)x; - b->b_process_method = m; -} - -void pdp_base_set_preproc_method(void *x, t_pdp_method m) -{ - t_pdp_base *b = (t_pdp_base *)x; - b->b_preproc_method = m; -} - - -void pdp_base_set_postproc_method(void *x, t_pdp_method m) -{ - t_pdp_base *b = (t_pdp_base *)x; - b->b_postproc_method = m; -} - - -void pdp_base_queue_wait(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - pdp_procqueue_wait(b->b_q); -} - -void pdp_base_set_queue(void *x, t_pdp_procqueue *q) -{ - t_pdp_base *b = (t_pdp_base *)x; - pdp_base_queue_wait(x); - b->b_q = q; -} - -t_pdp_procqueue *pdp_base_get_queue(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - return b->b_q; -} - -void pdp_base_setup(t_class *c) -{ - - /* add pdp base class methods */ - class_addmethod(c, (t_method)pdp_base_thread, gensym("thread"), A_FLOAT, A_NULL); - class_addmethod(c, (t_method)pdp_base_debug, gensym("debug"), A_NULL); - - /* hot packet handler */ - class_addmethod(c, (t_method)pdp_base_input_hot, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); - - /* cold packet handler */ - class_addanything(c, (t_method)pdp_base_input_cold); -} - -/* pdp base instance constructor */ -void pdp_base_init(void *x) -{ - int i; - t_pdp_base *b = (t_pdp_base *)x; - - b->b_channel_mask = -1; - - for(i=0; i<MAX_NB_PDP_BASE_INLETS; i++){ - b->b_packet[i] = -1; - b->b_packet_next[i] = -1; - b->b_type_template[i] = 0; - } - - b->b_queue_id = -1; - //b->b_dropped = 0; - b->b_process_method = 0; - b->b_preproc_method = 0; - b->b_inlets = 1; - b->b_outlets = 0; - b->b_active_inlet_enabled = 1; - b->b_active_inlet_readonly = 0; - b->b_thread_enabled = 1; - - // default queue is pdp queue - b->b_q = pdp_queue_get_queue(); - -} - -/* base instance destructor */ -void pdp_base_free(void *x) -{ - int i; - t_pdp_base *b = (t_pdp_base *)x; - /* remove process method from queue before deleting data */ - pdp_procqueue_finish(b->b_q, b->b_queue_id); - - /* delete stuff */ - for(i=0; i<MAX_NB_PDP_BASE_INLETS; i++){ - pdp_packet_mark_unused(b->b_packet[i]); - pdp_packet_mark_unused(b->b_packet_next[i]); - } - -} - -void pdp_base_readonly_active_inlet(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - b->b_active_inlet_readonly = 1; -} - -void pdp_base_disable_active_inlet(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - b->b_active_inlet_enabled = 0; -} - - -/* add an inlet */ -void pdp_base_add_pdp_inlet(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - char s[] = "pdp0"; - s[3] += b->b_inlets; - - if (b->b_inlets < MAX_NB_PDP_BASE_INLETS){ - inlet_new(&b->x_obj, &b->x_obj.ob_pd, gensym("pdp"), gensym(s)); - b->b_inlets++; - } - else { - post("pdp_base_add_pdp_inlet: only %d pdp inlets allowed. ignoring.", MAX_NB_PDP_BASE_INLETS); - } -} - - -/* add an outlet: only one allowed */ -t_outlet *pdp_base_add_pdp_outlet(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - t_outlet *outlet = outlet_new(&b->x_obj, &s_anything); - - - if (b->b_outlets < MAX_NB_PDP_BASE_OUTLETS){ - b->b_outlet[b->b_outlets] = outlet; - b->b_outlets++; - } - - return outlet; - -} - -void pdp_base_set_packet(void *x, int inlet, int packet) -{ - t_pdp_base *b = (t_pdp_base *)x; - - if (inlet < b->b_inlets){ - //post("%d %d", b->b_packet[inlet], b->b_packet_next[inlet]); - pdp_packet_mark_unused(b->b_packet[inlet]); - b->b_packet[inlet] = packet; - } -} - - -int pdp_base_get_packet(void *x, int inlet) -{ - t_pdp_base *b = (t_pdp_base *)x; - - if (inlet < b->b_inlets){ - //post("%d %d", b->b_packet[inlet], b->b_packet_next[inlet]); - return (b->b_packet[inlet]); - } - - return -1; -} - -int pdp_base_move_packet(void *x, int inlet) -{ - t_pdp_base *b = (t_pdp_base *)x; - int p; - - if (inlet < b->b_inlets){ - p = b->b_packet[inlet]; - b->b_packet[inlet] = -1; - return (p); - } - - return -1; -} - - - -t_object *pdp_base_get_object(void *x) -{ - return (t_object *)x; -} - -void pdp_base_add_gen_inlet(void *x, t_symbol *from, t_symbol *to) -{ - t_object *o = (t_object *)x; - inlet_new(o, &o->ob_pd, from, to); -} - -void pdp_base_disable_thread(void *x) -{ - - t_pdp_base *b = (t_pdp_base *)x; - b->b_thread_enabled = 0; -} - -void pdp_base_set_type_template(void *x, int inlet, t_pdp_symbol *type_template) -{ - t_pdp_base *b = (t_pdp_base *)x; - if (inlet < b->b_inlets){ - b->b_type_template[inlet] = type_template; - } -} diff --git a/puredata/pdp_comm.c b/puredata/pdp_comm.c deleted file mode 100644 index 4c67659..0000000 --- a/puredata/pdp_comm.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Pure Data Packet system implementation. - * 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. - * - */ - -/* this file contains misc communication (packet) methods for pd */ - - -#include <stdio.h> -#include "pdp_pd.h" -#include "pdp_internals.h" -#include "pdp_packet.h" -#include "pdp_comm.h" -#include "pdp_type.h" -#include "pdp_control.h" -#include "pdp_mem.h" -#include "pdp_queue.h" // for notify drop: fix this (should be from pdp_control.h) -#include "pdp_debug.h" - -/* all symbols are C style */ -#ifdef __cplusplus -extern "C" -{ -#endif - - -/* interface to pd system: - pdp/dpd communication protocol in pd - pd <-> pdp atom and list conversion */ - - /* NOTE: when using the outlet_pdp methods, the packet - is no longer read/write, but can be readonly */ - - - /* NOTE: since 0.13 the passing packet is no more. - in order to limit copying. processors should always register ro, - and replace with writable when packet needs to be written in the process method */ - - -/* send a packet to an outlet */ -void outlet_pdp_register(t_outlet *out, int packetid) -{ - t_atom atom[2]; - - SETFLOAT(atom+1, (float)packetid); - - /* during the following phase, - objects can register a ro copy */ - - SETSYMBOL(atom+0, S_REGISTER_RO); - outlet_anything(out, S_PDP, 2, atom); - - /* DEPRECIATED: objects can register a rw copy - but this will always copy the packet. it is better - to perform a pdp_packet_replace_with_writable operation during the process step */ - - SETSYMBOL(atom+0, S_REGISTER_RW); - outlet_anything(out, S_PDP, 2, atom); - -} -/* send a packet to an outlet */ -void outlet_pdp_process(t_outlet *out) -{ - t_atom atom[2]; - - /* set a dummy invalid packet. - this is for uniform pdp messages in pd, for ease of routing. */ - SETFLOAT(atom+1, (float)-1); - - /* during the process phase, objects can perform pdp_packet_replace_with_writable - and process the packet data */ - SETSYMBOL(atom+0, S_PROCESS); - outlet_anything(out, S_PDP, 2, atom); - -} - -/* for compat */ -void outlet_pdp(t_outlet *out, int packetid) -{ - outlet_pdp_register(out, packetid); - outlet_pdp_process(out); -} - -/* send an accumulation packet to an outlet */ -void outlet_dpd(t_outlet *out, int packetid) -{ - t_atom atom[2]; - - SETFLOAT(atom+1, (float)packetid); - - SETSYMBOL(atom+0, S_INSPECT); - outlet_anything(out, S_DPD, 2, atom); - - SETSYMBOL(atom+0, S_ACCUMULATE); - outlet_anything(out, S_DPD, 2, atom); - -} - -/* unregister a packet and send it to an outlet */ -void - -pdp_packet_pass_if_valid(t_outlet *outlet, int *packet_ptr) -{ - t_pdp *header = pdp_packet_header(*packet_ptr); - if (header){ - - /* send register phase */ - outlet_pdp_register(outlet, *packet_ptr); - - /* unregister */ - pdp_packet_mark_unused(*packet_ptr); - *packet_ptr = -1; - - /* send process phase */ - outlet_pdp_process(outlet); - - } -} - -void -pdp_packet_replace_if_valid(int *dpacket, int *spacket) -{ - if (-1 != *spacket){ - pdp_packet_mark_unused(*dpacket); - *dpacket = *spacket; - *spacket = -1; - } - -} - - -int -pdp_packet_copy_ro_or_drop(int *dpacket, int spacket) -{ - int drop = 0; - if (*dpacket == -1) *dpacket = pdp_packet_copy_ro(spacket); - else { - /* send a notification there is a dropped packet */ - pdp_control_notify_drop(spacket); - drop = 1; - } - return drop; -} - - -int -pdp_packet_copy_rw_or_drop(int *dpacket, int spacket) -{ - int drop = 0; - if (*dpacket == -1) *dpacket = pdp_packet_copy_rw(spacket); - else { - /* send a notification there is a dropped packet */ - pdp_control_notify_drop(spacket); - drop = 1; - } - return drop; -} - -int -pdp_packet_convert_ro_or_drop(int *dpacket, int spacket, t_pdp_symbol *template) -{ - int drop = 0; - - if (!template) return pdp_packet_copy_ro_or_drop(dpacket, spacket); - - if (*dpacket == -1) *dpacket = pdp_packet_convert_ro(spacket, template); - else { - /* send a notification there is a dropped packet */ - pdp_control_notify_drop(spacket); - drop = 1; - } - return drop; -} - - -int -pdp_packet_convert_rw_or_drop(int *dpacket, int spacket, t_pdp_symbol *template) -{ - int drop = 0; - - if (!template) return pdp_packet_copy_rw_or_drop(dpacket, spacket); - - if (*dpacket == -1) *dpacket = pdp_packet_convert_rw(spacket, template); - else { - /* send a notification there is a dropped packet */ - pdp_control_notify_drop(spacket); - drop = 1; - } - return drop; -} - - -/* send a pdp list to a pd outlet. packets are not copied but passed! */ -void outlet_pdp_atom(t_outlet *out, t_pdp_atom *a) -{ - int packet = -1; - if (!a) return; - switch(a->t){ - case a_float: - outlet_float(out, a->w.w_float); - return; - case a_int: - outlet_float(out, (float)a->w.w_int); - return; - case a_symbol: - outlet_symbol(out, gensym(a->w.w_symbol->s_name)); - return; - case a_list: - outlet_pdp_list(out, a->w.w_list); - return; - case a_packet: - pdp_packet_pass_if_valid(out, &a->w.w_packet); - return; - default: - return; - } -} - -void outlet_pdp_list(t_outlet *out, struct _pdp_list *l) -{ - int elements; - t_atom *atomlist; - t_pdp_atom *pdp_a; - t_atom *pd_a; - t_symbol *pd_selector; - - if (!l) return; - switch(l->elements){ - case 0: /* bang */ - outlet_bang(out); - return; - case 1: /* atom */ - outlet_pdp_atom(out, l->first); - return; - default: /* proper list*/ - elements = l->elements; - - /* allocate list */ - atomlist = pdp_alloc(sizeof (t_atom) * l->elements); - pd_a = atomlist; - pdp_a = l->first; - - /* setup selector */ - if (pdp_a->t != a_symbol){ - pd_selector = gensym("list"); - } - else { - pd_selector = gensym(pdp_a->w.w_symbol->s_name); - elements--; - pdp_a = pdp_a->next; - } - - /* setup atoms */ - while (pdp_a){ - switch(pdp_a->t){ - case a_float: - SETFLOAT(pd_a, pdp_a->w.w_float); - break; - case a_int: - SETFLOAT(pd_a, (float)pdp_a->w.w_int); - break; - case a_symbol: - SETSYMBOL(pd_a, gensym(pdp_a->w.w_symbol->s_name)); - break; - default: - SETSYMBOL(pd_a, gensym("invalid")); - break; - } - - pdp_a = pdp_a->next; - pd_a++; - } - - /* send out */ - outlet_anything(out, pd_selector, elements, atomlist); - - - - /* clean up */ - pdp_dealloc(atomlist); - - } - - -} - - -void pd_atom_to_pdp_atom(t_atom *pdatom, t_pdp_atom *pdpatom) -{ - switch (pdatom->a_type){ - case A_FLOAT: - pdpatom->t = a_float; - pdpatom->w.w_float = pdatom->a_w.w_float; - break; - case A_SYMBOL: - pdpatom->t = a_symbol; - pdpatom->w.w_symbol = pdp_gensym(pdatom->a_w.w_symbol->s_name); - break; - default: - pdpatom->t = a_undef; - break; - } -} - - - -/* some "accelerated" pd symbols */ -t_symbol s_pdp = {"pdp", 0, 0}; -t_symbol s_register_ro = {"register_ro", 0, 0}; -t_symbol s_register_rw = {"register_rw", 0, 0}; -t_symbol s_process = {"process", 0, 0}; -t_symbol s_dpd = {"dpd", 0, 0}; -t_symbol s_inspect = {"inspect", 0, 0}; -t_symbol s_accumulate = {"accumulate", 0, 0}; -t_symbol s_chanmask = {"chanmask", 0, 0}; - -// internal pd method -t_symbol *dogensym(char *s, t_symbol *oldsym); -static void _addsym(t_symbol *s) -{ - - /* don't kill me for this one.. - if the symbol is already defined and used, .. well, that's a problem - but right now it seems a reasonable hack */ - - t_symbol *sret = dogensym(s->s_name, s); - if (s != sret){ - post("PDP INIT ERROR: pd symbol clash adding symbol %s: new=%08x old=%08x", s->s_name, s, sret); - post("try loading pdp before other libraries"); - } -} - -void -pdp_pdsym_setup(void) -{ - - _addsym(&s_pdp); - _addsym(&s_register_ro); - _addsym(&s_register_rw); - _addsym(&s_process); - _addsym(&s_dpd); - _addsym(&s_inspect); - _addsym(&s_accumulate); - _addsym(&s_chanmask); - -} - - - -#ifdef __cplusplus -} -#endif diff --git a/puredata/pdp_compat.c b/puredata/pdp_compat.c deleted file mode 100644 index e7bc0c2..0000000 --- a/puredata/pdp_compat.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Pure Data Packet system implementation. Compatibility routines. - * 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. - * - */ - -/* this file contains misc communication methods */ - -#include <stdio.h> - -#include "pdp_pd.h" -#include "pdp_comm.h" -#include "pdp_internals.h" - -/* all symbols are C style */ -#ifdef __cplusplus -extern "C" -{ -#endif - - - -void -pdp_pass_if_valid(t_outlet *outlet, int *packet) -{ - pdp_packet_pass_if_valid(outlet, packet); -} - -void -pdp_replace_if_valid(int *dpacket, int *spacket) -{ - pdp_packet_replace_if_valid(dpacket, spacket); - -} - - - - - - -#ifdef __cplusplus -} -#endif diff --git a/puredata/pdp_control.c b/puredata/pdp_control.c deleted file mode 100644 index 0b49fd9..0000000 --- a/puredata/pdp_control.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Pure Data Packet system implementation: control object - * 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. - * - */ - - -/* this is an actual pd class that is used for communication with the - pdp framework */ - -#include "pdp_internals.h" -#include "pdp_control.h" -#include "pdp_packet.h" -#include <stdio.h> - -/* all symbols are C style */ -#ifdef __cplusplus -extern "C" -{ -#endif - - - -static long dropped_packets; - -static t_class* pdp_control_class; - - -/* pdp control instance data */ - -struct _pdp_control; -typedef struct _pdp_control -{ - t_object x_obj; - t_outlet *x_outlet0; - struct _pdp_control *x_next; - -} t_pdp_control; - - - -static t_pdp_control *pdp_control_list; - -static void pdp_control_info(t_pdp_control *x) -{ -} - -static void pdp_control_collectgarbage(t_pdp_control *x) -{ - int nb_packets_freed = pdp_pool_collect_garbage(); - post("pdp_control: freed %d packets", nb_packets_freed); - -} - -static void pdp_control_set_mem_limit(t_pdp_control *x, t_floatarg f) -{ - int limit = (int)f; - if (limit < 0) limit = 0; - pdp_pool_set_max_mem_usage(limit); - if (limit) post("pdp_control: set memory limit to %d bytes", limit); - else post("pdp_control: disabled memory limit"); - -} - -static void pdp_control_thread(t_pdp_control *x, t_floatarg f) -{ - int t = (int)f; - - if (t){ - post("pdp_control: pdp is now using its own processing thread"); - pdp_queue_use_thread(1); - } - else { - post("pdp_control: pdp is now using the main pd thread"); - pdp_queue_use_thread(0); - } -} - - -static void pdp_control_send_drop_message(t_pdp_control *x) -{ - t_atom atom[1]; - t_symbol *s = gensym("pdp_drop"); - - SETFLOAT(atom+0, (float)dropped_packets); - outlet_anything(x->x_outlet0, s, 1, atom); -} - - -static void pdp_control_free(t_pdp_control *x) -{ - /* remove from linked list */ - t_pdp_control *curr = pdp_control_list; - if (pdp_control_list == x) pdp_control_list = x->x_next; - else while (curr){ - if (curr->x_next == x) { - curr->x_next = x->x_next; - break; - } - else { - curr = curr->x_next; - } - - } -} - - -static void *pdp_control_new(void) -{ - t_pdp_control *x = (t_pdp_control *)pd_new(pdp_control_class); - x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); - - /* add to list */ - x->x_next = pdp_control_list; - pdp_control_list = x; - return x; -} - -/************************* class methods ***************************************/ - - -void pdp_control_addmethod(t_method m, t_symbol *s) -{ - class_addmethod(pdp_control_class, m, s, A_GIMME, A_NULL); -} - -void pdp_control_setup(void) -{ - - pdp_control_list = 0; - dropped_packets = 0; - - /* setup pd class data */ - pdp_control_class = class_new(gensym("pdp_control"), (t_newmethod)pdp_control_new, - (t_method)pdp_control_free, sizeof(t_pdp_control), 0, A_NULL); - - - class_addmethod(pdp_control_class, (t_method)pdp_control_info, gensym("info"), A_NULL); - class_addmethod(pdp_control_class, (t_method)pdp_control_thread, gensym("thread"), A_DEFFLOAT, A_NULL); - class_addmethod(pdp_control_class, (t_method)pdp_control_collectgarbage, gensym("collectgarbage"), A_NULL); - class_addmethod(pdp_control_class, (t_method)pdp_control_set_mem_limit, gensym("memlimit"), A_FLOAT, A_NULL); -} - - - -void pdp_control_notify_broadcast(t_pdp_control_method_notify *notify) -{ - t_pdp_control *curr = pdp_control_list; - while (curr){ - (*notify)(curr); - curr = curr->x_next; - } -} - - - -/************************* notify class methods *************************/ - -void pdp_control_notify_drop(int packet) -{ - dropped_packets++; - - /* send drop notify to controller class instances */ - pdp_control_notify_broadcast(pdp_control_send_drop_message); - //post("dropped packet"); -} - - - -#ifdef __cplusplus -} -#endif diff --git a/puredata/pdp_dpd_base.c b/puredata/pdp_dpd_base.c deleted file mode 100644 index 371b99e..0000000 --- a/puredata/pdp_dpd_base.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Pure Data Packet module. DPD base class implementation. - * 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. - * - */ - - -#include "pdp_dpd_base.h" -#include "pdp_internals.h" - - -#define THIS(b) t_pdp_dpd_base *b = (t_pdp_dpd_base *)x - - -#ifdef __cplusplus -extern "C" -{ -#endif - - - -/* PRIVATE METHODS */ - - - - -/* dpd packet context input handler */ -static void _pdp_dpd_base_context_input(t_pdp_dpd_base *b, t_symbol *s, t_floatarg f) -{ - - int p = (int)f; - int i; - - //post ("pdp_dpd_base_context_input: got %s %d", s->s_name, p); - - /* sources/sinks have active inlet disabled */ - if (b->b_dpd_active_inlet_disabled) return; - - /* handle inspect message */ - if (s == S_INSPECT){ - - /* store packet for inspector */ - b->b_context_packet = p; - - /* add inspector to pdp queue - this is special: it doesn't use a command object */ - pdp_dpd_base_queue_command(b, b, b->b_inspector_method, b->b_inspector_callback, 0); - } - - /* handle accumulate message */ - if (s == S_ACCUMULATE){ - - /* store context for accumulator methods */ - b->b_context_packet = p; - - /* call bang */ - pdp_dpd_base_bang(b); - - - } - -} - -/* default command object (returns self) */ -void *_pdp_dpd_base_get_command_object(void *x){return x;} - -/* PUBLIC METHODS */ - - -void pdp_dpd_base_queue_command(void *x, void *c, t_pdp_method process, - t_pdp_method callback, int *id) -{ - THIS(b); - t_pdp_procqueue *q = pdp_base_get_queue(x); - pdp_procqueue_add(q, c, process, callback, id); - -} - -/* bang method (propagate context to outlet) : it is not registered as a pd message by default ! */ -void pdp_dpd_base_bang(void *x) -{ - THIS(b); - int i, id; - void *cobj; - - /* move passive pdp packets in place */ - pdp_base_movepassive(x); - - /* get command object (or use self) */ - cobj = b->b_command_factory_method ? (b->b_command_factory_method)(b) : b; - //post(" command object is %x. object is %x", cobj, b); - - - /* queue acc method & propagate for all outlets */ - for (i=b->b_nb_context_outlets; i--;){ - - - /* propagate the context packet to the outlet */ - if (b->b_outlet_enable[i]){ - pdp_dpd_base_queue_command(x, cobj, b->b_accum_method[i], b->b_accum_callback[i], 0); - outlet_dpd(b->b_context_outlet[i], b->b_context_packet); - } - else{ - //post("outlet %d disabled", i); - } - } - - /* queue cleanup method */ - if (b->b_cleanup_method) - //pdp_procqueue_add(b->b_q, b, b->b_cleanup_method, 0, &b->b_cleanup_queue_id); - pdp_dpd_base_queue_command(x, cobj, b->b_cleanup_method, b->b_cleanup_callback, 0); - - /* send communication complete notify */ - if (b->b_complete_notify) - (b->b_complete_notify)(x); - -} - -/* get/set context packet */ -int pdp_dpd_base_get_context_packet(void *x){ - THIS(b); - return b->b_context_packet; -} -int pdp_dpd_base_move_context_packet(void *x){ - THIS(b); - int p = b->b_context_packet; - b->b_context_packet = -1; - return p; -} - -void pdp_dpd_base_set_context_packet(void *x, int p){ - THIS(b); - pdp_packet_mark_unused(b->b_context_packet); - b->b_context_packet = p; -} - -/* add a cleanup callback (called after all propagation is finished) for sources/sinks */ -void pdp_dpd_base_add_cleanup(void *x, t_pdp_method cleanup_method, t_pdp_method cleanup_callback) -{ - THIS(b); - b->b_cleanup_method = cleanup_method; - b->b_cleanup_callback = cleanup_callback; - //b->b_cleanup_queue_id = -1; -} - -/* add a inspector callback */ -void pdp_dpd_base_add_inspector(void *x, t_pdp_method inspector_method) -{ - THIS(b); - b->b_inspector_method = inspector_method; - //b->b_inspector_queue_id = -1; -} - -/* add a context outlet */ -t_outlet *pdp_dpd_base_add_outlet(void *x, t_pdp_method accum_method, t_pdp_method accum_callback) -{ - THIS(b); - int i = b->b_nb_context_outlets; - if (i < PDP_DPD_MAX_CONTEXT_OUTLETS){ - b->b_context_outlet[i] = outlet_new((t_object *)b, &s_anything); - b->b_outlet_enable[i] = 1; - b->b_accum_method[i] = accum_method; - b->b_accum_callback[i] = accum_callback; - //b->b_accum_queue_id[i] = -1; - b->b_nb_context_outlets++; - return b->b_context_outlet[i]; - } - else{ - post("pdp_dpd_base_add_outlet: no more free outlet slots"); - return 0; - } - -} - - -/* destructor */ -void pdp_dpd_base_free(void *x) -{ - THIS(b); - - /* free base */ - pdp_base_free(b); -} - - -void pdp_dpd_base_disable_active_inlet(void *x) -{ - THIS(b); - b->b_dpd_active_inlet_disabled = 1; -} - - - -void pdp_dpd_base_enable_outlet(void *x, int outlet, int toggle) -{ - THIS(b); - if (outlet >=0 && outlet < PDP_DPD_MAX_CONTEXT_OUTLETS){ - b->b_outlet_enable[outlet] = toggle; - } - -} - - -void pdp_dpd_base_register_complete_notify(void *x, t_pdp_method method) -{ - THIS(b); - b->b_complete_notify = method; -} - -void pdp_dpd_base_register_command_factory_method(void *x, t_pdp_newmethod command_factory_method) -{ - THIS(b); - b->b_command_factory_method = command_factory_method; -} - - -/* init method */ -void pdp_dpd_base_init(void *x) -{ - THIS(b); - - /* super init */ - pdp_base_init(b); - - /* disable pdp messages on active inlet (dpd messages are used as sync) */ - pdp_base_disable_active_inlet(b); - - /* init data */ - b->b_nb_context_outlets = 0; - b->b_context_packet = -1; - b->b_cleanup_method = 0; - //b->b_cleanup_queue_id = -1; - b->b_inspector_method = 0; - //b->b_inspector_queue_id = -1; - b->b_dpd_active_inlet_disabled = 0; - - // default notify == none - b->b_complete_notify = 0; - - // default command object getter - b->b_command_factory_method = 0; - -} - - -void pdp_dpd_base_setup(t_class *class) -{ - - pdp_base_setup(class); - class_addmethod(class, (t_method)_pdp_dpd_base_context_input, gensym("dpd"), A_SYMBOL, A_FLOAT, A_NULL); - -} - -#ifdef __cplusplus -} -#endif diff --git a/puredata/pdp_forthproc.c_bak b/puredata/pdp_forthproc.c_bak deleted file mode 100644 index e6517d5..0000000 --- a/puredata/pdp_forthproc.c_bak +++ /dev/null @@ -1,807 +0,0 @@ -/* - * 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. - * - */ - -/* TODO: ADD THREAD SUPPORT */ - -/* - -this is the pd interface to forth processes / processors. -in time, it should become the only interface between the processing -functionality in pdp, and pd objects representing this functionality - -example object definitions: - -a forth process is a virtual machine operating on a private -rotation stack, as found in hp rpn calcs (this is the machine state vector) -the tick operation leaves the stack size and relative position of -the elements invariant - -this is a very crude and simple framework. it is an experiment to -see how far this forth thing can be pushed to solve the problem -of dataflow processing in a simple way, by cutting out the fat. -yes, chuck moore's ideas are viral.. - -a forth process has a setup code that will construct an initial stack template - -an object definition is a list of -- list of symbolic input to stack location mappings (first = active) -- list of symbolic output to stack location mappings -- stack template init code (bootblock) -- process code - -the stack is the machine memory - -the mapping between pdp's forth processors and pd object -is handled by pdmaps. these can probably be reused to build other -object oriented interfaces to the forth processors - -*/ - - -/* pdp forthprocs support thread processing. - - there is only one stack, which - serves as the machine state and input/output storage. - - when processing in thread, the input/output event - queue is used, when processing directly pd events - are inserted into the stack directly and the queues - are bypassed - -*/ - - -#include <pthread.h> -#include "pdp_pd.h" -#include "pdp_comm.h" -#include "pdp_packet.h" -#include "pdp_mem.h" -#include "pdp_forth.h" -#include "pdp_pdmap.h" -#include "pdp_queue.h" -#include "pdp_debug.h" - - - -/* this object instantiates a forth processor */ - -typedef struct forthproc_struct -{ - t_object x_obj; - t_pdp_list *x_processor; // the processor definition - t_pdp_list *x_pdmap; // the pd port mappings - t_pdp_list *x_program; // the forth program - - - t_pdp_list *x_stack; // the state stack - t_pdp_list *x_stack_template; // a "fake" stack serving as a type template - - t_pdp_list *x_input_events; // current input event list - - t_pdp_list *x_queue_input; // queue of input event lists, event = (atom index, word) - t_pdp_list *x_queue_output; // queue of output event lists, event = (outlet ptr, word) - - t_pdp_procqueue *x_q; // process queue - - - pthread_mutex_t x_mut; // queue mutex - - int x_nb_outlets; // number of pd outlets - t_outlet **x_outlet; - - int x_thread; // use thread processing or not - - t_symbol *x_protocol; // protocol used (pdp or dpd) - - /* pdp image legacy */ - int x_chanmask; - - /* dpd */ - int x_dpd_packet; - t_outlet *x_dpd_outlet; - -} t_forthproc; - - -static inline void lock(t_forthproc *x){pthread_mutex_lock(&x->x_mut);} -static inline void unlock(t_forthproc *x){pthread_mutex_unlock(&x->x_mut);} - - -/* send an atom to an outlet */ -static void send_pdp_atom_to_outlet(t_outlet *out, t_pdp_atom *a) -{ - outlet_pdp_atom(out, a); -} - -/* output stack contents to outlet or output event list */ -static void output_from_stack(t_forthproc *x) -{ - t_pdp_list *outsym = pdp_forth_pdmap_outlist(x->x_pdmap); - - /* create an event list if we're in thread mode */ - t_pdp_list *eventlist = x->x_thread ? pdp_list_new(0) : 0; - - static void _do_outlet(int index, t_pdp_atom *pname, t_pdp_list *eventlist){ - t_outlet *out = x->x_outlet[index]; - t_pdp_atom *a = pdp_forth_processor_stackatom_from_outputname( - x->x_processor, x->x_stack, pname->w.w_symbol); - - PDP_ASSERT(a); - - /* bang in reverse order by using head recursion */ - if (pname->next) _do_outlet(index+1, pname->next, eventlist); - - /* send the atom to the outlet if no event list */ - if (!eventlist){ - send_pdp_atom_to_outlet(out, a); - } - /* or add it to the event list */ - else { - t_pdp_list *ev = pdp_list_new(2); - pdp_list_set_0(ev, a_pointer, - (t_pdp_word)(void*)out); // store outlet ptr - pdp_list_set_1(ev, a->t, a->w); // store atom - pdp_list_add_back(eventlist, a_list, - (t_pdp_word)ev); // store event in list - - /* if it was a packet, clear the stacks reference */ - if (a->t == a_packet) a->w.w_packet = -1; - } - - } - - _do_outlet(0, outsym->first, eventlist); - - /* add eventlist to output event queue */ - if (eventlist){ - - lock(x); - pdp_list_add_back(x->x_queue_output, a_list, - (t_pdp_word)eventlist); - unlock(x); - } -} - -/* legacy hack: setup channel mask for image processing */ -static void setup_chanmask(t_forthproc *x) -{ - if (x->x_chanmask != -1){ - t_pdp_symbol *pname = pdp_forth_pdmap_get_pname(x->x_pdmap, pdp_gensym("pdp")); - t_pdp_atom *a = pdp_forth_processor_stackatom_from_inputname(x->x_processor, x->x_stack, pname); - int *packet; - if (a && a->t == a_packet){ - packet = &a->w.w_packet; - pdp_packet_replace_with_writable(packet); // make sure it's a private copy - pdp_packet_image_set_chanmask(*packet, x->x_chanmask); - //post("chanmask set to %d", x->x_chanmask); - } - } -} - -static void exec_program(t_forthproc *x) -{ - int error; - setup_chanmask(x); - if (e_ok != (error = pdp_forth_execute_def(x->x_stack, x->x_program))){ - post("error %d (%s) executing forth processor", - error, pdp_forth_word_error(error)); - post("PROGRAM:"); - pdp_list_print(x->x_program); - post("STACK:"); - pdp_list_print(x->x_stack); - post(""); - - /* delete stack and create a new one */ - pdp_tree_strip_packets(x->x_stack); - pdp_tree_free(x->x_stack); - x->x_stack = pdp_forth_processor_setup_stack(x->x_processor); - - - } - - -} - - -static void thread_exec(t_forthproc *x) -{ - t_pdp_list *event_list; - t_pdp_atom *a; - - /* get input event list from input event queue */ - PDP_ASSERT(x->x_queue_input->elements); - lock(x); - event_list = pdp_list_pop(x->x_queue_input).w_list; - unlock(x); - - /* add input events to state stack */ - for (a=event_list->first; a; a=a->next){ - int index = a->w.w_list->first->w.w_int; - t_pdp_atom *src = a->w.w_list->first->next; - - t_pdp_atom *dest = x->x_stack->first; - while (index--) dest = dest->next; - - PDP_ASSERT(dest->t == src->t); - - switch(src->t){ - - /* copy pure atoms */ - case a_float: - case a_int: - case a_symbol: - dest->w = src->w; - break; - - /* move reference atoms */ - case a_packet: - pdp_packet_mark_unused(dest->w.w_packet); - dest->w = src->w; - src->w.w_packet = -1; - break; - - /* ignored */ - case a_pointer: - case a_list: - default: - break; - } - } - - - - /* free event list */ - pdp_tree_free(event_list); - - /* run the process */ - exec_program(x); - - /* send output events to output event queue */ - output_from_stack(x); - -} - -static void thread_output(t_forthproc *x) -{ - t_pdp_list *event_list; - t_pdp_atom *a; - - /* get output event list from output event queue */ - PDP_ASSERT(x->x_queue_output->elements); - lock(x); - event_list = pdp_list_pop(x->x_queue_output).w_list; - unlock(x); - - /* send */ - for (a=event_list->first; a; a=a->next){ - t_outlet *outlet = a->w.w_list->first->w.w_pointer; - t_pdp_atom *outatom = a->w.w_list->first->next; - PDP_ASSERT(outlet); - PDP_ASSERT(outatom); - send_pdp_atom_to_outlet(outlet, outatom); - } - - /* free event list */ - pdp_tree_strip_packets(event_list); - pdp_tree_free(event_list); - -} - -/* handle dpd packet passing */ -static void dpd_output(t_forthproc *x) -{ - //post("checking dpd"); - //post("protocol: %s, outlet: %08x, packet: %d", x->x_protocol->s_name, x->x_dpd_outlet, x->x_dpd_packet); - if ((x->x_protocol != S_DPD) - || (!x->x_dpd_outlet) - || (x->x_dpd_packet == -1)) return; - - /* send the dpd packet to the special (first) outlet */ - //post("sending dpd"); - outlet_dpd(x->x_dpd_outlet, x->x_dpd_packet); - x->x_dpd_packet = -1; - -} - - -/* this method is called after - an active event is received */ - -static void run(t_forthproc *x) -{ - - /* NO THREAD: - no brainer: execute and output in one go */ - - if (!x->x_thread){ - - /* run the word */ - exec_program(x); - - /* output stuff */ - output_from_stack(x); - dpd_output(x); - } - - /* THREAD: - start queueing operations - - this is a bit harder since we need to make a copy of the machine state (stack) - before we send off a command to process it in the queue - - this case is handled separately, because processing without thread is obviously - more efficient regarding memory usage and locality of reference. - - */ - - else { - - t_pdp_list *newstack; - - /* compared to the previous approach, no 'automatic' dropping is applied - for forth processors. the input and output queues are of indefinite length. - - dropping is the responsability of the sender or a special object - that uses the processing queue to synchronize (see 3dp_windowcontext) - - this allows for pipelining. - - a drawback is that feedback is a problem with this approach, - but it already was with the previous one. - - the only exception to the dropping rule is when the procqueue is full - - */ - - - /* make sure process queue is not full */ - if (pdp_procqueue_full(x->x_q)){ - - post("forthproc: WARNING: procqueue is full. dropping input events."); - - /* clear the input event list */ - pdp_tree_strip_packets(x->x_input_events); - pdp_tree_free(x->x_input_events); - x->x_input_events = pdp_list_new(0); - - /* exit */ - return; - } - - /* add collected input events to input event queue, and create - a new empty input event list */ - lock(x); - pdp_list_add_back(x->x_queue_input, a_list, (t_pdp_word)x->x_input_events); - x->x_input_events = pdp_list_new(0); - unlock(x); - - /* queue the process method & callback */ - pdp_procqueue_add(x->x_q, x, thread_exec, thread_output, 0); - - /* how to handle dpd packets? - they both have direct and indirect output - let's try this: the dpd input is always passed on directly. - the other outputs are just like pdp outputs */ - - dpd_output(x); - - } -} - - -static int handle_special_message(t_forthproc *x, t_symbol *s, int argc, t_atom *argv) -{ - /* handle the chanmask message. this is a legacy thingy */ - if (s == S_CHANMASK){ - if ((argc == 1) && (argv->a_type == A_FLOAT)){ - x->x_chanmask = (int)argv->a_w.w_float; - return 1; - } - } - - return 0; -} - - -/* pd message handler: - receives a pd message and stores an event in the input queue - or directly on the stack */ - -static void handle_pd_message(t_forthproc *x, t_symbol *s, int argc, t_atom *argv) -{ - int active = 0; - int index; - int i; - t_pdp_atom ta; - t_pdp_symbol *message_id; - t_pdp_symbol *pname; - - - /* get the param name from the received symbol */ - message_id = pdp_gensym(s->s_name); - pname = pdp_forth_pdmap_get_pname(x->x_pdmap, message_id); - - /* if the parameter name is null, it should be interpreted - as a active */ - if (pname == PDP_SYM_NULL){ - run(x); - return; - } - - - /* get the stack atom index */ - index = pdp_forth_processor_map_inputname_to_stackindex(x->x_processor, pname); - t_pdp_atom *stack_atom; - - if (index < 0){ - /* message is not in the pdmap: check any special messages */ - if (!handle_special_message(x, s, argc, argv)) - post("got invalid msg %s", s->s_name); - return; - } - - /* get stack atom - if thread processing is on, get an atom from the template stack - because the real stack is in an indeterminate state */ - i=index; - stack_atom = x->x_thread ? x->x_stack_template->first : x->x_stack->first; - while (i--) stack_atom = stack_atom->next; - - - /* store the type */ - ta.t = stack_atom->t; - - /* check if it is an active inlet - only floats, symbols, bangs, pdp and dpd messages can be active, - the others will be translated to different selectors */ - - if ((&s_float == s) - ||(&s_bang == s) - ||(&s_symbol == s) - ||(S_PDP == s) - ||(S_DPD == s)) active = 1; - - /* interprete the anything message according to expected type (ta.t) - and put the result in the input event queue w */ - - switch(ta.t){ - - case a_float: - if ((argc != 1) || argv[0].a_type != A_FLOAT) post("bad float msg"); - else ta.w.w_float = argv[0].a_w.w_float; - break; - - case a_int: - if ((argc != 1) || argv[0].a_type != A_FLOAT) post("bad float msg"); - else ta.w.w_int = (int)argv[0].a_w.w_float; - break; - - case a_symbol: - if ((argc != 1) || argv[0].a_type != A_SYMBOL) post("bad symbol msg"); - else ta.w.w_symbol = pdp_gensym(argv[0].a_w.w_symbol->s_name); - - case a_list: - post("a_list: not supported yet"); - break; - - case a_packet: - if ((argc != 2) - || argv[0].a_type != A_SYMBOL - || argv[1].a_type != A_FLOAT) post ("bad pdp msg"); - else{ - t_symbol *command = argv[0].a_w.w_symbol; - int packet = (int)argv[1].a_w.w_float; - - - /* PDP */ - /* register the pd packet readonly by default: stack owns a ro copy. - the forth words should convert a packet to rw if they need to - (we can't tell here) */ - if (command == S_REGISTER_RO){ - ta.w.w_packet = pdp_packet_copy_ro(packet); - } - - /* DPD: does not work when multiple context outlets are involved */ - - /* register readonly just like pdp packets. but for dpd context - processors it's understood that the packet can be modified. - and store the reference to pass it along, if it's an active dpd packet */ - else if (command == S_ACCUMULATE){ - - ta.w.w_packet = pdp_packet_copy_ro(packet); - - if (s == S_DPD){ // only store main (left) inlet's dpd messages - x->x_dpd_packet = ta.w.w_packet; - } - } - - else { - /* if it's not a register_ro (pdp) phase, or an accumulate (dpd) phase, - we're not going to do anything with the paket */ - ta.w.w_packet = -1; - } - - /* only the pdp process message or dpd accumulate message can be active */ - if ((command != S_PROCESS) - && (command != S_ACCUMULATE)) active = 0; - - } - break; - default: - post("unknown"); - return; - - } - - /* check if we need to store the atom into the processor stack - directly or should put it in the input event queue */ - - if (!x->x_thread){ - /* handle packets */ - if (ta.t == a_packet){ - - /* only copy if valid (if it was valid and it's a register_ro phase */ - if (ta.w.w_packet != -1){ - pdp_packet_mark_unused(stack_atom->w.w_packet); - stack_atom->w = ta.w; - } - } - /* handle other atoms: store directly */ - else{ - stack_atom->w = ta.w; - } - } - else { - - /* don't store invalid packets */ - if (!(ta.t == a_packet && ta.w.w_packet == -1)){ - - /* store atom + location in event list */ - t_pdp_list *ev = pdp_list_new(2); - pdp_list_set_0(ev, a_int, (t_pdp_word)index); // store atom location - pdp_list_set_1(ev, ta.t, ta.w); // store atom - pdp_list_add_back(x->x_input_events, a_list, - (t_pdp_word)ev); // store event in list - - } - } - - - /* run the processor if it was an active input */ - if (active) run(x); - - -} - - - -/* OTHER METHODS */ -/* these serve as a replacement for the pdp_base class - the most prominent messages are: - - debug - - chanmask - - thread on/off/default on a per object basis -*/ - - - -/* MEM & INIT */ - -static void forthproc_free(t_forthproc *x) -{ - /* wait for thread processing to finish */ - pdp_procqueue_flush(x->x_q); - - /* free state stack + template stack */ - pdp_tree_strip_packets(x->x_stack); - pdp_tree_free(x->x_stack); - pdp_tree_free(x->x_stack_template); - - - /* free input event list */ - pdp_tree_strip_packets(x->x_input_events); - pdp_tree_free(x->x_input_events); - - /* free input/output event queues */ - pdp_tree_strip_packets(x->x_queue_input); - pdp_tree_strip_packets(x->x_queue_output); - pdp_tree_free(x->x_queue_input); - pdp_tree_free(x->x_queue_output); - - /* delete outlet pointer array */ - if (x->x_outlet) pdp_dealloc(x->x_outlet); -} - -t_class *forthproc_class; - - - -static void *forthproc_new(t_symbol *protocol, int argc, t_atom *argv) -{ - t_forthproc *x; - t_pdp_atom *a; - t_symbol *procname; - int i; - - /* get processor name */ - if ((argc < 1) || (argv[0].a_type != A_SYMBOL)) return 0; - procname = argv[0].a_w.w_symbol; - argc--; - argv++; - - - /* allocate */ - x = (t_forthproc *)pd_new(forthproc_class); - - /* init */ - x->x_stack = 0; - x->x_stack_template = 0; - x->x_outlet = 0; - x->x_pdmap = 0; - x->x_processor = 0; - x->x_thread = 1; - x->x_program = 0; - x->x_chanmask = -1; - x->x_dpd_outlet = 0; - x->x_dpd_packet = -1; - - /* get the protocol */ - x->x_protocol = protocol; - //post("forthproc using protocol: %s", protocol->s_name); - - /* input event list */ - x->x_input_events = pdp_list_new(0); - - /* input/output event queues */ - x->x_queue_input = pdp_list_new(0); - x->x_queue_output = pdp_list_new(0); - - /* default queue is pdp queue */ - x->x_q = pdp_queue_get_queue(); - - - - /* get the pd mapper */ - x->x_pdmap = pdp_forth_pdmap_getbyname(pdp_gensym(procname->s_name)); - if (!x->x_pdmap) goto error; - - /* get the processor */ - x->x_processor = pdp_forth_pdmap_get_processor(x->x_pdmap); - if (!x->x_processor) goto error; - - /* get the program */ - x->x_program = x->x_processor->first->next->next->next->w.w_list; - - /* create state stack template and remove packets - so they don't consume resources */ - x->x_stack_template = pdp_forth_processor_setup_stack(x->x_processor); - pdp_tree_strip_packets(x->x_stack_template); - - /* create the state stack */ - x->x_stack = pdp_forth_processor_setup_stack(x->x_processor); - - - /* create additional inlets from description */ - for (a = pdp_forth_pdmap_inlist(x->x_pdmap)->first; a; a=a->next){ - t_pdp_symbol *message_id = a->w.w_symbol; - t_symbol *dsym = gensym(message_id->s_name); - t_symbol *ssym = 0; - - t_pdp_symbol *pname = pdp_forth_pdmap_get_pname(x->x_pdmap, message_id); - t_pdp_atom *sa = pdp_forth_processor_stackatom_from_inputname(x->x_processor, x->x_stack, pname); - if (sa) { - switch(sa->t){ - case a_float: - case a_int: - ssym = &s_float; break; - case a_packet: - ssym = S_PDP; break; - default: - post("unsupported type on stack"); break; - } - } - - /* add inlet */ - if (ssym){ - //post("adding %s inlet %s (forth processor param %s)", - // ssym->s_name, dsym->s_name, pname->s_name); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, ssym, dsym); - } - else { - post("error adding inlet"); - } - } - - /* create outlets */ - if (x->x_protocol == S_DPD){ - x->x_dpd_outlet = outlet_new(&x->x_obj, &s_anything); - } - - x->x_nb_outlets = pdp_forth_pdmap_outlist(x->x_pdmap)->elements; - if (x->x_nb_outlets){ - x->x_outlet = pdp_alloc(x->x_nb_outlets * sizeof(*x->x_outlet)); - for (i=0; i<x->x_nb_outlets; i++){ - x->x_outlet[i] = outlet_new(&x->x_obj, &s_anything); - } - } - - /* interpret arguments */ - //pdp_list_print(pdp_forth_pdmap_arglist(x->x_pdmap)); - for(a = pdp_forth_pdmap_arglist(x->x_pdmap)->first; - a && argc; - a=a->next, argv++, argc--){ - - t_pdp_atom *sa = pdp_forth_processor_stackatom_from_inputname - (x->x_processor, x->x_stack, a->w.w_symbol); - if (!sa) { - post("parameter %s not found", a->w.w_symbol->s_name); - continue; - } - //post("loading parameter %s", a->w.w_symbol->s_name); - /* handle symbols */ - if((sa->t == a_symbol) && (argv->a_type == A_SYMBOL)) - sa->w.w_symbol = pdp_gensym(argv->a_w.w_symbol->s_name); - /* handle floats */ - else if (argv->a_type == A_FLOAT){ - switch(sa->t){ - case a_float: sa->w.w_float = argv->a_w.w_float; break; - case a_int: sa->w.w_int = (int)argv->a_w.w_float; break; - default: break; - } - } - - } - - - /* finished */ - return (void *)x; - - error: - - post ("error creating forth processor %s", procname->s_name); - forthproc_free(x); - return 0; - -} - - -#ifdef __cplusplus -extern "C" -{ -#endif - - -void pdp_forthproc_setup(void) -{ - int i; - - /* create a standard pd class */ - forthproc_class = class_new(gensym("pdp"), (t_newmethod)forthproc_new, - (t_method)forthproc_free, sizeof(t_forthproc), 0, A_GIMME, A_NULL); - class_addcreator((t_newmethod)forthproc_new, gensym("dpd"), A_GIMME, A_NULL); - - /* add global message handler */ - class_addanything(forthproc_class, (t_method)handle_pd_message); - -} - -#ifdef __cplusplus -} -#endif diff --git a/puredata/pdp_imagebase.c b/puredata/pdp_imagebase.c deleted file mode 100644 index f9634e1..0000000 --- a/puredata/pdp_imagebase.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Pure Data Packet image processor base class implementation. - * 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. - * - */ - - -/* - - This file contains the pdp image base class object. -*/ - -#include "pdp_imagebase.h" -#include <stdarg.h> - - -static void pdp_imagebase_chanmask(t_pdp_base *b, t_floatarg f) -{ - int i = (int)f; - if (i < 0) i = -1; - b->b_channel_mask = i; -} - -void pdp_imagebase_setup(t_class *c) -{ - /* parent class setup */ - pdp_base_setup(c); - - /* add pdp base class methods */ - class_addmethod(c, (t_method)pdp_imagebase_chanmask, gensym("chanmask"), A_FLOAT, A_NULL); - -} - -/* pdp base instance constructor */ -void pdp_imagebase_init(void *x) -{ - int i; - t_pdp_imagebase *b = (t_pdp_imagebase *)x; - - /* init super */ - pdp_base_init(x); - - /* convert all active incoming packet types to image */ - pdp_base_set_type_template(x, 0, pdp_gensym("image/*/*")); - - /* default chanmask == all */ - b->b_channel_mask = -1; - -} - -/* base instance destructor */ -void pdp_imagebase_free(void *x) -{ - /* free super */ - pdp_base_free(x); - -} - -/* chanmask getter */ -u32 pdp_imagebase_get_chanmask(void *x) -{ - t_pdp_base *b = (t_pdp_base *)x; - return b->b_channel_mask; -} - diff --git a/puredata/pdp_queue.c b/puredata/pdp_queue.c deleted file mode 100644 index b66289a..0000000 --- a/puredata/pdp_queue.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Pure Data Packet - processor queue 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. - * - */ - - - -/* - this is a the processor queue pdp system module - it receives tasks from objects that are schedules to - be computed in another thread. the object is signalled back - when the task is completed, using a polling mechanism - based on a pd clock. - - the queue object can be reused. the pdp system however only - has one instance (one pdp queue. pdp remains a serial program, though - it can run in a separate thread) - - */ - - -#include <string.h> - -#include "pdp_queue.h" -#include "pdp_mem.h" - - -#define D if (0) - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define PDP_QUEUE_LOGSIZE 10 -#define PDP_QUEUE_DELTIME 10.0f - - -/* there are 3 synchro methods, which can be used i.e. to ensure - all processing is done before shared resources are freed. - - all 3 wait for the processing thread to finish, and - - _wait: leaves callback queue untouched - _finish: clears the queue_id item in the callback queue - _flush: waits for thread and calls callbacks - and loops until callback list is empty - -*/ - - - -/********************* general purpose pd process queue class *********************/ - -void pdp_procqueue_wait(t_pdp_procqueue *q) -{ - D post("pdp_procqueue_wait(%x): waiting for pdp_queue_thread to finish processing", q); - pthread_mutex_lock(&q->mut); - while(((q->curr - q->head) & q->mask) != 0){ - - pthread_cond_wait(&q->cond_processingdone, &q->mut); - } - pthread_mutex_unlock(&q->mut); - D post("pdp_procqueue_wait(%x): pdp_procqueue_thread has finished processing", q); - -} -void pdp_procqueue_finish(t_pdp_procqueue *q, int index) -{ - - if (-1 == index) { - //post("pdp_pq_remove: index == -1"); - return; - } - /* wait for processing thread to finish*/ - pdp_procqueue_wait(q); - - /* invalidate callback at index */ - q->q[index & q->mask].x_callback = 0; - q->q[index & q->mask].x_queue_id = 0; - -} - -static void pdp_procqueue_callback (t_pdp_procqueue *q); - -void pdp_procqueue_flush(t_pdp_procqueue *q) -{ - /* wait once */ - pdp_procqueue_wait(q); - - do { - - /* process callbacks and wait again - in case the callbacks introduced new tasks */ - pdp_procqueue_callback(q); - pdp_procqueue_wait(q); - - } - /* repeat if callback list is not empty */ - while ((q->curr - q->head) & q->mask); - - D post("pdp_procqueue_flush: done"); -} - -static void pdp_procqueue_signal_processor(t_pdp_procqueue *q) -{ - - //NOTE: uncommenting these post statements causes a libc crash - //in mutex lock in putc - //D post("pdp_procqueue_signal_processor(%x): signalling process thread", q); - pthread_mutex_lock(&q->mut); - pthread_cond_signal(&q->cond_dataready); - pthread_mutex_unlock(&q->mut); - //D post("pdp_procqueue_signal_processor(%x): signalling done", q); - - -} - -static void pdp_procqueue_wait_for_feeder(t_pdp_procqueue *q) -{ - - - /* only use locking when there is no data */ - if(((q->curr - q->head) & q->mask) == 0){ - - /* signal processing done */ - D post("pdp_procqueue_wait_for_feeder(%x): signalling processing is done", q); - pthread_mutex_lock(&q->mut); - pthread_cond_signal(&q->cond_processingdone); - - /* wait until there is an item in the queue */ - while(((q->curr - q->head) & q->mask) == 0){ - pthread_cond_wait(&q->cond_dataready, &q->mut); - } - - pthread_mutex_unlock(&q->mut); - D post("pdp_procqueue_wait_for_feeder(%x): waiting done", q); - - } -} - - -int pdp_procqueue_full(t_pdp_procqueue *q) -{ - return (1 == ((q->tail - q->head) & q->mask)); -} - - -void pdp_procqueue_add(t_pdp_procqueue *q, void *owner, void *process, void *callback, int *queue_id) -{ - int i; - - /* if processing is in not in thread, just call the funcs */ - if (!q->use_thread){ - D post("pdp_procqueue_add(%q): calling processing routine directly", q); - if (queue_id) *queue_id = -1; - if (process) ((t_pdpmethod) process)(owner); - if (callback) ((t_pdpmethod) callback)(owner); - return; - } - - - /* if queue is full, print an error message and return */ - if (pdp_procqueue_full(q)) { - post("pdp_procqueue_add: WARNING: processing queue (%x) is full.\n", q); - post("pdp_procqueue_add: WARNING: tail %08x, head %08x (%08x), mask %08x.\n", q->tail, q->head, q->head & q->mask, q->mask); - post("pdp_procqueue_add: WARNING: skipping process method, calling callback directly.\n"); - if (queue_id) *queue_id = -1; - if (callback) ((t_pdpmethod) callback)(owner); - return; - //exit(1); - } - - /* schedule method in thread queue */ - i = q->head & q->mask; - q->q[i].x_owner = owner; - q->q[i].x_process = process; - q->q[i].x_callback = callback; - q->q[i].x_queue_id = queue_id; - if (queue_id) *queue_id = i; - //post("pdp_queue_add: added method to queue, index %d", i); - - - // increase the packet count - q->packets++; - - // move head forward - q->head++; - - pdp_procqueue_signal_processor(q); - -} - - -/* processing thread */ -static void *pdp_procqueue_thread(void *vq) -{ - t_pdp_procqueue *q = (t_pdp_procqueue *)vq; - - D post("pdp_procqueue_thread(%x): thread started", q); - - while(1){ - t_process_queue_item *p; - - - D post("pdp_procqueue_thread(%x): waiting for feeder", q); - - /* wait until there is data available */ - pdp_procqueue_wait_for_feeder(q); - - - D post("pdp_procqueue_thread(%x): processing %d", q, q->curr & q->mask); - - - /* call the process routine */ - p = &q->q[q->curr & q->mask]; - if (p->x_process) - (p->x_process)(p->x_owner); - - /* advance */ - q->curr++; - - - } - return 0; -} - - -/* call back all the callbacks */ -static void pdp_procqueue_callback (t_pdp_procqueue *q) -{ - - /* call callbacks for finished packets */ - while(0 != ((q->curr - q->tail) & q->mask)) - { - int i = q->tail & q->mask; - /* invalidate queue id */ - if(q->q[i].x_queue_id) *q->q[i].x_queue_id = -1; - /* call callback */ - if(q->q[i].x_callback) (q->q[i].x_callback)(q->q[i].x_owner); - //else post("pdp_pq_tick: callback %d is disabled",i ); - q->tail++; - } - -} - -/* the clock method */ -static void pdp_procqueue_tick (t_pdp_procqueue *q) -{ - /* do work */ - //if (!(ticks % 1000)) post("pdp tick %d", ticks); - - if (!q->use_thread) return; - - /* call callbacks */ - pdp_procqueue_callback(q); - - /* increase counter */ - q->ticks++; - - /* set clock for next update */ - clock_delay(q->pdp_clock, q->deltime); -} - - - -void pdp_procqueue_use_thread(t_pdp_procqueue* q, int t) -{ - /* if thread usage is being disabled, - wait for thread to finish processing first */ - if (t == 0) { - pdp_procqueue_wait(q); - q->use_thread = 0; - pdp_procqueue_callback(q); - clock_unset(q->pdp_clock); - } - else { - clock_unset(q->pdp_clock); - clock_delay(q->pdp_clock, q->deltime); - q->use_thread = 1; - } - -} - -void pdp_procqueue_init(t_pdp_procqueue *q, double milliseconds, int logsize) -{ - pthread_attr_t attr; - int size = 1 << logsize; - - /* setup pdp queue processor object */ - q->ticks = 0; - q->deltime = milliseconds; - - /* setup queue data */ - q->mask = size - 1; - q->head = 0; - q->tail = 0; - q->curr = 0; - q->q = pdp_alloc(size * sizeof(t_process_queue_item)); - memset(q->q, 0, size * sizeof(t_process_queue_item)); - - /* enable threads */ - q->use_thread = 1; - - /* setup synchro stuff */ - pthread_mutex_init(&q->mut, NULL); - pthread_cond_init(&q->cond_dataready, NULL); - pthread_cond_init(&q->cond_processingdone, NULL); - - - /* allocate the clock */ - q->pdp_clock = clock_new(q, (t_method)pdp_procqueue_tick); - - /* set the clock */ - clock_delay(q->pdp_clock, 0); - - /* start processing thread */ - - /* glibc doc says SCHED_OTHER is default, - but it seems not to be when initiated from a RT thread - so we explicitly set it here */ - pthread_attr_init (&attr); - //pthread_attr_setschedpolicy(&attr, SCHED_FIFO); - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - - D post("pdp_procqueue_init(%x): starting thread", q); - pthread_create(&q->thread_id, &attr, pdp_procqueue_thread, (void *)q); - D post("pdp_procqueue_init(%x): back in pd thread", q); - - /* wait for processing thread to finish */ - //pdp_procqueue_wait(q); - - /* set default disable/enable thread here */ - //post("pdp_queue: THREAD PROCESSING ON BY DEFAULT!!"); - pdp_procqueue_use_thread(q,0); - -} - - - - -/* the (static) pdp queue object */ -static t_pdp_procqueue pdp_queue; - - -/* get the default queue */ -t_pdp_procqueue *pdp_queue_get_queue(void){return &pdp_queue;} - - -#if 1 -/* default pdp queue shortcut methods */ -void pdp_queue_wait() {pdp_procqueue_wait(&pdp_queue);} -void pdp_queue_finish(int index) { pdp_procqueue_finish(&pdp_queue, index);} -void pdp_queue_add(void *owner, void *process, void *callback, int *queue_id) { - pdp_procqueue_add(&pdp_queue, owner, process, callback, queue_id); -} -void pdp_queue_use_thread(int t) {pdp_procqueue_use_thread(&pdp_queue, t);} -void pdp_queue_setup(void){ - pdp_procqueue_init(&pdp_queue, PDP_QUEUE_DELTIME, PDP_QUEUE_LOGSIZE); - pdp_procqueue_use_thread(&pdp_queue,0); -} -#endif - - - - - - - -#ifdef __cplusplus -} -#endif diff --git a/puredata/pdp_ut.c b/puredata/pdp_ut.c deleted file mode 100644 index a1369e3..0000000 --- a/puredata/pdp_ut.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Pure Data Packet - Utility toolkit objects. - * 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. - * - */ - - -/* This file contains some small utility pd objects that make working with - pdp objects a lot easier. Mainly as glue to be used in the abstractions - in the distro. */ - - -#include "pdp_pd.h" -#include <math.h> - -/* this object does an add, scale, clip operation */ - -t_class *pdp_ut_addscaleclip_class; - -typedef struct pdp_ut_addscaleclip_struct -{ - t_object x_obj; - t_outlet *x_outlet0; - t_float x_min; - t_float x_max; - t_float x_offset; - t_float x_scale; -} t_pdp_ut_addscaleclip; - - -static void pdp_ut_addscaleclip_float(t_pdp_ut_addscaleclip *x, t_floatarg f) -{ - f += x->x_offset; - f *= x->x_scale; - f = (f < x->x_min) ? x->x_min : f; - f = (f > x->x_max) ? x->x_max : f; - outlet_float(x->x_outlet0, f); -} - -static void pdp_ut_addscaleclip_free(t_pdp_ut_addscaleclip *x){} - -void *pdp_ut_addscaleclip_new(t_floatarg offset, t_floatarg scale, t_floatarg min, t_floatarg max) -{ - t_pdp_ut_addscaleclip *x = (t_pdp_ut_addscaleclip *)pd_new(pdp_ut_addscaleclip_class); - x->x_outlet0 = outlet_new(&x->x_obj, &s_float); - x->x_offset = offset; - x->x_scale = scale; - x->x_min = min; - x->x_max = max; - return (void *)x; -} - -void pdp_ut_addscaleclip_setup(void) -{ - pdp_ut_addscaleclip_class = class_new(gensym("pdp_ut_addscaleclip"), (t_newmethod)pdp_ut_addscaleclip_new, - (t_method)pdp_ut_addscaleclip_free, sizeof(t_pdp_ut_addscaleclip), 0, - A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); - class_addfloat(pdp_ut_addscaleclip_class, pdp_ut_addscaleclip_float); -} - - -/* pdp_ut_logmap does a logarithmic parameter mapping [0->1] x -> min(max/min)^x max an add, scale, clip operation */ -/* pdp_ut_logmap_comp does x -> min(max/min)^(1-x) */ -/* pdp_ut_linmap dos x -> min + (max - min * x */ - -t_class *pdp_ut_linmap_class; -t_class *pdp_ut_logmap_class; -t_class *pdp_ut_logmap_comp_class; - -typedef struct pdp_ut_map_struct -{ - t_object x_obj; - t_outlet *x_outlet0; - t_float x_min; - t_float x_max; -} t_pdp_ut_map; - - -static void pdp_ut_logmap_float(t_pdp_ut_map *x, t_floatarg f) -{ - f = (f < 0.0f) ? 0.0f : f; - f = (f > 1.0f) ? 1.0f : f; - - f = x->x_min * pow((x->x_max / x->x_min), f); - - outlet_float(x->x_outlet0, f); -} - -static void pdp_ut_linmap_float(t_pdp_ut_map *x, t_floatarg f) -{ - f = (f < 0.0f) ? 0.0f : f; - f = (f > 1.0f) ? 1.0f : f; - - f = x->x_min + ((x->x_max - x->x_min) * f); - - outlet_float(x->x_outlet0, f); -} - -static void pdp_ut_logmap_comp_float(t_pdp_ut_map *x, t_floatarg f) -{ - f = (f < 0.0f) ? 0.0f : f; - f = (f > 1.0f) ? 1.0f : f; - - f = x->x_min * pow((x->x_max / x->x_min), (1.0f - f)); - - outlet_float(x->x_outlet0, f); -} - -static void pdp_ut_map_free(t_pdp_ut_map *x){} - - -void pdp_ut_map_init(t_pdp_ut_map *x, t_floatarg min, t_floatarg max) -{ - x->x_outlet0 = outlet_new(&x->x_obj, &s_float); - x->x_min = min; - x->x_max = max; -} - -void *pdp_ut_logmap_new(t_floatarg min, t_floatarg max) -{ - t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_logmap_class); - pdp_ut_map_init(x, min, max); - return (void *)x; -} - -void *pdp_ut_linmap_new(t_floatarg min, t_floatarg max) -{ - t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_linmap_class); - pdp_ut_map_init(x, min, max); - return (void *)x; -} - -void *pdp_ut_logmap_comp_new(t_floatarg min, t_floatarg max) -{ - t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_logmap_comp_class); - pdp_ut_map_init(x, min, max); - return (void *)x; -} - -void pdp_ut_logmap_setup(void) -{ - pdp_ut_logmap_class = class_new(gensym("pdp_ut_logmap"), (t_newmethod)pdp_ut_logmap_new, - (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0, - A_FLOAT, A_FLOAT, A_NULL); - class_addfloat(pdp_ut_logmap_class, pdp_ut_logmap_float); -} - -void pdp_ut_logmap_comp_setup(void) -{ - pdp_ut_logmap_comp_class = class_new(gensym("pdp_ut_logmap_comp"), (t_newmethod)pdp_ut_logmap_comp_new, - (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0, - A_FLOAT, A_FLOAT, A_NULL); - class_addfloat(pdp_ut_logmap_comp_class, pdp_ut_logmap_comp_float); -} - -void pdp_ut_linmap_setup(void) -{ - pdp_ut_linmap_class = class_new(gensym("pdp_ut_linmap"), (t_newmethod)pdp_ut_linmap_new, - (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0, - A_FLOAT, A_FLOAT, A_NULL); - class_addfloat(pdp_ut_linmap_class, pdp_ut_linmap_float); -} - - - -t_class *pdp_ut_rgb2ycrcb_class; - -typedef struct pdp_ut_rgb2ycrcb -{ - t_object x_obj; - t_outlet *x_outlet_luma; - t_outlet *x_outlet_chroma_red; - t_outlet *x_outlet_chroma_blue; - - t_float x_red, x_green, x_blue; - -} t_pdp_ut_rgb2ycrcb; - - -static void pdp_ut_rgb2ycrcb_bang (t_pdp_ut_rgb2ycrcb* x) -{ - - float luma = 0.299f * x->x_red + 0.587f * x->x_green + 0.114f * x->x_blue; - float chroma_red = (x->x_red - luma) * 0.713f; - float chroma_blue = (x->x_blue - luma) * 0.565f; - - outlet_float(x->x_outlet_chroma_blue, chroma_blue); - outlet_float(x->x_outlet_chroma_red, chroma_red); - outlet_float(x->x_outlet_luma, luma); - -} - - -static void pdp_ut_rgb2ycrcb_red (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_red = f; pdp_ut_rgb2ycrcb_bang(x);} -static void pdp_ut_rgb2ycrcb_green (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_green = f; pdp_ut_rgb2ycrcb_bang(x);} -static void pdp_ut_rgb2ycrcb_blue (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_blue = f; pdp_ut_rgb2ycrcb_bang(x);} - - - -static void pdp_ut_rgb2ycrcb_free (t_pdp_ut_rgb2ycrcb* x) {} -static void* pdp_ut_rgb2ycrcb_new(void) -{ - t_pdp_ut_rgb2ycrcb *x = (t_pdp_ut_rgb2ycrcb *)pd_new(pdp_ut_rgb2ycrcb_class); - - - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("green")); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("blue")); - - x->x_outlet_luma = outlet_new(&x->x_obj, &s_float); - x->x_outlet_chroma_red = outlet_new(&x->x_obj, &s_float); - x->x_outlet_chroma_blue = outlet_new(&x->x_obj, &s_float); - - x->x_red = 0.0f; - x->x_green = 0.0f; - x->x_blue = 0.0f; - - - return (void *)x; -} - -void pdp_ut_rgb2ycrcb_setup(void) -{ - pdp_ut_rgb2ycrcb_class = class_new(gensym("pdp_ut_rgb2ycrcb"), (t_newmethod)pdp_ut_rgb2ycrcb_new, - (t_method)pdp_ut_rgb2ycrcb_free, sizeof(t_pdp_ut_rgb2ycrcb), 0, A_NULL); - class_addfloat(pdp_ut_rgb2ycrcb_class, pdp_ut_rgb2ycrcb_red); - class_addmethod(pdp_ut_rgb2ycrcb_class, (t_method)pdp_ut_rgb2ycrcb_green, gensym("green"), A_FLOAT, A_NULL); - class_addmethod(pdp_ut_rgb2ycrcb_class, (t_method)pdp_ut_rgb2ycrcb_blue, gensym("blue"), A_FLOAT, A_NULL); -} - - -#ifdef __cplusplus -extern "C" -{ -#endif - -void pdp_ut_setup(void) -{ - pdp_ut_addscaleclip_setup(); - pdp_ut_logmap_setup(); - pdp_ut_logmap_comp_setup(); - pdp_ut_linmap_setup(); - pdp_ut_rgb2ycrcb_setup(); -} - - -#ifdef __cplusplus -} -#endif |