diff options
author | N.N. <krzyszcz@users.sourceforge.net> | 2003-05-23 12:29:55 +0000 |
---|---|---|
committer | N.N. <krzyszcz@users.sourceforge.net> | 2003-05-23 12:29:55 +0000 |
commit | faada59567f8cb252f4a909116595ce309ff5828 (patch) | |
tree | 5874954c6f2d5392d921208e49a45ef266beeb7f /cyclone/sickle/peek.c |
This commit was generated by cvs2svn to compensate for changes in r647,svn2git-root
which included commits to RCS files with non-trunk default branches.
svn path=/trunk/externals/miXed/; revision=648
Diffstat (limited to 'cyclone/sickle/peek.c')
-rw-r--r-- | cyclone/sickle/peek.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/cyclone/sickle/peek.c b/cyclone/sickle/peek.c new file mode 100644 index 0000000..7397577 --- /dev/null +++ b/cyclone/sickle/peek.c @@ -0,0 +1,147 @@ +/* Copyright (c) 2002-2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* LATER: 'click' method */ + +#include <string.h> +#include "m_pd.h" +#include "sickle/sic.h" +#include "sickle/arsic.h" + +#define PEEK_MAXCHANNELS 4 /* LATER implement arsic resizing feature */ + +typedef struct _peek +{ + t_arsic x_arsic; + int x_maxchannels; + int x_effchannel; /* effective channel (clipped reqchannel) */ + int x_reqchannel; /* requested channel */ + int x_clipmode; + int x_pokemode; + t_float x_value; + t_clock *x_clock; + double x_clocklasttick; + int x_clockset; +} t_peek; + +static t_class *peek_class; + +static void peek_tick(t_peek *x) +{ + arsic_redraw((t_arsic *)x); /* LATER redraw only dirty channel(s!) */ + x->x_clockset = 0; + x->x_clocklasttick = clock_getsystime(); +} + +static void peek_set(t_peek *x, t_symbol *s) +{ + arsic_setarray((t_arsic *)x, s, 1); +} + +#define peek_doclip(f) (f < -1. ? -1. : (f > 1. ? 1. : f)) + +/* CHECKED refman error: ``if the number received in the left inlet + specifies a sample index that does not exist in the buffer~ object's + currently allocated memory, nothing happens.'' This is plainly wrong, + at least for max/msp 4.0.7 bundle: the index is clipped (just like + in tabread/tabwrite). As a kind of an experiment, lets make this + the refman's way... */ +static void peek_float(t_peek *x, t_float f) +{ + t_arsic *sic = (t_arsic *)x; + t_float *vp; + arsic_validate(sic, 0); /* LATER rethink (efficiency, and complaining) */ + if (vp = sic->s_vectors[x->x_effchannel]) + { + int ndx = (int)f; + if (vp && ndx >= 0 && ndx < sic->s_vecsize) + { + if (x->x_pokemode) + { + double timesince; + t_float f = x->x_value; + vp[ndx] = (x->x_clipmode ? peek_doclip(f) : f); + x->x_pokemode = 0; + timesince = clock_gettimesince(x->x_clocklasttick); + if (timesince > 1000) peek_tick(x); + else if (!x->x_clockset) + { + clock_delay(x->x_clock, 1000 - timesince); + x->x_clockset = 1; + } + } + /* CHECKED: output not clipped */ + else outlet_float(((t_object *)x)->ob_outlet, vp[ndx]); + } + } +} + +static void peek_ft1(t_peek *x, t_floatarg f) +{ + x->x_value = f; + x->x_pokemode = 1; + /* CHECKED: poke-mode is reset only after receiving left inlet input + -- it is kept across 'ft2', 'clip', and 'set' inputs. */ +} + +static void peek_ft2(t_peek *x, t_floatarg f) +{ + if ((x->x_reqchannel = (f > 1 ? (int)f - 1 : 0)) > x->x_maxchannels) + x->x_effchannel = x->x_maxchannels - 1; + else + x->x_effchannel = x->x_reqchannel; +} + +static void peek_clip(t_peek *x, t_floatarg f) +{ + x->x_clipmode = ((int)f != 0); +} + +static void peek_free(t_peek *x) +{ + if (x->x_clock) clock_free(x->x_clock); + arsic_free((t_arsic *)x); +} + +static void *peek_new(t_symbol *s, t_floatarg f1, t_floatarg f2) +{ + int ch = (f1 > 0 ? (int)f1 : 0); + t_peek *x = (t_peek *)arsic_new(peek_class, s, + (ch ? PEEK_MAXCHANNELS : 0), 0, 0); + if (x) + { + if (ch > PEEK_MAXCHANNELS) + ch = PEEK_MAXCHANNELS; + x->x_maxchannels = (ch ? PEEK_MAXCHANNELS : 1); + x->x_effchannel = x->x_reqchannel = (ch ? ch - 1 : 0); + /* CHECKED (refman error) clipping is disabled by default */ + x->x_clipmode = ((int)f2 != 0); + x->x_pokemode = 0; + inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); + inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft2")); + outlet_new((t_object *)x, &s_float); + x->x_clock = clock_new(x, (t_method)peek_tick); + x->x_clocklasttick = clock_getsystime(); + x->x_clockset = 0; + } + return (x); +} + +void peek_tilde_setup(void) +{ + peek_class = class_new(gensym("peek~"), + (t_newmethod)peek_new, + (t_method)peek_free, + sizeof(t_peek), 0, + A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addfloat(peek_class, peek_float); + class_addmethod(peek_class, (t_method)peek_set, + gensym("set"), A_SYMBOL, 0); + class_addmethod(peek_class, (t_method)peek_ft1, + gensym("ft1"), A_FLOAT, 0); + class_addmethod(peek_class, (t_method)peek_ft2, + gensym("ft2"), A_FLOAT, 0); + class_addmethod(peek_class, (t_method)peek_clip, + gensym("clip"), A_FLOAT, 0); +} |