From 71b83fc040b848c98c5065d95ecbc72b0b4f8943 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 17 Jan 2013 22:54:00 +0000 Subject: merging maxlib v1.5.5 from branches/pd-extended/0.43 svn path=/trunk/externals/maxlib/; revision=16897 --- pulse.c | 602 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 301 insertions(+), 301 deletions(-) (limited to 'pulse.c') diff --git a/pulse.c b/pulse.c index 4205315..6b7ca62 100644 --- a/pulse.c +++ b/pulse.c @@ -1,301 +1,301 @@ -/* --------------------------- pong ------------------------------------------ */ -/* */ -/* A more accurate replacement for the tempo object. */ -/* Written by Olaf Matthes */ -/* Based on pulse for Max written by James McCartney. */ -/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ -/* */ -/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* */ -/* Based on PureData by Miller Puckette and others. */ -/* */ -/* ---------------------------------------------------------------------------- */ - -/* pulse.c ---- a more accurate replacement for the tempo object */ -/* updated for CW 68K / PPC summer 96 -RD */ -/* written for Max by James McCartney */ - -#include "m_pd.h" -#include - -static char *version = "pulse v0.1b, written by James McCartney for Max \n" - " ported to Pd by Olaf Matthes "; - -/* Pulse object data structure */ -typedef struct pulse -{ - t_object p_ob; - t_clock *p_clock; - t_outlet *p_out1; /* outlet */ - t_outlet *p_out2; /* outlet */ - t_int p_onoff, p_changenumer, p_changedenom; - t_int p_tempo, p_durnumer, p_durdenom, p_maxbeats, p_count; - double p_starttime, p_endtime, p_startremain, p_endremain, p_mspbquotient; - t_int p_newdurnumer, p_newdurdenom; - t_int p_mspbnumer, p_mspbdenom, p_mspbremainder; -} Pulse; - -static t_class *pulse_class; - -static void durcalc(Pulse *x) -{ - /* recalc duration */ - x->p_mspbnumer = 240000 * x->p_durnumer; - if (x->p_tempo * x->p_durdenom != 0) /* bug fix by Frank Barknecht */ - x->p_mspbdenom = x->p_tempo * x->p_durdenom; - x->p_mspbquotient = x->p_mspbnumer / x->p_mspbdenom; - x->p_mspbremainder = x->p_mspbnumer % x->p_mspbdenom; - if (x->p_mspbquotient < 5) { - x->p_mspbquotient = 5; - x->p_mspbremainder = 0; - } -} - -static void pulse_onoff(Pulse *x, t_floatarg f) -{ - int i = (int)f; - if (i && !x->p_onoff) { - x->p_onoff = 1; - x->p_count = 0; - outlet_float(x->p_out1, x->p_count); - if (x->p_changedenom) { - x->p_durdenom = x->p_newdurdenom; - x->p_changedenom = 0; - } - if (x->p_changenumer) { - x->p_durnumer = x->p_newdurnumer; - x->p_changenumer = 0; - } - durcalc(x); - x->p_startremain = 0; - x->p_endremain = x->p_mspbremainder; - x->p_starttime = clock_getlogicaltime(); - x->p_endtime = x->p_starttime + x->p_mspbquotient; - // clock_set(x->p_clock, x->p_endtime); - clock_delay(x->p_clock, x->p_mspbquotient); - } else if (i==0 && x->p_onoff) { - x->p_onoff = 0; - clock_unset(x->p_clock); - } -} - -static void pulse_bang(Pulse *x) -{ - if (!x->p_onoff) { - x->p_onoff = 1; - x->p_count = 0; - outlet_float(x->p_out1, x->p_count); - if (x->p_changedenom) { - x->p_durdenom = x->p_newdurdenom; - x->p_changedenom = 0; - } - if (x->p_changenumer) { - x->p_durnumer = x->p_newdurnumer; - x->p_changenumer = 0; - } - durcalc(x); - x->p_startremain = 0; - x->p_endremain = x->p_mspbremainder; - x->p_starttime = clock_getlogicaltime(); - x->p_endtime = x->p_starttime + x->p_mspbquotient; - clock_set(x->p_clock, x->p_endtime); - } else { - x->p_onoff = 0; - clock_unset(x->p_clock); - } -} - -/* clock tick routine */ -static void pulse_tick(Pulse *x) -{ - x->p_count ++; - if ((x->p_maxbeats > 0) && (x->p_count >= x->p_maxbeats)) { /* turn off time */ - x->p_onoff = 0; - outlet_bang(x->p_out2); - } else { - outlet_float(x->p_out1, x->p_count); - x->p_startremain = x->p_endremain; /* save in case we have to re do it */ - if (x->p_changenumer || x->p_changedenom) { /* duration changed */ - if (x->p_changedenom) { - /* this statement may cause a slight drift of (1/(tempo*denom) msecs) */ - x->p_startremain = (x->p_startremain * x->p_newdurdenom + (x->p_durdenom>>1)) - /x->p_durdenom; - x->p_durdenom = x->p_newdurdenom; - x->p_changedenom = 0; - } - if (x->p_changenumer) { - x->p_durnumer = x->p_newdurnumer; - x->p_changenumer = 0; - } - durcalc(x); - } - x->p_endremain = x->p_startremain + x->p_mspbremainder; - x->p_starttime = x->p_endtime; - x->p_endtime = x->p_starttime + x->p_mspbquotient; - if (x->p_endremain >= x->p_mspbdenom) { - x->p_endremain -= x->p_mspbdenom; - x->p_endtime ++; - } - // clock_set(x->p_clock, x->p_endtime); - clock_delay(x->p_clock, x->p_mspbquotient); - } -} - -/* deal with tempo change */ -static void pulse_tempo(Pulse *x, t_floatarg t) -{ - double time, msecdur, tickdur, fracremain; - t_int fracnumer, fracquotient, oldtempo; - oldtempo = x->p_tempo; - x->p_tempo = (t<5) ? 5 : ((t>500) ? 500 : t); - if (x->p_onoff) { - /* calculate fraction of the beat we have done */ - time = clock_getlogicaltime(); - if (time != x->p_endtime) { - /* if pulse_tempo is called as a result of a call from pulse_tick - (call chain from outlet_float()) - then this stuff doesn't need to be done (time will == x->p_endtime) - */ - msecdur = time - x->p_starttime; - tickdur = msecdur * x->p_mspbdenom - x->p_startremain; - fracnumer = (t_int)(x->p_mspbnumer - tickdur); - - durcalc(x); - - /* calculate end time */ - fracquotient = fracnumer / x->p_mspbdenom; - fracremain = fracnumer % x->p_mspbdenom; - - x->p_endtime = time + fracquotient; - x->p_endremain = fracremain; - - /* recalculate starttime so future tempo changes work */ - x->p_starttime = x->p_endtime - x->p_mspbquotient; - x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain; - if (x->p_mspbremainder > fracremain) { - x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain; - x->p_starttime --; - } else { - x->p_startremain = fracremain - x->p_mspbremainder; - } - clock_unset(x->p_clock); - clock_set(x->p_clock, x->p_endtime); - // clock_delay(x->p_clock, fracquotient); - } - } -} - -static void pulse_numer(Pulse *x, t_floatarg n) -{ - int i = (t_int)n; - if(i >= 0) - { - if (x->p_onoff) { - if (x->p_durnumer != i) { - x->p_changenumer = 1; - x->p_newdurnumer = i; - } - } else { - x->p_durnumer = i; - } - } -} - -static void pulse_denom(Pulse *x, t_floatarg n) -{ - int i = (t_int)n; - if(i >= 0) - { - if (x->p_onoff) { - if (x->p_durdenom != i) { - x->p_changedenom = 1; - x->p_newdurdenom = i; - } - } else { - x->p_durdenom = i; - } - } -} - -static void pulse_beat(Pulse *x, t_floatarg n) -{ - int i = (t_int)n; - if(i >= 0) - { - x->p_maxbeats = i; - } -} - - -static void pulse_free(Pulse *x) -{ - clock_free(x->p_clock); -} - - -/* function run to create a new instance of the Pulse class */ -static void *pulse_new(t_floatarg t, t_floatarg n, t_floatarg d, t_floatarg b) -{ - Pulse *x; - - x = (Pulse *)pd_new(pulse_class); /* allocates memory and sticks in an inlet */ - - inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("tempo")); - inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("numer")); - inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("denom")); - inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("beat")); - x->p_out1 = outlet_new(&x->p_ob, gensym("float")); - x->p_out2 = outlet_new(&x->p_ob, gensym("float")); - x->p_clock = clock_new(x, (t_method)pulse_tick); - x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t)); - x->p_durnumer = (n<=0) ? 1 : n; - x->p_durdenom = (d<=0) ? 4 : d; - x->p_maxbeats = (b<=0) ? 0 : b; - x->p_changenumer = 0; - x->p_changedenom = 0; - x->p_onoff = 0; - - return (x); /* always return a copy of the created object */ -} - -#ifndef MAXLIB -void pulse_setup(void) -{ - pulse_class = class_new(gensym("pulse"), (t_newmethod)pulse_new, - (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0); - class_addfloat(pulse_class, pulse_onoff); - class_addbang(pulse_class, pulse_bang); - - post(version); -} -#else -void maxlib_pulse_setup(void) -{ - pulse_class = class_new(gensym("maxlib_pulse"), (t_newmethod)pulse_new, - (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)pulse_new, gensym("pulse"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0); - class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0); - class_addfloat(pulse_class, pulse_onoff); - class_addbang(pulse_class, pulse_bang); - class_sethelpsymbol(pulse_class, gensym("maxlib/pulse-help.pd")); -} -#endif +/* --------------------------- pong ------------------------------------------ */ +/* */ +/* A more accurate replacement for the tempo object. */ +/* Written by Olaf Matthes */ +/* Based on pulse for Max written by James McCartney. */ +/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */ +/* */ +/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +/* pulse.c ---- a more accurate replacement for the tempo object */ +/* updated for CW 68K / PPC summer 96 -RD */ +/* written for Max by James McCartney */ + +#include "m_pd.h" +#include + +static char *version = "pulse v0.1b, written by James McCartney for Max \n" + " ported to Pd by Olaf Matthes "; + +/* Pulse object data structure */ +typedef struct pulse +{ + t_object p_ob; + t_clock *p_clock; + t_outlet *p_out1; /* outlet */ + t_outlet *p_out2; /* outlet */ + t_int p_onoff, p_changenumer, p_changedenom; + t_int p_tempo, p_durnumer, p_durdenom, p_maxbeats, p_count; + double p_starttime, p_endtime, p_startremain, p_endremain, p_mspbquotient; + t_int p_newdurnumer, p_newdurdenom; + t_int p_mspbnumer, p_mspbdenom, p_mspbremainder; +} Pulse; + +static t_class *pulse_class; + +static void durcalc(Pulse *x) +{ + /* recalc duration */ + x->p_mspbnumer = 240000 * x->p_durnumer; + if (x->p_tempo * x->p_durdenom != 0) /* bug fix by Frank Barknecht */ + x->p_mspbdenom = x->p_tempo * x->p_durdenom; + x->p_mspbquotient = x->p_mspbnumer / x->p_mspbdenom; + x->p_mspbremainder = x->p_mspbnumer % x->p_mspbdenom; + if (x->p_mspbquotient < 5) { + x->p_mspbquotient = 5; + x->p_mspbremainder = 0; + } +} + +static void pulse_onoff(Pulse *x, t_floatarg f) +{ + int i = (int)f; + if (i && !x->p_onoff) { + x->p_onoff = 1; + x->p_count = 0; + outlet_float(x->p_out1, x->p_count); + if (x->p_changedenom) { + x->p_durdenom = x->p_newdurdenom; + x->p_changedenom = 0; + } + if (x->p_changenumer) { + x->p_durnumer = x->p_newdurnumer; + x->p_changenumer = 0; + } + durcalc(x); + x->p_startremain = 0; + x->p_endremain = x->p_mspbremainder; + x->p_starttime = clock_getlogicaltime(); + x->p_endtime = x->p_starttime + x->p_mspbquotient; + // clock_set(x->p_clock, x->p_endtime); + clock_delay(x->p_clock, x->p_mspbquotient); + } else if (i==0 && x->p_onoff) { + x->p_onoff = 0; + clock_unset(x->p_clock); + } +} + +static void pulse_bang(Pulse *x) +{ + if (!x->p_onoff) { + x->p_onoff = 1; + x->p_count = 0; + outlet_float(x->p_out1, x->p_count); + if (x->p_changedenom) { + x->p_durdenom = x->p_newdurdenom; + x->p_changedenom = 0; + } + if (x->p_changenumer) { + x->p_durnumer = x->p_newdurnumer; + x->p_changenumer = 0; + } + durcalc(x); + x->p_startremain = 0; + x->p_endremain = x->p_mspbremainder; + x->p_starttime = clock_getlogicaltime(); + x->p_endtime = x->p_starttime + x->p_mspbquotient; + clock_set(x->p_clock, x->p_endtime); + } else { + x->p_onoff = 0; + clock_unset(x->p_clock); + } +} + +/* clock tick routine */ +static void pulse_tick(Pulse *x) +{ + x->p_count ++; + if ((x->p_maxbeats > 0) && (x->p_count >= x->p_maxbeats)) { /* turn off time */ + x->p_onoff = 0; + outlet_bang(x->p_out2); + } else { + outlet_float(x->p_out1, x->p_count); + x->p_startremain = x->p_endremain; /* save in case we have to re do it */ + if (x->p_changenumer || x->p_changedenom) { /* duration changed */ + if (x->p_changedenom) { + /* this statement may cause a slight drift of (1/(tempo*denom) msecs) */ + x->p_startremain = (x->p_startremain * x->p_newdurdenom + (x->p_durdenom>>1)) + /x->p_durdenom; + x->p_durdenom = x->p_newdurdenom; + x->p_changedenom = 0; + } + if (x->p_changenumer) { + x->p_durnumer = x->p_newdurnumer; + x->p_changenumer = 0; + } + durcalc(x); + } + x->p_endremain = x->p_startremain + x->p_mspbremainder; + x->p_starttime = x->p_endtime; + x->p_endtime = x->p_starttime + x->p_mspbquotient; + if (x->p_endremain >= x->p_mspbdenom) { + x->p_endremain -= x->p_mspbdenom; + x->p_endtime ++; + } + // clock_set(x->p_clock, x->p_endtime); + clock_delay(x->p_clock, x->p_mspbquotient); + } +} + +/* deal with tempo change */ +static void pulse_tempo(Pulse *x, t_floatarg t) +{ + double time, msecdur, tickdur, fracremain; + t_int fracnumer, fracquotient, oldtempo; + oldtempo = x->p_tempo; + x->p_tempo = (t<5) ? 5 : ((t>500) ? 500 : t); + if (x->p_onoff) { + /* calculate fraction of the beat we have done */ + time = clock_getlogicaltime(); + if (time != x->p_endtime) { + /* if pulse_tempo is called as a result of a call from pulse_tick + (call chain from outlet_float()) + then this stuff doesn't need to be done (time will == x->p_endtime) + */ + msecdur = time - x->p_starttime; + tickdur = msecdur * x->p_mspbdenom - x->p_startremain; + fracnumer = (t_int)(x->p_mspbnumer - tickdur); + + durcalc(x); + + /* calculate end time */ + fracquotient = fracnumer / x->p_mspbdenom; + fracremain = fracnumer % x->p_mspbdenom; + + x->p_endtime = time + fracquotient; + x->p_endremain = fracremain; + + /* recalculate starttime so future tempo changes work */ + x->p_starttime = x->p_endtime - x->p_mspbquotient; + x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain; + if (x->p_mspbremainder > fracremain) { + x->p_startremain = x->p_mspbdenom - x->p_mspbremainder + fracremain; + x->p_starttime --; + } else { + x->p_startremain = fracremain - x->p_mspbremainder; + } + clock_unset(x->p_clock); + clock_set(x->p_clock, x->p_endtime); + // clock_delay(x->p_clock, fracquotient); + } + } +} + +static void pulse_numer(Pulse *x, t_floatarg n) +{ + int i = (t_int)n; + if(i >= 0) + { + if (x->p_onoff) { + if (x->p_durnumer != i) { + x->p_changenumer = 1; + x->p_newdurnumer = i; + } + } else { + x->p_durnumer = i; + } + } +} + +static void pulse_denom(Pulse *x, t_floatarg n) +{ + int i = (t_int)n; + if(i >= 0) + { + if (x->p_onoff) { + if (x->p_durdenom != i) { + x->p_changedenom = 1; + x->p_newdurdenom = i; + } + } else { + x->p_durdenom = i; + } + } +} + +static void pulse_beat(Pulse *x, t_floatarg n) +{ + int i = (t_int)n; + if(i >= 0) + { + x->p_maxbeats = i; + } +} + + +static void pulse_free(Pulse *x) +{ + clock_free(x->p_clock); +} + + +/* function run to create a new instance of the Pulse class */ +static void *pulse_new(t_floatarg t, t_floatarg n, t_floatarg d, t_floatarg b) +{ + Pulse *x; + + x = (Pulse *)pd_new(pulse_class); /* allocates memory and sticks in an inlet */ + + inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("tempo")); + inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("numer")); + inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("denom")); + inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("beat")); + x->p_out1 = outlet_new(&x->p_ob, gensym("float")); + x->p_out2 = outlet_new(&x->p_ob, gensym("float")); + x->p_clock = clock_new(x, (t_method)pulse_tick); + x->p_tempo = (t==0) ? 120 : ((t<5) ? 5 : ((t>500) ? 500 : t)); + x->p_durnumer = (n<=0) ? 1 : n; + x->p_durdenom = (d<=0) ? 4 : d; + x->p_maxbeats = (b<=0) ? 0 : b; + x->p_changenumer = 0; + x->p_changedenom = 0; + x->p_onoff = 0; + + return (x); /* always return a copy of the created object */ +} + +#ifndef MAXLIB +void pulse_setup(void) +{ + pulse_class = class_new(gensym("pulse"), (t_newmethod)pulse_new, + (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0); + class_addfloat(pulse_class, pulse_onoff); + class_addbang(pulse_class, pulse_bang); + + logpost(NULL, 4, version); +} +#else +void maxlib_pulse_setup(void) +{ + pulse_class = class_new(gensym("maxlib_pulse"), (t_newmethod)pulse_new, + (t_method)pulse_free, sizeof(Pulse), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)pulse_new, gensym("pulse"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_beat, gensym("beat"), A_FLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_denom, gensym("denom"), A_FLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_numer, gensym("numer"), A_FLOAT, 0); + class_addmethod(pulse_class, (t_method)pulse_tempo, gensym("tempo"), A_FLOAT, 0); + class_addfloat(pulse_class, pulse_onoff); + class_addbang(pulse_class, pulse_bang); + class_sethelpsymbol(pulse_class, gensym("maxlib/pulse-help.pd")); +} +#endif -- cgit v1.2.1