maxlib-1.5.5/0000755000076500007650000000000012076107644011463 5ustar hanshansmaxlib-1.5.5/score-help.pd0000644000076500007650000000437712076104537014062 0ustar hanshans#N canvas 0 26 623 545 12; #X floatatom 30 301 5 0 0 0 - - -; #X obj 30 12 notein; #X obj 193 202 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 95 93 start; #X msg 104 118 stop; #X text 217 203 reset; #X text 145 92 start / stop score following; #X msg 111 146 start 4; #X text 176 146 start skipping first 4 notes; #X obj 193 286 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -258699 -1; #X text 217 287 error; #X text 148 24 score :: score follower that tries to match incoming ; #X text 221 41 MIDI data to a score stored in an array; #X text 219 57 outputs the index number of current position; #X obj 23 423 loadbang; #N canvas 0 0 450 300 (subpatch) 0; #X array sco_array 25 float 1; #A 0 60 61 62 63 64 65 66 67 68 69 70 71 72 71 70 69 68 67 66 65 64 63 62 61 60; #X coords 0 127 24 0 200 140 1; #X restore 402 361 graph; #X obj 30 235 score sco_array 2 300; #X msg 130 173 set sco_array; #X msg 23 449 \; sco_array resize 25 \; sco_array read examples/score.txt \;; #X text 250 174 set to array that contains the score; #X text 88 303 position on score; #X text 86 322 (x index of array); #X obj 30 356 tabread sco_array; #X floatatom 30 387 5 0 0 0 - - -; #X text 86 388 note from score; #X text 291 255 array: name of array containing score; #X text 235 234 USAGE: score ; #X text 292 272 skipitems: max. number of notes to skip; #X text 292 289 skip time: max. time [ms] to rewind; #X text 378 307 input data; #N canvas 292 198 494 344 META 0; #X text 12 205 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 185 AUTHOR Olaf Matthes ; #X text 12 105 INLET_1 float; #X text 12 45 DESCRIPTION score follower that tries to match incoming MIDI data to a score stored in an array; #X text 12 85 INLET_0 float start stop set; #X text 12 125 INLET_2 bang; #X text 12 145 OUTLET_0 float; #X text 12 165 OUTLET_0 bang; #X text 12 5 KEYWORDS control MIDI analysis; #X restore 563 517 pd META; #X connect 0 0 22 0; #X connect 1 0 16 0; #X connect 1 1 16 1; #X connect 2 0 16 2; #X connect 3 0 16 0; #X connect 4 0 16 0; #X connect 7 0 16 0; #X connect 14 0 18 0; #X connect 16 0 0 0; #X connect 16 1 9 0; #X connect 17 0 16 0; #X connect 22 0 23 0; maxlib-1.5.5/deny.c0000644000076500007650000001003312076104537012561 0ustar hanshans/* ---------------------------- deny --------------------------------------- */ /* */ /* Lets only floats/symbols through that are denyed to do so. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include static char *version = "deny v0.1, written by Olaf Matthes "; typedef struct deny { t_object x_obj; t_outlet *x_out; t_atom *x_elem; // list of elemets that are denyed to pass t_int x_numelem; // the number of elemetns in our deny-list } t_deny; /* we got a symbol... */ static void deny_symbol(t_deny *x, t_symbol *s) { int i, deny = 0; for(i = 0; i < x->x_numelem; i++) { if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s) { deny = 1; return; } } if(!deny)outlet_symbol(x->x_out, s); } /* we got a float... */ static void deny_float(t_deny *x, t_floatarg f) { int i, deny = 0; for(i = 0; i < x->x_numelem; i++) { if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f) { deny = 1; // input is in deny-list return; } } if(!deny)outlet_float(x->x_out, f); } static t_class *deny_class; static void deny_free(t_deny *x) { freebytes(x->x_elem, x->x_numelem*sizeof(t_atom)); } static void *deny_new(t_symbol *s, int argc, t_atom *argv) { t_deny *x = (t_deny *)pd_new(deny_class); x->x_numelem = argc; // get the number of elements x->x_elem = getbytes(argc*sizeof(t_atom)); memcpy(x->x_elem, argv, argc*sizeof(t_atom)); x->x_out = outlet_new(&x->x_obj, gensym("anything")); // post("deny: got %d elements", x->x_numelem); return (x); } #ifndef MAXLIB void deny_setup(void) { /* the object's class: */ deny_class = class_new(gensym("deny"), (t_newmethod)deny_new, (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0); #else void maxlib_deny_setup(void) { /* the object's class: */ deny_class = class_new(gensym("maxlib_deny"), (t_newmethod)deny_new, (t_method)deny_free, sizeof(t_deny), 0, A_GIMME, 0); class_addcreator((t_newmethod)deny_new, gensym("deny"), A_GIMME, 0); #endif class_addsymbol(deny_class, deny_symbol); class_addfloat(deny_class, deny_float); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(deny_class, gensym("maxlib/deny-help.pd")); #endif } maxlib-1.5.5/divide.c0000644000076500007650000000777412076104537013110 0ustar hanshans/* ------------------------- divide ------------------------------------------ */ /* */ /* Like '/', but calculates output whenever _any_ of the inlets changes. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #define MAXSIZE 32 static char *version = "divide v0.2, written by Olaf Matthes "; typedef struct divide { t_object x_ob; t_inlet *x_inleft; /* leftmost inlet */ t_inlet *x_inright; /* right inlet */ t_outlet *x_outlet; /* result */ t_int x_numvalues; /* number of values / inlets */ t_float x_dividevalue[MAXSIZE]; } t_divide; static void divide_bang(t_divide *x) { int i; t_float result = x->x_dividevalue[0]; for(i = 1; i < x->x_numvalues; i++) result /= x->x_dividevalue[i]; outlet_float(x->x_outlet, result); } static void divide_float(t_divide *x, t_floatarg f) { x->x_dividevalue[0] = f; divide_bang(x); /* calculate result */ } static void divide_ft1(t_divide *x, t_floatarg f) { x->x_dividevalue[1] = f; divide_bang(x); /* calculate result */ } static t_class *divide_class; static void *divide_new(t_symbol *s, t_int argc, t_atom* argv) { int i; t_divide *x = (t_divide *)pd_new(divide_class); x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); for(i = 2; i < argc; i++) /* create additional inlets, if any */ { floatinlet_new(&x->x_ob, &x->x_dividevalue[i]); } x->x_outlet = outlet_new(&x->x_ob, gensym("float")); for(i = 0; i < argc; i++) { x->x_dividevalue[i] = atom_getfloatarg(i, argc, argv); } x->x_numvalues = i; return (void *)x; } #ifndef MAXLIB void divide_setup(void) { divide_class = class_new(gensym("divide"), (t_newmethod)divide_new, 0, sizeof(t_divide), 0, A_GIMME, 0); #else void maxlib_divide_setup(void) { divide_class = class_new(gensym("maxlib_divide"), (t_newmethod)divide_new, 0, sizeof(t_divide), 0, A_GIMME, 0); #endif class_addfloat(divide_class, divide_float); class_addmethod(divide_class, (t_method)divide_ft1, gensym("ft1"), A_FLOAT, 0); class_addbang(divide_class, (t_method)divide_bang); #ifndef MAXLIB logpost(NULL, 4, version); #else class_addcreator((t_newmethod)divide_new, gensym("divide"), A_GIMME, 0); class_sethelpsymbol(divide_class, gensym("maxlib/divide-help.pd")); #endif } maxlib-1.5.5/tilt-help.pd0000644000076500007650000000242012076104537013706 0ustar hanshans#N canvas 0 26 562 330 12; #X floatatom 24 114 5 0 0 0 - - -; #X obj 54 293 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 153 227 5 0 0 0 - - -; #X text 210 228 interval; #X text 39 20 tilt :: meassure 'tilt' of input; #X text 226 186 trip point :: alert when exceeding; #X text 339 203 this value; #X text 215 128 low limit :: reset 'start tilt' in case; #X text 319 143 value is below this for a; #X text 319 160 longer time; #X text 184 80 high limit :: ignore chnages higher than this; #X text 163 56 tilt :: maximum value change within one interval; #X obj 54 250 tilt 0.78 100; #X msg 126 81 hi 230; #X msg 139 127 low 17.3; #X msg 139 186 trip 173; #X msg 100 55 tilt 25; #N canvas 304 317 494 344 META 0; #X text 12 145 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 125 AUTHOR Olaf Matthes ; #X text 12 85 INLET_1 float; #X text 12 45 DESCRIPTION meassure 'tilt' of input; #X text 12 5 KEYWORDS control; #X text 12 65 INLET_0 float tilt hi low trip; #X text 12 105 OUTLET_0 bang; #X restore 501 299 pd META; #X connect 0 0 12 0; #X connect 2 0 12 1; #X connect 12 0 1 0; #X connect 13 0 12 0; #X connect 14 0 12 0; #X connect 15 0 12 0; #X connect 16 0 12 0; maxlib-1.5.5/urn-help.pd0000644000076500007650000000173612076104537013547 0ustar hanshans#N canvas 0 0 462 312 12; #X obj 59 162 urn 8; #X msg 117 92 clear; #X floatatom 59 221 5 0 0 0 - - -; #X msg 59 65 bang; #X obj 149 221 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 104 65 choose next number; #X text 169 93 clear / refill urn; #X floatatom 109 130 5 0 0 0 - - -; #X text 161 130 change number of items in urn; #X text 29 10 urn :: urn selection model; #X text 181 221 bang if urn is empty; #N canvas 293 158 494 344 META 0; #X text 12 165 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 145 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control random; #X text 12 45 DESCRIPTION urn selection model; #X text 12 65 INLET_0 bang clear; #X text 12 85 INLET_1 float; #X text 12 105 OUTLET_0 float; #X text 12 125 OUTLET_1 bang; #X restore 390 274 pd META; #X connect 0 0 2 0; #X connect 0 1 4 0; #X connect 1 0 0 0; #X connect 3 0 0 0; #X connect 7 0 0 1; maxlib-1.5.5/maxlib.c0000644000076500007650000001454212076104537013107 0ustar hanshans/* -------------------------- maxlib ---------------------------------------- */ /* */ /* maxlib :: music analysis extensions library. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #ifndef VERSION #define VERSION "1.5.4" #endif #include "m_pd.h" #ifndef __DATE__ #define __DATE__ "without using a gnu compiler" #endif typedef struct _maxlib { t_object x_obj; } t_maxlib; static t_class* maxlib_class; /* objects */ void maxlib_allow_setup(); void maxlib_arbran_setup(); void maxlib_arraycopy_setup(); void maxlib_average_setup(); void maxlib_beat_setup(); void maxlib_beta_setup(); void maxlib_bilex_setup(); void maxlib_borax_setup(); void maxlib_cauchy_setup(); void maxlib_chord_setup(); void maxlib_delta_setup(); void maxlib_deny_setup(); void maxlib_dist_setup(); void maxlib_divide_setup(); void maxlib_divmod_setup(); void maxlib_edge_setup(); void maxlib_expo_setup(); void maxlib_fifo_setup(); void maxlib_gauss_setup(); void maxlib_gestalt_setup(); void maxlib_history_setup(); void maxlib_ignore_setup(); void maxlib_iso_setup(); void maxlib_lifo_setup(); void maxlib_limit_setup(); void maxlib_linear_setup(); void maxlib_listfifo_setup(); void maxlib_listfunnel_setup(); void maxlib_match_setup(); void maxlib_minus_setup(); void maxlib_mlife_setup(); void maxlib_multi_setup(); void maxlib_nchange_setup(); void maxlib_netclient_setup(); void maxlib_netdist_setup(); void maxlib_netrec_setup(); void maxlib_netserver_setup(); void maxlib_nroute_setup(); void maxlib_pitch_setup(); void maxlib_plus_setup(); void maxlib_poisson_setup(); void maxlib_pong_setup(); void maxlib_pulse_setup(); void maxlib_remote_setup(); void maxlib_rewrap_setup(); void maxlib_rhythm_setup(); void maxlib_scale_setup(); void maxlib_score_setup(); void maxlib_speedlim_setup(); void maxlib_split_setup(); void maxlib_step_setup(); void maxlib_subst_setup(); void maxlib_sync_setup(); void maxlib_temperature_setup(); void maxlib_tilt_setup(); void maxlib_timebang_setup(); void maxlib_triang_setup(); void maxlib_unroute_setup(); void maxlib_urn_setup(); void maxlib_velocity_setup(); void maxlib_weibull_setup(); void maxlib_wrap_setup(); static void* maxlib_new(t_symbol* s) { t_maxlib *x = (t_maxlib *)pd_new(maxlib_class); return (x); } void maxlib_setup(void) { maxlib_class = class_new(gensym("maxlib"), (t_newmethod)maxlib_new, 0, sizeof(t_maxlib), 0,0); maxlib_allow_setup(); maxlib_arbran_setup(); maxlib_arraycopy_setup(); maxlib_average_setup(); maxlib_beat_setup(); maxlib_beta_setup(); maxlib_bilex_setup(); maxlib_borax_setup(); maxlib_cauchy_setup(); maxlib_chord_setup(); maxlib_delta_setup(); maxlib_deny_setup(); maxlib_dist_setup(); maxlib_divide_setup(); maxlib_divmod_setup(); maxlib_edge_setup(); maxlib_expo_setup(); maxlib_fifo_setup(); maxlib_gauss_setup(); maxlib_gestalt_setup(); maxlib_history_setup(); maxlib_ignore_setup(); maxlib_iso_setup(); maxlib_lifo_setup(); maxlib_limit_setup(); maxlib_linear_setup(); maxlib_listfifo_setup(); maxlib_listfunnel_setup(); maxlib_match_setup(); maxlib_minus_setup(); maxlib_mlife_setup(); maxlib_multi_setup(); maxlib_nchange_setup(); maxlib_netclient_setup(); maxlib_netdist_setup(); maxlib_netrec_setup(); maxlib_netserver_setup(); maxlib_nroute_setup(); maxlib_pitch_setup(); maxlib_plus_setup(); maxlib_poisson_setup(); maxlib_pong_setup(); maxlib_pulse_setup(); maxlib_remote_setup(); maxlib_rewrap_setup(); maxlib_rhythm_setup(); maxlib_scale_setup(); maxlib_score_setup(); maxlib_speedlim_setup(); maxlib_split_setup(); maxlib_step_setup(); maxlib_subst_setup(); maxlib_sync_setup(); maxlib_temperature_setup(); maxlib_tilt_setup(); maxlib_timebang_setup(); maxlib_triang_setup(); maxlib_unroute_setup(); maxlib_urn_setup(); maxlib_velocity_setup(); maxlib_weibull_setup(); maxlib_wrap_setup(); post("\n maxlib :: Music Analysis eXtensions LIBrary"); post(" written by Olaf Matthes "); logpost(NULL, 4, " version "VERSION); post(" compiled "__DATE__); logpost(NULL, 4, " latest version at http://www.akustische-kunst.org/puredata/maxlib/"); post(" objects: allow arbran arraycopy average beat beta bilex borax cauchy "); post(" chord delta deny dist divide divmod edge expo fifo gauss "); post(" gestalt history ignore iso lifo linear listfifo listfunnel "); post(" match minus mlife multi nchange netclient netdist netrec "); post(" netserver nroute pitch plus poisson pong pulse remote rewrap "); post(" rhythm scale score speedlim split step subst sync temperature "); post(" tilt timebang triang unroute urn velocity weibull wrap\n"); } maxlib-1.5.5/netserver.c0000644000076500007650000004771112076104537013654 0ustar hanshans/* -------------------------- netserver ------------------------------------- */ /* */ /* A server for bidirectional communication from within Pd. */ /* Allows to send back data to specific clients connected to the server. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include "s_stuff.h" #include "m_imp.h" #include #include #include #include #include #include #include #include #ifdef WIN32 #include #include #include #else #include #include #include #include #include #include #include #include #define SOCKET_ERROR -1 #endif #define MAX_CONNECT 32 /* maximum number of connections */ #define INBUFSIZE 4096 /* size of receiving data buffer */ /* message levels from syslog.h */ #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ static char *version = "netserver v0.2.hcs1 :: bidirectional communication for Pd\n" " written by Olaf Matthes \n" " syslogging by Hans-Christoph Steiner "; /* ----------------------------- netserver ------------------------- */ static t_class *netserver_class; static t_binbuf *inbinbuf; typedef void (*t_netserver_socketnotifier)(void *x); typedef void (*t_netserver_socketreceivefn)(void *x, t_binbuf *b); typedef struct _netserver { t_object x_obj; t_outlet *x_msgout; t_outlet *x_connectout; t_outlet *x_clientno; t_outlet *x_connectionip; t_symbol *x_host[MAX_CONNECT]; t_int x_fd[MAX_CONNECT]; t_int x_sock_fd; t_int x_connectsocket; t_int x_nconnections; /* for syslog style logging priorities */ t_int x_log_pri; } t_netserver; typedef struct _netserver_socketreceiver { char *sr_inbuf; int sr_inhead; int sr_intail; void *sr_owner; t_netserver_socketnotifier sr_notifier; t_netserver_socketreceivefn sr_socketreceivefn; } t_netserver_socketreceiver; static t_netserver_socketreceiver *netserver_socketreceiver_new(void *owner, t_netserver_socketnotifier notifier, t_netserver_socketreceivefn socketreceivefn) { t_netserver_socketreceiver *x = (t_netserver_socketreceiver *)getbytes(sizeof(*x)); x->sr_inhead = x->sr_intail = 0; x->sr_owner = owner; x->sr_notifier = notifier; x->sr_socketreceivefn = socketreceivefn; if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netserver_socketreceiver"); return (x); } /* this is in a separately called subroutine so that the buffer isn't sitting on the stack while the messages are getting passed. */ static int netserver_socketreceiver_doread(t_netserver_socketreceiver *x) { char messbuf[INBUFSIZE], *bp = messbuf; int indx; int inhead = x->sr_inhead; int intail = x->sr_intail; char *inbuf = x->sr_inbuf; if (intail == inhead) return (0); for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1)) { char c = *bp++ = inbuf[indx]; if (c == ';' && (!indx || inbuf[indx-1] != '\\')) { intail = (indx+1)&(INBUFSIZE-1); binbuf_text(inbinbuf, messbuf, bp - messbuf); x->sr_inhead = inhead; x->sr_intail = intail; return (1); } } return (0); } static void netserver_socketreceiver_read(t_netserver_socketreceiver *x, int fd) { char *semi; int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); int ret; t_netserver *y = x->sr_owner; y->x_sock_fd = fd; /* the input buffer might be full. If so, drop the whole thing */ if (readto == x->sr_inhead) { if (y->x_log_pri >= LOG_ERR) post("netserver: dropped message"); x->sr_inhead = x->sr_intail = 0; readto = INBUFSIZE; } else { ret = recv(fd, x->sr_inbuf + x->sr_inhead, readto - x->sr_inhead, 0); if (ret < 0) { sys_sockerror("recv"); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret == 0) { if (y->x_log_pri >= LOG_NOTICE) post("netserver: << connection closed on socket %d", fd); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else { x->sr_inhead += ret; if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; while (netserver_socketreceiver_doread(x)) { outlet_setstacklim(); if (x->sr_socketreceivefn) (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); else binbuf_eval(inbinbuf, 0, 0, 0); } } } } static void netserver_socketreceiver_free(t_netserver_socketreceiver *x) { free(x->sr_inbuf); freebytes(x, sizeof(*x)); } /* ---------------- main netserver (send) stuff --------------------- */ /* send message to client using socket number */ static void netserver_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv) { int sockfd, client = -1, i; if(x->x_nconnections < 0) { if (x->x_log_pri >= LOG_WARNING) post("netserver: no clients connected"); return; } if(argc < 2) { if (x->x_log_pri >= LOG_WARNING) post("netserver: nothing to send"); return; } /* get socket number of connection (first element in list) */ if(argv[0].a_type == A_FLOAT) { sockfd = atom_getfloatarg(0, argc, argv); for(i = 0; i < x->x_nconnections; i++) /* check if connection exists */ { if(x->x_fd[i] == sockfd) { client = i; /* the client we're sending to */ break; } } if(client == -1) { if (x->x_log_pri >= LOG_CRIT) post("netserver: no connection on socket %d", sockfd); return; } } else { if (x->x_log_pri >= LOG_CRIT) post("netserver: no socket specified"); return; } /* process & send data */ if(sockfd > 0) { t_binbuf *b = binbuf_new(); char *buf, *bp; int length, sent; t_atom at; binbuf_add(b, argc - 1, argv + 1); /* skip first element */ SETSEMI(&at); binbuf_add(b, 1, &at); binbuf_gettext(b, &buf, &length); if (x->x_log_pri >= LOG_DEBUG) { post("netserver: sending data to client %d on socket %d", client + 1, sockfd); post("netserver: sending \"%s\"", buf); } for (bp = buf, sent = 0; sent < length;) { static double lastwarntime; static double pleasewarn; double timebefore = clock_getlogicaltime(); int res = send(sockfd, buf, length-sent, 0); double timeafter = clock_getlogicaltime(); int late = (timeafter - timebefore > 0.005); if (late || pleasewarn) { if (timeafter > lastwarntime + 2) { if (x->x_log_pri >= LOG_WARNING) post("netserver blocked %d msec", (int)(1000 * ((timeafter - timebefore) + pleasewarn))); pleasewarn = 0; lastwarntime = timeafter; } else if (late) pleasewarn += timeafter - timebefore; } if (res <= 0) { sys_sockerror("netserver"); if (x->x_log_pri >= LOG_ERR) post("netserver: could not send data to client"); break; } else { sent += res; bp += res; } } t_freebytes(buf, length); binbuf_free(b); } else if (x->x_log_pri >= LOG_CRIT) post("netserver: not a valid socket number (%d)", sockfd); } /* send message to client using client number note that the client numbers might change in case a client disconnects! */ static void netserver_client_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv) { int sockfd, client; if(x->x_nconnections < 0) { if (x->x_log_pri >= LOG_WARNING) post("netserver: no clients connected"); return; } if(argc < 2) { if (x->x_log_pri >= LOG_WARNING) post("netserver: nothing to send"); return; } /* get number of client (first element in list) */ if(argv[0].a_type == A_FLOAT) client = atom_getfloatarg(0, argc, argv); else { if (x->x_log_pri >= LOG_WARNING) post("netserver: no client specified"); return; } sockfd = x->x_fd[client - 1]; /* get socket number for that client */ /* process & send data */ if(sockfd > 0) { t_binbuf *b = binbuf_new(); char *buf, *bp; int length, sent; t_atom at; binbuf_add(b, argc - 1, argv + 1); /* skip first element */ SETSEMI(&at); binbuf_add(b, 1, &at); binbuf_gettext(b, &buf, &length); if (x->x_log_pri >= LOG_DEBUG) { post("netserver: sending data to client %d on socket %d", client, sockfd); post("netserver: >> sending \"%s\"", buf); } for (bp = buf, sent = 0; sent < length;) { static double lastwarntime; static double pleasewarn; double timebefore = clock_getlogicaltime(); int res = send(sockfd, buf, length-sent, 0); double timeafter = clock_getlogicaltime(); int late = (timeafter - timebefore > 0.005); if (late || pleasewarn) { if (timeafter > lastwarntime + 2) { if (x->x_log_pri >= LOG_WARNING) post("netserver blocked %d msec", (int)(1000 * ((timeafter - timebefore) + pleasewarn))); pleasewarn = 0; lastwarntime = timeafter; } else if (late) pleasewarn += timeafter - timebefore; } if (res <= 0) { sys_sockerror("netserver"); if (x->x_log_pri >= LOG_ERR) post("netserver: could not send data to cient"); break; } else { sent += res; bp += res; } } t_freebytes(buf, length); binbuf_free(b); } else if (x->x_log_pri >= LOG_CRIT) post("netserver: not a valid socket number (%d)", sockfd); } /* broadcasts a message to all connected clients */ static void netserver_broadcast(t_netserver *x, t_symbol *s, int argc, t_atom *argv) { int i, client = x->x_nconnections; /* number of clients to send to */ t_atom at[256]; for(i = 0; i < argc; i++) { at[i + 1] = argv[i]; } argc++; /* enumerate through the clients and send each the message */ while(client--) { SETFLOAT(at, client + 1); /* prepend number of client */ netserver_client_send(x, s, argc, at); } } /* ---------------- main netserver (receive) stuff --------------------- */ static void netserver_notify(t_netserver *x) { int i, k; /* remove connection from list */ for(i = 0; i < x->x_nconnections; i++) { if(x->x_fd[i] == x->x_sock_fd) { x->x_nconnections--; if (x->x_log_pri >= LOG_NOTICE) post("netserver: \"%s\" removed from list of clients", x->x_host[i]->s_name); x->x_host[i] = NULL; /* delete entry */ x->x_fd[i] = -1; /* rearrange list now: move entries to close the gap */ for(k = i; k < x->x_nconnections; k++) { x->x_host[k] = x->x_host[k + 1]; x->x_fd[k] = x->x_fd[k + 1]; } } } outlet_float(x->x_connectout, x->x_nconnections); } static void netserver_doit(void *z, t_binbuf *b) { t_atom messbuf[1024]; t_netserver *x = (t_netserver *)z; int msg, natom = binbuf_getnatom(b); t_atom *at = binbuf_getvec(b); int i; /* output clients IP and socket no. */ for(i = 0; i < x->x_nconnections; i++) /* search for corresponding IP */ { if(x->x_fd[i] == x->x_sock_fd) { outlet_symbol(x->x_connectionip, x->x_host[i]); break; } } outlet_float(x->x_clientno, x->x_sock_fd); /* the socket number */ /* process data */ for (msg = 0; msg < natom;) { int emsg; for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA && at[emsg].a_type != A_SEMI; emsg++); if (emsg > msg) { int ii; for (ii = msg; ii < emsg; ii++) if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM) { pd_error(x, "netserver: got dollar sign in message"); goto nodice; } if (at[msg].a_type == A_FLOAT) { if (emsg > msg + 1) outlet_list(x->x_msgout, 0, emsg-msg, at + msg); else outlet_float(x->x_msgout, at[msg].a_w.w_float); } else if (at[msg].a_type == A_SYMBOL) outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, emsg-msg-1, at + msg + 1); } nodice: msg = emsg + 1; } } static void netserver_connectpoll(t_netserver *x) { struct sockaddr_in incomer_address; int sockaddrl = (int) sizeof( struct sockaddr ); int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl); if (fd < 0) post("netserver: accept failed"); else { t_netserver_socketreceiver *y = netserver_socketreceiver_new((void *)x, (t_netserver_socketnotifier)netserver_notify, (x->x_msgout ? netserver_doit : 0)); sys_addpollfn(fd, (t_fdpollfn)netserver_socketreceiver_read, y); x->x_nconnections++; x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr)); x->x_fd[x->x_nconnections - 1] = fd; if (x->x_log_pri >= LOG_NOTICE) post("netserver: ** accepted connection from %s on socket %d", x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]); outlet_float(x->x_connectout, x->x_nconnections); } } static void netserver_print(t_netserver *x) { int i; if(x->x_nconnections > 0) { post("netserver: %d open connections:", x->x_nconnections); for(i = 0; i < x->x_nconnections; i++) { post(" \"%s\" on socket %d", x->x_host[i]->s_name, x->x_fd[i]); } } else post("netserver: no open connections"); } static void netserver_emerg(t_netserver *x) { x->x_log_pri = LOG_EMERG; } static void netserver_alert(t_netserver *x) { x->x_log_pri = LOG_ALERT; } static void netserver_crit(t_netserver *x) { x->x_log_pri = LOG_CRIT; } static void netserver_err(t_netserver *x) { x->x_log_pri = LOG_ERR; } static void netserver_warning(t_netserver *x) { x->x_log_pri = LOG_WARNING; } static void netserver_notice(t_netserver *x) { x->x_log_pri = LOG_NOTICE; } static void netserver_info(t_netserver *x) { x->x_log_pri = LOG_INFO; } static void netserver_debug(t_netserver *x) { x->x_log_pri = LOG_DEBUG; } static void *netserver_new(t_floatarg fportno) { t_netserver *x; int i; struct sockaddr_in server; int sockfd, portno = fportno; x = (t_netserver *)pd_new(netserver_class); /* set default debug message level */ x->x_log_pri = LOG_ERR; /* create a socket */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (x->x_log_pri >= LOG_NOTICE) post("netserver: receive socket %d", sockfd); if (sockfd < 0) { sys_sockerror("socket"); return (0); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; #ifdef IRIX /* this seems to work only in IRIX but is unnecessary in Linux. Not sure what NT needs in place of this. */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) post("setsockopt failed\n"); #endif /* assign server port number */ server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { sys_sockerror("bind"); sys_closesocket(sockfd); return (0); } x->x_msgout = outlet_new(&x->x_obj, &s_anything); /* streaming protocol */ if (listen(sockfd, 5) < 0) { sys_sockerror("listen"); sys_closesocket(sockfd); sockfd = -1; } else { sys_addpollfn(sockfd, (t_fdpollfn)netserver_connectpoll, x); x->x_connectout = outlet_new(&x->x_obj, &s_float); x->x_clientno = outlet_new(&x->x_obj, &s_float); x->x_connectionip = outlet_new(&x->x_obj, &s_symbol); inbinbuf = binbuf_new(); } x->x_connectsocket = sockfd; x->x_nconnections = 0; for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1; return (x); } static void netserver_free(t_netserver *x) { int i; for(i = 0; i < x->x_nconnections; i++) { sys_rmpollfn(x->x_fd[i]); sys_closesocket(x->x_fd[i]); } if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } binbuf_free(inbinbuf); } #ifndef MAXLIB void netserver_setup(void) { netserver_class = class_new(gensym("netserver"),(t_newmethod)netserver_new, (t_method)netserver_free, sizeof(t_netserver), 0, A_DEFFLOAT, 0); class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0); class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0); class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0); class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0); /* syslog log level messages */ class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emerg"), 0); class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emergency"), 0); class_addmethod(netserver_class, (t_method)netserver_alert, gensym("alert"), 0); class_addmethod(netserver_class, (t_method)netserver_crit, gensym("crit"), 0); class_addmethod(netserver_class, (t_method)netserver_crit, gensym("critical"), 0); class_addmethod(netserver_class, (t_method)netserver_err, gensym("err"), 0); class_addmethod(netserver_class, (t_method)netserver_err, gensym("error"), 0); class_addmethod(netserver_class, (t_method)netserver_err, gensym("quiet"), 0); class_addmethod(netserver_class, (t_method)netserver_warning, gensym("warning"), 0); class_addmethod(netserver_class, (t_method)netserver_notice, gensym("notice"), 0); class_addmethod(netserver_class, (t_method)netserver_info, gensym("info"), 0); class_addmethod(netserver_class, (t_method)netserver_info, gensym("verbose"), 0); class_addmethod(netserver_class, (t_method)netserver_debug, gensym("debug"), 0); logpost(NULL, 4, version); } #else void maxlib_netserver_setup(void) { netserver_class = class_new(gensym("maxlib_netserver"),(t_newmethod)netserver_new, (t_method)netserver_free, sizeof(t_netserver), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)netserver_new, gensym("netserver"), A_DEFFLOAT, 0); class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0); class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0); class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0); class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0); class_sethelpsymbol(netserver_class, gensym("maxlib/netserver-help.pd")); } #endif maxlib-1.5.5/pong.c0000644000076500007650000002407212076104537012575 0ustar hanshans/* --------------------------- pong ------------------------------------------ */ /* */ /* A virtual bouncing ball. */ /* Written by Olaf Matthes */ /* Based on pong (for Max) version 1.5 written by Richard Dudas. */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" static char *version = "pong v0.1, ported by Olaf Matthes \n" " written for Max by Richard Dudas"; typedef struct pong { t_object x_obj; t_outlet *p_bounceout; t_outlet *p_handout; t_outlet *p_velout; t_outlet *p_heightout; t_clock *p_klok; t_int p_ms; // ms count t_float p_time; // current time div by warp t_float p_timegrain; // timegrain in seconds t_float p_timegrainin; // timegrain in ms t_float p_warp; // timewarp in ms t_float p_dinit; // init distance t_float p_vinit; // init velocity t_float p_ainit; // base acceleration def -100 t_float p_damping; // realtime multiplicative damping t_float p_dhand; // virtual hand distance t_float p_force; // force of hand 1.0 = no force t_float p_accel; // current accel value t_float p_vi; // current velocity t_float p_di; // current distance t_float p_dt; // distance out t_float p_dtprev; // previous distance out for accel computation t_float p_vt; // velocity out t_int p_prevchg; // for logical transition } t_pong; /* ---------------------------------------------------------- */ /* ---- this stuff is mainly for the timer, on off etc... --- */ /* ---------------------------------------------------------- */ static void pong_reset(t_pong *x) { x->p_di = x->p_dinit; x->p_dt = x->p_dinit; // added x->p_dtprev = x->p_dinit; // added x->p_vi = x->p_vinit; x->p_vt = x->p_vinit; // added x->p_ms = 0; x->p_time = 0.; x->p_ainit = -100.; // added, but currently disabled x->p_accel = -100.; // reactivated (?) x->p_damping = 1.; // i.e. no initial damping x->p_prevchg = 0; // added /* x->p_ms = 0; x->p_time = 0.; x->p_timegrain = 0.05; // if ms grain = 50 x->p_timegrainin = 50; x->p_vinit = 0.; x->p_dinit = 100.; x->p_ainit = -100.; x->p_damping = 1.; // i.e. no initial damping x->p_dhand = 100.; x->p_force = 1.; // i.e. hand does nothing initially x->p_accel = -100.; x->p_vi = 0.; x->p_di = 100.; x->p_dt = 100.; // changed from 0 to 100 x->p_dtprev = 100.; // changed from 0 to 100 x->p_vt = 0.; x->p_prevchg = 0; */ } /* ---------------------------------------------------------- */ static void pong_timein(t_pong *x, t_floatarg n) { int thischg; x->p_time = n / x->p_warp; x->p_dt = ((x->p_accel * (x->p_time*x->p_time)) + (x->p_time * x->p_vi) + x->p_di); x->p_vt = ((x->p_dt - x->p_dtprev) / x->p_timegrain); if (x->p_dt < 0.) { x->p_dt *= -1.; x->p_di = 0.; x->p_vi = x->p_vt * (-1. * x->p_damping); // -1 will eventually be a damping variable //post("vel at bounce %f", x->p_vi); outlet_bang(x->p_bounceout); x->p_ms = 0; //x->p_dtprev= 0.; } //else x->p_dtprev = x->p_dt; /* ---------------------------------- virtual hand below ------------ */ if (x->p_dt > x->p_dhand) // presuming the hand is initially equal to the dinit thischg = 1; else thischg = 0; if (thischg != x->p_prevchg) { x->p_ms = 0; x->p_vi = x->p_vt; x->p_di = x->p_dhand; if (thischg == 0) { x->p_accel = -100.; // x->p_ainit in lieu of -100. outlet_float(x->p_handout, 0); } else { x->p_accel = (x->p_force * -100.); // x->p_ainit in lieu of -100. outlet_float(x->p_handout, 1); } } x->p_prevchg = thischg; outlet_float(x->p_velout, x->p_vt); outlet_float(x->p_heightout, x->p_dt); } static void pong_onoff(t_pong *x, t_floatarg n) { if (n != 0) clock_delay(x->p_klok, 0); else clock_unset(x->p_klok); } /* ---------------------------------------------------------- */ static void pong_bang(t_pong *x) { x->p_ms = 0; clock_delay(x->p_klok, 0); } static void pong_stop(t_pong *x) { clock_unset(x->p_klok); } /* ---------------------------------------------------------- */ static void pong_tick(t_pong *x) { clock_delay(x->p_klok, (t_int)x->p_timegrainin); pong_timein(x, x->p_ms); //outlet_float(x->p_heightout, (float)x->p_ms); x->p_ms = x->p_ms + x->p_timegrainin; } /* ---------------------------------------------------------- */ static void pong_tgrain(t_pong *x, t_floatarg n) { x->p_timegrain = n / x->p_warp; x->p_timegrainin = n; post("timegrain %f", x->p_timegrain); } /* ---------------------------------------------------------- */ static void pong_warpin(t_pong *x, t_floatarg n) { x->p_warp = n; x->p_timegrain = x->p_timegrainin / x->p_warp; post("timewarp %f ms = one sec", x->p_warp); } /* ---------------------------------------------------------- */ /* ----- these are to receive and store the init values ----- */ /* ---------------------------------------------------------- */ static void pong_initdist(t_pong *x, t_floatarg n) { x->p_dinit = n; } static void pong_initvel(t_pong *x, t_floatarg n) { x->p_vinit = n; } static void pong_damp(t_pong *x, t_floatarg n) { x->p_damping = n; } /* ---------------------------------------------------------- */ static void pong_baseacc(t_pong *x, t_floatarg n) { //post ("baseaccel currently disabled", 0); x->p_ainit = n; x->p_accel = x->p_ainit; } /* ---------------------------------------------------------- */ static void pong_hand(t_pong *x, t_floatarg n) { x->p_dhand = n; } static void pong_force(t_pong *x, t_floatarg n) { x->p_force = n; } /* ---------------------------------------------------------- */ static t_class *pong_class; static void *pong_new(t_floatarg n) { t_pong *x = (t_pong *)pd_new(pong_class); x->p_klok = clock_new(x, (t_method)pong_tick); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("dist")); // distance inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("velo")); // velocity inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("damp")); // damping inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("force")); // hand force 1.0 = no force inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("hand")); // virtual hand (distance) if (n > 0) x->p_warp = n; else x->p_warp = 1000.; x->p_ms = 0; x->p_time = 0.; x->p_timegrain = 0.05; // if ms grain = 50 x->p_timegrainin = 50.0; x->p_vinit = 0.; x->p_dinit = 100.; x->p_ainit = -100.; x->p_damping = 1.; // i.e. no initial damping x->p_dhand = 100.; x->p_force = 1.; // i.e. hand does nothing initially x->p_accel = -100.; x->p_vi = 0.; x->p_di = 100.; x->p_dt = 100.; // changed from 0 to 100 x->p_dtprev = 100.; // changed from 0 to 100 x->p_vt = 0.; x->p_prevchg = 0; x->p_bounceout = outlet_new(&x->x_obj, gensym("bang")); x->p_handout = outlet_new(&x->x_obj, gensym("float")); x->p_velout = outlet_new(&x->x_obj, gensym("float")); x->p_heightout = outlet_new(&x->x_obj, gensym("float")); return (x); } #ifndef MAXLIB void pong_setup(void) { pong_class = class_new(gensym("pong"), (t_newmethod)pong_new, 0, sizeof(t_pong), 0, A_DEFFLOAT, 0); #else void maxlib_pong_setup(void) { pong_class = class_new(gensym("maxlib_pong"), (t_newmethod)pong_new, 0, sizeof(t_pong), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)pong_new, gensym("pong"), A_DEFFLOAT, 0); #endif /* method handlers for inlets */ class_addmethod(pong_class, (t_method)pong_initdist, gensym("dist"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_initvel, gensym("velo"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_damp, gensym("damp"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_force, gensym("force"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_hand, gensym("hand"), A_FLOAT, 0); /* method handlers for other messages to first inlet */ class_addmethod(pong_class, (t_method)pong_tgrain, gensym("timegrain"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_warpin, gensym("timewarp"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_baseacc, gensym("baseaccel"), A_FLOAT, 0); class_addmethod(pong_class, (t_method)pong_reset, gensym("reset"), 0); class_addmethod(pong_class, (t_method)pong_stop, gensym("stop"), 0); class_addfloat(pong_class, pong_onoff); class_addbang(pong_class, pong_bang); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(pong_class, gensym("maxlib/pong-help.pd")); #endif } maxlib-1.5.5/split.c0000644000076500007650000000725412076104537012770 0ustar hanshans/* ------------------------- split ------------------------------------------ */ /* */ /* splits input to lie within an output range. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include static char *version = "split v0.1, written by Olaf Matthes "; typedef struct split { t_object x_ob; t_float x_min; /* low border of input range */ t_float x_max; /* high border of input range */ t_int x_revert; /* range is inverted */ t_outlet *x_outlet1; /* path-through outlet */ t_outlet *x_outlet2; /* split outlet */ } t_split; static void split_float(t_split *x, t_floatarg f) { if(x->x_max >= x->x_min) { if(f <= x->x_max && f >= x->x_min) outlet_float(x->x_outlet1, f); else outlet_float(x->x_outlet2, f); } else { if(f >= x->x_max && f <= x->x_min) outlet_float(x->x_outlet1, f); else outlet_float(x->x_outlet2, f); } } static t_class *split_class; static void *split_new(t_floatarg fmin, t_floatarg fmax) { t_split *x = (t_split *)pd_new(split_class); floatinlet_new(&x->x_ob, &x->x_min); floatinlet_new(&x->x_ob, &x->x_max); x->x_outlet1 = outlet_new(&x->x_ob, gensym("float")); x->x_outlet2 = outlet_new(&x->x_ob, gensym("float")); x->x_min = fmin; x->x_max = fmax; return (void *)x; } #ifndef MAXLIB void split_setup(void) { split_class = class_new(gensym("split"), (t_newmethod)split_new, 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addfloat(split_class, split_float); logpost(NULL, 4, version); } #else void maxlib_split_setup(void) { split_class = class_new(gensym("maxlib_split"), (t_newmethod)split_new, 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)split_new, gensym("split"), A_DEFFLOAT, A_DEFFLOAT, 0); class_addfloat(split_class, split_float); class_sethelpsymbol(split_class, gensym("maxlib/split-help.pd")); } #endif maxlib-1.5.5/timebang.c0000644000076500007650000001476512076104537013430 0ustar hanshans/* ------------------------- timebang --------------------------------------- */ /* */ /* Send out bangs at given times (time of day!). */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include #define MAX_TIMES 256 /* maximum number of times to process */ static char *version = "timebang v0.2, written by Olaf Matthes "; typedef struct timebang { t_object x_ob; t_clock *x_clock; t_outlet *x_outlet[MAX_TIMES]; /* the bang outlets */ t_int x_sec[MAX_TIMES]; /* seconds (0 - 59) */ t_int x_min[MAX_TIMES]; /* minutes (0 - 59) */ t_int x_hour[MAX_TIMES]; /* hours (0 - 11) */ t_int x_mday[MAX_TIMES]; /* day of month (1 - 31) */ t_int x_mon[MAX_TIMES]; /* month (0 - 11) */ t_int x_year[MAX_TIMES]; /* year (current year minus 1900) */ t_int x_wday[MAX_TIMES]; /* day of week (0 - 6, Sunday = 0, -1 = all days) */ t_int x_over[MAX_TIMES]; /* indicate that time is over */ t_int x_notimes; /* number of times to bang */ } t_timebang; static void timebang_tick(t_timebang *x) { time_t now = time(NULL); struct tm *newtime; int i; newtime = localtime(&now); /* convert to local time. */ for(i = 0; i < x->x_notimes; i++) { if(!x->x_over[i]) { if(newtime->tm_hour == x->x_hour[i] && newtime->tm_min == x->x_min[i] && newtime->tm_sec >= x->x_sec[i]) { x->x_over[i] = 1; /* mark as 'time is over' */ outlet_bang(x->x_outlet[i]); /* send corresponding bang */ } } else if(newtime->tm_hour != x->x_hour[i]) x->x_over[i] = 0; /* reactivate time one hour later */ } clock_delay(x->x_clock, 1000); /* come back in one second */ } static void timebang_set(t_timebang *x, t_symbol *s, int ac, t_atom *av) { int i, j; if(ac == x->x_notimes * 3) { for(i = 0, j = 0; i < ac; i += 3, j++) { if (av[i].a_type == A_FLOAT) x->x_hour[j] = av[i].a_w.w_float; else { post ("timebang: first argument must be (int) hours"); return; } if (av[i+1].a_type == A_FLOAT) x->x_min[j] = av[i+1].a_w.w_float; else { post ("timebang: second argument must be (int) minutes"); return; } if (av[i+2].a_type == A_FLOAT) x->x_sec[j] = av[i+2].a_w.w_float; else { post ("timebang: third argument must be (int) seconds"); return; } x->x_over[i] = 0; } post("timebang: read in %d times of day:", x->x_notimes); for(i = 0; i < x->x_notimes; i++) { post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]); } } else post("timebang: wrong number of parameter"); } static void timebang_bang(t_timebang *x) { time_t now = time(NULL); struct tm *newtime = localtime(&now); /* convert to local time. */ post("timebang: local time is %02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec); } static t_class *timebang_class; static void *timebang_new(t_symbol *s, int ac, t_atom *av) { int i; t_timebang *x = (t_timebang *)pd_new(timebang_class); x->x_clock = clock_new(x, (t_method)timebang_tick); if(ac > MAX_TIMES * 3) { post("timebang: too many creation arguments"); ac = MAX_TIMES * 3; } x->x_notimes = 0; for(i = 0; i < ac; i += 3) { if (av[i].a_type == A_FLOAT) x->x_hour[x->x_notimes] = av[i].a_w.w_float; else { post ("timebang: first argument must be (int) hours"); return 0; } if (av[i+1].a_type == A_FLOAT) x->x_min[x->x_notimes] = av[i+1].a_w.w_float; else { post ("timebang: second argument must be (int) minutes"); return 0; } if (av[i+2].a_type == A_FLOAT) x->x_sec[x->x_notimes] = av[i+2].a_w.w_float; else { post ("timebang: third argument must be (int) seconds"); return 0; } x->x_over[x->x_notimes] = 0; x->x_notimes++; } post("timebang: read in %d times of day:", x->x_notimes); for(i = 0; i < x->x_notimes; i++) { x->x_outlet[i] = outlet_new(&x->x_ob, gensym("bang")); /* create specific bang outlet for time */ post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]); } clock_set(x->x_clock, 0); return (void *)x; } static void timebang_free(t_timebang *x) { clock_free(x->x_clock); } #ifndef MAXLIB void timebang_setup(void) { timebang_class = class_new(gensym("timebang"), (t_newmethod)timebang_new, (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0); #else void maxlib_timebang_setup(void) { timebang_class = class_new(gensym("maxlib_timebang"), (t_newmethod)timebang_new, (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0); class_addcreator((t_newmethod)timebang_new, gensym("timebang"), A_GIMME, 0); #endif class_addmethod(timebang_class, (t_method)timebang_set, gensym("set"), A_GIMME, 0); class_addbang(timebang_class, (t_method)timebang_bang); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(timebang_class, gensym("maxlib/timebang-help.pd")); #endif } maxlib-1.5.5/limit.c0000644000076500007650000001022512076104537012743 0ustar hanshans/* ------------------------- limit ------------------------------------------ */ /* */ /* limits input to lie within an output range. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include static char *version = "limit v0.1, written by Olaf Matthes "; typedef struct limit { t_object x_ob; t_float x_ol; /* low border of output range */ t_float x_oh; /* high border of output range */ t_float x_ratio; /* 'compression ratio' */ t_outlet *x_outlet1; /* result */ t_float x_f; } t_limit; static void limit_float(t_limit *x, t_floatarg f) { if(x->x_oh < x->x_ol) /* swap values */ { int i = x->x_oh; x->x_oh = x->x_ol; x->x_ol = i; } if(x->x_ratio == 0) /* 'clip' mode */ { if(f > x->x_oh)f = x->x_oh; else if(f < x->x_ol)f = x->x_ol; } else /* 'compress' mode */ { int diff; if(f > x->x_oh) { diff = f - x->x_oh; f = x->x_oh + (diff / x->x_ratio); } else if(f < x->x_ol) { diff = x->x_ol - f; f = x->x_ol - (diff / x->x_ratio); } } outlet_float(x->x_outlet1, f); x->x_f = f; } static void limit_bang(t_limit *x) { limit_float(x, x->x_f); /* recalculate result */ } static t_class *limit_class; static void *limit_new(t_floatarg fol, t_floatarg foh, t_floatarg fr) { t_limit *x = (t_limit *)pd_new(limit_class); floatinlet_new(&x->x_ob, &x->x_ol); floatinlet_new(&x->x_ob, &x->x_oh); floatinlet_new(&x->x_ob, &x->x_ratio); x->x_outlet1 = outlet_new(&x->x_ob, gensym("float")); /* default values taken from Max's limit */ x->x_ol = fol; x->x_oh = foh; if(x->x_oh < x->x_ol) /* swap values */ { int i = x->x_oh; x->x_oh = x->x_ol; x->x_ol = i; } x->x_ratio = fr; x->x_f = 0; return (void *)x; } #ifndef MAXLIB void limit_setup(void) { limit_class = class_new(gensym("limit"), (t_newmethod)limit_new, 0, sizeof(t_limit), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); #else void maxlib_limit_setup(void) { limit_class = class_new(gensym("maxlib_limit"), (t_newmethod)limit_new, 0, sizeof(t_limit), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)limit_new, gensym("limit"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); #endif class_addfloat(limit_class, limit_float); class_addbang(limit_class, limit_bang); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(limit_class, gensym("maxlib/limit-help.pd")); #endif } maxlib-1.5.5/listfunnel-help.pd0000644000076500007650000000201112076104537015111 0ustar hanshans#N canvas 0 26 452 302 12; #X obj 47 160 listfunnel; #X floatatom 47 89 5 0 0 0 - - -; #X obj 47 219 unpack f f; #X floatatom 47 244 5 0 0 0 - - -; #X floatatom 122 246 5 0 0 0 - - -; #X obj 61 194 print listfunnel; #X msg 73 114 17.3 23 147 11; #X text 37 23 listfunnel :: send values out as a list with; #X text 149 38 source index; #X text 149 55 based on code found on the web; #X msg 210 113 99 \$1 12; #X floatatom 210 86 5 0 0 0 - - -; #N canvas 399 175 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 85 OUTLET_0 list; #X text 12 5 KEYWORDS control list_op; #X text 12 45 DESCRIPTION send values out as a list with source index ; #X text 12 65 INLET_0 float list; #X restore 386 264 pd META; #X connect 0 0 5 0; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 2 1 4 0; #X connect 6 0 0 0; #X connect 10 0 0 0; #X connect 11 0 10 0; maxlib-1.5.5/edge-help.pd0000644000076500007650000000177012076104537013645 0ustar hanshans#N canvas 0 26 452 302 12; #X obj 100 154 edge; #X obj 100 215 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 127 186 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 156 186 falling edge detected; #X text 128 216 rising edge detected; #X text 31 16 edge :: detect rising or falling edge in floats; #X floatatom 126 111 5 0 0 0 - - -; #X obj 100 79 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 94 35 written by ; #N canvas 293 158 494 344 META 0; #X text 12 145 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 125 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control analysis; #X text 12 45 DESCRIPTION detect rising or falling edge in floats; #X text 12 65 INLET_0 float; #X text 12 85 OUTLET_0 bang; #X text 12 105 OUTLET_1 bang; #X restore 385 273 pd META; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 6 0 0 0; #X connect 7 0 0 0; maxlib-1.5.5/beat.c0000644000076500007650000003036712076104537012551 0ustar hanshans/* --------------------------- beat ------------------------------------------ */ /* */ /* Detect the beats per minute of a MIDI stream. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code written by Robert Rowe. */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include #define BEAT_LONG 1500 /* longest time we take into concideration (40 bpm) */ #define BEAT_SHORT 300 /* shortest time we take into concideration (200 bpm) */ static char *version = "beat v0.1, written by Olaf Matthes "; typedef struct { t_int points; /* number of points assigned to this theory */ double expect; /* time of next expected hit */ t_int onbeat; /* whether (1) or not (0) it was on the beat */ } beat_theory; typedef struct /* used for sorting theories */ { t_int points; t_int theory; } beat_sort_record; typedef struct beat { t_object x_ob; t_clock *x_clock; t_outlet *x_outbpm; /* beat as MIDI note number */ t_outlet *x_outms; /* beat in milliseconds */ t_outlet *x_outbeat; /* send a bang whenever beat is 'on beat' */ t_int x_print; /* switch printing to console window on / off */ t_int x_num_beats; /* number of beats we've received */ double x_beat_period; /* time in ms until next expected beat / beat pulse */ beat_theory x_beats[BEAT_LONG]; double x_beatexpect; /* expected time for next beat */ t_int x_on_beat; /* indicate if last event was on beat */ t_int x_band_percent; t_int x_pitch; t_int x_velo; /* helpers needed to do the time calculations */ double x_this_input; double x_last_input; double x_lasttime; double x_lastlasttime; } t_beat; /* ---------------- mathematical functions to work with doubles -------------- */ static double double_abs(double value) { if(value < 0) return (value * -1); else return (value); } /* --------------- beat stuff ------------------------------------------------ */ /* evaluate results: find theory that is the most likely one and print out internal data to console window if print is enabled */ static int beat_evaluate(t_beat *x) { int i, j, K; char string[256]; char info[40]; beat_sort_record theories[BEAT_LONG], *sortp, R; int value; /* the result of the sorting */ for (i = 0; i < BEAT_LONG; i++) { /* prepare sort records */ sortp = &(theories[i]); sortp->points = x->x_beats[i].points; sortp->theory = i; } for (j = 2; j < BEAT_LONG; j++) { /* sort */ i = j - 1; K = theories[j].points; R = theories[j]; while (i > 0) { if (K >= theories[i].points) { theories[i+1] = R; break; } else { theories[i+1] = theories[i]; i -= 1; } } if (i==0) theories[i+1] = R; } /* get leading result */ sortp = &(theories[BEAT_LONG - 1]); value = sortp->theory; /* get our resulting theory */ if(x->x_print) { post(" 0 1 2 3 4 R E"); *string = '\0'; /* print out five leading theories */ sprintf(info, "%4g", x->x_this_input); strcat(string, info); for(i = 1; i < 6; i++) { sortp = &(theories[BEAT_LONG - i]); sprintf(info, " %4d[%3d]", (int) sortp->theory, (int) sortp->points); strcat(string, info); } sprintf(info, " %g %g", clock_getlogicaltime(), x->x_beatexpect); strcat(string, info); post(string); } return value; } /* reduce duration to fit into our processing window */ /* some sort of 'double modulo'... */ static double beat_reduce_offset(double duration) { double temp = duration; int divisor = 2; /* first try dividing by two */ while (temp > BEAT_LONG) /* while duration is too long */ temp = duration / divisor++; /* divide by progressively higher divisors */ return temp; /* return a value in bounds */ } /* * beat_eligible: determine whether an event is eligible for consideration * as a beat theory */ static int beat_eligible(double candidate, int* offsets, int num_offsets) { double diff; int i; if (candidate >= BEAT_LONG) /* if too long try subharmonics */ candidate = beat_reduce_offset(candidate); /* if candidate is close to one already found */ for(i = 0; i < num_offsets; i++) { diff = double_abs((candidate - offsets[i])); if (diff < offsets[i]/20) { if (candidate > offsets[i]) ++offsets[i]; else /* pull existing one */ if (candidate < offsets[i]) /* toward new candidate */ --offsets[i]; return 0; /* declare candidate ineligible */ } } return candidate; /* otherwise return legal candidate */ } static void beat_float(t_beat *x, t_floatarg f) { t_int velo = x->x_velo; int i, j, indx; int num_offsets, candidate; int low_limit, high_limit, width, deviation; int points, band, center_offset, period; beat_theory* t; int offsets[7]; static int factors[10] = { 200, 50, 300, 150, 66, 400, 600, 133, 33, 75 }; double now = clock_getlogicaltime(); t_float outvalue; x->x_pitch = (t_int)f; x->x_this_input = clock_gettimesince(x->x_last_input); if(velo != 0) /* note-on received */ { if(++x->x_num_beats == 1) { goto time; /* only one event, no beats yet */ } num_offsets = 0; candidate = beat_eligible(x->x_this_input, offsets, num_offsets); if(candidate) offsets[num_offsets++] = candidate; /* offset[0] set to incoming offset */ if(x->x_num_beats > 2) { /* if three events */ /* check previous for eligibility */ candidate = beat_eligible(x->x_lasttime, offsets, num_offsets); if (candidate) offsets[num_offsets++] = candidate; candidate = x->x_this_input + x->x_lasttime; /* add current and previous offsets */ candidate = beat_eligible(candidate, offsets, num_offsets); if (candidate) /* add to list if eligible */ offsets[num_offsets++] = candidate; } if(x->x_num_beats > 3) { candidate = beat_eligible(x->x_lastlasttime, offsets, num_offsets); if (candidate) offsets[num_offsets++] = candidate; candidate += x->x_lasttime; candidate = beat_eligible(candidate, offsets, num_offsets); if (candidate) offsets[num_offsets++] = candidate; } indx = 0; for(i = num_offsets; i < 7; i++) { offsets[i] = 0; if (indx >= 10) break; candidate = 0; while ((indx < 10) && (!candidate)) candidate = beat_eligible((x->x_this_input * factors[indx++])/100, offsets, num_offsets); if (candidate) offsets[num_offsets++] = candidate; } for(i = 0; i < num_offsets; i++) { band = offsets[i] * x->x_band_percent / 100; if ((low_limit = offsets[i] - band) < 0) /* add points in a critical band */ low_limit = 0; /* around calculated offset */ if ((high_limit = offsets[i] + band) > BEAT_LONG) high_limit = BEAT_LONG; center_offset = offsets[i]; /* midpoint of increment */ points = 0; for (j = low_limit; j < high_limit; j++) { if ((points = x->x_beats[j].points) > 0) { /* if there is already activation */ deviation = j - center_offset; /* record deviation from midpoint */ x->x_beats[j].points = 0; if (deviation < 0) { /* if there is activation below midpoint */ t = &(x->x_beats[j+1]); /* take theory one above prior */ } else if (deviation > 0) { /* if there is activation above midpoint */ t = &(x->x_beats[j-1]); /* take theory one below prior */ } else t = &(x->x_beats[j]); /* landed right on it */ t->points = points + (num_offsets-i); break; } } if (!points) x->x_beats[center_offset].points = num_offsets - i; } /* boost hits, and suppress theories with missed beats */ period = 0; points = 0; for (i = BEAT_SHORT; i < BEAT_LONG; i++) { t = &(x->x_beats[i]); width = 5 > (t->expect / 7) ? 5 : (t->expect / 7); t->expect -= x->x_this_input; t->onbeat = 0; if(double_abs(t->expect) <= width) /* lies within range */ { t->expect = i; t->onbeat = 1; if (t->points > 0) t->points += 4; /* add 4 points */ } else if(t->expect < 0) { t->points -= 8; t->expect = i; } if (t->points < 0) t->points = 0; else if (t->points > 200) t->points = 200; if (t->points > points) { points = t->points; period = i; } } x->x_beat_period = (double)period; t = &(x->x_beats[period]); x->x_beatexpect = now + (double)t->expect; x->x_on_beat = t->onbeat; time: x->x_lastlasttime = x->x_lasttime; x->x_lasttime = x->x_this_input; //now; x->x_last_input = now; if(x->x_on_beat)outlet_bang(x->x_outbeat); outvalue = (t_float)beat_evaluate(x); outlet_float(x->x_outms, outvalue); if(x->x_beat_period)outlet_float(x->x_outbpm, (t_float)(60000.0 / outvalue)); } return; } static void beat_ft1(t_beat *x, t_floatarg f) { x->x_velo = (t_int)f; } /* toggle printing on/off */ static void beat_print(t_beat *x) { if(x->x_print)x->x_print = 0; else x->x_print = 1; } static void beat_reset(t_beat *x) { int i; for(i = 0; i < BEAT_LONG; i++) { x->x_beats[i].points = 0; x->x_beats[i].expect = i; x->x_beats[i].onbeat = 0; } x->x_lastlasttime = 0; x->x_lasttime = 0; x->x_num_beats = 0; x->x_beat_period = 0; x->x_on_beat = 0; } static t_class *beat_class; static void beat_free(t_beat *x) { /* nothing to do */ } static void *beat_new(t_floatarg f) { t_beat *x = (t_beat *)pd_new(beat_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); x->x_outbpm = outlet_new(&x->x_ob, gensym("float")); x->x_outms = outlet_new(&x->x_ob, gensym("float")); x->x_outbeat = outlet_new(&x->x_ob, gensym("bang")); beat_reset(x); x->x_band_percent = 4; /* allow 4% 'jitter' by default */ if(f)x->x_band_percent = (t_int)f; post("beat: band percentage set to %d", x->x_band_percent); return (void *)x; } #ifndef MAXLIB void beat_setup(void) { beat_class = class_new(gensym("beat"), (t_newmethod)beat_new, (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0); #else void maxlib_beat_setup(void) { beat_class = class_new(gensym("maxlib_beat"), (t_newmethod)beat_new, (t_method)beat_free, sizeof(t_beat), 0, A_DEFFLOAT, 0); #endif class_addfloat(beat_class, beat_float); class_addmethod(beat_class, (t_method)beat_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(beat_class, (t_method)beat_reset, gensym("reset"), 0); class_addmethod(beat_class, (t_method)beat_print, gensym("print"), 0); #ifndef MAXLIB logpost(NULL, 4, version); #else class_addcreator((t_newmethod)beat_new, gensym("beat"), A_DEFFLOAT, 0); class_sethelpsymbol(beat_class, gensym("maxlib/beat-help.pd")); #endif } maxlib-1.5.5/unroute.c0000644000076500007650000001221312076104537013325 0ustar hanshans/* -------------------------- unroute ------------------------------------- */ /* */ /* Opposit to croute. */ /* Written by Olaf Matthes */ /* Get source at http://www.akustische-kunst.org/puredata/ */ /* */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #define MAX_INLET 256 static char *version = "unroute v0.1, written by Olaf Matthes "; typedef struct unroute { t_object x_obj; t_outlet *x_outlet; t_int x_ninstance; t_atom x_id; } t_unroute; typedef struct proxy { t_object obj; t_int index; /* number of proxy inlet(s) */ t_atom id; t_unroute *x; /* we'll put the other struct in here */ } t_proxy; static void unroute_any(t_unroute *x, t_symbol *s, int argc, t_atom *argv) { int i; t_atom at[MAXPDSTRING]; for(i = 0; i < argc; i++) { at[i + 2] = argv[i]; } argc += 2; SETSYMBOL(at+1, s); at[0] = x->x_id; /* prepend id of that inlet */ outlet_list(x->x_outlet, NULL, argc, at); } static void unroute_list(t_unroute *x, t_symbol *s, int argc, t_atom *argv) { int i; t_atom at[MAXPDSTRING]; for(i = 0; i < argc; i++) { at[i + 1] = argv[i]; } argc++; at[0] = x->x_id; /* prepend id of that inlet */ outlet_list(x->x_outlet, NULL, argc, at); } static void unroute_float(t_unroute *x, t_floatarg f) { t_atom list[2]; list[0] = x->x_id; /* prepend id of that inlet */ SETFLOAT(list+1, f); outlet_list(x->x_outlet, NULL, 2, list); } static void unroute_input(t_proxy *p, t_symbol *s, int argc, t_atom *argv) { t_unroute *x = (t_unroute *)(p->x); int i; t_atom at[MAXPDSTRING]; if(s == gensym("list")) { for(i = 0; i < argc; i++) { at[i + 1] = argv[i]; } argc++; } else { for(i = 0; i < argc; i++) { at[i + 2] = argv[i]; } argc += 2; SETSYMBOL(at+1, s); } at[0] = p->id; /* prepend id for that inlet */ outlet_list(x->x_outlet, NULL, argc, at); } static t_class *unroute_class; static t_class *proxy_class; static void *unroute_new(t_symbol *s, int argc, t_atom *argv) { int i; t_unroute *x = (t_unroute *)pd_new(unroute_class); t_proxy *inlet[MAX_INLET]; x->x_ninstance = argc; x->x_id = argv[0]; for(i = 0; i < x->x_ninstance - 1; i++) { inlet[i] = (t_proxy *)pd_new(proxy_class); inlet[i]->x = x; /* make x visible to the proxy inlets */ inlet[i]->index = i; /* remember our number */ inlet[i]->id = argv[i+1]; /* the inlet we're going to create belongs to the object 't_unroute' but the destination is the instance 'i' of the proxy class 't_proxy' */ inlet_new(&x->x_obj, &inlet[i]->obj.ob_pd, 0,0); } x->x_outlet = outlet_new(&x->x_obj, gensym("float")); return (void *)x; } #ifndef MAXLIB void unroute_setup(void) { unroute_class = class_new(gensym("unroute"), (t_newmethod)unroute_new, 0, sizeof(t_unroute), 0, A_GIMME, 0); #else void maxlib_unroute_setup(void) { unroute_class = class_new(gensym("maxlib_unroute"), (t_newmethod)unroute_new, 0, sizeof(t_unroute), 0, A_GIMME, 0); #endif /* a class for the proxy inlet: */ proxy_class = class_new(gensym("maxlib_unroute_proxy"), NULL, NULL, sizeof(t_proxy), CLASS_PD|CLASS_NOINLET, A_NULL); class_addanything(proxy_class, unroute_input); class_addfloat(unroute_class, unroute_float); class_addlist(unroute_class, unroute_list); class_addanything(unroute_class, unroute_any); #ifndef MAXLIB logpost(NULL, 4, version); #else class_addcreator((t_newmethod)unroute_new, gensym("unroute"), A_GIMME, 0); class_sethelpsymbol(unroute_class, gensym("maxlib/unroute-help.pd")); #endif } maxlib-1.5.5/history.c0000644000076500007650000002124212076104537013327 0ustar hanshans/* -------------------------- history ----------------------------------------- */ /* */ /* Calculates the average value of the elements within the last N seconds. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #define MAX_ARG 1024 /* maximum number of items to average */ #define MAX_TIME 60000 /* maximum time to look back */ static char *version = "history v0.1, written by Olaf Matthes "; typedef struct history { t_object x_ob; t_clock *x_clock; t_inlet *x_inindex; t_outlet *x_outfloat; /* output the history */ t_outlet *x_outtendency; /* outputs the tendency of the average */ t_int x_limit; /* indicates if input is 'blocked' (1) */ t_int x_index; /* the number of elements to average */ t_float x_input[MAX_ARG]; /* stores the input values we need for averaging */ double x_intime[MAX_ARG]; /* stores the time of arrival of an element */ t_int x_inpointer; /* actual position in above array */ t_float x_average; /* what do you guess ? */ t_float x_lastaverage; t_int x_mode; /* how to history: linear or geometric */ t_int x_time; } t_history; /* there must be a function for this in math.h but how is the german 'Fakultät' called in english ???? */ static int normalise(int i) { int ret = i; while(i--) { if(i == 0)break; ret += i; } return (ret); } static void history_tick(t_history *x) { t_float tendency = 0.0; if(x->x_lastaverage < x->x_average) { tendency = 1.0; /* getting more */ } else if(x->x_lastaverage > x->x_average) { tendency = -1.0; /* getting less */ } else tendency = 0.0; /* nothing has changed */ outlet_float(x->x_outtendency, tendency); x->x_lastaverage = x->x_average; clock_delay(x->x_clock, x->x_time); } static void history_float(t_history *x, t_floatarg f) { int i, j = 0, k = 0, l; t_float geo = 1.0; x->x_average = 0; /* put value into array */ x->x_input[x->x_inpointer] = f; x->x_intime[x->x_inpointer] = clock_getlogicaltime(); /* look for elements that are too old */ x->x_index = 0; for(i = 0; i < MAX_ARG; i++) /* check all valid elements */ { if(x->x_intime[i] != 0) { if(clock_gettimesince(x->x_intime[i]) <= x->x_time) /* it's in our time window */ { x->x_index++; /* count valid entries */ } else /* too old, delete entry */ { x->x_intime[i] = 0; } } } if(x->x_index > 1) { /* calulate history */ for(i = 0; i < MAX_ARG; i++) /* check all valid elements */ { if(x->x_intime[i] != 0) /* it's a valid entry */ { k++; l = MAX_ARG; if(x->x_mode == 0) /* linear */ { x->x_average += x->x_input[i] * (1.0 / (float)x->x_index); } else if(x->x_mode == 1) /* geometric */ { if(x->x_input[i] == 0)x->x_input[i] = 0.001; /* need to cheat a bit... */ geo *= x->x_input[i]; if(k == x->x_index) x->x_average = pow(geo, (1.0/(float)x->x_index)); } else if(x->x_mode == 2) /* weighted */ { /* normalise output */ if(k == x->x_index) { x->x_average += x->x_input[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] * (float)(x->x_index - k); x->x_average = x->x_average / (float)normalise(x->x_index - 1); } else { x->x_average += x->x_input[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] * (float)(x->x_index - k); j--; /* go back in array */ while(l--) /* check if this will result in a valid value */ { if(x->x_intime[(j + x->x_inpointer + MAX_ARG) % MAX_ARG] == 0) { j--; /* go back more if necessary */ } else break; /* finished on first non-zero */ } } } else post("history: internal error!"); } } } else x->x_average = x->x_input[x->x_inpointer]; if(++x->x_inpointer > MAX_ARG) { x->x_inpointer = 0; } outlet_float(x->x_outfloat, x->x_average); } static void history_time(t_history *x, t_floatarg f) { x->x_time = (t_int)f; if(x->x_time < 1) x->x_time = 1; if(x->x_time > MAX_TIME)x->x_time = MAX_TIME; clock_unset(x->x_clock); clock_delay(x->x_clock, 0); } static void history_reset(t_history *x) { int i; /* zeroe out the array */ for(i = 0; i < MAX_ARG; i++) { x->x_input[i] = 0.0; x->x_intime[i] = 0.0; } x->x_index = 0; x->x_inpointer = 0; x->x_average = 0; x->x_lastaverage = 0; post("history: reset"); } static void history_linear(t_history *x) { x->x_mode = 0; post("history: linear"); } static void history_geometric(t_history *x) { x->x_mode = 1; post("history: geometric"); } static void history_weight(t_history *x) { x->x_mode = 2; post("history: weighted"); } static void history_free(t_history *x) { clock_free(x->x_clock); } static t_class *history_class; static void *history_new(t_floatarg f) { int i; t_history *x = (t_history *)pd_new(history_class); x->x_inindex = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time")); x->x_outfloat = outlet_new(&x->x_ob, gensym("float")); x->x_outtendency = outlet_new(&x->x_ob, gensym("float")); x->x_clock = clock_new(x, (t_method)history_tick); /* zeroe out the array */ for(i = 0; i < MAX_ARG; i++) { x->x_input[i] = 0.0; x->x_intime[i] = 0.0; } x->x_time = (t_int)f; if(x->x_time < 1) x->x_time = 1; if(x->x_time > MAX_TIME) { x->x_time = MAX_TIME; post("history: set number time to %d", x->x_time); } x->x_index = 0; x->x_inpointer = 0; x->x_average = 0; x->x_mode = 0; clock_delay(x->x_clock, 0); return (void *)x; } #ifndef MAXLIB void history_setup(void) { history_class = class_new(gensym("history"), (t_newmethod)history_new, (t_method)history_free, sizeof(t_history), 0, A_DEFFLOAT, 0); class_addmethod(history_class, (t_method)history_reset, gensym("reset"), 0); class_addmethod(history_class, (t_method)history_linear, gensym("linear"), 0); class_addmethod(history_class, (t_method)history_geometric, gensym("geometric"), 0); class_addmethod(history_class, (t_method)history_weight, gensym("weight"), 0); class_addfloat(history_class, history_float); class_addmethod(history_class, (t_method)history_time, gensym("time"), A_FLOAT, 0); logpost(NULL, 4, version); } #else void maxlib_history_setup(void) { history_class = class_new(gensym("maxlib_history"), (t_newmethod)history_new, (t_method)history_free, sizeof(t_history), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)history_new, gensym("history"), A_DEFFLOAT, 0); class_addmethod(history_class, (t_method)history_reset, gensym("reset"), 0); class_addmethod(history_class, (t_method)history_linear, gensym("linear"), 0); class_addmethod(history_class, (t_method)history_geometric, gensym("geometric"), 0); class_addmethod(history_class, (t_method)history_weight, gensym("weight"), 0); class_addfloat(history_class, history_float); class_addmethod(history_class, (t_method)history_time, gensym("time"), A_FLOAT, 0); class_sethelpsymbol(history_class, gensym("maxlib/history-help.pd")); } #endif maxlib-1.5.5/allow-help.pd0000644000076500007650000000177612076104537014065 0ustar hanshans#N canvas 0 26 471 308 12; #X text 24 17 allow :: lets only 'allowed' floats or symbols through ; #X text 97 34 written by Olaf Matthes ; #X msg 125 65 cat; #X msg 147 97 dog; #X msg 157 126 bird; #X floatatom 82 269 5 0 0 0 - - -; #X symbolatom 151 246 10 0 0 0 - - -; #X floatatom 40 81 5 0 0 0 - - -; #X obj 82 217 route float symbol; #X obj 82 189 allow 17 cat dog 23; #N canvas 293 158 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 45 DESCRIPTION let only 'allowed' floats or symbols through ; #X text 12 65 INLET_0 float symbol; #X text 12 85 OUTLET_0 float symbol; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control filter; #X restore 415 283 pd META; #X msg 125 157 symbol \$1; #X connect 2 0 11 0; #X connect 3 0 11 0; #X connect 4 0 11 0; #X connect 7 0 9 0; #X connect 8 0 5 0; #X connect 8 1 6 0; #X connect 9 0 8 0; #X connect 11 0 9 0; maxlib-1.5.5/weibull-help.pd0000644000076500007650000000165012076104537014401 0ustar hanshans#N canvas 0 26 467 282 12; #X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 70 192 5 0 0 0 - - -; #X floatatom 151 94 5 0 0 0 - - -; #X floatatom 233 116 5 0 0 0 - - -; #X obj 70 140 weibull 0.78 1.3; #X text 286 117 t; #X text 204 95 s; #X text 103 247 s and t must be greater than zero; #X text 39 21 weibull :: Weibull distributed random numbers; #N canvas 341 152 494 344 META 0; #X text 12 165 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 145 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control random; #X text 12 125 OUTLET_0 float; #X text 12 45 DESCRIPTION Weibull distributed random numbers; #X text 12 85 INLET_1 float; #X text 12 105 INLET_2 float; #X text 12 65 INLET_0 bang; #X restore 410 254 pd META; #X connect 0 0 4 0; #X connect 2 0 4 1; #X connect 3 0 4 2; #X connect 4 0 1 0; maxlib-1.5.5/nroute-help.pd0000644000076500007650000000277112076104537014257 0ustar hanshans#N canvas 10 3 630 380 12; #X floatatom 116 199 5 0 0 0 - - -; #X obj 41 290 print matched; #X obj 116 256 print failed; #X msg 78 151 8; #X obj 41 226 nroute 8 2; #X msg 41 77 0 8 15; #X msg 56 105 17 3 45; #X msg 116 153 3; #X text 170 197 position to match; #X floatatom 427 204 5 0 0 0 - - -; #X obj 336 293 print matched; #X obj 427 259 print failed; #X obj 336 229 nroute fly 2; #X msg 381 178 go; #X msg 417 178 walk; #X msg 336 80 swifts fly high; #X msg 351 108 dogs walk slow; #X msg 363 141 please go go; #X text 153 152 what to match; #X text 54 8 nroute :: route if Nth argument is matched; #X text 135 24 written by Olaf Matthes ; #N canvas 260 141 494 344 META 0; #X text 12 65 TEMPLATE template-help.pd v0.1; #X text 12 85 PLATFORM windows macosx gnulinux; #X text 12 5 GENRE help; #X text 12 165 WEBSITE; #X text 12 205 RELEASE_VERSION 0.42; #X text 12 225 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 125 LIBRARY external maxlib; #X text 12 45 LICENSE; #X text 12 185 RELEASE_DATE; #X text 12 25 KEYWORDS control; #X text 12 105 DATATYPE float symbol list; #X text 12 145 AUTHOR Olaf Matthes; #X restore 571 354 pd META; #X connect 0 0 4 2; #X connect 3 0 4 1; #X connect 4 0 1 0; #X connect 4 1 2 0; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 7 0 4 1; #X connect 9 0 12 2; #X connect 12 0 10 0; #X connect 12 1 11 0; #X connect 13 0 12 1; #X connect 14 0 12 1; #X connect 15 0 12 0; #X connect 16 0 12 0; #X connect 17 0 12 0; maxlib-1.5.5/rewrap.c0000644000076500007650000001143012076104537013124 0ustar hanshans/* ------------------------- rewrap ------------------------------------------ */ /* */ /* rewraps input to lie within an output range. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include static char *version = "rewrap v0.1, written by Olaf Matthes "; typedef struct rewrap { t_object x_ob; t_float x_min; /* low border of input range */ t_float x_max; /* high border of input range */ t_outlet *x_outlet1; /* path-through outlet */ t_outlet *x_outlet2; /* rewrap outlet */ } t_rewrap; static void rewrap_float(t_rewrap *x, t_floatarg f) { t_float min = x->x_min; t_float max = x->x_max; t_float range = 2.0f * (max - min); t_int i; if(range == 0.0f) { f = min; outlet_float(x->x_outlet2, 0); } else if(f < min) { float diff = min - f; float n = ceil(diff / range); f += n * range; if(f >= max) { f = 2 * max - f; n -= 0.5; } outlet_float(x->x_outlet2, (t_int)(-2.0f * n)); } else if (f >= max) { float diff = f - max; float n = floor(diff / range) + 1.0f; f -= n * range; if(f < min) { f = 2 * min - f; n -= 0.5; } outlet_float(x->x_outlet2, (t_int)(2.0f * n)); } else outlet_float(x->x_outlet2, 0.0f); outlet_float(x->x_outlet1, f); } static void rewrap_a(t_rewrap *x, t_floatarg a) { t_float max = x->x_max; if(a <= max) x->x_min = a; else { x->x_min = max; x->x_max = a; } } static void rewrap_b(t_rewrap *x, t_floatarg b) { t_float min = x->x_min; if(b >= min) x->x_max = b; else { x->x_max = min; x->x_min = b; } } static t_class *rewrap_class; static void *rewrap_new(t_floatarg fmin, t_floatarg fmax) { t_rewrap *x = (t_rewrap *)pd_new(rewrap_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a")); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b")); x->x_outlet1 = outlet_new(&x->x_ob, gensym("float")); x->x_outlet2 = outlet_new(&x->x_ob, gensym("float")); x->x_min = fmin; rewrap_b(x, fmax); return (void *)x; } #ifndef MAXLIB void rewrap_setup(void) { rewrap_class = class_new(gensym("rewrap"), (t_newmethod)rewrap_new, 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addfloat(rewrap_class, rewrap_float); class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0); class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0); logpost(NULL, 4, version); } #else void maxlib_rewrap_setup(void) { rewrap_class = class_new(gensym("maxlib_rewrap"), (t_newmethod)rewrap_new, 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)rewrap_new, gensym("rewrap"), A_DEFFLOAT, A_DEFFLOAT, 0); class_addfloat(rewrap_class, rewrap_float); class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0); class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0); class_sethelpsymbol(rewrap_class, gensym("maxlib/rewrap-help.pd")); } #endif maxlib-1.5.5/pong-help.pd0000644000076500007650000000135312076104537013701 0ustar hanshans#N canvas 1 88 450 300 10; #X text 24 14 a bouncing ball model!; #X text 53 45 Based on pong (for Max) version 1.5 written by Richard Dudas.; #N canvas 458 88 494 344 META 0; #X text 12 285 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 265 AUTHOR Olaf Matthes ; #X text 12 165 INLET_5; #X text 12 145 INLET_4; #X text 12 125 INLET_3; #X text 12 105 INLET_2; #X text 12 85 INLET_1; #X text 12 65 INLET_0; #X text 12 185 OUTLET_0; #X text 12 205 OUTLET_1; #X text 12 225 OUTLET_2; #X text 12 245 OUTLET_3; #X text 12 45 DESCRIPTION bouncing ball model; #X text 12 5 KEYWORDS control; #X restore 390 269 pd META; #X obj 153 121 pong 1.23321e+07; maxlib-1.5.5/deny-help.pd0000644000076500007650000000172412076104537013677 0ustar hanshans#N canvas 0 26 437 310 12; #X text 97 34 written by Olaf Matthes ; #X msg 125 65 cat; #X msg 147 97 dog; #X msg 157 126 bird; #X floatatom 82 269 5 0 0 0 - - -; #X symbolatom 151 246 10 0 0 0 - - -; #X obj 114 156 symbol \$1; #X floatatom 40 81 5 0 0 0 - - -; #X obj 82 217 route float symbol; #X obj 82 189 deny 17 cat dog 23; #N canvas 293 158 494 344 META 0; #X text 12 126 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 106 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control; #X text 12 45 DESCRIPTION blocks denied floats or symbols; #X text 12 66 INLET_0 symbol float; #X text 12 86 OUTLET_0 float symbol; #X restore 375 278 pd META; #X text 32 18 deny :: blocks denied floats or symbols; #X connect 1 0 6 0; #X connect 2 0 6 0; #X connect 3 0 6 0; #X connect 6 0 9 0; #X connect 7 0 9 0; #X connect 8 0 4 0; #X connect 8 1 5 0; #X connect 9 0 8 0; maxlib-1.5.5/chord-help.pd0000644000076500007650000000333312076104537014035 0ustar hanshans#N canvas 0 26 500 334 12; #X floatatom 15 276 5 0 0 0 - - -; #X symbolatom 44 212 48 0 0 0 - - -; #X floatatom 74 149 5 0 0 0 - - -; #X floatatom 131 149 5 0 0 0 - - -; #X floatatom 189 149 5 0 0 0 - - -; #X floatatom 248 149 5 0 0 0 - - -; #X floatatom 59 182 5 0 0 0 - - -; #X text 71 276 MIDI note number of bass note; #X text 116 175 root position (0) \, 1st inversion (1); #X text 115 188 or 2nd inversion (2); #X floatatom 29 249 5 0 0 0 - - -; #X text 84 251 class of bass note; #X text 231 118 list of chord notes; #X obj 15 51 notein; #X obj 15 86 chord 59; #X text 90 86 <-- notes higher than 59 get ignored; #X text 15 9 chord :: tries to detect chords; #X text 89 232 notes in chord : chord name; #X text 89 26 written by Olaf Matthes ; #X text 89 44 based on code by Rober Rowe; #X obj 74 118 unpack f f f f f f; #X floatatom 303 149 5 0 0 0 - - -; #X floatatom 362 149 5 0 0 0 - - -; #N canvas 293 158 494 344 META 0; #X text 12 226 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 206 AUTHOR Olaf Matthes ; #X text 12 86 INLET_1 float; #X text 12 106 OUTLET_0 float; #X text 12 45 DESCRIPTION tries to detect chords; #X text 12 5 KEYWORDS control analysis; #X text 12 126 OUTLET_1 float; #X text 12 166 OUTLET_3 float; #X text 12 146 OUTLET_2 symbol; #X text 12 186 OUTLET_4 list; #X text 12 66 INLET_0 float; #X restore 435 308 pd META; #X connect 13 0 14 0; #X connect 13 1 14 1; #X connect 14 0 0 0; #X connect 14 1 10 0; #X connect 14 2 1 0; #X connect 14 3 6 0; #X connect 14 4 20 0; #X connect 20 0 2 0; #X connect 20 1 3 0; #X connect 20 2 4 0; #X connect 20 3 5 0; #X connect 20 4 21 0; #X connect 20 5 22 0; maxlib-1.5.5/rewrap-help.pd0000644000076500007650000000235012076104537014234 0ustar hanshans#N canvas 0 26 483 404 12; #X floatatom 27 304 8 0 0 0 - - -; #X floatatom 27 73 5 0 0 0 - - -; #X text 202 47 written by ; #X floatatom 60 133 5 0 0 0 - - -; #X floatatom 94 158 5 0 0 0 - - -; #X text 84 71 input value; #X text 57 102 creation arguments can be changed dynamically:; #X text 35 341 creation arguments:; #X text 115 132 lower limit; #X text 146 157 upper limit; #X floatatom 110 276 5 0 0 0 - - -; #X text 36 358 wrap ; #X obj 27 249 rewrap 6 40; #X text 200 27 into a range; #X text 169 275 wrap period; #X text 107 305 output; #X text 122 11 rewrap :: wraps floats back and forth; #N canvas 293 158 494 344 META 0; #X text 12 185 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 165 AUTHOR Olaf Matthes ; #X text 12 45 DESCRIPTION wraps floats back and forth into a range ; #X text 12 5 KEYWORDS control; #X text 12 65 INLET_0 float; #X text 12 85 INLET_1 float; #X text 12 105 INLET_2 float; #X text 12 125 OUTLET_0 float; #X text 12 145 OUTLET_1 float; #X restore 413 364 pd META; #X connect 1 0 12 0; #X connect 3 0 12 1; #X connect 4 0 12 2; #X connect 12 0 0 0; #X connect 12 1 10 0; maxlib-1.5.5/listfifo.c0000644000076500007650000001023412076104537013444 0ustar hanshans/* ---------------------------- listfifo -------------------------------------- */ /* */ /* Fifo buffer of lists, empties itselfe on every bang (in order of coming in) */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #define MAX_ELEM 256 /* maximum number of list elements to pass on */ static char *version = "listfifo v0.1, written by Olaf Matthes "; typedef struct listfifo { t_object d_ob; t_atom *getal; /* stores the list values */ t_int *getsize; /* stores the number of elements in list */ t_int count, end, size; t_outlet *out; }t_listfifo; static t_class *listfifo_class; static void listfifo_list(t_listfifo *x, t_symbol *s, int argc, t_atom *argv) { int i; if(argc > MAX_ELEM) { post("listfifo: to many arguments in list, ignored"); return; } for(i = 0; i < argc; i++) x->getal[(x->count * MAX_ELEM) + i] = argv[i]; x->getsize[x->count] = argc; x->count = (x->count + 1) % x->size; // post("got %d elements", argc); } static void listfifo_bang(t_listfifo *x) { // post("count = %d, end = %d", x->count, x->end); if (x->end != x->count){ outlet_list(x->out, NULL, x->getsize[x->end], x->getal+(x->end * MAX_ELEM)); x->end = (x->end + 1) % x->size; } } static void listfifo_free(t_listfifo *x) { freebytes(x->getsize, x->size * sizeof(t_int)); freebytes(x->getal, x->size * sizeof(t_float) * MAX_ELEM); } static void *listfifo_new(t_floatarg n) { int i; t_listfifo *x = (t_listfifo *)pd_new(listfifo_class); if (n<10) n = 10; x->size = (t_int)n; x->end = 0; x->count = 0; x->getsize = (t_int *)getbytes(x->size * sizeof(t_int)); x->getal = (t_atom *)getbytes(x->size * sizeof(t_atom) * MAX_ELEM); x->out = outlet_new(&x->d_ob, gensym("list")); return (x); } #ifndef MAXLIB void listfifo_setup(void) { listfifo_class = class_new(gensym("listfifo"), (t_newmethod)listfifo_new, (t_method)listfifo_free, sizeof(t_listfifo), 0, A_DEFFLOAT, 0); class_addbang(listfifo_class, listfifo_bang); class_addlist(listfifo_class, listfifo_list); logpost(NULL, 4, version); } #else void maxlib_listfifo_setup(void) { listfifo_class = class_new(gensym("maxlib_listfifo"), (t_newmethod)listfifo_new, (t_method)listfifo_free, sizeof(t_listfifo), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)listfifo_new, gensym("listfifo"), A_DEFFLOAT, 0); class_addbang(listfifo_class, listfifo_bang); class_addlist(listfifo_class, listfifo_list); class_sethelpsymbol(listfifo_class, gensym("maxlib/listfifo-help.pd")); } #endif maxlib-1.5.5/minus-help.pd0000644000076500007650000000205712076104537014073 0ustar hanshans#N canvas 0 26 464 316 12; #X floatatom 54 217 5 0 0 0 - - -; #X floatatom 54 127 5 0 0 0 - - -; #X floatatom 107 127 5 0 0 0 - - -; #X text 39 20 minus :: like '-' but calculates result; #X text 133 204 use creation arguments to set initial; #X text 133 220 values for inlets; #X msg 23 83 bang; #X text 69 82 calculate and output result now; #X obj 54 172 minus 8 6 4; #X floatatom 161 127 5 0 0 0 - - -; #X text 120 38 when leftmost or second inlet is changed; #N canvas 474 26 494 344 META 0; #X text 12 185 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 165 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control; #X text 12 45 DESCRIPTION like [-] but calculates result when leftmost or second inlet is changed; #X text 12 85 INLET_0 bang float; #X text 12 105 INLET_1 float; #X text 12 145 OUTLET_0 float; #X text 12 125 INLET_N float; #X restore 406 287 pd META; #X connect 1 0 8 0; #X connect 2 0 8 1; #X connect 6 0 8 0; #X connect 8 0 0 0; #X connect 9 0 8 2; maxlib-1.5.5/linear.c0000644000076500007650000000700212076104537013076 0ustar hanshans/* ---------------------------- rand_linear ----------------------------------- */ /* */ /* rand_linear generates a linearly distributed random variable. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code found in Dodge/Jerse "Computer Music" */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include #define fran() (t_float)rand()/(t_float)RAND_MAX static char *version = "linear v0.1, generates linearly distributed random variable\n" " written by Olaf Matthes "; /* -------------------------- rand_linear ------------------------------ */ static t_class *rand_linear_class; typedef struct _rand_linear { t_object x_obj; } t_rand_linear; static void *rand_linear_new(t_floatarg f) { t_rand_linear *x = (t_rand_linear *)pd_new(rand_linear_class); srand( (unsigned)time( NULL ) ); outlet_new(&x->x_obj, &s_float); return (x); } static void rand_linear_bang(t_rand_linear *x) { t_float u1, u2; u1 = fran(); u2 = fran(); if(u2 < u1) u1 = u2; outlet_float(x->x_obj.ob_outlet, u1); } #ifndef MAXLIB void linear_setup(void) { rand_linear_class = class_new(gensym("linear"), (t_newmethod)rand_linear_new, 0, sizeof(t_rand_linear), 0, A_DEFFLOAT, 0); class_addbang(rand_linear_class, rand_linear_bang); class_sethelpsymbol(rand_linear_class, gensym("linear-help.pd")); logpost(NULL, 4, version); } #else void maxlib_linear_setup(void) { rand_linear_class = class_new(gensym("maxlib_linear"), (t_newmethod)rand_linear_new, 0, sizeof(t_rand_linear), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)rand_linear_new, gensym("linear"), A_DEFFLOAT, 0); class_addbang(rand_linear_class, rand_linear_bang); class_sethelpsymbol(rand_linear_class, gensym("maxlib/linear-help.pd")); } #endif maxlib-1.5.5/subst.c0000644000076500007650000002773112076104537012777 0ustar hanshans/* ------------------------- subst ------------------------------------------ */ /* */ /* Performs 'self-similar' substitution of a given list of values. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" static char *version = "subst v0.1, self-similar substitution of rows (list or array)\n" " written by Olaf Matthes "; #undef DEBUG //#define DEBUG #define MAXSIZE 1024 #include #include // // Maxlife object data structure // typedef struct subst { t_object x_obj; // must begin every object t_outlet *x_outlist; // outlet for the processed list t_outlet *x_outlength; t_atom x_row[MAXSIZE]; // row of values to get processed t_int x_length; // length of row t_int x_order; // size of the CA field/world t_symbol *x_array; // name of array that holds the data t_garray *x_buf; // content of that array } t_subst; // // Function prototypes for our methods and functions // static t_class *subst_class; // global variable that points to the Maxlife class // // get the sum of intervals from no a to no b // Parameters: the row, it's length, intv a, intev b // static int sum_intv(t_atom *argv, int argc, int a, int b) { int i; int summe = 0; // sum of intervals if(a==b) return(0); // same index if(atom_getintarg(a, argc, argv) == atom_getintarg(b, argc, argv)) return(0); // same value for(i=a;i atom_getintarg(i, argc, argv)) // positive intv. { summe += ((atom_getintarg(i + 1, argc, argv) - atom_getintarg(i, argc, argv)) % 12); } else // negative interval { summe -= ((atom_getintarg(i + 1, argc, argv) - atom_getintarg(i, argc, argv)) % 12); } } return(summe); } //----- Anzahl Partialreihen mit Interval d ------------------------------- static int no_part(t_atom *argv, int argc, int a, int b, int d) // nn { int i,j,r = 0; if(a = b)return(0); for(i = a; i < b; i++) { for(j=a+1;j no_part(argv, argc, a, b, d)) return(-1); for(i = 1; i = (b - a); i++) { for(j = 1; j = b; j++) { if(sum_intv(argv, argc, i, j) == d) r++; } } return(r); } //----- Test, ob Partialreihe der Ordnung o mit Interval d existiert ---------- static int check_part_intv(t_atom *argv, int argc, int o, int d) { int z; for(z = 0; z < argc - o; z++) { if(sum_intv(argv, argc, z, z + o) == d) return(z); // Abstand von Reihenanfang } return(-1); } static int my_random(int range) { int ret = rand(); ret = ret % range; // limit to desired output range return(ret); } // // the substitution algorhythm // static int subst_calc(t_subst *x, int n) { int i,j,k,l,o = x->x_order; int s = -1; int intv; t_atom newrow[MAXSIZE]; t_garray *A = x->x_buf; int npoints; t_float *vec; if(x->x_length <= 1) { post("subst: need some data first!"); return(-1); } srand((unsigned int)clock_getlogicaltime()); if(n == -1) // no interval given: choose one by chance { do { n = my_random(x->x_length - 1); // choose interval intv = sum_intv(x->x_row, x->x_length, n, n + 1); // size of this interval } while(intv == 0); // ...until we found one that is not 0! } else intv = sum_intv(x->x_row, x->x_length, n, n + 1); #ifdef DEBUG post("subst: substitution of %dth interval (%d halftones)", n+1, intv); #endif /* for-Schleife für möglichst lange Substitutionen for(j=anzahlReihe(alteReihe);j>2;j--) */ for(j = x->x_order; j < x->x_length; j++) // prefer lower orders (min. 2) { // search for possible order... s = check_part_intv(x->x_row, x->x_length, j, intv); if(s != -1) // check if there is a partial row with the interval we want { o = j; // save actual order, might be larger then x->x_order break; // ... do it! } if(o == j)break; // found one } for(i = 0; i < x->x_length; i++) { if(i <= n) // just copy values before substitution { newrow[i] = x->x_row[i]; } if((i == n) && (s != -1)) // now substitute { for(k=1;kx_row, x->x_length, s+k-1, s+k))); #ifdef DEBUG post("subst: new interval[%d]: %d ", k, sum_intv(x->x_row, x->x_length, s+k-1, s+k)); #endif } post("subst: replaced interval %d (%d halftones) with %d new intervals", n, intv, o); } else if((i == n) && (s == -1)) // not partial row found { o = 1; // order is 1 -> now substitution newrow[i] = x->x_row[i]; // copy the next value of the row post("subst: coundn't find any partial rows to fit in!"); } if(i>n) // behind substitution { newrow[i+(o-1)] = x->x_row[i]; // copy rest or row } } // copy stuff back... x->x_length = l = x->x_length + o - 1; for(i = 0; i < x->x_length; i++) x->x_row[i] = newrow[i]; // write to array if(x->x_array)if (!(A = (t_garray *)pd_findbyclass(x->x_array, garray_class))) error("subst: %s: no such array", x->x_array->s_name); else if (!garray_getfloatarray(A, &npoints, &vec)) error("subst: %s: bad template ", x->x_array->s_name); else { i = 0; if (l >= npoints) // keep end of array { while(npoints--) { *vec++ = atom_getfloat(x->x_row + i); i++; } } else // update { npoints -= l; while (l--) { *vec++ = atom_getfloat(x->x_row + i); i++; } while (npoints--) *vec++ = 0; } garray_redraw(A); } // output stuff outlet_float(x->x_outlength, x->x_length); outlet_list(x->x_outlist, NULL, x->x_length, x->x_row); return(0); } static void subst_list(t_subst *x, t_symbol *s, int argc, t_atom *argv) { t_garray *b = x->x_buf; /* make local copy of array */ float *tab; /* we'll store notes in here */ int items; int i; for(i = 0; i < argc; i++) { x->x_row[i] = argv[i]; // just copy input } x->x_length = argc; } // // choose the array that holds the processed row (output!!) // void subst_set(t_subst *x, t_symbol *s) { t_garray *b; x->x_array = s; if ((b = (t_garray *)pd_findbyclass(s, garray_class))) { post("subst: array set to \"%s\"", s->s_name); x->x_buf = b; } else { post("subst: no array \"%s\" (error %d)", s->s_name, b); x->x_buf = 0; } } // // load row from array (input!!) // static void subst_load(t_subst *x, t_symbol *s) { t_garray *b; /* make local copy of array */ t_float *tab; /* the content itselfe */ int items, i; if ((b = (t_garray *)pd_findbyclass(s, garray_class))) { post("subst: array set to \"%s\"", s->s_name); } else { post("subst: no array \"%s\" (error %d)", s->s_name, b); return; } // read from our array if (!garray_getfloatarray(b, &items, &tab)) { post("subst: couldn't read from array!"); return; } for(i = 0; i < items; i++) { SETFLOAT(x->x_row + i, tab[i]); // copy array into x->x_row } x->x_length = items; post("subst: loaded %d values from array \"%s\"", items, s->s_name); } // // substitute an interval choosen by chance // static void subst_bang(t_subst *x) { subst_calc(x, -1); } // // substitute the Nth interval // static void subst_intv(t_subst *x, t_floatarg f) { int i = (int)f; if(i > x->x_length) i = x->x_length; subst_calc(x, i); } // // set the minimum order of substitution // static void subst_set_order(t_subst *x, t_floatarg f) { x->x_order = (t_int)f; if(x->x_order < 2)x->x_order = 2; post("subst: set order to %d", x->x_order); } // // method to print out: but what? // static void subst_display(t_subst *x) { } // // function to create an instance of the subst class // static void *subst_new(t_symbol *s, int argc, t_atom *argv) { long i; t_symbol *sym; t_subst *x = (t_subst *)pd_new(subst_class); // read in order... x->x_order = 3; if(argc == 1) { x->x_order = atom_getintarg(0, argc, argv); } else if(argc == 2) { sym = atom_getsymbolarg(0, argc, argv); x->x_order = atom_getintarg(1, argc, argv); subst_set(x, sym); } // create outlets x->x_outlist = outlet_new(&x->x_obj, gensym("list")); x->x_outlength = outlet_new(&x->x_obj, gensym("float")); return(x); // always return a copy of the created object } static void subst_free(t_subst *x) { /* nothing to do */ } #ifndef MAXLIB void subst_setup(void) { subst_class = class_new(gensym("subst"), (t_newmethod)subst_new, (t_method)subst_free, sizeof(t_subst), 0, A_GIMME, 0); class_addmethod(subst_class, (t_method)subst_set_order, gensym("order"), A_FLOAT, 0); class_addmethod(subst_class, (t_method)subst_intv, gensym("interval"), A_FLOAT, 0); class_addmethod(subst_class, (t_method)subst_set, gensym("set"), A_SYMBOL, 0); class_addmethod(subst_class, (t_method)subst_load, gensym("load"), A_SYMBOL, 0); class_addmethod(subst_class, (t_method)subst_display, gensym("display"), 0); class_addlist(subst_class, subst_list); class_addbang(subst_class, subst_bang); logpost(NULL, 4, version); } #else void maxlib_subst_setup(void) { subst_class = class_new(gensym("maxlib_subst"), (t_newmethod)subst_new, (t_method)subst_free, sizeof(t_subst), 0, A_GIMME, 0); class_addcreator((t_newmethod)subst_new, gensym("subst"), A_GIMME, 0); class_addmethod(subst_class, (t_method)subst_set_order, gensym("order"), A_FLOAT, 0); class_addmethod(subst_class, (t_method)subst_intv, gensym("interval"), A_FLOAT, 0); class_addmethod(subst_class, (t_method)subst_set, gensym("set"), A_SYMBOL, 0); class_addmethod(subst_class, (t_method)subst_load, gensym("load"), A_SYMBOL, 0); class_addmethod(subst_class, (t_method)subst_display, gensym("display"), 0); class_addlist(subst_class, subst_list); class_addbang(subst_class, subst_bang); class_sethelpsymbol(subst_class, gensym("maxlib/subst-help.pd")); } #endif maxlib-1.5.5/arraycopy-help.pd0000644000076500007650000000512312076104537014746 0ustar hanshans#N canvas 0 26 810 584 12; #N canvas 0 0 450 300 (subpatch) 0; #X array a1 20 float 1; #A 0 0 0 0.342857 0.542857 0.6 -0.442857 -0.485714 0.0142858 -0.428571 -0.114286 0.0857143 -0.2 -0.214285 0.314285 -0.157143 -0.314285 -0.142857 -0.0428571 0.114286 -0.685713; #X coords 0 1 19 -1 200 140 1; #X restore 580 27 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array a2 20 float 1; #A 0 -0.214286 -0.171429 0.1 0.614286 0.757143 0.757143 0.542857 0.2 -0.0285714 -0.271429 -0.414286 -0.514286 -0.528571 -0.485714 -0.371429 -0.157143 0.214286 0.557143 0.714286 0.757143; #X coords 0 1 19 -1 200 140 1; #X restore 581 196 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array a3 20 float 1; #A 0 1.86265e-09 1.86265e-09 1.86265e-09 1.86265e-09 1.86265e-09 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0142857 -0.0285714 -0.0285714 -0.0285714 -0.0285714 -0.0142857 -0.0142857 -0.0142857 ; #X coords 0 1 19 -1 200 140 1; #X restore 580 371 graph; #X text 339 402 set the destination array; #X text 41 1 arraycopy :: copy data from one array to another; #X text 146 22 written by Olaf Matthes ; #X text 87 107 copy the whole array; #X text 156 138 copy from value 10 to 15; #X text 173 168 copy from value 10 the next 5 values; #X msg 85 359 print \$1; #X obj 85 333 tgl 20 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 116 334 switch console printout on/off; #X text 217 200 copy from value 10 to 15; #X text 248 249 copy from value 10 to 15; #X msg 86 414 bang; #X text 137 412 perform last copy; #X text 137 429 operation again; #X text 20 537 creation argument: initial destination array to copy data to; #X obj 200 502 symbol; #N canvas 293 158 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control array; #X text 12 45 DESCRIPTION copy data from one array to another; #X text 12 65 INLET_0 bang copy print; #X text 12 85 INLET_1 symbol; #X restore 745 553 pd META; #X msg 22 109 copy a1; #X msg 43 139 copy a1 10 15; #X msg 60 169 copy a1 10 +5; #X msg 73 201 copy a1 10 15 a2; #X msg 92 250 copy a1 10 15 a2 4; #X text 216 220 into a2 (starting at 0); #X text 247 269 into a2 starting at 4; #X msg 339 428 a2; #X msg 368 454 a3; #X obj 22 500 arraycopy a3; #X connect 9 0 29 0; #X connect 10 0 9 0; #X connect 14 0 29 0; #X connect 18 0 29 1; #X connect 20 0 29 0; #X connect 21 0 29 0; #X connect 22 0 29 0; #X connect 23 0 29 0; #X connect 24 0 29 0; #X connect 27 0 18 0; #X connect 28 0 18 0; maxlib-1.5.5/nchange-help.pd0000644000076500007650000000234612076104537014344 0ustar hanshans#N canvas 0 26 519 345 12; #X obj 30 213 nchange f; #X obj 371 215 nchange l; #X msg 367 144 bla foo dog; #X msg 387 169 bla foo 23; #X msg 348 121 bla foo dog 17; #X obj 200 214 nchange s; #X obj 200 185 symbol; #X msg 200 126 dog; #X msg 216 153 cat; #X obj 162 15 change; #X obj 371 253 print list; #X obj 200 255 print symbol; #X msg 30 152 0; #X msg 43 180 1; #X obj 30 257 print float; #X text 100 34 written by Olaf Matthes ; #X text 12 15 nchange :: a 'new'; #X text 22 77 The creation argument specifies whether nchange works for floats \, symbols or lists.; #N canvas 518 27 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 45 DESCRIPTION change for floats \, symbols \, and lists ; #X text 12 5 KEYWORDS control anything_op symbol_op; #X text 12 65 INLET_0 anything; #X text 12 85 OUTLET_0 anything; #X restore 456 317 pd META; #X connect 0 0 14 0; #X connect 1 0 10 0; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 4 0 1 0; #X connect 5 0 11 0; #X connect 6 0 5 0; #X connect 7 0 6 0; #X connect 8 0 6 0; #X connect 12 0 0 0; #X connect 13 0 0 0; maxlib-1.5.5/linear-help.pd0000644000076500007650000000123412076104537014206 0ustar hanshans#N canvas 0 26 357 302 12; #X obj 70 140 linear; #X obj 70 95 bng 20 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 70 192 5 0 0 0 - - -; #X text 23 20 linear :: linearly distributed random numbers; #N canvas 293 158 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 85 OUTLET_0 float; #X text 12 45 DESCRIPTION linearly distributed random numbers; #X text 12 5 KEYWORDS control random; #X text 12 65 INLET_0 bang; #X restore 295 273 pd META; #X connect 0 0 2 0; #X connect 1 0 0 0; maxlib-1.5.5/step.c0000644000076500007650000001455212076104537012607 0ustar hanshans/* -------------------------- step ------------------------------------------ */ /* */ /* Step to a new value in N milliseconds (similar to line). */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" /* -------------------------- step ------------------------------ */ static char *version = "step v0.1, written by Olaf Matthes "; static t_class *step_class; typedef struct _step { t_object x_obj; t_clock *x_clock; double x_targettime; t_float x_targetval; double x_prevtime; t_float x_setval; int x_gotinlet; t_float x_grain; /* time interval for output */ t_float x_step; /* step size for output */ t_float x_steptime; /* length for one step */ t_int x_stepcall; double x_1overtimediff; double x_in1val; } t_step; static void step_tick(t_step *x) { t_float outvalue; double timenow = clock_getsystime(); double msectogo = - clock_gettimesince(x->x_targettime); if (msectogo < 1E-9) { outlet_float(x->x_obj.ob_outlet, x->x_targetval); } else { if(x->x_setval < x->x_targetval) { /* count upwards */ outvalue = x->x_setval + x->x_stepcall * x->x_step; } else { /* count downwards */ outvalue = x->x_setval - x->x_stepcall * x->x_step; } outlet_float(x->x_obj.ob_outlet, outvalue); clock_delay(x->x_clock, (x->x_steptime > msectogo ? msectogo : x->x_steptime)); } x->x_stepcall++; } static void step_float(t_step *x, t_float f) { double timenow = clock_getsystime(); if (x->x_gotinlet && x->x_in1val > 0 && x->x_step != 0 && f != x->x_setval) { if (timenow > x->x_targettime) x->x_setval = x->x_targetval; else x->x_setval = x->x_setval + x->x_1overtimediff * (timenow - x->x_prevtime) * (x->x_targetval - x->x_setval); x->x_prevtime = timenow; x->x_targetval = f; /* where to end */ x->x_stepcall = 0; /* how long does it take ? */ x->x_targettime = clock_getsystimeafter(x->x_in1val); if(x->x_setval < x->x_targetval) { x->x_steptime = x->x_in1val / (int)((x->x_targetval - x->x_setval) / x->x_step); } else { x->x_steptime = x->x_in1val / (int)((x->x_setval - x->x_targetval) / x->x_step); } // post("steptime %g", x->x_steptime); step_tick(x); x->x_gotinlet = 0; x->x_1overtimediff = 1./ (x->x_targettime - timenow); /* call tick function */ clock_delay(x->x_clock, x->x_steptime); } else { clock_unset(x->x_clock); x->x_targetval = x->x_setval = f; outlet_float(x->x_obj.ob_outlet, f); } x->x_gotinlet = 0; } static void step_ft1(t_step *x, t_floatarg g) { x->x_in1val = g; x->x_gotinlet = 1; } static void step_ft2(t_step *x, t_floatarg g) { if (g <= 0) g = 1; x->x_step = g; x->x_gotinlet = 1; } static void step_stop(t_step *x) { x->x_targetval = x->x_setval; clock_unset(x->x_clock); } static void step_free(t_step *x) { clock_free(x->x_clock); } static void *step_new(t_floatarg f, t_floatarg step, t_floatarg grain) { t_step *x = (t_step *)pd_new(step_class); x->x_targetval = x->x_setval = f; x->x_gotinlet = 0; x->x_1overtimediff = 1; x->x_clock = clock_new(x, (t_method)step_tick); x->x_targettime = x->x_prevtime = clock_getsystime(); if (grain <= 0) grain = 20; x->x_grain = grain; if (step <= 0) step = 1; x->x_step = step; outlet_new(&x->x_obj, gensym("float")); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2")); return (x); } #ifndef MAXLIB void step_setup(void) { step_class = class_new(gensym("step"), (t_newmethod)step_new, (t_method)step_free, sizeof(t_step), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(step_class, (t_method)step_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(step_class, (t_method)step_ft2, gensym("ft2"), A_FLOAT, 0); class_addmethod(step_class, (t_method)step_stop, gensym("stop"), 0); class_addfloat(step_class, (t_method)step_float); logpost(NULL, 4, version); } #else void maxlib_step_setup(void) { step_class = class_new(gensym("maxlib_step"), (t_newmethod)step_new, (t_method)step_free, sizeof(t_step), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)step_new, gensym("step"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(step_class, (t_method)step_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(step_class, (t_method)step_ft2, gensym("ft2"), A_FLOAT, 0); class_addmethod(step_class, (t_method)step_stop, gensym("stop"), 0); class_addfloat(step_class, (t_method)step_float); class_sethelpsymbol(step_class, gensym("maxlib/step-help.pd")); } #endif maxlib-1.5.5/plus-help.pd0000644000076500007650000000206312076104537013720 0ustar hanshans#N canvas 0 26 464 316 12; #X floatatom 54 217 5 0 0 0 - - -; #X floatatom 54 127 5 0 0 0 - - -; #X floatatom 107 127 5 0 0 0 - - -; #X text 133 204 use creation arguments to set initial; #X text 133 220 values for inlets; #X text 26 20 plus :: like '+' but calculates result; #X msg 23 83 bang; #X text 69 82 calculate and output result now; #X obj 54 172 plus 8 6 2; #X floatatom 161 127 5 0 0 0 - - -; #X text 91 40 whenever leftmost or second inlet is changed; #N canvas 295 203 494 344 META 0; #X text 12 185 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 165 AUTHOR Olaf Matthes ; #X text 12 105 INLET_1 float; #X text 12 45 DESCRIPTION like + but calculates result whenever leftmost or second inlet is changed; #X text 12 85 INLET_0 float bang; #X text 12 125 INLET_2 float; #X text 12 145 OUTLET_0 float; #X text 12 5 KEYWORDS control; #X restore 395 283 pd META; #X connect 1 0 8 0; #X connect 2 0 8 1; #X connect 6 0 8 0; #X connect 8 0 0 0; #X connect 9 0 8 2; maxlib-1.5.5/gauss.c0000644000076500007650000000747112076104537012760 0ustar hanshans/* ---------------------------- rand_gauss ----------------------------------- */ /* */ /* rand_gauss generates a gauss distributed random variable. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code found in Dodge/Jerse "Computer Music" */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include #define fran() (t_float)rand()/(t_float)RAND_MAX static char *version = "gauss v0.1, generates a Gaussian distributed random variable\n" " with mean 'mu' and standard deviation 'sigma',\n" " written by Olaf Matthes "; /* -------------------------- rand_gauss ------------------------------ */ static t_class *rand_gauss_class; typedef struct _rand_gauss { t_object x_obj; t_float x_sigma; t_float x_mu; } t_rand_gauss; static void *rand_gauss_new(t_floatarg fs, t_floatarg fm) { t_rand_gauss *x = (t_rand_gauss *)pd_new(rand_gauss_class); srand( (unsigned)time( NULL ) ); floatinlet_new(&x->x_obj, &x->x_sigma); floatinlet_new(&x->x_obj, &x->x_mu); outlet_new(&x->x_obj, &s_float); x->x_sigma = fs; return (x); } static void rand_gauss_bang(t_rand_gauss *x) { t_float u, halfN = 6.0, sum = 0, scale; t_int k, N = 12; scale = 1/sqrt(N/12); for(k = 1; k <= N; k++) sum += fran(); outlet_float(x->x_obj.ob_outlet, x->x_sigma*scale*(sum-halfN)+x->x_mu); } #ifndef MAXLIB void gauss_setup(void) { rand_gauss_class = class_new(gensym("gauss"), (t_newmethod)rand_gauss_new, 0, sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addbang(rand_gauss_class, rand_gauss_bang); class_sethelpsymbol(rand_gauss_class, gensym("gauss-help.pd")); logpost(NULL, 4, version); } #else void maxlib_gauss_setup(void) { rand_gauss_class = class_new(gensym("maxlib_gauss"), (t_newmethod)rand_gauss_new, 0, sizeof(t_rand_gauss), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addcreator((t_newmethod)rand_gauss_new, gensym("gauss"), A_DEFFLOAT, 0); class_addbang(rand_gauss_class, rand_gauss_bang); class_sethelpsymbol(rand_gauss_class, gensym("maxlib/gauss-help.pd")); } #endif maxlib-1.5.5/split-help.pd0000644000076500007650000000260112076104537014066 0ustar hanshans#N canvas 0 26 514 431 12; #X floatatom 27 304 8 0 0 0 - - -; #X floatatom 27 73 5 0 0 0 - - -; #X text 196 28 written by ; #X floatatom 56 131 5 0 0 0 - - -; #X floatatom 85 152 5 0 0 0 - - -; #X text 84 71 input value; #X text 57 104 creation arguments can be changed dynamically:; #X text 35 341 creation arguments:; #X obj 27 249 split 6 40; #X text 111 130 lower limit; #X text 137 151 upper limit; #X text 35 378 All floats that fall below the lower limit or above the upper limit get routed to the 2nd outlet.; #X text 36 358 split ; #X floatatom 102 276 5 0 0 0 - - -; #X text 154 276 floats 'out of range'; #X text 122 11 split :: split incoming floats according to value; #X text 106 305 floats 'in range' (including borders!); #N canvas 292 198 494 344 META 0; #X text 12 190 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 170 AUTHOR Olaf Matthes ; #X text 12 90 INLET_1 float; #X text 12 5 KEYWORDS control filter anything_op; #X text 12 45 DESCRIPTION split incoming floats according to value ; #X text 12 70 INLET_0 float; #X text 12 110 INLET_2 float; #X text 12 130 OUTLET_0 float; #X text 12 150 OUTLET_1 float; #X restore 453 402 pd META; #X connect 1 0 8 0; #X connect 3 0 8 1; #X connect 4 0 8 2; #X connect 8 0 0 0; #X connect 8 1 13 0; maxlib-1.5.5/triang.c0000644000076500007650000000672512076104537013123 0ustar hanshans/* ---------------------------- rand_triang ----------------------------------- */ /* */ /* rand_triang generates a triangularly distributed random variable. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code found in Dodge/Jerse "Computer Music" */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include #define fran() (t_float)rand()/(t_float)RAND_MAX static char *version = "triang v0.1, generates triangularly distributed random variable\n" " written by Olaf Matthes "; /* -------------------------- rand_triang ------------------------------ */ static t_class *rand_triang_class; typedef struct _rand_triang { t_object x_obj; } t_rand_triang; static void *rand_triang_new(t_floatarg f) { t_rand_triang *x = (t_rand_triang *)pd_new(rand_triang_class); srand( (unsigned)time( NULL ) ); outlet_new(&x->x_obj, &s_float); return (x); } static void rand_triang_bang(t_rand_triang *x) { t_float u1, u2; u1 = fran(); u2 = fran(); outlet_float(x->x_obj.ob_outlet, 0.5*(u1+u2)); } #ifndef MAXLIB void triang_setup(void) { rand_triang_class = class_new(gensym("triang"), (t_newmethod)rand_triang_new, 0, sizeof(t_rand_triang), 0, A_DEFFLOAT, 0); #else void maxlib_triang_setup(void) { rand_triang_class = class_new(gensym("maxlib_triang"), (t_newmethod)rand_triang_new, 0, sizeof(t_rand_triang), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)rand_triang_new, gensym("triang"), A_DEFFLOAT, 0); #endif class_addbang(rand_triang_class, rand_triang_bang); #ifndef MAXLIB class_sethelpsymbol(rand_triang_class, gensym("triang-help.pd")); logpost(NULL, 4, version); #else class_sethelpsymbol(rand_triang_class, gensym("maxlib/triang-help.pd")); #endif } maxlib-1.5.5/netrec.c0000644000076500007650000003165012076104537013112 0ustar hanshans/* -------------------------- netrec ---------------------------------------- */ /* */ /* A 'netreceive' that tells the IP of the connecting netsend. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include "s_stuff.h" #include "m_imp.h" #include #include #include #include #include #include #include #ifdef WIN32 #include #include #include #else #include #include #include #include #include #include #include #include #define SOCKET_ERROR -1 #endif #define MAX_CONNECT 32 /* maximum number of connections */ #define INBUFSIZE 4096 /* size of receiving data buffer */ static char *version = "netrec v0.1, written by Olaf Matthes "; /* ----------------------------- netrec ------------------------- */ static t_class *netrec_class; static t_binbuf *inbinbuf; typedef void (*t_netrec_socketnotifier)(void *x); typedef void (*t_netrec_socketreceivefn)(void *x, t_binbuf *b); typedef struct _netrec { t_object x_obj; t_outlet *x_msgout; t_outlet *x_connectout; t_outlet *x_clientno; t_outlet *x_connectionip; t_symbol *x_host[MAX_CONNECT]; t_int x_fd[MAX_CONNECT]; t_int x_sock_fd; int x_connectsocket; int x_nconnections; int x_udp; } t_netrec; typedef struct _netrec_socketreceiver { char *sr_inbuf; int sr_inhead; int sr_intail; void *sr_owner; int sr_udp; t_netrec_socketnotifier sr_notifier; t_netrec_socketreceivefn sr_socketreceivefn; } t_netrec_socketreceiver; static t_netrec_socketreceiver *netrec_socketreceiver_new(void *owner, t_netrec_socketnotifier notifier, t_netrec_socketreceivefn socketreceivefn, int udp) { t_netrec_socketreceiver *x = (t_netrec_socketreceiver *)getbytes(sizeof(*x)); x->sr_inhead = x->sr_intail = 0; x->sr_owner = owner; x->sr_notifier = notifier; x->sr_socketreceivefn = socketreceivefn; x->sr_udp = udp; if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netrec_socketreceiver"); return (x); } /* this is in a separately called subroutine so that the buffer isn't sitting on the stack while the messages are getting passed. */ static int netrec_socketreceiver_doread(t_netrec_socketreceiver *x) { char messbuf[INBUFSIZE], *bp = messbuf; int indx; int inhead = x->sr_inhead; int intail = x->sr_intail; char *inbuf = x->sr_inbuf; if (intail == inhead) return (0); for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1)) { char c = *bp++ = inbuf[indx]; if (c == ';' && (!indx || inbuf[indx-1] != '\\')) { intail = (indx+1)&(INBUFSIZE-1); binbuf_text(inbinbuf, messbuf, bp - messbuf); x->sr_inhead = inhead; x->sr_intail = intail; return (1); } } return (0); } static void netrec_socketreceiver_getudp(t_netrec_socketreceiver *x, int fd) { char buf[INBUFSIZE+1]; int ret = recv(fd, buf, INBUFSIZE, 0); if (ret < 0) { sys_sockerror("recv"); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret > 0) { buf[ret] = 0; #if 0 post("%s", buf); #endif if (buf[ret-1] != '\n') { #if 0 buf[ret] = 0; error("dropped bad buffer %s\n", buf); #endif } else { char *semi = strchr(buf, ';'); if (semi) *semi = 0; binbuf_text(inbinbuf, buf, strlen(buf)); outlet_setstacklim(); if (x->sr_socketreceivefn) (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); else bug("netrec_socketreceiver_getudp"); } } } static void netrec_socketreceiver_read(t_netrec_socketreceiver *x, int fd) { if (x->sr_udp) /* UDP ("datagram") socket protocol */ netrec_socketreceiver_getudp(x, fd); else /* TCP ("streaming") socket protocol */ { char *semi; int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); int ret; t_netrec *y = x->sr_owner; y->x_sock_fd = fd; /* the input buffer might be full. If so, drop the whole thing */ if (readto == x->sr_inhead) { fprintf(stderr, "netrec: dropped message"); x->sr_inhead = x->sr_intail = 0; readto = INBUFSIZE; } else { ret = recv(fd, x->sr_inbuf + x->sr_inhead, readto - x->sr_inhead, 0); if (ret < 0) { sys_sockerror("recv"); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else if (ret == 0) { post("netrec: connection closed on socket %d", fd); if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); sys_rmpollfn(fd); sys_closesocket(fd); } else { x->sr_inhead += ret; if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; while (netrec_socketreceiver_doread(x)) { outlet_setstacklim(); if (x->sr_socketreceivefn) (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); else binbuf_eval(inbinbuf, 0, 0, 0); } } } } } static void netrec_socketreceiver_free(t_netrec_socketreceiver *x) { free(x->sr_inbuf); freebytes(x, sizeof(*x)); } /* ---------------- main netrec stuff --------------------- */ static void netrec_notify(t_netrec *x) { int i, k; /* remove connection from list */ for(i = 0; i < x->x_nconnections; i++) { if(x->x_fd[i] == x->x_sock_fd) { x->x_nconnections--; post("netrec: \"%s\" removed from list of clients", x->x_host[i]->s_name); x->x_host[i] = NULL; /* delete entry */ x->x_fd[i] = -1; /* rearrange list now: move entries to close the gap */ for(k = i; k < x->x_nconnections; k++) { x->x_host[k] = x->x_host[k + 1]; x->x_fd[k] = x->x_fd[k + 1]; } } } outlet_float(x->x_connectout, x->x_nconnections); } static void netrec_doit(void *z, t_binbuf *b) { t_atom messbuf[1024]; t_netrec *x = (t_netrec *)z; int msg, natom = binbuf_getnatom(b); t_atom *at = binbuf_getvec(b); int i; /* output clients IP and socket no */ for(i = 0; i < x->x_nconnections; i++) { if(x->x_fd[i] == x->x_sock_fd) { outlet_symbol(x->x_connectionip, x->x_host[i]); break; } } outlet_float(x->x_clientno, x->x_sock_fd); /* process data */ for (msg = 0; msg < natom;) { int emsg; for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA && at[emsg].a_type != A_SEMI; emsg++); if (emsg > msg) { int ii; for (ii = msg; ii < emsg; ii++) if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM) { pd_error(x, "netrec: got dollar sign in message"); goto nodice; } if (at[msg].a_type == A_FLOAT) { if (emsg > msg + 1) outlet_list(x->x_msgout, 0, emsg-msg, at + msg); else outlet_float(x->x_msgout, at[msg].a_w.w_float); } else if (at[msg].a_type == A_SYMBOL) outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, emsg-msg-1, at + msg + 1); } nodice: msg = emsg + 1; } } static void netrec_connectpoll(t_netrec *x) { struct sockaddr_in incomer_address; int sockaddrl = (int) sizeof( struct sockaddr ); int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl); if (fd < 0) post("netrec: accept failed"); else { t_netrec_socketreceiver *y = netrec_socketreceiver_new((void *)x, (t_netrec_socketnotifier)netrec_notify, (x->x_msgout ? netrec_doit : 0), 0); sys_addpollfn(fd, (t_fdpollfn)netrec_socketreceiver_read, y); x->x_nconnections++; x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr)); x->x_fd[x->x_nconnections - 1] = fd; // outlet_symbol( x->x_connectionip, x->x_host[x->x_nconnections - 1]); post("netrec: accepted connection from %s on socket %d", x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]); outlet_float(x->x_connectout, x->x_nconnections); } } static void netrec_print(t_netrec *x) { int i; if(x->x_nconnections > 0) { post("netrec: %d open connections:", x->x_nconnections); for(i = 0; i < x->x_nconnections; i++) { post(" \"%s\" on socket %d", x->x_host[i]->s_name, x->x_fd[i]); } } else post("netrec: no open connections"); } static void *netrec_new(t_symbol *compatflag, t_floatarg fportno, t_floatarg udpflag) { t_netrec *x; int i; struct sockaddr_in server; int sockfd, portno = fportno, udp = (udpflag != 0); int old = !strcmp(compatflag->s_name , "old"); /* create a socket */ sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0); #if 1 post("netrec: receive socket %d\n", sockfd); #endif if (sockfd < 0) { sys_sockerror("socket"); return (0); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; #ifdef IRIX /* this seems to work only in IRIX but is unnecessary in Linux. Not sure what NT needs in place of this. */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) post("setsockopt failed\n"); #endif /* assign server port number */ server.sin_port = htons((u_short)portno); /* name the socket */ if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) { sys_sockerror("bind"); sys_closesocket(sockfd); return (0); } x = (t_netrec *)pd_new(netrec_class); if (old) { /* old style, nonsecure version */ x->x_msgout = 0; } else x->x_msgout = outlet_new(&x->x_obj, &s_anything); if (udp) /* datagram protocol */ { t_netrec_socketreceiver *y = netrec_socketreceiver_new((void *)x, (t_netrec_socketnotifier)netrec_notify, (x->x_msgout ? netrec_doit : 0), 1); sys_addpollfn(sockfd, (t_fdpollfn)netrec_socketreceiver_read, y); x->x_connectout = 0; } else /* streaming protocol */ { if (listen(sockfd, 5) < 0) { sys_sockerror("listen"); sys_closesocket(sockfd); sockfd = -1; } else { sys_addpollfn(sockfd, (t_fdpollfn)netrec_connectpoll, x); x->x_connectout = outlet_new(&x->x_obj, &s_float); x->x_clientno = outlet_new(&x->x_obj, &s_float); x->x_connectionip = outlet_new(&x->x_obj, &s_symbol); inbinbuf = binbuf_new(); } } x->x_connectsocket = sockfd; x->x_nconnections = 0; x->x_udp = udp; for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1; return (x); } static void netrec_free(t_netrec *x) { /* LATER make me clean up open connections */ if (x->x_connectsocket >= 0) { sys_rmpollfn(x->x_connectsocket); sys_closesocket(x->x_connectsocket); } binbuf_free(inbinbuf); } #ifndef MAXLIB void netrec_setup(void) { netrec_class = class_new(gensym("netrec"),(t_newmethod)netrec_new, (t_method)netrec_free, sizeof(t_netrec), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0); class_addmethod(netrec_class, (t_method)netrec_print, gensym("print"), 0); logpost(NULL, 4, version); } #else void maxlib_netrec_setup(void) { netrec_class = class_new(gensym("maxlib_netrec"),(t_newmethod)netrec_new, (t_method)netrec_free, sizeof(t_netrec), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0); class_addcreator((t_newmethod)netrec_new, gensym("netrec"), A_DEFFLOAT, A_DEFFLOAT, A_DEFSYM, 0); class_addmethod(netrec_class, (t_method)netrec_print, gensym("print"), 0); class_sethelpsymbol(netrec_class, gensym("maxlib/netrec-help.pd")); } #endif maxlib-1.5.5/iso.c0000644000076500007650000001635512076104537012431 0ustar hanshans/* ---------------------------- iso ------------------------------------------- */ /* */ /* Queue up pitch and attack point series. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on iso for Max by Charlie Baker (baker@foxtrot.ccmrc.ucsb.edu). */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #define MAXPOLY 32 static char *version = "iso v0.1, written for Max by Charlie Baker \n" " ported to Pd by Olaf Matthes "; /* Iso object data structure */ typedef struct iso { t_object iso_ob; t_outlet *iso_out1; /* outlet 1*/ t_outlet *iso_out2; /* outlet 2*/ t_inlet *iso_in2; /* inlet 2 (attack list) */ t_clock *iso_clock; t_int ptchlength,atklength,curptch,curatk; t_float pitches[MAXPOLY]; t_float atks[MAXPOLY]; t_int loop,stop; t_float hook,duty; } t_iso; static t_class *iso_class; /* take list and create matrix */ static void iso_bang(t_iso *x) { x->stop = 0; x->curptch = 0; x->curatk = 0; clock_delay(x->iso_clock, 0); } static void iso_clock_fun(t_iso *x) { if (!x->stop) { clock_delay(x->iso_clock, (double)(x->atks[x->curatk] * x->hook)); outlet_float(x->iso_out2,(t_float)(x->atks[x->curatk] * x->hook * x->duty)); outlet_float(x->iso_out1,x->pitches[x->curptch] ); if (x->loop) { x->curatk = ((x->curatk + 1) % x->atklength); x->curptch = ((x->curptch + 1) % x->ptchlength); } else { if (((x->curatk + 1) >= x->atklength) || ((x->curptch + 1) >= x->ptchlength)) x->stop = 1; else { x->curptch += 1; x->curatk += 1; } } } } static void iso_hook(t_iso *x, t_floatarg hook) { if (hook < 1.0) hook = 1.0; x->hook = (t_float)hook; } static void iso_duty(t_iso *x, t_floatarg duty) { if (duty < 1.0) duty = 1.0; x->duty = (t_float)duty; } static void iso_list(t_iso *x, t_symbol *s, t_int argc, t_atom* argv) { int i; if (argc > MAXPOLY) post("iso: only %d values max. allowed in list!", MAXPOLY); for (i = 0; i < argc; i++) x->atks[i] = argv[i].a_w.w_float; x->atklength = argc; } static void iso_pitch(t_iso *x, t_symbol *s, t_int argc, t_atom* argv) { int i; if (argc > MAXPOLY) post("iso: only %d values max. allowed in list!", MAXPOLY); for (i = 0; i < argc; i++) x->pitches[i] = argv[i].a_w.w_float; x->ptchlength = argc; } static void iso_start(t_iso *x, t_symbol *s, t_int argc, t_atom* argv) { t_int start = atom_getfloatarg(0, argc, argv); x->stop = 0; if (start) { x->curptch = (t_int)((start - 1) % x->ptchlength); x->curatk = (t_int)((start - 1) % x->atklength); } else { x->curptch = 0; x->curatk = 0; } clock_delay(x->iso_clock, 0); } static void iso_stop(t_iso *x) { x->stop = 1; x->curatk = 0; x->curptch = 0; } static void iso_pause(t_iso *x) { x->stop = 1; } static void iso_loop(t_iso *x) { x->loop = 1; } static void iso_resume(t_iso *x) { x->stop = 0; clock_delay(x->iso_clock, 0); } static void iso_unloop(t_iso *x) { x->loop = 0; } static void *iso_new(void) { t_iso *x = (t_iso *)pd_new(iso_class); /* allocates memory and sticks in an inlet */ x->iso_clock = clock_new(x, (t_method)iso_clock_fun); x->iso_out1 = outlet_new(&x->iso_ob, gensym("float")); x->iso_out2 = outlet_new(&x->iso_ob, gensym("float")); x->iso_in2 = inlet_new(&x->iso_ob, &x->iso_ob.ob_pd, gensym("list"), gensym("attack")); x->stop = 0; x->loop = 1; x->hook = 1.0; x->curptch = 0; x->curatk = 0; x->ptchlength = 1; x->atklength = 1; x->pitches[0] = 60; x->atks[0] = 500; x->duty = 1.0; return (x); /* always return a copy of the created object */ } static void iso_free(t_iso *x) { clock_free(x->iso_clock); } #ifndef MAXLIB void iso_setup(void) { iso_class = class_new(gensym("iso"), (t_newmethod)iso_new, (t_method)iso_free, sizeof(t_iso), 0, 0); class_addmethod(iso_class, (t_method)iso_duty, gensym("duty"), A_FLOAT, 0); class_addmethod(iso_class, (t_method)iso_list, gensym("attack"), A_GIMME, 0); class_addmethod(iso_class, (t_method)iso_start, gensym("start"), A_GIMME, 0); class_addmethod(iso_class, (t_method)iso_stop, gensym("stop"), 0); class_addmethod(iso_class, (t_method)iso_pause, gensym("pause"), 0); class_addmethod(iso_class, (t_method)iso_loop, gensym("loop"), 0); class_addmethod(iso_class, (t_method)iso_unloop, gensym("unloop"), 0); class_addmethod(iso_class, (t_method)iso_resume, gensym("resume"), 0); class_addmethod(iso_class, (t_method)iso_hook, gensym("hook"), A_FLOAT, 0); class_addbang(iso_class, iso_bang); class_addlist(iso_class, iso_pitch); logpost(NULL, 4, version); } #else void maxlib_iso_setup(void) { iso_class = class_new(gensym("maxlib_iso"), (t_newmethod)iso_new, (t_method)iso_free, sizeof(t_iso), 0, 0); class_addcreator((t_newmethod)iso_new, gensym("iso"), 0); class_addmethod(iso_class, (t_method)iso_duty, gensym("duty"), A_FLOAT, 0); class_addmethod(iso_class, (t_method)iso_list, gensym("attack"), A_GIMME, 0); class_addmethod(iso_class, (t_method)iso_start, gensym("start"), A_GIMME, 0); class_addmethod(iso_class, (t_method)iso_stop, gensym("stop"), 0); class_addmethod(iso_class, (t_method)iso_pause, gensym("pause"), 0); class_addmethod(iso_class, (t_method)iso_loop, gensym("loop"), 0); class_addmethod(iso_class, (t_method)iso_unloop, gensym("unloop"), 0); class_addmethod(iso_class, (t_method)iso_resume, gensym("resume"), 0); class_addmethod(iso_class, (t_method)iso_hook, gensym("hook"), A_FLOAT, 0); class_addbang(iso_class, iso_bang); class_addlist(iso_class, iso_pitch); class_sethelpsymbol(iso_class, gensym("maxlib/iso-help.pd")); } #endif maxlib-1.5.5/netdist-help.pd0000644000076500007650000000300012076104537014377 0ustar hanshans#N canvas 0 26 458 404 12; #X obj 23 299 netdist; #X obj 275 249 netreceive 3000; #X floatatom 275 275 5 0 0 0 - - -; #X floatatom 390 275 5 0 0 0 - - -; #X msg 23 64 connect localhost 3000; #X floatatom 276 328 5 0 0 0 - - -; #X floatatom 391 328 5 0 0 0 - - -; #X obj 276 302 netreceive 3001; #X msg 67 120 disconnect localhost 3000; #X msg 42 93 connect localhost 3001; #X msg 88 147 disconnect localhost 3001; #X msg 102 177 print; #X msg 113 203 clear; #X floatatom 23 326 5 0 0 0 - - -; #X msg 120 232 send 23; #X msg 146 259 send 17.3; #X text 151 178 print list of connections; #X text 164 202 disconnect all; #X text 189 232 send values; #X text 213 64 add connection to list; #X text 278 119 remove connection; #X text 33 8 netdist :: distribute data to several netreceive; #X text 122 24 written by Olaf Matthes; #N canvas 293 158 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 45 DESCRIPTION distribute data to several netreceive; #X text 12 5 KEYWORDS control network; #X text 12 65 INLET_0 connect disconnect print clear send; #X text 12 85 OUTLET_0 float; #X restore 395 373 pd META; #X connect 0 0 13 0; #X connect 1 0 2 0; #X connect 1 1 3 0; #X connect 4 0 0 0; #X connect 7 0 5 0; #X connect 7 1 6 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 0 0; #X connect 12 0 0 0; #X connect 14 0 0 0; #X connect 15 0 0 0; maxlib-1.5.5/scale-help.pd0000644000076500007650000000312012076104537014017 0ustar hanshans#N canvas 0 26 533 385 12; #X floatatom 27 277 8 0 0 0 - - -; #X floatatom 27 73 5 0 0 0 - - -; #X text 213 48 written by ; #X text 37 306 creation:; #X text 141 11 scale :: scale input from a certain input range; #X text 212 29 to lie between output boundaries; #X floatatom 56 131 5 0 0 0 - - -; #X floatatom 85 152 5 0 0 0 - - -; #X floatatom 115 173 5 0 0 0 - - -; #X floatatom 144 194 5 0 0 0 - - -; #X text 84 71 input value; #X text 106 278 scaled output value; #X text 111 130 in low; #X text 137 151 in high; #X text 171 172 out low; #X text 200 194 out high; #X text 57 104 creation arguments can be changed dynamically:; #X text 53 323 scale ; #X floatatom 174 220 5 0 0 0 - - -; #X text 227 219 log coefficient; #X text 265 237 0 = linear 1 = log; #N canvas 293 158 494 344 META 0; #X text 12 245 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 225 AUTHOR Olaf Matthes ; #X text 12 205 OUTLET_0 float; #X text 12 105 INLET_1 float; #X text 12 45 DESCRIPTION scale input from a certain input range to lie between output boundaries; #X text 12 5 KEYWORDS control; #X text 12 85 INLET_0 float; #X text 12 125 INLET_2 float; #X text 12 145 INLET_3 float; #X text 12 165 INLET_4 float; #X text 12 185 INLET_5 float; #X restore 473 357 pd META; #X obj 27 249 maxlib/scale 0 9 100 255 0; #X connect 1 0 22 0; #X connect 6 0 22 1; #X connect 7 0 22 2; #X connect 8 0 22 3; #X connect 9 0 22 4; #X connect 18 0 22 5; #X connect 22 0 0 0; maxlib-1.5.5/multi.c0000644000076500007650000001015212076104537012756 0ustar hanshans/* -------------------------- multi ------------------------------------------ */ /* */ /* Like '*', but calculates output whenever _any_ of the inlets changes. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #define MAXSIZE 32 static char *version = "multi v0.2, written by Olaf Matthes "; typedef struct multi { t_object x_ob; t_inlet *x_inleft; /* leftmost inlet */ t_inlet *x_inright; /* right inlet */ t_outlet *x_outlet; /* result */ t_int x_numvalues; /* number of values / inlets */ t_float x_multivalue[MAXSIZE]; } t_multi; static void multi_bang(t_multi *x) { int i; t_float result = x->x_multivalue[0]; for(i = 1; i < x->x_numvalues; i++) result *= x->x_multivalue[i]; outlet_float(x->x_outlet, result); } static void multi_float(t_multi *x, t_floatarg f) { x->x_multivalue[0] = f; multi_bang(x); /* calculate result */ } static void multi_ft1(t_multi *x, t_floatarg f) { x->x_multivalue[1] = f; multi_bang(x); /* calculate result */ } static t_class *multi_class; static void *multi_new(t_symbol *s, t_int argc, t_atom* argv) { int i; t_multi *x = (t_multi *)pd_new(multi_class); x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); for(i = 2; i < argc; i++) /* create additional inlets, if any */ { floatinlet_new(&x->x_ob, &x->x_multivalue[i]); } x->x_outlet = outlet_new(&x->x_ob, gensym("float")); for(i = 0; i < argc; i++) { x->x_multivalue[i] = atom_getfloatarg(i, argc, argv);; } x->x_numvalues = i; return (void *)x; } #ifndef MAXLIB void multi_setup(void) { multi_class = class_new(gensym("multi"), (t_newmethod)multi_new, 0, sizeof(t_multi), 0, A_GIMME, 0); class_addfloat(multi_class, multi_float); class_addmethod(multi_class, (t_method)multi_ft1, gensym("ft1"), A_FLOAT, 0); class_addbang(multi_class, (t_method)multi_bang); logpost(NULL, 4, version); } #else void maxlib_multi_setup(void) { multi_class = class_new(gensym("maxlib_multi"), (t_newmethod)multi_new, 0, sizeof(t_multi), 0, A_GIMME, 0); class_addcreator((t_newmethod)multi_new, gensym("multi"), A_GIMME, 0); class_addfloat(multi_class, multi_float); class_addmethod(multi_class, (t_method)multi_ft1, gensym("ft1"), A_FLOAT, 0); class_addbang(multi_class, (t_method)multi_bang); class_sethelpsymbol(multi_class, gensym("maxlib/multi-help.pd")); } #endif maxlib-1.5.5/listfunnel.c0000644000076500007650000000703212076104537014012 0ustar hanshans/* ------------------------- listfunnel ------------------------------------- */ /* */ /* Convert list into two-element lists with source index. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include static char *version = "listfunnel v0.1, written by Olaf Matthes "; typedef struct listfunnel { t_object x_ob; t_outlet *x_outlet; /* result */ } t_listfunnel; static void listfunnel_list(t_listfunnel *x, t_symbol *s, int argc, t_atom *argv) { int i; t_atom list[2]; for(i = 0; i < argc; i++) { SETFLOAT(list, i); list[1] = argv[i]; // SETFLOAT(list+1, atom_getfloatarg(i, argc, argv)); outlet_list(x->x_outlet, NULL, 2, list); } } static void listfunnel_float(t_listfunnel *x, t_floatarg f) { t_atom list[2]; SETFLOAT(list, 0); SETFLOAT(list+1, f); outlet_list(x->x_outlet, NULL, 2, list); } static t_class *listfunnel_class; static void *listfunnel_new(void) { int i; t_listfunnel *x = (t_listfunnel *)pd_new(listfunnel_class); x->x_outlet = outlet_new(&x->x_ob, gensym("float")); return (void *)x; } #ifndef MAXLIB void listfunnel_setup(void) { listfunnel_class = class_new(gensym("listfunnel"), (t_newmethod)listfunnel_new, 0, sizeof(t_listfunnel), 0, 0, 0); class_addfloat(listfunnel_class, listfunnel_float); class_addlist(listfunnel_class, listfunnel_list); logpost(NULL, 4, version); } #else void maxlib_listfunnel_setup(void) { listfunnel_class = class_new(gensym("maxlib_listfunnel"), (t_newmethod)listfunnel_new, 0, sizeof(t_listfunnel), 0, 0, 0); class_addcreator((t_newmethod)listfunnel_new, gensym("listfunnel"), 0); class_addfloat(listfunnel_class, listfunnel_float); class_addlist(listfunnel_class, listfunnel_list); class_sethelpsymbol(listfunnel_class, gensym("maxlib/listfunnel-help.pd")); } #endif maxlib-1.5.5/urn.c0000644000076500007650000001172112076104537012433 0ustar hanshans/* ------------------------------- urn -------------------------------------- */ /* */ /* urn - urn selection model (random numbers without repetition). */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code found in Dodge/Jerse "Computer Music" */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include static char *version = "urn v0.1, urn selection model\n" " written by Olaf Matthes "; /* -------------------------- urn ------------------------------ */ static t_class *urn_class; typedef struct _urn { t_object x_obj; t_outlet *x_numberout; t_outlet *x_notify; t_float x_f; /* number of numbers in urn */ t_int x_numbers; /* numbers left in urn */ t_int *x_selected; unsigned int x_state; } t_urn; static int makeseed(void) { static unsigned int random_nextseed = 1489853723; random_nextseed = random_nextseed * 435898247 + 938284287; return (random_nextseed & 0x7fffffff); } static void *urn_new(t_floatarg f) { t_urn *x = (t_urn *)pd_new(urn_class); srand( (unsigned)time( NULL ) ); x->x_numbers = x->x_f = f; if(x->x_f < 0)x->x_f = 0; x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int)); x->x_state = makeseed(); inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("f")); x->x_numberout = outlet_new(&x->x_obj, &s_float); x->x_notify = outlet_new(&x->x_obj, &s_bang); return (x); } /* set new size of urn */ static void urn_f(t_urn *x, t_floatarg f) { int i; if(f < 0) f = 0; freebytes(x->x_selected, ((t_int)x->x_f+1)*sizeof(t_int)); x->x_numbers = x->x_f = f; x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int)); for(i = 0; i <= x->x_f; i++) x->x_selected[i] = 0; } /* clear (refill) urn */ static void urn_clear(t_urn *x) { int i; x->x_numbers = x->x_f; for(i = 0; i <= x->x_f; i++) x->x_selected[i] = 0; } static void urn_seed(t_urn *x, float f, float glob) { x->x_state = f; } /* choose from urn */ static void urn_bang(t_urn *x) { int n = x->x_f, nval; int range = (n < 1 ? 1 : n); unsigned int randval = x->x_state; if(x->x_numbers == 0) goto notify; do { x->x_state = randval = randval * 472940017 + 832416023; nval = ((double)range) * ((double)randval) * (1./4294967296.); if (nval >= range) nval = range-1; } while(x->x_selected[nval]); x->x_selected[nval] = 1; outlet_float(x->x_numberout, nval); if(--x->x_numbers == 0) /* urn is now empty */ goto notify; return; notify: outlet_bang(x->x_notify); } #ifndef MAXLIB void urn_setup(void) { urn_class = class_new(gensym("urn"), (t_newmethod)urn_new, 0, sizeof(t_urn), 0, A_DEFFLOAT, 0); #else void maxlib_urn_setup(void) { urn_class = class_new(gensym("maxlib_urn"), (t_newmethod)urn_new, 0, sizeof(t_urn), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)urn_new, gensym("urn"), A_DEFFLOAT, 0); #endif class_addbang(urn_class, urn_bang); class_addmethod(urn_class, (t_method)urn_f, gensym("f"), A_FLOAT, 0); class_addmethod(urn_class, (t_method)urn_clear, gensym("clear"), 0); class_addmethod(urn_class, (t_method)urn_seed, gensym("seed"), A_FLOAT, 0); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(urn_class, gensym("maxlib/urn-help.pd")); #endif } maxlib-1.5.5/temperature-help.pd0000644000076500007650000000173212076104537015274 0ustar hanshans#N canvas 0 26 454 304 12; #X obj 45 139 temperature 500; #X floatatom 45 193 5 0 0 0 - - -; #X floatatom 45 91 5 0 0 0 - - -; #X text 132 27 written by ; #X floatatom 160 104 5 0 0 0 - - -; #X text 219 103 set new time interval; #X text 104 192 number of changes (i.e. the 'temperature'); #X text 104 209 of the input during one time interval; #X msg 68 112 foo; #X text 11 10 temperature :: output number of input changes in N ms ; #N canvas 293 158 494 344 META 0; #X text 12 145 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 125 AUTHOR Olaf Matthes ; #X text 12 105 OUTLET_0 float; #X text 12 85 INLET_1 float; #X text 12 45 DESCRIPTION output number of input changes in N ms; #X text 12 65 INLET_0 anything; #X text 12 5 KEYWORDS control analysis; #X restore 393 277 pd META; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 4 0 0 1; #X connect 8 0 0 0; maxlib-1.5.5/temperature.c0000644000076500007650000001133312076104537014163 0ustar hanshans/* -------------------------- temperature ------------------------------------- */ /* */ /* Calculates temperature: number of 'events' within N milliseconds. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include static char *version = "temperature v0.1, written by Olaf Matthes "; typedef struct temperature { t_object x_ob; t_clock *x_clock; t_outlet *x_outfloat; /* output the temperature */ t_int x_index; /* the number of elements to average */ t_int x_time; } t_temperature; static void temperature_tick(t_temperature *x) { outlet_float(x->x_outfloat, x->x_index); x->x_index = 0; clock_delay(x->x_clock, x->x_time); } static void temperature_float(t_temperature *x, t_floatarg f) { x->x_index++; /* just count number of 'events' */ } static void temperature_anything(t_temperature *x, t_symbol *s, int argc, t_atom *argv) { x->x_index++; /* just count number of 'events' */ } static void temperature_time(t_temperature *x, t_floatarg f) { x->x_time = (t_int)f; if(x->x_time < 1) x->x_time = 1; clock_unset(x->x_clock); clock_delay(x->x_clock, x->x_time); } static void temperature_reset(t_temperature *x) { x->x_index = 0; post("temperature: reset"); } static void temperature_free(t_temperature *x) { clock_free(x->x_clock); } static t_class *temperature_class; static void *temperature_new(t_floatarg f) { t_temperature *x = (t_temperature *)pd_new(temperature_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("time")); x->x_outfloat = outlet_new(&x->x_ob, gensym("float")); x->x_clock = clock_new(x, (t_method)temperature_tick); x->x_time = (t_int)f; if(x->x_time < 1) { x->x_time = 1; post("temperature: set time to %d ms", x->x_time); } x->x_index = 0; clock_delay(x->x_clock, x->x_time); return (void *)x; } #ifndef MAXLIB void temperature_setup(void) { temperature_class = class_new(gensym("temperature"), (t_newmethod)temperature_new, (t_method)temperature_free, sizeof(t_temperature), 0, A_DEFFLOAT, 0); class_addmethod(temperature_class, (t_method)temperature_reset, gensym("reset"), 0); class_addfloat(temperature_class, temperature_float); class_addmethod(temperature_class, (t_method)temperature_time, gensym("time"), A_FLOAT, 0); class_addanything(temperature_class, temperature_anything); logpost(NULL, 4, version); } #else void maxlib_temperature_setup(void) { temperature_class = class_new(gensym("maxlib_temperature"), (t_newmethod)temperature_new, (t_method)temperature_free, sizeof(t_temperature), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)temperature_new, gensym("temperature"), A_DEFFLOAT, 0); class_addmethod(temperature_class, (t_method)temperature_reset, gensym("reset"), 0); class_addfloat(temperature_class, temperature_float); class_addmethod(temperature_class, (t_method)temperature_time, gensym("time"), A_FLOAT, 0); class_addanything(temperature_class, temperature_anything); class_sethelpsymbol(temperature_class, gensym("maxlib/temperature-help.pd")); } #endif maxlib-1.5.5/limit-help.pd0000644000076500007650000000270012076104537014051 0ustar hanshans#N canvas 0 26 510 365 12; #X floatatom 27 277 8 0 0 0 - - -; #X floatatom 27 73 5 0 0 0 - - -; #X text 215 46 written by ; #X floatatom 54 131 5 0 0 0 - - -; #X floatatom 82 152 5 0 0 0 - - -; #X floatatom 110 173 5 0 0 0 - - -; #X text 84 71 input value; #X text 57 104 creation arguments can be changed dynamically:; #X obj 27 249 limit 0 9 5; #X text 35 316 creation arguments:; #X text 170 172 0 = limit \, others: compression ratio; #X text 35 340 limit ; #X text 324 195 values between 0 and 1; #X text 325 213 result in expansion !; #X text 106 278 limited / compressed output value; #X text 141 11 limit :: limits input to lie between boundaries; #X text 213 27 allows for compression / expansion; #X text 114 129 lower boundary; #X text 144 151 upper boundary; #N canvas 520 26 494 344 META 0; #X text 12 225 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 165 OUTLET_0 float; #X text 12 5 KEYWORDS control filter; #X text 12 45 DESCRIPTION limits input to lie between boundaries and allows for compression / expansion; #X text 12 85 INLET_0 float; #X text 12 105 INLET_1 float; #X text 12 125 INLET_2 float; #X text 12 145 INLET_3 float; #X text 12 185 AUTHOR Olaf Matthes ; #X restore 442 334 pd META; #X connect 1 0 8 0; #X connect 3 0 8 1; #X connect 4 0 8 2; #X connect 5 0 8 3; #X connect 8 0 0 0; maxlib-1.5.5/arraycopy.c0000644000076500007650000002414412076104537013643 0ustar hanshans/* ------------------------- arraycopy --------------------------------------- */ /* */ /* Copy data from one array to another . */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include static char *version = "arraycopy v0.2.1, written by Olaf Matthes "; typedef struct arraycopy { t_object x_obj; t_symbol *x_destarray; t_symbol *x_sourcearray; t_garray *x_destbuf; t_garray *x_sourcebuf; t_int x_start; t_int x_end; t_int x_pos; short x_print; } t_arraycopy; /* choose the destination array to copy to */ static void arraycopy_setdestarray(t_arraycopy *x, t_symbol *s) { t_garray *b; if ((b = (t_garray *)pd_findbyclass(s, garray_class))) { // post("arraycopy: destination array set to \"%s\"", s->s_name); x->x_destbuf = b; } else { post("arraycopy: no array \"%s\" (error %d)", s->s_name, b); x->x_destbuf = 0; } } static void arraycopy_setdest(t_arraycopy *x, t_symbol *s) { x->x_destarray = s; arraycopy_setdestarray(x, x->x_destarray); } /* choose the source array to copy from */ static void arraycopy_setsourcearray(t_arraycopy *x, t_symbol *s) { t_garray *b; if ((b = (t_garray *)pd_findbyclass(s, garray_class))) { // post("arraycopy: source array set to \"%s\"", s->s_name); x->x_sourcebuf = b; } else { post("arraycopy: no array \"%s\" (error %d)", s->s_name, b); x->x_sourcebuf = 0; } } /* this is the routine that actually does the copying */ /* get's called directly when we get a 'bang' */ static void arraycopy_docopy(t_arraycopy *x) { /* use new 64-bit compatible array API if available */ #if (defined PD_MAJOR_VERSION && defined PD_MINOR_VERSION) && (PD_MAJOR_VERSION > 0 || PD_MINOR_VERSION >= 41) # define arraynumber_t t_word # define array_getarray garray_getfloatwords # define array_get(pointer, index) (pointer[index].w_float) # define array_set(pointer, index, value) ((pointer[index].w_float)=value) #else # define arraynumber_t t_float # define array_getarray garray_getfloatarray # define array_get(pointer, index) (pointer[index]) # define array_set(pointer, index, value) ((pointer[index])=value) #endif t_garray *b; /* make local copy of array */ arraynumber_t *tab; /* the content itself */ int sourcesize, destsize; t_int i; t_garray *A; arraynumber_t *vec; if(!x->x_destarray) { post("arraycopy: no destination array specified"); return; } if(!x->x_sourcearray) { post("arraycopy: no source array specified"); return; } A = x->x_destbuf; if ((b = (t_garray *)pd_findbyclass(x->x_sourcearray, garray_class))) { // post("arraycopy: source array set to \"%s\"", x->x_sourcearray->s_name); } else { post("arraycopy: no array \"%s\" (error %d)", x->x_sourcearray->s_name, b); return; } // read from our array if (!array_getarray(b, &sourcesize, &tab)) { pd_error(x, "arraycopy: couldn't read from source array '%s'!", x->x_sourcearray->s_name); return; } if (!(A = (t_garray *)pd_findbyclass(x->x_destarray, garray_class))) error("arraycopy: %s: no such array", x->x_destarray->s_name); else if (!array_getarray(A, &destsize, &vec)) error("arraycopy: %s: bad template ", x->x_destarray->s_name); else { if(x->x_start > sourcesize) { pd_error(x, "arraycopy: start point %i out of range for source '%s'", (int)x->x_start, x->x_sourcearray->s_name); return; } if(x->x_start > destsize) { pd_error(x, "arraycopy: start point %i out of range for destination '%s'", (int)x->x_start, x->x_destarray->s_name); return; } if(x->x_end) // end point is specified { if(x->x_end > sourcesize) { logpost(x, 2, "arraycopy: end point %i out of range for source '%s', using %i", (int)x->x_end, x->x_sourcearray->s_name, sourcesize); x->x_end = sourcesize; } if(x->x_end > destsize) { logpost(x, 2, "arraycopy: end point %i out of range for destination '%s', using %i", (int)x->x_end, x->x_destarray->s_name, destsize); x->x_end = destsize; } } else x->x_end = (sourcesize < destsize ? sourcesize : destsize); if(x->x_pos) vec += x->x_pos; for(i = x->x_start; i < x->x_end; i++) { array_set(vec, 0, array_get(tab, i)); vec++; } garray_redraw(A); if(x->x_print)post("arraycopy: copied %d values from array \"%s\" to array \"%s\"", x->x_end-x->x_start, x->x_sourcearray->s_name, x->x_destarray->s_name); } } static void arraycopy_list(t_arraycopy *x, t_symbol *s, int argc, t_atom *argv) { if(argc > 1) { x->x_sourcearray = atom_getsymbolarg(0, argc, argv); x->x_destarray = atom_getsymbolarg(1, argc, argv); } } static void arraycopy_source(t_arraycopy *x, t_symbol *s) { x->x_sourcearray = s; x->x_start = x->x_end = x->x_pos = 0; arraycopy_docopy(x); } static void arraycopy_print(t_arraycopy *x, t_floatarg f) { if(f) x->x_print = 1; else x->x_print = 0; } static void arraycopy_copy(t_arraycopy *x, t_symbol *s, int argc, t_atom *argv) { if(argc == 1) // source array name supplied { x->x_sourcearray = atom_getsymbolarg(0, argc, argv); x->x_start = x->x_end = x->x_pos = 0; } else if(argc == 2) // array name and start point supplied { x->x_sourcearray = atom_getsymbolarg(0, argc, argv); x->x_start = atom_getfloatarg(1, argc, argv); x->x_end = x->x_pos = 0; } else if(argc == 3) // arrayname and start & end point supplied { x->x_sourcearray = atom_getsymbolarg(0, argc, argv); x->x_start = atom_getfloatarg(1, argc, argv); if(argv[2].a_type == A_FLOAT) // real position { x->x_end = atom_getfloatarg(2, argc, argv); } else // offset given { t_symbol *offset = atom_getsymbolarg(2, argc, argv); x->x_end = (t_int)atoi(offset->s_name) + x->x_start; } x->x_pos = 0; } else if(argc == 4) // as above & dest. array { x->x_sourcearray = atom_getsymbolarg(0, argc, argv); x->x_start = atom_getfloatarg(1, argc, argv); if(argv[2].a_type == A_FLOAT) // real position { x->x_end = atom_getfloatarg(2, argc, argv); } else // offset given { t_symbol *offset = atom_getsymbolarg(2, argc, argv); x->x_end = (t_int)atoi(offset->s_name) + x->x_start; } x->x_destarray = atom_getsymbolarg(3, argc, argv); arraycopy_setdestarray(x, x->x_destarray); x->x_pos = 0; } else if(argc == 5) // as above & dest. array & pos. in dest. { x->x_sourcearray = atom_getsymbolarg(0, argc, argv); x->x_start = atom_getfloatarg(1, argc, argv); if(argv[2].a_type == A_FLOAT) // real position { x->x_end = atom_getfloatarg(2, argc, argv); } else // offset given { t_symbol *offset = atom_getsymbolarg(2, argc, argv); x->x_end = (t_int)atoi(offset->s_name) + x->x_start; } x->x_destarray = atom_getsymbolarg(3, argc, argv); arraycopy_setdestarray(x, x->x_destarray); x->x_pos = atom_getfloatarg(4, argc, argv); } else post("arraycopy: copy: wrong number of arguments"); arraycopy_docopy(x); } static t_class *arraycopy_class; static void *arraycopy_new(t_symbol *s, int argc, t_atom *argv) { t_arraycopy *x = (t_arraycopy *)pd_new(arraycopy_class); if (argc > 0) { x->x_destarray = atom_getsymbolarg(0, argc, argv); arraycopy_setdestarray(x, x->x_destarray); } inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("symbol"), gensym("dest")); x->x_start = x->x_end = x->x_pos = x->x_print = 0; return (x); } #ifndef MAXLIB void arraycopy_setup(void) { /* the object's class: */ arraycopy_class = class_new(gensym("arraycopy"), (t_newmethod)arraycopy_new, 0, sizeof(t_arraycopy), 0, A_GIMME, 0); #else void maxlib_arraycopy_setup(void) { /* the object's class: */ arraycopy_class = class_new(gensym("maxlib_arraycopy"), (t_newmethod)arraycopy_new, 0, sizeof(t_arraycopy), 0, A_GIMME, 0); class_addcreator((t_newmethod)arraycopy_new, gensym("arraycopy"), A_GIMME, 0); #endif class_addmethod(arraycopy_class, (t_method)arraycopy_copy, gensym("copy"), A_GIMME, 0); class_addmethod(arraycopy_class, (t_method)arraycopy_print, gensym("print"), A_FLOAT, 0); class_addmethod(arraycopy_class, (t_method)arraycopy_setdest, gensym("dest"), A_SYMBOL, 0); class_addsymbol(arraycopy_class, arraycopy_source); class_addbang(arraycopy_class, arraycopy_docopy); // class_addlist(arraycopy_class, arraycopy_list); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(arraycopy_class, gensym("maxlib/arraycopy-help.pd")); #endif } maxlib-1.5.5/dist-help.pd0000644000076500007650000000270712076104537013705 0ustar hanshans#N canvas 0 26 498 441 12; #X text 33 10 dist :: send data to a list of receive objects; #X obj 34 364 dist; #X msg 85 127 connect bla; #X msg 103 154 connect foo; #X msg 131 209 disconnect bla; #X msg 145 237 disconnect foo; #X msg 158 295 clear; #X obj 200 374 receive bla; #X obj 306 374 receive foo; #X obj 200 400 print bla; #X obj 306 400 print foo; #X floatatom 34 69 5 0 0 0 - - -; #X msg 170 328 print; #X msg 56 98 send anything 1 2 dog; #X obj 34 397 d bla foo; #X msg 122 180 connect dog cat; #X msg 159 265 disconnect cat dog; #X text 210 295 empty receiver list; #X text 218 328 print list of receive names; #X text 190 126 add 'bla' to list of receivers; #X text 253 209 remove 'bla' from list; #X text 238 99 send anything you want; #X text 97 28 written by Olaf Matthes ; #N canvas 293 158 494 344 META 0; #X text 12 105 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 85 AUTHOR Olaf Matthes ; #X text 12 45 DESCRIPTION send data to a list of receive objects; #X text 12 5 KEYWORDS control nonlocal; #X text 12 65 INLET_0 float send connect disconnect clear print; #X restore 435 413 pd META; #X connect 2 0 1 0; #X connect 3 0 1 0; #X connect 4 0 1 0; #X connect 5 0 1 0; #X connect 6 0 1 0; #X connect 7 0 9 0; #X connect 8 0 10 0; #X connect 11 0 1 0; #X connect 12 0 1 0; #X connect 13 0 1 0; #X connect 15 0 1 0; #X connect 16 0 1 0; maxlib-1.5.5/edge.c0000644000076500007650000000646212076104537012541 0ustar hanshans/* --------------------------- edge ----------------------------------------- */ /* */ /* Detect rising or falling edge of float input. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include static char *version = "edge v0.1, written by Olaf Matthes "; typedef struct edge { t_object x_ob; t_outlet *x_out1; /* bang on rising edge */ t_outlet *x_out2; /* bang on falling edge */ t_float x_lastval; /* last input value */ } t_edge; static void edge_float(t_edge *x, t_floatarg f) { if((x->x_lastval <= 0) && (f >= 1)) /* rising edge */ outlet_bang(x->x_out1); else if((x->x_lastval >= 1) && (f <= 0)) /* falling edge */ outlet_bang(x->x_out2); x->x_lastval = f; /* save last value */ } static t_class *edge_class; static void *edge_new(t_floatarg f) { int i; t_edge *x = (t_edge *)pd_new(edge_class); x->x_out1 = outlet_new(&x->x_ob, gensym("bang")); x->x_out2 = outlet_new(&x->x_ob, gensym("bang")); x->x_lastval = f; return (void *)x; } #ifndef MAXLIB void edge_setup(void) { edge_class = class_new(gensym("edge"), (t_newmethod)edge_new, 0, sizeof(t_edge), 0, A_DEFFLOAT, 0); class_addfloat(edge_class, edge_float); logpost(NULL, 4, version); } #else void maxlib_edge_setup(void) { edge_class = class_new(gensym("maxlib_edge"), (t_newmethod)edge_new, 0, sizeof(t_edge), 0, A_DEFFLOAT, 0); class_addfloat(edge_class, edge_float); class_addcreator((t_newmethod)edge_new, gensym("edge"), A_DEFFLOAT, 0); class_sethelpsymbol(edge_class, gensym("maxlib/edge-help.pd")); } #endif maxlib-1.5.5/fifo-help.pd0000644000076500007650000000147212076104537013663 0ustar hanshans#N canvas 0 26 452 302 12; #X obj 38 176 fifo 10; #X floatatom 38 231 5 0 0 0 - - -; #X floatatom 61 132 5 0 0 0 - - -; #X msg 38 98 bang; #X text 83 98 hit to get next number; #X text 111 176 fifo ; #X text 92 233 output of fifo; #X text 42 14 fifo :: first in first out buffer for floats; #X text 105 32 written for Max by St. Rainstick; #N canvas 293 158 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 85 OUTLET_0 float; #X text 12 45 DESCRIPTION first in first out buffer for floats; #X text 12 5 KEYWORDS control storage; #X text 12 65 INLET_0 bang float; #X restore 385 268 pd META; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 3 0 0 0; maxlib-1.5.5/rhythm.c0000644000076500007650000002575312076104537013154 0ustar hanshans/* --------------------------- rhythm ---------------------------------------- */ /* */ /* Detect the beats per minute of a MIDI stream. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code written by Robert Rowe. */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #ifndef _WIN32 #include #endif #define ALPHA 10 #define ADAPT_ARRAY_SIZE 1000 #ifndef M_PI #define M_PI 3.14159265358979 #endif #ifndef TWO_PI #define TWO_PI 2.0*M_PI #endif static char *version = "rhythm v0.1, written by Olaf Matthes "; typedef struct rhythm { t_object x_ob; t_clock *x_tick; t_outlet *x_out_bpm; /* beats per minute */ t_outlet *x_out_period; /* beats in milliseconds */ t_outlet *x_out_pulse; t_int x_print; /* switch printing to console window on / off */ t_int x_ticking; /* indicates if clock is ticking or not */ t_int x_model; /* algorhythm to use: 0 - Large & Kolen, 1 - Toiviainen */ t_float x_long_term[ADAPT_ARRAY_SIZE]; t_float x_short_term[ADAPT_ARRAY_SIZE]; t_float x_phi_at_pulse; /* phase at latest pulse */ t_float x_phiVel_at_pulse; /* phase velocity */ t_float x_adapt; t_float x_errFunc; /* error function */ t_float x_etaLong; /* strength of long-term adaptation */ t_float x_etaShort; /* strength of short-term adaptation */ t_float x_gamma; /* gain parameter */ double x_lastIoi; /* last inter-onset interval */ double x_lastPulseTime; /* time of last pulse */ t_float x_output; /* current output value of the oscillator */ t_float x_phi; /* phase */ double x_expected; /* estimated time of arrival */ t_float x_period; t_float x_periodStrength; t_float x_phaseStrength; double x_startTime; t_int x_pitch; t_int x_velo; /* helpers needed to do the time calculations */ double x_last_input; } t_rhythm; /* --------------- rhythm stuff ------------------------------------------------ */ /* bang at the rhythm's pulse */ static void rhythm_tick(t_rhythm *x) { outlet_bang(x->x_out_pulse); clock_delay(x->x_tick, x->x_period); } static t_float rhythm_get_adapt_long(t_rhythm *x, t_float arg) { int address; if (arg > 1.0) address = ADAPT_ARRAY_SIZE - 1; else if (arg < -1.0) address = ADAPT_ARRAY_SIZE - 1; else address = abs((int)(arg*1000.0)); return x->x_long_term[address]; } static t_float rhythm_get_adapt_short(t_rhythm *x, t_float arg) { int address; if (arg > 1.0) address = ADAPT_ARRAY_SIZE - 1; else if (arg < -1.0) address = ADAPT_ARRAY_SIZE - 1; else address = abs((int)(arg*1000.0)); return x->x_short_term[address]; } /* Large & Kolen adaptation model */ static void rhythm_large(t_rhythm *x, t_int pulse, double time) { while (time > (x->x_expected+(x->x_period/2))) // move the expectation point x->x_expected += x->x_period; // to be within one period of onset x->x_phi = (t_float)(time - x->x_expected) / x->x_period; // calculate phi if (pulse) { // if this was an onset x->x_adapt = x->x_gamma * (cos(TWO_PI*x->x_phi)-1.0); x->x_adapt = 1.0 / cosh(x->x_adapt); x->x_adapt *= x->x_adapt; x->x_adapt *= sin(TWO_PI*x->x_phi); x->x_adapt *= (x->x_period / TWO_PI); x->x_period += (x->x_periodStrength*x->x_adapt); // update period x->x_expected += (x->x_phaseStrength *x->x_adapt); // and phase x->x_phi = (t_float)(time - x->x_expected) / x->x_period; } x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0)); // oscillator output } /* Toiviainen adaptation model */ static void rhythm_toiviainen(t_rhythm *x, t_int pulse, double time) { t_float deltaTime, varPhi, adaptLong, adaptShort; /* if just starting, initialize phi */ if(x->x_lastPulseTime < 0) { x->x_phi = x->x_phi_at_pulse + x->x_phiVel_at_pulse * ((t_float)(time-x->x_startTime) / 1000.0); } else { deltaTime = time - x->x_lastPulseTime; varPhi = (deltaTime/1000.0) * x->x_phiVel_at_pulse; adaptLong = rhythm_get_adapt_long(x, varPhi); // get long adaptation from table adaptShort = rhythm_get_adapt_short(x, varPhi); // get short adaptation from table x->x_phi = x->x_phi_at_pulse + varPhi + x->x_errFunc * (x->x_etaLong*adaptLong + x->x_etaShort*adaptShort); if (pulse) // change tempo if on pulse x->x_phiVel_at_pulse = x->x_phiVel_at_pulse * (1 + x->x_etaLong * x->x_errFunc * adaptShort); } if (pulse) { x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0)); x->x_errFunc = x->x_output * (x->x_output - 2.0) * sin(TWO_PI * x->x_phi); x->x_phi_at_pulse = x->x_phi; } x->x_period = 1000.0 / x->x_phiVel_at_pulse; // update period } static void rhythm_move(t_rhythm *x, t_int pulse, double time) { switch (x->x_model) /* choose adaptation model */ { case 0: rhythm_large(x, pulse, time); break; case 1: rhythm_toiviainen(x, pulse, time); break; } if(x->x_ticking == 0) { x->x_ticking = 1; /* prevent us from further calls */ clock_delay(x->x_tick, 0); /* start pulse bangs */ } } /* main processing function */ static void rhythm_float(t_rhythm *x, t_floatarg f) { t_int velo = x->x_velo; double time = clock_gettimesince(x->x_last_input); x->x_pitch = (t_int)f; if(velo != 0) /* note-on received */ { if (x->x_startTime == 0) { x->x_startTime = time; return; } if (x->x_period < 2.0) { x->x_period = (t_float)(time - x->x_startTime); x->x_phiVel_at_pulse = 1000.0 / x->x_period; } rhythm_move(x, 1, time); if (x->x_lastPulseTime >= 0) { x->x_lastIoi = time - x->x_lastPulseTime; } x->x_lastPulseTime = time; x->x_last_input = clock_getlogicaltime(); outlet_float(x->x_out_period, x->x_period); outlet_float(x->x_out_bpm, 60000.0/x->x_period); } return; } /* get velocity */ static void rhythm_ft1(t_rhythm *x, t_floatarg f) { x->x_velo = (t_int)f; } /* toggle printing on/off (not used right now!) */ static void rhythm_print(t_rhythm *x) { if(x->x_print)x->x_print = 0; else x->x_print = 1; } /* initialise array for Toiviainen adaptation model */ static void rhythm_calculate_adaptations(t_rhythm *x) { int i; t_float f; for(i = 0; i < ADAPT_ARRAY_SIZE; i++) { f = (t_float)i/(t_float)ADAPT_ARRAY_SIZE; x->x_long_term[i] = f+(ALPHA*f*f/2.0+2.0*f+3.0/ALPHA)*exp(-ALPHA*f)-3.0/ALPHA; x->x_short_term[i] = 1.0-(ALPHA*ALPHA*f*f/2.0+ALPHA*f+1.0)*exp(-ALPHA*f); } } static void rhythm_reset(t_rhythm *x) { if(x->x_ticking)clock_unset(x->x_tick); x->x_ticking = 0; x->x_gamma = 1.0; /* default value for gain parameter */ x->x_phi = 0.0; x->x_output = 1+tanh(x->x_gamma*(cos(TWO_PI*x->x_phi)-1.0)); x->x_expected = 0; x->x_lastIoi = 0; x->x_lastPulseTime = -1; x->x_period = 1.0; x->x_periodStrength = 0.2; x->x_phaseStrength = 0.2; x->x_errFunc = 0.0; x->x_etaLong = 0.2; x->x_etaShort = 0.2; x->x_phi_at_pulse = 0.0; x->x_phiVel_at_pulse = 0.9; x->x_startTime = 0; rhythm_calculate_adaptations(x); } static void rhythm_model(t_rhythm *x, t_floatarg f) { if(f == 1) { x->x_model = 1; /* Toiviainen model */ rhythm_reset(x); post("rhythm: using \"Toiviainen\" adaptation model"); } else { x->x_model = 0; /* Large and Kolen model */ rhythm_reset(x); post("rhythm: using \"Large and Kolen\" adaptation model"); } } static t_class *rhythm_class; static void rhythm_free(t_rhythm *x) { clock_free(x->x_tick); } static void *rhythm_new(t_floatarg f) { t_rhythm *x = (t_rhythm *)pd_new(rhythm_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); x->x_out_bpm = outlet_new(&x->x_ob, gensym("float")); x->x_out_period = outlet_new(&x->x_ob, gensym("float")); x->x_out_pulse = outlet_new(&x->x_ob, gensym("bang")); x->x_tick = clock_new(x, (t_method)rhythm_tick); rhythm_reset(x); if(f == 1) { x->x_model = 1; /* Toiviainen model */ post("rhythm: using \"Toiviainen\" adaptation model"); } else { x->x_model = 0; /* Large and Kolen model */ post("rhythm: using \"Large and Kolen\" adaptation model"); } return (void *)x; } #ifndef MAXLIB void rhythm_setup(void) { rhythm_class = class_new(gensym("rhythm"), (t_newmethod)rhythm_new, (t_method)rhythm_free, sizeof(t_rhythm), 0, A_DEFFLOAT, 0); class_addfloat(rhythm_class, rhythm_float); class_addmethod(rhythm_class, (t_method)rhythm_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(rhythm_class, (t_method)rhythm_model, gensym("model"), A_FLOAT, 0); class_addmethod(rhythm_class, (t_method)rhythm_reset, gensym("reset"), 0); class_addmethod(rhythm_class, (t_method)rhythm_print, gensym("print"), 0); logpost(NULL, 4, version); } #else void maxlib_rhythm_setup(void) { rhythm_class = class_new(gensym("maxlib_rhythm"), (t_newmethod)rhythm_new, (t_method)rhythm_free, sizeof(t_rhythm), 0, A_DEFFLOAT, 0); class_addcreator((t_newmethod)rhythm_new, gensym("rhythm"), A_DEFFLOAT, 0); class_addfloat(rhythm_class, rhythm_float); class_addmethod(rhythm_class, (t_method)rhythm_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(rhythm_class, (t_method)rhythm_model, gensym("model"), A_FLOAT, 0); class_addmethod(rhythm_class, (t_method)rhythm_reset, gensym("reset"), 0); class_addmethod(rhythm_class, (t_method)rhythm_print, gensym("print"), 0); class_sethelpsymbol(rhythm_class, gensym("maxlib/rhythm-help.pd")); } #endif maxlib-1.5.5/borax.c0000644000076500007650000002026112076104537012741 0ustar hanshans/* ------------------------- borax ------------------------------------------ */ /* */ /* "swiss army knife" for music analysis. Inspired by 'borax' for Max. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #define MAX_POLY 128 /* maximum number of notes played at a time */ static char *version = "borax v0.1, written by Olaf Matthes "; typedef struct borax { t_object x_ob; t_inlet *x_invelo; /* inlet for velocity */ t_inlet *x_inreset; /* inlet to reset the object */ t_outlet *x_outnotecount; /* counts notes */ t_outlet *x_outvoicealloc; /* assigns every note a unique number */ t_outlet *x_outpoly; /* number of notes playing (polyphony) */ t_outlet *x_outpitch; /* pitch of current note */ t_outlet *x_outvelo; /* velocity of current note */ t_outlet *x_outdurcount; /* number assigned to duration value */ t_outlet *x_outdurval; /* duration value */ t_outlet *x_outtimecount; /* number assigned to delta time value */ t_outlet *x_outtimeval; /* delta time value */ t_float x_notecount; t_int x_pitch; t_int x_velo; t_float x_voicecount; t_int x_voicealloc; t_int x_poly; t_float x_durcount; t_float x_durval; t_float x_timecount; t_float x_timeval; /* helpers needed to do the calculations */ double x_starttime[MAX_POLY]; double x_laststarttime; t_int x_alloctable[MAX_POLY]; } t_borax; static void borax_float(t_borax *x, t_floatarg f) { t_int velo = x->x_velo; t_int allloc = 0; int i; x->x_pitch = (t_int)f; if(velo == 0) { /* note off received... */ if(x->x_poly > 0)x->x_poly--; /* polyphony has decreased by one */ x->x_durcount++; /* we can calculate the duration */ for(i = 0; i < MAX_POLY; i++) /* search for voice allocation number */ { /* search for corresponding alloc number */ if(x->x_alloctable[i] == x->x_pitch) { x->x_voicealloc = i; x->x_alloctable[i] = 0; /* free the alloc number */ break; } /* couldn't find it ? */ if(i == MAX_POLY - 1) { post("borax: no corresponding note-on found (ignored)"); return; } } x->x_durval = clock_gettimesince(x->x_starttime[x->x_voicealloc]); } else if(velo != 0) { /* note on received... */ x->x_poly++; /* number of currently playing notes has increased */ x->x_notecount++; /* total number of notes has increased */ /* assign a voice allocation number */ for(i = 0; i < MAX_POLY; i++) { /* search for free alloc number */ if(x->x_alloctable[i] == 0) { x->x_voicealloc = i; /* take the number */ x->x_alloctable[i] = x->x_pitch; /* ... and store pitch */ break; } /* couldn't find any ? */ if(i == MAX_POLY - 1) { post("borax: too many note-on messages (ignored)"); return; } } /* calculate time in case it's not the first note */ if(x->x_notecount > 1) { x->x_timecount++; x->x_timeval = clock_gettimesince(x->x_laststarttime); } /* save the new start time */ x->x_laststarttime = x->x_starttime[x->x_voicealloc] = clock_getlogicaltime(); } /* output values from right to left */ outlet_float(x->x_outtimeval, x->x_timeval); outlet_float(x->x_outtimecount, x->x_timecount); outlet_float(x->x_outdurval, x->x_durval); outlet_float(x->x_outdurcount, x->x_durcount); outlet_float(x->x_outvelo, velo); outlet_float(x->x_outpitch, x->x_pitch); outlet_float(x->x_outpoly, x->x_poly); outlet_float(x->x_outvoicealloc, x->x_voicealloc); outlet_float(x->x_outnotecount, x->x_notecount); } static void borax_ft1(t_borax *x, t_floatarg f) { x->x_velo = (t_int)f; } static void borax_reset(t_borax *x) { int i; post("borax: reset"); x->x_notecount = 0; x->x_pitch = 0; x->x_velo = 0; x->x_voicecount = 0; x->x_voicealloc = 0; x->x_poly = 0; x->x_durcount = 0; x->x_durval = 0; x->x_timecount = 0; x->x_timeval = 0; outlet_float(x->x_outtimeval, x->x_timeval); outlet_float(x->x_outtimecount, x->x_timecount); outlet_float(x->x_outdurval, x->x_durval); outlet_float(x->x_outdurcount, x->x_durcount); for(i = 0; i < MAX_POLY; i++) { if(x->x_alloctable[i] != 0) { x->x_poly--; /* send note-off */ outlet_float(x->x_outvelo, 0); outlet_float(x->x_outpitch, x->x_alloctable[i]); outlet_float(x->x_outpoly, x->x_poly); outlet_float(x->x_outvoicealloc, i); } x->x_alloctable[i] = 0; } outlet_float(x->x_outvelo, x->x_velo); outlet_float(x->x_outpitch, x->x_pitch); outlet_float(x->x_outpoly, x->x_poly); outlet_float(x->x_outvoicealloc, x->x_voicealloc); outlet_float(x->x_outnotecount, x->x_notecount); } static t_class *borax_class; static void *borax_new(void) { int i; t_borax *x = (t_borax *)pd_new(borax_class); x->x_invelo = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); x->x_inreset = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("bang"), gensym("ft2")); x->x_outnotecount = outlet_new(&x->x_ob, gensym("float")); x->x_outvoicealloc = outlet_new(&x->x_ob, gensym("float")); x->x_outpoly = outlet_new(&x->x_ob, gensym("float")); x->x_outpitch = outlet_new(&x->x_ob, gensym("float")); x->x_outvelo = outlet_new(&x->x_ob, gensym("float")); x->x_outdurcount = outlet_new(&x->x_ob, gensym("float")); x->x_outdurval = outlet_new(&x->x_ob, gensym("float")); x->x_outtimecount = outlet_new(&x->x_ob, gensym("float")); x->x_outtimeval = outlet_new(&x->x_ob, gensym("float")); for(i = 0; i < MAX_POLY; i++)x->x_alloctable[i] = 0; x->x_notecount = 0; x->x_pitch = 0; x->x_velo = 0; x->x_voicecount = 0; x->x_voicealloc = 0; x->x_poly = 0; x->x_durcount = 0; x->x_durval = 0; x->x_timecount = 0; x->x_timeval = 0; return (void *)x; } #ifndef MAXLIB void borax_setup(void) { borax_class = class_new(gensym("borax"), (t_newmethod)borax_new, 0, sizeof(t_borax), 0, 0); #else void maxlib_borax_setup(void) { borax_class = class_new(gensym("maxlib_borax"), (t_newmethod)borax_new, 0, sizeof(t_borax), 0, 0); #endif class_addmethod(borax_class, (t_method)borax_reset, gensym("reset"), 0); class_addmethod(borax_class, (t_method)borax_ft1, gensym("ft1"), A_FLOAT, 0); class_addmethod(borax_class, (t_method)borax_reset, gensym("ft2"), A_GIMME, 0); class_addfloat(borax_class, borax_float); #ifndef MAXLIB logpost(NULL, 4, version); #else class_addcreator((t_newmethod)borax_new, gensym("borax"), 0); class_sethelpsymbol(borax_class, gensym("maxlib/borax-help.pd")); #endif } maxlib-1.5.5/plus.c0000644000076500007650000001007112076104537012607 0ustar hanshans/* --------------------------- plus ------------------------------------------ */ /* */ /* Like '+', but calculates output whenever _any_ of the inlets changes. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #define MAXSIZE 32 static char *version = "plus v0.2, written by Olaf Matthes "; typedef struct plus { t_object x_ob; t_inlet *x_inleft; /* leftmost inlet */ t_inlet *x_inright; /* right inlet */ t_outlet *x_outlet; /* result */ t_int x_numvalues; /* number of values / inlets */ t_float x_plusvalue[MAXSIZE]; } t_plus; static void plus_bang(t_plus *x) { int i; t_float result = x->x_plusvalue[0]; for(i = 1; i < x->x_numvalues; i++) result += x->x_plusvalue[i]; outlet_float(x->x_outlet, result); } static void plus_float(t_plus *x, t_floatarg f) { x->x_plusvalue[0] = f; plus_bang(x); /* calculate result */ } static void plus_ft1(t_plus *x, t_floatarg f) { x->x_plusvalue[1] = f; plus_bang(x); /* calculate result */ } static t_class *plus_class; static void *plus_new(t_symbol *s, t_int argc, t_atom* argv) { int i; t_plus *x = (t_plus *)pd_new(plus_class); x->x_inright = inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); for(i = 2; i < argc; i++) /* create additional inlets, if any */ { floatinlet_new(&x->x_ob, &x->x_plusvalue[i]); } x->x_outlet = outlet_new(&x->x_ob, gensym("float")); for(i = 0; i < argc; i++) { x->x_plusvalue[i] = atom_getfloatarg(i, argc, argv);; } x->x_numvalues = i; return (void *)x; } #ifndef MAXLIB void plus_setup(void) { plus_class = class_new(gensym("plus"), (t_newmethod)plus_new, 0, sizeof(t_plus), 0, A_GIMME, 0); class_addfloat(plus_class, plus_float); class_addmethod(plus_class, (t_method)plus_ft1, gensym("ft1"), A_FLOAT, 0); class_addbang(plus_class, (t_method)plus_bang); logpost(NULL, 4, version); } #else void maxlib_plus_setup(void) { plus_class = class_new(gensym("maxlib_plus"), (t_newmethod)plus_new, 0, sizeof(t_plus), 0, A_GIMME, 0); class_addcreator((t_newmethod)plus_new, gensym("plus"), A_GIMME, 0); class_addfloat(plus_class, plus_float); class_addmethod(plus_class, (t_method)plus_ft1, gensym("ft1"), A_FLOAT, 0); class_addbang(plus_class, (t_method)plus_bang); class_sethelpsymbol(plus_class, gensym("maxlib/plus-help.pd")); } #endif maxlib-1.5.5/expo.c0000644000076500007650000000707112076104537012605 0ustar hanshans/* ---------------------------- rand_expo ------------------------------------- */ /* */ /* rand_expo generates a exponentially distributed random variable. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Based on code found in Dodge/Jerse "Computer Music" */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #include #include #define fran() (t_float)rand()/(t_float)RAND_MAX static char *version = "expo v0.1, generates exponentially distributed random variable\n" " written by Olaf Matthes "; /* -------------------------- rand_expo ------------------------------ */ static t_class *rand_expo_class; typedef struct _rand_expo { t_object x_obj; t_float x_lambda; } t_rand_expo; static void *rand_expo_new(t_floatarg f) { t_rand_expo *x = (t_rand_expo *)pd_new(rand_expo_class); srand( (unsigned)time( NULL ) ); floatinlet_new(&x->x_obj, &x->x_lambda); outlet_new(&x->x_obj, &s_float); x->x_lambda = f; return (x); } static void rand_expo_bang(t_rand_expo *x) { t_float u, l; l = (x->x_lambda <= 0 ? 0.0001 : x->x_lambda); do { u = fran(); } while(u == 0); outlet_float(x->x_obj.ob_outlet, -log(u)/l); } #ifndef MAXLIB void expo_setup(void) { rand_expo_class = class_new(gensym("expo"), (t_newmethod)rand_expo_new, 0, sizeof(t_rand_expo), 0, A_DEFFLOAT, 0); class_addbang(rand_expo_class, rand_expo_bang); class_sethelpsymbol(rand_expo_class, gensym("expo-help.pd")); logpost(NULL, 4, version); } #else void maxlib_expo_setup(void) { rand_expo_class = class_new(gensym("maxlib_expo"), (t_newmethod)rand_expo_new, 0, sizeof(t_rand_expo), 0, A_DEFFLOAT, 0); class_addbang(rand_expo_class, rand_expo_bang); class_addcreator((t_newmethod)rand_expo_new, gensym("expo"), A_DEFFLOAT, 0); class_sethelpsymbol(rand_expo_class, gensym("maxlib/expo-help.pd")); } #endif maxlib-1.5.5/allow.c0000644000076500007650000000776012076104537012755 0ustar hanshans/* ---------------------------- allow --------------------------------------- */ /* */ /* Lets only floats/symbols through that are allowed to do so. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include static char *version = "allow v0.1, written by Olaf Matthes "; typedef struct allow { t_object x_obj; t_outlet *x_out; t_atom *x_elem; // list of elemets that are allowed to pass t_int x_numelem; // the number of elemetns in our allow-list } t_allow; /* we got a symbol... */ static void allow_symbol(t_allow *x, t_symbol *s) { int i; for(i = 0; i < x->x_numelem; i++) { if(x->x_elem[i].a_type == A_SYMBOL) // compare with all symbols in our list if(atom_getsymbolarg(i, x->x_numelem, x->x_elem) == s) { outlet_symbol(x->x_out, s); return; } } } /* we got a float... */ static void allow_float(t_allow *x, t_floatarg f) { int i; for(i = 0; i < x->x_numelem; i++) { if(x->x_elem[i].a_type == A_FLOAT) // compare with all floats in our list if(atom_getfloatarg(i, x->x_numelem, x->x_elem) == f) { outlet_float(x->x_out, f); return; } } } static t_class *allow_class; static void allow_free(t_allow *x) { freebytes(x->x_elem, x->x_numelem*sizeof(t_atom)); } static void *allow_new(t_symbol *s, int argc, t_atom *argv) { t_allow *x = (t_allow *)pd_new(allow_class); x->x_numelem = argc; // get the number of elements x->x_elem = getbytes(argc*sizeof(t_atom)); memcpy(x->x_elem, argv, argc*sizeof(t_atom)); x->x_out = outlet_new(&x->x_obj, gensym("anything")); // post("allow: got %d elements", x->x_numelem); return (x); } #ifndef MAXLIB void allow_setup(void) { /* the object's class: */ allow_class = class_new(gensym("allow"), (t_newmethod)allow_new, (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0); #else void maxlib_allow_setup(void) { /* the object's class: */ allow_class = class_new(gensym("maxlib_allow"), (t_newmethod)allow_new, (t_method)allow_free, sizeof(t_allow), 0, A_GIMME, 0); class_addcreator((t_newmethod)allow_new, gensym("allow"), A_GIMME, 0); #endif class_addsymbol(allow_class, allow_symbol); class_addfloat(allow_class, allow_float); #ifndef MAXLIB logpost(NULL, 4, version); #else class_sethelpsymbol(allow_class, gensym("maxlib/allow-help.pd")); #endif } maxlib-1.5.5/delta.c0000644000076500007650000001040712076104537012720 0ustar hanshans/* ------------------------- delta ------------------------------------------ */ /* */ /* Claculate 1st or 2nd order difference. */ /* Written by Olaf Matthes (olaf.matthes@gmx.de) */ /* Inspired by code written by Trond Lossius. */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #include "m_pd.h" #include #define MAXSIZE 32 static char *version = "delta v0.1, written by Olaf Matthes "; typedef struct delta { t_object x_ob; t_outlet *x_out; /* result */ t_int x_order; /* 1st or second order */ t_int x_clearflag; t_float x_delta; /* the result */ t_float x_prev; /* previous value */ t_float x_prev2; /* value previous to previous value */ } t_delta; static void delta_clear(t_delta *x) { if(x->x_order == 2) x->x_clearflag = 2; else x->x_clearflag = 1; x->x_delta = 0; } static void delta_bang(t_delta *x) { outlet_float(x->x_out, x->x_delta); } static void delta_float(t_delta *x, t_floatarg f) { if(x->x_order != 2) /* first order */ { if(x->x_clearflag) { x->x_prev = f; x->x_delta = 0; x->x_clearflag = 0; } else { x->x_delta = f - x->x_prev; x->x_prev = f; } } else { switch(x->x_clearflag) { case 0: x->x_delta = f - 2*x->x_prev + x->x_prev2; x->x_prev2 = x->x_prev; x->x_prev = f; break; case 1: x->x_prev = f; x->x_clearflag--; break; case 2: x->x_prev2 = f; x->x_clearflag--; break; } } delta_bang(x); } static t_class *delta_class; static void *delta_new(t_floatarg f) { int i; t_delta *x = (t_delta *)pd_new(delta_class); x->x_out = outlet_new(&x->x_ob, gensym("float")); x->x_order = (int)f; if(x->x_order == 2) x->x_clearflag = 2; else x->x_clearflag = 1; x->x_delta = 0; return (void *)x; } #ifndef MAXLIB void delta_setup(void) { delta_class = class_new(gensym("delta"), (t_newmethod)delta_new, 0, sizeof(t_delta), 0, A_DEFFLOAT, 0); #else void maxlib_delta_setup(void) { delta_class = class_new(gensym("maxlib_delta"), (t_newmethod)delta_new, 0, sizeof(t_delta), 0, A_DEFFLOAT, 0); #endif class_addfloat(delta_class, delta_float); class_addbang(delta_class, (t_method)delta_bang); class_addmethod(delta_class, (t_method)delta_clear, gensym("clear"), 0); class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd")); #ifndef MAXLIB logpost(NULL, 4, version); #else class_addcreator((t_newmethod)delta_new, gensym("delta"), A_DEFFLOAT, 0); class_sethelpsymbol(delta_class, gensym("maxlib/delta-help.pd")); #endif } maxlib-1.5.5/nchange.c0000644000076500007650000001351712076104537013237 0ustar hanshans/* ------------------------- ignore ------------------------------------------- */ /* */ /* A 'new' change object for more than just floats. */ /* Written by Olaf Matthes */ /* 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. */ /* */ /* ---------------------------------------------------------------------------- */ #define A_LIST 254; #define A_ANYTHING 255; #include "m_pd.h" // #include // #include /* -------------------------- nchange ------------------------------ */ static char *version = "nchange v0.1, written by Olaf Matthes "; static t_class *nchange_class; typedef struct _nchange { t_object x_obj; t_atom x_a[256]; int x_c; int x_type; } t_nchange; static void *nchange_new(t_symbol *s) { int i; t_nchange *x = (t_nchange *)pd_new(nchange_class); if(s == gensym("s")) { x->x_type = A_SYMBOL; outlet_new(&x->x_obj, &s_symbol); } else if(s == gensym("f")) { x->x_type = A_FLOAT; outlet_new(&x->x_obj, &s_float); } else if(s == gensym("l")) { x->x_type = A_LIST; outlet_new(&x->x_obj, &s_list); } else { x->x_type = A_ANYTHING; outlet_new(&x->x_obj, &s_anything); } return (x); } static void nchange_bang(t_nchange *x) { if (x->x_type == A_FLOAT) outlet_float(x->x_obj.ob_outlet, x->x_a->a_w.w_float); else if (x->x_type == A_SYMBOL) outlet_symbol(x->x_obj.ob_outlet, x->x_a->a_w.w_symbol); else outlet_list(x->x_obj.ob_outlet, NULL, x->x_c, x->x_a); } static void nchange_float(t_nchange *x, t_float f) { if (x->x_type == A_FLOAT) { if (f != x->x_a->a_w.w_float) { // x->x_f = f; SETFLOAT(x->x_a, f); outlet_float(x->x_obj.ob_outlet, x->x_a->a_w.w_float); } } } static void nchange_symbol(t_nchange *x, t_symbol *s) { if (x->x_type == A_SYMBOL) { if (s != x->x_a->a_w.w_symbol) { // x->x_s = s; SETSYMBOL(x->x_a, s); outlet_symbol(x->x_obj.ob_outlet, x->x_a->a_w.w_symbol); } } } static void nchange_list(t_nchange *x, t_symbol *s, int argc, t_atom *argv) { int i, change = 0; int c = argc; if(c == x->x_c) // same number of elements for (i = 0; i < c; i++) { /* if(x->x_a[i].a_type != argv[i].a_type) { change = 1; break; } */ if (x->x_a[i].a_type == A_FLOAT) { if (argv[i].a_type != A_FLOAT || x->x_a[i].a_w.w_float != argv[i].a_w.w_float) { change = 1; break; } } else if (x->x_a[i].a_type == A_SYMBOL) { if (argv[i].a_type != A_SYMBOL || x->x_a[i].a_w.w_symbol != argv[i].a_w.w_symbol) { change = 1; break; } } } else change = 1; // different number of elems. if (change) { x->x_c = c; for (i = 0; i < c; i++) // same new list { x->x_a[i] = argv[i]; } outlet_list(x->x_obj.ob_outlet, s, argc, argv); } } static void nchange_set(t_nchange *x, t_symbol *s, int argc, t_atom *argv) { int i; if (x->x_type == A_SYMBOL) { SETSYMBOL(x->x_a, argv->a_w.w_symbol); } else if (x->x_type == A_FLOAT) { SETFLOAT(x->x_a, argv->a_w.w_float); } else // list or anything { x->x_c = argc; for (i = 0; i < argc; i++) { x->x_a[i] = argv[i]; } } } #ifndef MAXLIB void nchange_setup(void) { nchange_class = class_new(gensym("nchange"), (t_newmethod)nchange_new, 0, sizeof(t_nchange), 0, A_SYMBOL, 0); class_addbang(nchange_class, nchange_bang); class_addfloat(nchange_class, nchange_float); class_addsymbol(nchange_class, nchange_symbol); class_addlist(nchange_class, nchange_list); class_addanything(nchange_class, nchange_list); class_addmethod(nchange_class, (t_method)nchange_set, gensym("set"), A_GIMME, 0); logpost(NULL, 4, version); } #else void maxlib_nchange_setup(void) { nchange_class = class_new(gensym("maxlib_nchange"), (t_newmethod)nchange_new, 0, sizeof(t_nchange), 0, A_SYMBOL, 0); class_addcreator((t_newmethod)nchange_new, gensym("nchange"), A_SYMBOL, 0); class_addbang(nchange_class, nchange_bang); class_addfloat(nchange_class, nchange_float); class_addsymbol(nchange_class, nchange_symbol); class_addlist(nchange_class, nchange_list); class_addanything(nchange_class, nchange_list); class_addmethod(nchange_class, (t_method)nchange_set, gensym("set"), A_GIMME, 0); class_sethelpsymbol(nchange_class, gensym("maxlib/nchange-help.pd")); } #endif maxlib-1.5.5/velocity-help.pd0000644000076500007650000000162212076104537014573 0ustar hanshans#N canvas 0 26 454 244 12; #X text 30 16 velocity :: get velocity of digits per second; #X obj 50 137 velocity; #X floatatom 50 72 5 0 0 0 - - -; #X floatatom 50 187 8 0 0 0 - - -; #X text 150 77 sending a float every second would; #X text 151 95 result in a velocity of 1 \, higher; #X text 151 114 rates produce higher velocities; #X msg 65 102 bang; #X text 151 148 originally written for Max by; #X text 151 164 Trond Lossius \, BEK; #N canvas 293 158 494 344 META 0; #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan Wilkes for Pd version 0.42.; #X text 12 25 LICENSE GPL v2; #X text 12 105 AUTHOR Olaf Matthes ; #X text 12 5 KEYWORDS control random; #X text 12 85 OUTLET_0 float; #X text 12 45 DESCRIPTION get velocity of digits per second; #X text 12 65 INLET_0 bang float; #X restore 390 214 pd META; #X connect 1 0 3 0; #X connect 2 0 1 0; #X connect 7 0 1 0; maxlib-1.5.5/step-help.pd0000644000076500007650000000232412076104537013710 0ustar hanshans#N canvas 0 26 510 321 12; #X floatatom 33 229 5 0 0 0 - - -; #X text 72 7 step :: output sequence of numbers (similar to 'line') ; #X text 138 25 written by Olaf Matthes (olaf.matthes@gmx.de); #X text 222 250 stepsize :: step between two numbers; #X msg 33 76 23 6000 2; #X msg 62 119 230; #X obj 101 282 line; #X text 98 117 send a single number to jump; #X text 121 77 send a triplet to step to a new value; #X text 22 282 see also:; #X msg 80 146 stop; #X text 127 147 "stop" message to stop output; #X text 121 92