From b6ae9da8c7dfba6587038cac42684949bf2faaf0 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Mon, 2 Jun 2003 14:12:00 +0000 Subject: adding pong and mtr svn path=/trunk/externals/miXed/; revision=673 --- cyclone/sickle/pong.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 cyclone/sickle/pong.c (limited to 'cyclone/sickle/pong.c') diff --git a/cyclone/sickle/pong.c b/cyclone/sickle/pong.c new file mode 100644 index 0000000..59a8beb --- /dev/null +++ b/cyclone/sickle/pong.c @@ -0,0 +1,247 @@ +/* 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. */ + +/* CHECKED whatever args, there are always 3 inlets (refman's rubbish) */ + +#include "m_pd.h" +#include "unstable/forky.h" +#include "sickle/sic.h" + +//#define PONG_DEBUG + +#define PONG_DEFLO 0. +#define PONG_DEFHI 1. + +typedef struct _pong +{ + t_sic x_sic; + t_glist *x_glist; + int x_mode; +} t_pong; + +static t_class *pong_class; + +static t_int *pong_perform(t_int *w) +{ + t_pong *x = (t_pong *)(w[1]); + int nblock = (int)(w[2]); + t_float *in1 = (t_float *)(w[3]); + t_float *in2 = (t_float *)(w[4]); + t_float *in3 = (t_float *)(w[5]); + t_float *out = (t_float *)(w[6]); + if (x->x_mode) while (nblock--) + { + float f = *in1++; + float lo = *in2++; + float hi = *in3++; + float range; + if (lo < hi) range = hi - lo; + else if (lo > hi) + { + range = lo; + lo = hi; + hi = range; + range -= lo; + } + else + { + *out++ = lo; + continue; + } + if (f < lo) + { + if (f < lo - range) + { + double dnorm = (f - lo) / range; + dnorm -= (int)dnorm; + *out++ = hi + dnorm * range; + } + else *out++ = f + range; + } + else if (f > hi) + { + if (f > hi + range) + { + double dnorm = (f - lo) / range; + dnorm -= (int)dnorm; + *out++ = lo + dnorm * range; + } + else *out++ = f - range; + } + else *out++ = f; + } + else while (nblock--) + { + float f = *in1++; + float lo = *in2++; + float hi = *in3++; + float range; + if (lo < hi) range = hi - lo; + else if (lo > hi) + { + range = lo; + lo = hi; + hi = range; + range -= lo; + } + else + { + *out++ = lo; + continue; + } + if (f < lo) + { + f = lo - f; + if (f <= range) + { + *out++ = lo + f; + continue; + } + } + else if (f > hi) f -= lo; + else + { + *out++ = f; + continue; + } + if (f > range + range) + { + double dnorm = f / range; + int inorm = (int)dnorm; + if (inorm % 2) + *out++ = lo + ((inorm + 1) - dnorm) * range; + else + *out++ = lo + (dnorm - inorm) * range; + } + else *out++ = hi + range - f; + } + return (w + 7); +} + +static t_int *pong_perform_nofeeders(t_int *w) +{ + t_pong *x = (t_pong *)(w[1]); + int nblock = (int)(w[2]); + t_float *in1 = (t_float *)(w[3]); + t_float *in2 = (t_float *)(w[4]); + t_float *in3 = (t_float *)(w[5]); + t_float *out = (t_float *)(w[6]); + float lo = *in2; + float hi = *in3; + float range; + double coef; + if (lo < hi) range = hi - lo; + else if (lo > hi) + { + range = lo; + lo = hi; + hi = range; + range -= lo; + } + else + { + while (nblock--) *out++ = lo; + goto done; + } + coef = 1. / range; + if (x->x_mode) while (nblock--) + { + float f = *in1++; + if (f < lo) + { + if (f < lo - range) + { + double dnorm = (f - lo) * coef; + dnorm -= (int)dnorm; + *out++ = hi + dnorm * range; + } + else *out++ = f + range; + } + else if (f > hi) + { + if (f > hi + range) + { + double dnorm = (f - lo) * coef; + dnorm -= (int)dnorm; + *out++ = lo + dnorm * range; + } + else *out++ = f - range; + } + else *out++ = f; + } + else while (nblock--) + { + float f = *in1++; + if (f < lo) + { + f = lo - f; + if (f <= range) + { + *out++ = lo + f; + continue; + } + } + else if (f > hi) f -= lo; + else + { + *out++ = f; + continue; + } + if (f > range + range) + { + double dnorm = f * coef; + int inorm = (int)dnorm; + if (inorm % 2) + *out++ = lo + ((inorm + 1) - dnorm) * range; + else + *out++ = lo + (dnorm - inorm) * range; + } + else *out++ = hi + range - f; + } +done: + return (w + 7); +} + +static void pong_dsp(t_pong *x, t_signal **sp) +{ + if (forky_hasfeeders((t_object *)x, x->x_glist, 1, &s_signal) || + forky_hasfeeders((t_object *)x, x->x_glist, 2, &s_signal)) + dsp_add(pong_perform, 6, x, sp[0]->s_n, + sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec); + else + { +#ifdef PONG_DEBUG + post("using pong_perform_nofeeders"); +#endif + dsp_add(pong_perform_nofeeders, 6, x, sp[0]->s_n, + sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec); + } +} + +static void pong_mode(t_pong *x, t_floatarg f) +{ + x->x_mode = ((int)f != 0); +} + +static void *pong_new(t_symbol *s, int ac, t_atom *av) +{ + t_pong *x = (t_pong *)pd_new(pong_class); + x->x_glist = canvas_getcurrent(); + x->x_mode = (ac && av->a_type == A_FLOAT + && (int)av->a_w.w_float != 0); + sic_inlet((t_sic *)x, 1, PONG_DEFLO, 1, ac, av); + sic_inlet((t_sic *)x, 2, PONG_DEFHI, 2, ac, av); + outlet_new((t_object *)x, &s_signal); + return (x); +} + +void pong_tilde_setup(void) +{ + pong_class = class_new(gensym("pong~"), + (t_newmethod)pong_new, 0, + sizeof(t_pong), 0, A_GIMME, 0); + sic_setup(pong_class, pong_dsp, SIC_FLOATTOSIGNAL); + class_addmethod(pong_class, (t_method)pong_mode, + gensym("mode"), A_FLOAT, 0); +} -- cgit v1.2.1