diff options
Diffstat (limited to 'cyclone')
34 files changed, 965 insertions, 167 deletions
diff --git a/cyclone/Makefile.objects b/cyclone/Makefile.objects index 2a076ba..2641eee 100644 --- a/cyclone/Makefile.objects +++ b/cyclone/Makefile.objects @@ -4,22 +4,27 @@ HFORKY_OBJECTS = common/loud.o unstable/forky.o HFRAGILE_OBJECTS = common/loud.o unstable/fragile.o HGROW_OBJECTS = common/grow.o common/loud.o HGROWFITTER_OBJECTS = common/grow.o common/loud.o common/fitter.o -HFILE_OBJECTS = hammer/file.o common/loud.o common/fitter.o unstable/forky.o +HFILE_OBJECTS = hammer/file.o common/loud.o common/os.o \ + common/fitter.o unstable/forky.o HRAND_OBJECTS = common/rand.o common/loud.o -HRANDFILE_OBJECTS = common/rand.o hammer/file.o common/loud.o common/fitter.o \ +HRANDFILE_OBJECTS = common/rand.o hammer/file.o common/loud.o common/os.o \ + common/fitter.o \ unstable/forky.o HRANDGROW_OBJECTS = common/rand.o common/grow.o common/loud.o common/fitter.o HRANDGROWFILE_OBJECTS = common/rand.o common/grow.o hammer/file.o \ - common/loud.o unstable/forky.o + common/loud.o common/os.o unstable/forky.o HTREE_OBJECTS = hammer/tree.o common/loud.o -HTREEFILEVEFL_OBJECTS = hammer/tree.o hammer/file.o \ - common/vefl.o common/loud.o unstable/forky.o unstable/fragile.o +HTREEFILEVEFL_OBJECTS = hammer/tree.o hammer/file.o common/vefl.o \ + common/loud.o common/os.o unstable/forky.o unstable/fragile.o HGUI_OBJECTS = hammer/gui.o common/loud.o HSEQ_OBJECTS = common/mifi.o hammer/file.o \ - common/grow.o common/loud.o common/fitter.o unstable/forky.o + common/grow.o common/loud.o common/os.o common/fitter.o unstable/forky.o +SPLAINNOTILDE_OBJECTS = common/loud.o common/fitter.o SSIC_OBJECTS = sickle/sic.o common/loud.o SFORKY_OBJECTS = sickle/sic.o common/loud.o unstable/forky.o SFRAGILE_OBJECTS = sickle/sic.o common/loud.o unstable/fragile.o +SFRAGILEFITTER_OBJECTS = sickle/sic.o common/loud.o common/fitter.o \ + unstable/fragile.o SGROW_OBJECTS = common/grow.o sickle/sic.o common/loud.o SGROWCLC_OBJECTS = common/grow.o common/clc.o sickle/sic.o common/loud.o SGROWFORKY_OBJECTS = common/grow.o sickle/sic.o \ @@ -29,6 +34,7 @@ SARSIC_OBJECTS = sickle/sic.o sickle/arsic.o common/vefl.o \ common/loud.o unstable/fragile.o SARSICFITTER_OBJECTS = sickle/sic.o sickle/arsic.o common/vefl.o \ common/loud.o common/fitter.o unstable/fragile.o -SFILE_OBJECTS = hammer/file.o sickle/sic.o common/loud.o unstable/forky.o +SFILE_OBJECTS = hammer/file.o sickle/sic.o common/loud.o common/os.o \ + unstable/forky.o RELEASE_LIBS = cyclone hammer sickle dummies maxmode RELEASE_APPS = cyclist diff --git a/cyclone/Makefile.sources b/cyclone/Makefile.sources index bcadba2..2ec02fc 100644 --- a/cyclone/Makefile.sources +++ b/cyclone/Makefile.sources @@ -1,8 +1,8 @@ TYPES = HPLAIN HLOUD HFITTER HFORKY HFRAGILE HGROW HGROWFITTER \ HFILE HRAND HRANDFILE HRANDGROW HRANDGROWFILE \ HTREE HTREEFILEVEFL HGUI HSEQ \ - SPLAINNOTILDE SPLAIN SSIC SFORKY SFRAGILE SGROW SGROWCLC SGROWFORKY \ - SVEFL SARSIC SARSICFITTER SFILE + SPLAINNOTILDE SPLAIN SSIC SFORKY SFRAGILE SFRAGILEFITTER \ + SGROW SGROWCLC SGROWFORKY SVEFL SARSIC SARSICFITTER SFILE HPLAIN_SOURCES = \ hammer/testmess.c \ @@ -184,6 +184,10 @@ SFRAGILE_SOURCES = \ sickle/cartopol.c \ sickle/poltocar.c +SFRAGILEFITTER_TILDE = $(TILDE) +SFRAGILEFITTER_SOURCES = \ +sickle/matrix.c + SGROW_TILDE = $(TILDE) SGROW_SOURCES = \ sickle/click.c \ diff --git a/cyclone/build_counter b/cyclone/build_counter index 10003f3..55027b1 100644 --- a/cyclone/build_counter +++ b/cyclone/build_counter @@ -1,7 +1,7 @@ #define CYCLONE_VERSION "0.1" #define CYCLONE_RELEASE "alpha" -#define CYCLONE_BUILD 51 +#define CYCLONE_BUILD 52 #if 0 -CYCLONE_SNAPSHOT = 0.1-alpha51 +CYCLONE_SNAPSHOT = 0.1-alpha52 #endif diff --git a/cyclone/cyclone-shared.include b/cyclone/cyclone-shared.include index 6b0cce8..2180624 100644 --- a/cyclone/cyclone-shared.include +++ b/cyclone/cyclone-shared.include @@ -15,6 +15,8 @@ shared/common/loud.c shared/common/loud.h shared/common/grow.c shared/common/grow.h +shared/common/os.c +shared/common/os.h shared/common/fitter.c shared/common/fitter.h shared/common/lex.c diff --git a/cyclone/hammer/Append.c b/cyclone/hammer/Append.c index 16b65cc..4be4807 100644 --- a/cyclone/hammer/Append.c +++ b/cyclone/hammer/Append.c @@ -34,8 +34,7 @@ typedef struct _appendxy static t_class *append_class; static t_class *appendxy_class; -static t_symbol *appendps_compatibility = 0; -static t_symbol *appendps_max; +static int append_iscompatible = 0; /* FIXME per-object */ /* Usually a preallocation method is used, except in special cases of: 1) reentrant output request, or 2) an output request which would cause @@ -155,7 +154,7 @@ static void append_anything(t_append *x, t_symbol *s, int ac, t_atom *av) static void append_bang(t_append *x) { - if (appendps_compatibility == appendps_max) + if (append_iscompatible) { /* CHECKED: a nop */ } @@ -325,6 +324,11 @@ static void *append_new(t_symbol *s, int ac, t_atom *av) return (x); } +static void append_fitter(void) +{ + append_iscompatible = fittermax_get(); +} + void Append_setup(void) { append_class = class_new(gensym("Append"), @@ -348,6 +352,5 @@ void Append_setup(void) class_addlist(appendxy_class, appendxy_list); class_addanything(appendxy_class, appendxy_anything); - appendps_max = gensym("max"); - fitter_setup(append_class, &appendps_compatibility, 0); + fitter_setup(append_class, append_fitter); } diff --git a/cyclone/hammer/Decode.c b/cyclone/hammer/Decode.c index 0342594..0d62237 100644 --- a/cyclone/hammer/Decode.c +++ b/cyclone/hammer/Decode.c @@ -108,5 +108,5 @@ void Decode_setup(void) gensym("ft1"), A_FLOAT, 0); class_addmethod(Decode_class, (t_method)Decode_alloff, gensym("ft2"), A_FLOAT, 0); - fitter_setup(Decode_class, 0, 0); + fitter_setup(Decode_class, 0); } diff --git a/cyclone/hammer/Makefile.objects b/cyclone/hammer/Makefile.objects index eb54f17..a7099d8 100644 --- a/cyclone/hammer/Makefile.objects +++ b/cyclone/hammer/Makefile.objects @@ -4,6 +4,7 @@ unstable/fragile.o \ unstable/fringe.o \ common/loud.o \ common/grow.o \ +common/os.o \ common/fitter.o \ common/rand.o \ common/vefl.o \ diff --git a/cyclone/hammer/bangbang.c b/cyclone/hammer/bangbang.c index 5ae3506..aa8363d 100644 --- a/cyclone/hammer/bangbang.c +++ b/cyclone/hammer/bangbang.c @@ -71,5 +71,5 @@ void bangbang_setup(void) sizeof(t_bangbang), 0, A_DEFFLOAT, 0); class_addbang(bangbang_class, bangbang_bang); class_addanything(bangbang_class, bangbang_anything); - fitter_setup(bangbang_class, 0, 0); + fitter_setup(bangbang_class, 0); } diff --git a/cyclone/hammer/counter.c b/cyclone/hammer/counter.c index 0b29b3f..dd987d4 100644 --- a/cyclone/hammer/counter.c +++ b/cyclone/hammer/counter.c @@ -398,5 +398,5 @@ void counter_setup(void) CLASS_PD | CLASS_NOINLET, 0); class_addbang(counter_proxy_class, counter_proxy_bang); class_addfloat(counter_proxy_class, counter_proxy_float); - fitter_setup(counter_class, 0, 0); + fitter_setup(counter_class, 0); } diff --git a/cyclone/hammer/cycle.c b/cyclone/hammer/cycle.c index 73f3b80..5063629 100644 --- a/cyclone/hammer/cycle.c +++ b/cyclone/hammer/cycle.c @@ -151,5 +151,5 @@ void cycle_setup(void) gensym("set"), A_FLOAT, 0); /* CHECKED: arg required */ class_addmethod(cycle_class, (t_method)cycle_thresh, gensym("thresh"), A_FLOAT, 0); - fitter_setup(cycle_class, 0, 0); + fitter_setup(cycle_class, 0); } diff --git a/cyclone/hammer/gate.c b/cyclone/hammer/gate.c index 6fa2ac5..d626906 100644 --- a/cyclone/hammer/gate.c +++ b/cyclone/hammer/gate.c @@ -145,5 +145,5 @@ void gate_setup(void) class_addpointer(gate_proxy_class, gate_proxy_pointer); class_addlist(gate_proxy_class, gate_proxy_list); class_addanything(gate_proxy_class, gate_proxy_anything); - fitter_setup(gate_class, 0, 0); + fitter_setup(gate_class, 0); } diff --git a/cyclone/hammer/hammer.c b/cyclone/hammer/hammer.c index a728ec7..7e0d6e4 100644 --- a/cyclone/hammer/hammer.c +++ b/cyclone/hammer/hammer.c @@ -13,8 +13,6 @@ void allhammers_setup(void); typedef struct _hammer { t_object x_ob; - t_symbol *x_dir; - t_symbol *x_canvasdir; t_hammerfile *x_filehandle; } t_hammer; @@ -24,39 +22,43 @@ static int hammer_lastndx; static void hammer_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { - import_max(fn->s_name, ""); + int result = import_max(fn->s_name, ""); + outlet_float(((t_object *)z)->ob_outlet, (t_float)result); } -static void hammer_doimport(t_hammer *x, t_symbol *fn, t_symbol *dir) +static void hammer_doimport(t_hammer *x, t_symbol *fn) { - if (!dir || dir == &s_) - dir = x->x_dir; if (fn && fn != &s_) - import_max(fn->s_name, (dir && dir != &s_) ? dir->s_name : ""); - else - hammerpanel_open(x->x_filehandle, dir); + { + t_symbol *dir = hammerpanel_getopendir(x->x_filehandle); + int result = + import_max(fn->s_name, (dir && dir != &s_ ? dir->s_name : "")); + outlet_float(((t_object *)x)->ob_outlet, (t_float)result); + } + else hammerpanel_open(x->x_filehandle, 0); } static void hammer_click(t_hammer *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { - hammer_doimport(x, 0, 0); + hammer_doimport(x, 0); } static void hammer_import(t_hammer *x, t_symbol *fn) { - hammer_doimport(x, fn, 0); + hammer_doimport(x, fn); } static void hammer_cd(t_hammer *x, t_symbol *dir) { - /* LATER hammerfile interface for relative jumps, etc. */ - x->x_dir = (dir && dir != &s_ ? dir : x->x_canvasdir); + hammerpanel_setopendir(x->x_filehandle, dir); } -static void hammer_pwd(t_hammer *x) +static void hammer_pwd(t_hammer *x, t_symbol *s) { - outlet_symbol(((t_object *)x)->ob_outlet, x->x_dir); + t_symbol *dir; + if (s && s->s_thing && (dir = hammerpanel_getopendir(x->x_filehandle))) + pd_symbol(s->s_thing, dir); } static void hammer_bang(t_hammer *x) @@ -74,9 +76,7 @@ static void *hammer_new(void) { t_hammer *x = (t_hammer *)pd_new(hammer_class); x->x_filehandle = hammerfile_new((t_pd *)x, 0, hammer_readhook, 0, 0); - x->x_canvasdir = canvas_getdir(x->x_filehandle->f_canvas); - x->x_dir = x->x_canvasdir; - outlet_new((t_object *)x, &s_symbol); + outlet_new((t_object *)x, &s_float); return (x); } @@ -106,7 +106,7 @@ void hammer_setup(void) class_addmethod(hammer_class, (t_method)hammer_cd, gensym("cd"), A_DEFSYM, 0); class_addmethod(hammer_class, (t_method)hammer_pwd, - gensym("pwd"), 0); + gensym("pwd"), A_SYMBOL, 0); class_addmethod(hammer_class, (t_method)hammer_import, gensym("import"), A_DEFSYM, 0); class_addmethod(hammer_class, (t_method)hammer_click, diff --git a/cyclone/hammer/maximum.c b/cyclone/hammer/maximum.c index 5f49765..42ab22d 100644 --- a/cyclone/hammer/maximum.c +++ b/cyclone/hammer/maximum.c @@ -89,5 +89,5 @@ void maximum_setup(void) class_addbang(maximum_class, maximum_bang); class_addfloat(maximum_class, maximum_float); class_addlist(maximum_class, maximum_list); - fitter_setup(maximum_class, 0, 0); + fitter_setup(maximum_class, 0); } diff --git a/cyclone/hammer/minimum.c b/cyclone/hammer/minimum.c index a1124a5..c679799 100644 --- a/cyclone/hammer/minimum.c +++ b/cyclone/hammer/minimum.c @@ -89,5 +89,5 @@ void minimum_setup(void) class_addbang(minimum_class, minimum_bang); class_addfloat(minimum_class, minimum_float); class_addlist(minimum_class, minimum_list); - fitter_setup(minimum_class, 0, 0); + fitter_setup(minimum_class, 0); } diff --git a/cyclone/hammer/mtr.c b/cyclone/hammer/mtr.c index cf9927f..15dc5f6 100644 --- a/cyclone/hammer/mtr.c +++ b/cyclone/hammer/mtr.c @@ -860,5 +860,5 @@ void mtr_setup(void) gensym("debug"), 0); #endif hammerfile_setup(mtr_class, 0); - fitter_setup(mtr_class, 0, 0); + fitter_setup(mtr_class, 0); } diff --git a/cyclone/hammer/past.c b/cyclone/hammer/past.c index 553ccfa..2ed2193 100644 --- a/cyclone/hammer/past.c +++ b/cyclone/hammer/past.c @@ -152,5 +152,5 @@ void past_setup(void) class_addlist(past_class, past_list); class_addmethod(past_class, (t_method)past_clear, gensym("clear"), 0); class_addmethod(past_class, (t_method)past_set, gensym("set"), A_GIMME, 0); - fitter_setup(past_class, 0, 0); + fitter_setup(past_class, 0); } diff --git a/cyclone/hammer/prepend.c b/cyclone/hammer/prepend.c index 2dbe7be..b305f2f 100644 --- a/cyclone/hammer/prepend.c +++ b/cyclone/hammer/prepend.c @@ -34,8 +34,7 @@ typedef struct _prependxy static t_class *prepend_class; static t_class *prependxy_class; -static t_symbol *prependps_compatibility = 0; -static t_symbol *prependps_max; +static int prepend_iscompatible = 0; /* FIXME per-object */ /* Usually a preallocation method is used, except in special cases of: 1) reentrant output request, or 2) an output request which would cause @@ -153,7 +152,7 @@ static void prepend_bang(t_prepend *x) { if (x->x_selector) { - if (prependps_compatibility == prependps_max) + if (prepend_iscompatible) { t_atom at; SETSYMBOL(&at, &s_bang); /* CHECKED */ @@ -324,7 +323,7 @@ static void *prepend_new(t_symbol *s, int ac, t_atom *av) } else { - if (prependps_compatibility == prependps_max) + if (prepend_iscompatible) /* CHECKED in max an object without an outlet is created, and there is no warning when loading from a file. */ fittermax_warning(prepend_class, @@ -337,6 +336,11 @@ static void *prepend_new(t_symbol *s, int ac, t_atom *av) return (x); } +static void prepend_fitter(void) +{ + prepend_iscompatible = fittermax_get(); +} + void prepend_setup(void) { prepend_class = class_new(gensym("prepend"), @@ -360,6 +364,5 @@ void prepend_setup(void) class_addlist(prependxy_class, prependxy_list); class_addanything(prependxy_class, prependxy_anything); - prependps_max = gensym("max"); - fitter_setup(prepend_class, &prependps_compatibility, 0); + fitter_setup(prepend_class, prepend_fitter); } diff --git a/cyclone/hammer/prob.c b/cyclone/hammer/prob.c index 8772d83..2794858 100644 --- a/cyclone/hammer/prob.c +++ b/cyclone/hammer/prob.c @@ -307,5 +307,5 @@ void prob_setup(void) gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); hammerfile_setup(prob_class, 1); - fitter_setup(prob_class, 0, 0); + fitter_setup(prob_class, 0); } diff --git a/cyclone/hammer/seq.c b/cyclone/hammer/seq.c index 97fd733..030a7ab 100644 --- a/cyclone/hammer/seq.c +++ b/cyclone/hammer/seq.c @@ -49,6 +49,7 @@ typedef struct _seq t_hammerfile *x_filehandle; int x_mode; int x_playhead; + double x_nextscoretime; float x_timescale; float x_newtimescale; double x_prevtime; @@ -248,6 +249,7 @@ static void seq_stopplayback(t_seq *x) /* CHECKED bang not sent if playback stopped early */ clock_unset(x->x_clock); x->x_playhead = 0; + x->x_nextscoretime = 0.; } static void seq_stopslavery(t_seq *x) @@ -256,6 +258,7 @@ static void seq_stopslavery(t_seq *x) clock_unset(x->x_clock); clock_unset(x->x_slaveclock); x->x_playhead = 0; + x->x_nextscoretime = 0.; } static void seq_startrecording(t_seq *x, int modechanged) @@ -275,21 +278,22 @@ static void seq_startplayback(t_seq *x, int modechanged) if (modechanged) { x->x_playhead = 0; + x->x_nextscoretime = x->x_sequence->e_delta; /* playback data never sent within the scheduler event of a start message (even for the first delta <= 0), LATER rethink */ x->x_clockdelay = x->x_sequence->e_delta * x->x_newtimescale; } else - { - /* CHECKED timescale change */ - x->x_clockdelay -= clock_gettimesince(x->x_prevtime); + { /* CHECKED timescale change */ + if (x->x_prevtime > 0.) /* running state */ + x->x_clockdelay -= clock_gettimesince(x->x_prevtime); x->x_clockdelay *= x->x_newtimescale / x->x_timescale; } if (x->x_clockdelay < 0.) x->x_clockdelay = 0.; + x->x_timescale = x->x_newtimescale; clock_delay(x->x_clock, x->x_clockdelay); x->x_prevtime = clock_getlogicaltime(); - x->x_timescale = x->x_newtimescale; } else x->x_mode = SEQ_IDLEMODE; } @@ -299,6 +303,7 @@ static void seq_startslavery(t_seq *x, int modechanged) if (x->x_nevents) { x->x_playhead = 0; + x->x_nextscoretime = 0.; x->x_prevtime = 0.; x->x_slaveprevtime = 0.; } @@ -380,6 +385,7 @@ nextevent: if (x->x_playhead < x->x_nevents) { ep++; + x->x_nextscoretime += ep->e_delta; if (ep->e_delta < SEQ_TICKEPSILON) /* continue output in the same scheduler event, LATER rethink */ { @@ -556,7 +562,8 @@ static void seq_pause(t_seq *x) fittermax_warning(*(t_pd *)x, "'pause' not supported in Max"); warned = 1; } - if (x->x_mode == SEQ_PLAYMODE && x->x_prevtime > 0.) + if (x->x_mode == SEQ_PLAYMODE && + x->x_prevtime > 0.) /* running state */ { x->x_clockdelay -= clock_gettimesince(x->x_prevtime); if (x->x_clockdelay < 0.) @@ -574,7 +581,8 @@ static void seq_continue(t_seq *x) fittermax_warning(*(t_pd *)x, "'continue' not supported in Max"); warned = 1; } - if (x->x_mode == SEQ_PLAYMODE) + if (x->x_mode == SEQ_PLAYMODE && + x->x_prevtime <= 0.) /* pause state */ { if (x->x_clockdelay < 0.) x->x_clockdelay = 0.; @@ -591,30 +599,91 @@ static void seq_goto(t_seq *x, t_floatarg f1, t_floatarg f2) fittermax_warning(*(t_pd *)x, "'goto' not supported in Max"); warned = 1; } - if (x->x_nevents && x->x_mode == SEQ_PLAYMODE) + if (x->x_nevents) { t_seqevent *ev; int ndx, nevents = x->x_nevents; double ms = f1 * 1000. + f2, sum; if (ms < SEQ_TICKEPSILON) ms = 0.; + if (x->x_mode != SEQ_PLAYMODE) + { + seq_settimescale(x, x->x_timescale); + seq_setmode(x, SEQ_PLAYMODE); + /* clock_delay() has been called in setmode, LATER avoid */ + clock_unset(x->x_clock); + x->x_prevtime = 0.; + } for (ndx = 0, ev = x->x_sequence, sum = SEQ_TICKEPSILON; ndx < nevents; ndx++, ev++) { if ((sum += ev->e_delta) >= ms) { x->x_playhead = ndx; + x->x_nextscoretime = sum; x->x_clockdelay = sum - SEQ_TICKEPSILON - ms; if (x->x_clockdelay < 0.) x->x_clockdelay = 0.; - clock_delay(x->x_clock, x->x_clockdelay); - x->x_prevtime = clock_getlogicaltime(); + if (x->x_prevtime > 0.) /* running state */ + { + clock_delay(x->x_clock, x->x_clockdelay); + x->x_prevtime = clock_getlogicaltime(); + } break; } } } } +static void seq_scoretime(t_seq *x, t_symbol *s) +{ + static int warned = 0; + if (fittermax_get() && !warned) + { + fittermax_warning(*(t_pd *)x, "'scoretime' not supported in Max"); + warned = 1; + } + if (s && s->s_thing && + x->x_mode == SEQ_PLAYMODE) /* LATER other modes */ + { + t_atom aout[2]; + double ms, clockdelay = x->x_clockdelay; + t_float f1, f2; + if (x->x_prevtime > 0.) /* running state */ + clockdelay -= clock_gettimesince(x->x_prevtime); + ms = x->x_nextscoretime - clockdelay / x->x_timescale; + f1 = ms / 1000.; + f2 = ms - f1; + SETFLOAT(&aout[0], f1); + SETFLOAT(&aout[1], f2); + pd_list(s->s_thing, &s_list, 2, aout); + } +} + +static void seq_cd(t_seq *x, t_symbol *s) +{ + static int warned = 0; + if (fittermax_get() && !warned) + { + fittermax_warning(*(t_pd *)x, "'cd' not supported in Max"); + warned = 1; + } + hammerpanel_setopendir(x->x_filehandle, s); +} + +static void seq_pwd(t_seq *x, t_symbol *s) +{ + t_symbol *dir; + static int warned = 0; + if (fittermax_get() && !warned) + { + fittermax_warning(*(t_pd *)x, "'pwd' not supported in Max"); + warned = 1; + } + if (s && s->s_thing && (dir = hammerpanel_getopendir(x->x_filehandle))) + pd_symbol(s->s_thing, dir); +} + static int seq_eventcomparehook(const void *e1, const void *e2) { return (((t_seqevent *)e1)->e_delta > ((t_seqevent *)e2)->e_delta ? 1 : -1); @@ -963,7 +1032,8 @@ static void seq_read(t_seq *x, t_symbol *s) { if (s && s != &s_) seq_doread(x, s, 0); - else /* CHECKED no default */ + else /* CHECKED no default file name */ + /* start in a dir last read from, if any, otherwise in a canvas dir */ hammerpanel_open(x->x_filehandle, 0); } @@ -971,8 +1041,9 @@ static void seq_write(t_seq *x, t_symbol *s) { if (s && s != &s_) seq_dowrite(x, s); - else /* CHECKED creation arg is a default */ + else /* CHECKED creation arg is a default file name */ hammerpanel_save(x->x_filehandle, + /* always start in canvas dir */ canvas_getdir(x->x_canvas), x->x_defname); } @@ -1123,8 +1194,14 @@ void seq_setup(void) gensym("continue"), 0); class_addmethod(seq_class, (t_method)seq_goto, gensym("goto"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(seq_class, (t_method)seq_scoretime, + gensym("scoretime"), A_SYMBOL, 0); + class_addmethod(seq_class, (t_method)seq_cd, + gensym("cd"), A_DEFSYM, 0); + class_addmethod(seq_class, (t_method)seq_pwd, + gensym("pwd"), A_SYMBOL, 0); forky_setpropertiesfn(seq_class, seq_properties); hammerfile_setup(seq_class, 0); - fitter_setup(seq_class, 0, 0); + fitter_setup(seq_class, 0); } diff --git a/cyclone/hammer/switch.c b/cyclone/hammer/switch.c index ce985de..2a6846e 100644 --- a/cyclone/hammer/switch.c +++ b/cyclone/hammer/switch.c @@ -150,5 +150,5 @@ void switch_setup(void) class_addpointer(switch_proxy_class, switch_proxy_pointer); class_addlist(switch_proxy_class, switch_proxy_list); class_addanything(switch_proxy_class, switch_proxy_anything); - fitter_setup(switch_class, 0, 0); + fitter_setup(switch_class, 0); } diff --git a/cyclone/hammer/urn.c b/cyclone/hammer/urn.c index b02d891..a3ee8ae 100644 --- a/cyclone/hammer/urn.c +++ b/cyclone/hammer/urn.c @@ -146,5 +146,5 @@ void urn_setup(void) gensym("seed"), A_FLOAT, 0); /* CHECKED arg obligatory */ class_addmethod(urn_class, (t_method)urn_clear, gensym("clear"), 0); - fitter_setup(urn_class, 0, 0); + fitter_setup(urn_class, 0); } diff --git a/cyclone/notes.txt b/cyclone/notes.txt new file mode 100644 index 0000000..6f83d33 --- /dev/null +++ b/cyclone/notes.txt @@ -0,0 +1,40 @@ +TODO for cyclone + * using maxmode object arguments for abstraction-scoped, selective + compatibility control + * comment behaving better in windows (or is it gatom's fault?) + +DONE for cyclone + +alpha52 + * compatibility mode interface in maxmode object: + messages 'set', 'get' (reply through the second outlet) + * better handling of initial directory in open panels + * relative path handling in 'cd' (library objects, seq, more to come) + * remote reply to 'pwd' message of library objects (target argument required) + * instead, left outlet of library objects sends return code from import + (negative value indicates an error) + * new class: matrix~ + * linedrive: more compatible in maxmode, bipolar otherwise + * seq: + . paused state fixes (state preserved in 'goto', proper delay in 'start') + . 'goto' fix (works in idlemode) + . more incompatible messages: 'scoretime', 'cd', 'pwd' + +alpha51 + * dummies loaded by maxmode, not cyclone + * setting directory in creation argument replaced with 'cd' message + to library objects (cyclone, maxmode, hammer and sickle) + * 'pwd' message to library objects sends directory symbol to an outlet + * creating cyclone and maxmode library objects possible without + loading component libraries + * prepend and Append: + . bang handling, controlled by maxmode + . restored max-like 'set' handling as default for objects with arguments + * fix for parsing creation arguments in svf~ + * incompatible additions to seq: 'pause', 'continue', 'goto' + +alpha50 + * max-compatibility mode switch for cyclone + . turned on by loading cyclone libs through "-lib maxmode" + . affects max-compatibility of prepend and Append, controls + compatibility warnings diff --git a/cyclone/shadow/Makefile.objects b/cyclone/shadow/Makefile.objects index 66aea0d..1ddea9c 100644 --- a/cyclone/shadow/Makefile.objects +++ b/cyclone/shadow/Makefile.objects @@ -1,6 +1,7 @@ SHARED_OBJECTS = \ common/loud.o \ common/grow.o \ +common/os.o \ common/fitter.o \ common/lex.o \ common/binport.o \ diff --git a/cyclone/shadow/cyclone.c b/cyclone/shadow/cyclone.c index 30f1c84..cb051b6 100644 --- a/cyclone/shadow/cyclone.c +++ b/cyclone/shadow/cyclone.c @@ -19,8 +19,6 @@ typedef struct _cyclone { t_object x_ob; - t_symbol *x_dir; - t_symbol *x_canvasdir; t_hammerfile *x_filehandle; } t_cyclone; @@ -32,39 +30,43 @@ static int cyclone_lastndx; static void cyclone_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { - import_max(fn->s_name, ""); + int result = import_max(fn->s_name, ""); + outlet_float(((t_object *)z)->ob_outlet, (t_float)result); } -static void cyclone_doimport(t_cyclone *x, t_symbol *fn, t_symbol *dir) +static void cyclone_doimport(t_cyclone *x, t_symbol *fn) { - if (!dir || dir == &s_) - dir = x->x_dir; if (fn && fn != &s_) - import_max(fn->s_name, (dir && dir != &s_) ? dir->s_name : ""); - else - hammerpanel_open(x->x_filehandle, dir); + { + t_symbol *dir = hammerpanel_getopendir(x->x_filehandle); + int result = + import_max(fn->s_name, (dir && dir != &s_ ? dir->s_name : "")); + outlet_float(((t_object *)x)->ob_outlet, (t_float)result); + } + else hammerpanel_open(x->x_filehandle, 0); } static void cyclone_click(t_cyclone *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { - cyclone_doimport(x, 0, 0); + cyclone_doimport(x, 0); } static void cyclone_import(t_cyclone *x, t_symbol *fn) { - cyclone_doimport(x, fn, 0); + cyclone_doimport(x, fn); } static void cyclone_cd(t_cyclone *x, t_symbol *dir) { - /* LATER hammerfile interface for relative jumps, etc. */ - x->x_dir = (dir && dir != &s_ ? dir : x->x_canvasdir); + hammerpanel_setopendir(x->x_filehandle, dir); } -static void cyclone_pwd(t_cyclone *x) +static void cyclone_pwd(t_cyclone *x, t_symbol *s) { - outlet_symbol(((t_object *)x)->ob_outlet, x->x_dir); + t_symbol *dir; + if (s && s->s_thing && (dir = hammerpanel_getopendir(x->x_filehandle))) + pd_symbol(s->s_thing, dir); } static void cyclone_bang(t_cyclone *x) @@ -89,9 +91,7 @@ static void *cyclone_new(void) { t_cyclone *x = (t_cyclone *)pd_new(cyclone_class); x->x_filehandle = hammerfile_new((t_pd *)x, 0, cyclone_readhook, 0, 0); - x->x_canvasdir = canvas_getdir(x->x_filehandle->f_canvas); - x->x_dir = x->x_canvasdir; - outlet_new((t_object *)x, &s_symbol); + outlet_new((t_object *)x, &s_float); return (x); } @@ -114,7 +114,7 @@ void cyclone_setup(void) class_addmethod(cyclone_class, (t_method)cyclone_cd, gensym("cd"), A_DEFSYM, 0); class_addmethod(cyclone_class, (t_method)cyclone_pwd, - gensym("pwd"), 0); + gensym("pwd"), A_SYMBOL, 0); class_addmethod(cyclone_class, (t_method)cyclone_import, gensym("import"), A_DEFSYM, 0); class_addmethod(cyclone_class, (t_method)cyclone_click, diff --git a/cyclone/shadow/dummies.c b/cyclone/shadow/dummies.c index 5ad7cc1..f55c683 100644 --- a/cyclone/shadow/dummies.c +++ b/cyclone/shadow/dummies.c @@ -148,6 +148,7 @@ static void *dummy_if_new(t_symbol *s, int ac, t_atom *av) return (x); } +#if 0 static void *dummy_matrix_tilde_new(t_symbol *s, int ac, t_atom *av) { t_dummy_slot *sl; @@ -168,6 +169,7 @@ static void *dummy_matrix_tilde_new(t_symbol *s, int ac, t_atom *av) dummy_io(x, nins, nouts + 1); /* CHECKME */ return (x); } +#endif static void *dummy_rewire_tilde_new(t_symbol *s, int ac, t_atom *av) { @@ -406,7 +408,9 @@ static t_dummy_slot dummy_slots[] = { "lcd", 1, 4, 0, 0 }, /* CHECKME nouts */ { "led", 1, 1, 0, 0 }, { "matrixctrl", 1, 1, 0, 0 }, /* CHECKME nins, nouts */ +#if 0 { "matrix~", -1, -1, 0, (t_newmethod)dummy_matrix_tilde_new }, +#endif { "menubar", 1, 4, 0, 0 }, /* LATER parse #Xs (additional outs) */ { "meter~", 1, 1, 0, 0 }, /* LATER consider mapping to the vu */ { "movie", 1, 3, 0, 0 }, diff --git a/cyclone/shadow/maxmode.c b/cyclone/shadow/maxmode.c index 9cd1055..189c83e 100644 --- a/cyclone/shadow/maxmode.c +++ b/cyclone/shadow/maxmode.c @@ -16,9 +16,8 @@ typedef struct _maxmode { t_object x_ob; - t_symbol *x_dir; - t_symbol *x_canvasdir; t_hammerfile *x_filehandle; + t_outlet *x_modeout; } t_maxmode; static t_class *maxmode_class; @@ -29,39 +28,59 @@ static int maxmode_withbanner = 0; static void maxmode_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { - import_max(fn->s_name, ""); + int result = import_max(fn->s_name, ""); + outlet_float(((t_object *)z)->ob_outlet, (t_float)result); } -static void maxmode_doimport(t_maxmode *x, t_symbol *fn, t_symbol *dir) +static void maxmode_doimport(t_maxmode *x, t_symbol *fn) { - if (!dir || dir == &s_) - dir = x->x_dir; if (fn && fn != &s_) - import_max(fn->s_name, (dir && dir != &s_) ? dir->s_name : ""); - else - hammerpanel_open(x->x_filehandle, dir); + { + t_symbol *dir = hammerpanel_getopendir(x->x_filehandle); + int result = + import_max(fn->s_name, (dir && dir != &s_ ? dir->s_name : "")); + outlet_float(((t_object *)x)->ob_outlet, (t_float)result); + } + else hammerpanel_open(x->x_filehandle, 0); + } static void maxmode_click(t_maxmode *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { - maxmode_doimport(x, 0, 0); + maxmode_doimport(x, 0); } static void maxmode_import(t_maxmode *x, t_symbol *fn) { - maxmode_doimport(x, fn, 0); + maxmode_doimport(x, fn); } static void maxmode_cd(t_maxmode *x, t_symbol *dir) { - /* LATER hammerfile interface for relative jumps, etc. */ - x->x_dir = (dir && dir != &s_ ? dir : x->x_canvasdir); + hammerpanel_setopendir(x->x_filehandle, dir); } -static void maxmode_pwd(t_maxmode *x) +static void maxmode_pwd(t_maxmode *x, t_symbol *s) { - outlet_symbol(((t_object *)x)->ob_outlet, x->x_dir); + t_symbol *dir; + if (s && s->s_thing && (dir = hammerpanel_getopendir(x->x_filehandle))) + pd_symbol(s->s_thing, dir); +} + +static void maxmode_set(t_maxmode *x, t_symbol *s) +{ + if (!s || s == &s_) + s = gensym("none"); + if (s != fitter_getmode()) + fitter_setmode(s); +} + +static void maxmode_get(t_maxmode *x) +{ + t_symbol *mode; + if (mode = fitter_getmode()) + outlet_symbol(x->x_modeout, mode); } static void maxmode_bang(t_maxmode *x) @@ -79,12 +98,14 @@ static void maxmode_bang(t_maxmode *x) static void maxmode_free(t_maxmode *x) { + /* FIXME cancel registration */ hammerfile_free(x->x_filehandle); } static void *maxmode_new(t_symbol *s, int ac, t_atom *av) { t_maxmode *x = (t_maxmode *)pd_new(maxmode_class); + int selective = ac; if (maxmode_withbanner && !ac) { post("this is maxmode %s, %s %s build", @@ -93,25 +114,22 @@ static void *maxmode_new(t_symbol *s, int ac, t_atom *av) "creating maxmode object without loading cyclone components"); maxmode_withbanner = 0; } - if (!fittermax_get()) + if (selective) { - int selective = 0; - if (ac) + /* a numeric argument is valid -- transparent object is created + (global mode is not set, nothing is registered) */ + while (ac--) if (av->a_type == A_SYMBOL) { - while (ac--) if (av->a_type == A_SYMBOL) - { - /* FIXME register into fitter for per-patch, selective - compatibility control */ - av++; - } + /* FIXME register into fitter for per-patch-file, selective + compatibility control */ + av++; } - if (!selective) - fittermax_set(); } + else if (!fittermax_get()) + fittermax_set(); x->x_filehandle = hammerfile_new((t_pd *)x, 0, maxmode_readhook, 0, 0); - x->x_canvasdir = canvas_getdir(x->x_filehandle->f_canvas); - x->x_dir = x->x_canvasdir; - outlet_new((t_object *)x, &s_symbol); + outlet_new((t_object *)x, &s_float); + x->x_modeout = outlet_new((t_object *)x, &s_symbol); return (x); } @@ -128,10 +146,14 @@ void maxmode_setup(void) (t_method)maxmode_free, sizeof(t_maxmode), 0, A_GIMME, 0); class_addbang(maxmode_class, maxmode_bang); + class_addmethod(maxmode_class, (t_method)maxmode_set, + gensym("set"), A_DEFSYM, 0); + class_addmethod(maxmode_class, (t_method)maxmode_get, + gensym("get"), 0); class_addmethod(maxmode_class, (t_method)maxmode_cd, gensym("cd"), A_DEFSYM, 0); class_addmethod(maxmode_class, (t_method)maxmode_pwd, - gensym("pwd"), 0); + gensym("pwd"), A_SYMBOL, 0); class_addmethod(maxmode_class, (t_method)maxmode_import, gensym("import"), A_DEFSYM, 0); class_addmethod(maxmode_class, (t_method)maxmode_click, @@ -141,7 +163,7 @@ void maxmode_setup(void) if (canvas_getcurrent()) { - fitter_setup(0, 0, 0); + fitter_setup(0, 0); if (!zgetfn(&pd_objectmaker, gensym("cyclone"))) /* cycloneless maxmode -- banner is posted by the oldest maxmode object with no creation arguments */ diff --git a/cyclone/sickle/Makefile.objects b/cyclone/sickle/Makefile.objects index 1d80296..e85d2c9 100644 --- a/cyclone/sickle/Makefile.objects +++ b/cyclone/sickle/Makefile.objects @@ -4,6 +4,7 @@ unstable/fragile.o \ unstable/fringe.o \ common/loud.o \ common/grow.o \ +common/os.o \ common/fitter.o \ common/vefl.o \ common/clc.o \ diff --git a/cyclone/sickle/Makefile.sources b/cyclone/sickle/Makefile.sources index 901be5b..c66b33e 100644 --- a/cyclone/sickle/Makefile.sources +++ b/cyclone/sickle/Makefile.sources @@ -44,6 +44,7 @@ linedrive.c \ log.c \ lookup.c \ lores.c \ +matrix.c \ maximum.c \ minimum.c \ minmax.c \ diff --git a/cyclone/sickle/Scope.c b/cyclone/sickle/Scope.c index 8a71cb5..4668afe 100644 --- a/cyclone/sickle/Scope.c +++ b/cyclone/sickle/Scope.c @@ -1051,5 +1051,5 @@ void Scope_tilde_setup(void) gensym("_click"), A_FLOAT, 0); class_addmethod(scopehandle_class, (t_method)scopehandle__motionhook, gensym("_motion"), A_FLOAT, A_FLOAT, 0); - fitter_setup(scope_class, 0, 0); + fitter_setup(scope_class, 0); } diff --git a/cyclone/sickle/allsickles.c b/cyclone/sickle/allsickles.c index 7771cf8..b8432d5 100644 --- a/cyclone/sickle/allsickles.c +++ b/cyclone/sickle/allsickles.c @@ -1,6 +1,6 @@ // Do not edit this file, run "make" instead. -/* Copyright (c) 2002-2003 krzYszcz and others. +/* Copyright (c) 2002-2004 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ @@ -45,6 +45,7 @@ void linedrive_setup(void); void log_tilde_setup(void); void lookup_tilde_setup(void); void lores_tilde_setup(void); +void matrix_tilde_setup(void); void maximum_tilde_setup(void); void minimum_tilde_setup(void); void minmax_tilde_setup(void); @@ -124,6 +125,7 @@ void allsickles_setup(void) log_tilde_setup(); lookup_tilde_setup(); lores_tilde_setup(); + matrix_tilde_setup(); maximum_tilde_setup(); minimum_tilde_setup(); minmax_tilde_setup(); diff --git a/cyclone/sickle/buffir.c b/cyclone/sickle/buffir.c index 1fd9d23..13eee79 100644 --- a/cyclone/sickle/buffir.c +++ b/cyclone/sickle/buffir.c @@ -211,5 +211,5 @@ void buffir_tilde_setup(void) gensym("clear"), 0); class_addmethod(buffir_class, (t_method)buffir_set, gensym("set"), A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0); - fitter_setup(buffir_class, 0, 0); + fitter_setup(buffir_class, 0); } diff --git a/cyclone/sickle/linedrive.c b/cyclone/sickle/linedrive.c index 8b133ab..99c3720 100644 --- a/cyclone/sickle/linedrive.c +++ b/cyclone/sickle/linedrive.c @@ -1,67 +1,134 @@ -/* Copyright (c) 2002-2003 krzYszcz and others. +/* Copyright (c) 2002-2005 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ -/* CHECKME polarity */ - #include <math.h> #include "m_pd.h" +#include "common/fitter.h" #if defined(NT) || defined(MACOSX) #define logf log #define expf exp #endif -static t_class *linedrive_class; +#define LINEDRIVE_MININPUT .5 /* CHECKED */ +#define LINEDRIVE_MINCURVE 1. /* CHECKED */ + +#define LINEDRIVE_INPUTEPSILON 1e-19f +#define LINEDRIVE_CURVEEPSILON 1e-19f typedef struct _linedrive { t_object x_ob; + t_float x_usermaxin; + t_float x_usermaxout; + t_float x_usercurve; t_float x_maxin; t_float x_maxout; t_float x_expcoef; t_float x_lincoef; - t_atom x_vec[2]; - int x_linear; + int x_islinear; + int x_iscompatible; + t_atom x_outvec[2]; } t_linedrive; +static t_class *linedrive_class; + static void linedrive_float(t_linedrive *x, t_floatarg f) { - float outval = f - x->x_maxin; - if (outval >= 0) - outval = x->x_maxout; /* CHECKED */ - else if (x->x_linear) - outval = x->x_maxout + outval * x->x_lincoef; + t_float outval; + if (x->x_iscompatible) + { + if (f < LINEDRIVE_MININPUT) /* CHECKED */ + outval = 0.; + else if (f >= x->x_maxin) /* CHECKED */ + outval = x->x_maxin; + else + outval = expf((f - x->x_maxin) * x->x_expcoef) * x->x_maxout; + } else - outval = expf(outval * x->x_expcoef) * x->x_maxout; - SETFLOAT(x->x_vec, outval); - outlet_list(((t_object *)x)->ob_outlet, 0, 2, x->x_vec); + { + if (x->x_islinear) + outval = x->x_maxout + (f - x->x_maxin) * x->x_lincoef; + else if (f < -LINEDRIVE_INPUTEPSILON) + outval = -expf((-f - x->x_maxin) * x->x_expcoef) * x->x_maxout; + else if (f > LINEDRIVE_INPUTEPSILON) + outval = expf((f - x->x_maxin) * x->x_expcoef) * x->x_maxout; + else + outval = 0.; + } + SETFLOAT(x->x_outvec, outval); + outlet_list(((t_object *)x)->ob_outlet, 0, 2, x->x_outvec); } -static void *linedrive_new(t_floatarg maxin, t_floatarg maxout, - t_floatarg curve, t_floatarg deltime) +static void linedrive_calculate(t_linedrive *x) { - t_linedrive *x = (t_linedrive *)pd_new(linedrive_class); - x->x_maxin = (maxin < 1.0e-20f && maxin > -1e-20f ? 0 : maxin); - x->x_maxout = maxout; - if (curve < 1.0e-20f) curve = 1.0; /* a bug in msp? */ - if (curve == 1.0) + t_float maxin = x->x_usermaxin; + t_float maxout = x->x_usermaxout; + t_float curve = x->x_usercurve; + if (x->x_iscompatible = fittermax_get()) { - x->x_expcoef = 0; - x->x_lincoef = (x->x_maxin == 0 ? 0 : x->x_maxout / x->x_maxin); - x->x_linear = 1; + /* CHECKED */ + x->x_maxin = (maxin > LINEDRIVE_MININPUT ? maxin : LINEDRIVE_MININPUT); + /* CHECKED */ + x->x_expcoef = (curve > LINEDRIVE_MINCURVE ? logf(curve) : 0.); + x->x_lincoef = 0.; + x->x_islinear = 0; } - else { - x->x_expcoef = logf(curve); - x->x_lincoef = 0; - x->x_linear = 0; + else + { + if (maxin >= -LINEDRIVE_INPUTEPSILON && maxin <= LINEDRIVE_INPUTEPSILON) + { + x->x_maxin = 0.; + x->x_expcoef = 0.; + x->x_lincoef = 0.; + x->x_islinear = 1; + } + else if (curve >= (1. - LINEDRIVE_CURVEEPSILON) && + curve <= (1. + LINEDRIVE_CURVEEPSILON)) + { + x->x_maxin = maxin; + x->x_expcoef = 0.; + x->x_lincoef = maxout / maxin; + x->x_islinear = 1; + } + else + { + if (maxin < 0.) + { + x->x_maxin = -maxin; + maxout = -maxout; + } + else x->x_maxin = maxin; + if (curve < LINEDRIVE_CURVEEPSILON) + curve = LINEDRIVE_CURVEEPSILON; + x->x_expcoef = logf(curve); + x->x_lincoef = 0.; + x->x_islinear = 0; + } } - SETFLOAT(&x->x_vec[1], deltime); /* CHECKED: any value accepted */ - floatinlet_new((t_object *)x, &x->x_vec[1].a_w.w_float); + x->x_maxout = maxout; /* CHECKED negative value accepted and used */ +} + +static void *linedrive_new(t_floatarg maxin, t_floatarg maxout, + t_floatarg curve, t_floatarg deltime) +{ + t_linedrive *x = (t_linedrive *)pd_new(linedrive_class); + x->x_usermaxin = maxin; + x->x_usermaxout = maxout; + x->x_usercurve = curve; + linedrive_calculate(x); + SETFLOAT(&x->x_outvec[1], deltime); /* CHECKED any value accepted */ + floatinlet_new((t_object *)x, &x->x_outvec[1].a_w.w_float); outlet_new((t_object *)x, &s_list); return (x); } +static void linedrive_fitter(void) +{ + /* FIXME for all objects in scope do recalculate */ +} + void linedrive_setup(void) { linedrive_class = class_new(gensym("linedrive"), @@ -70,4 +137,5 @@ void linedrive_setup(void) A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addfloat(linedrive_class, linedrive_float); + fitter_setup(linedrive_class, linedrive_fitter); } diff --git a/cyclone/sickle/matrix.c b/cyclone/sickle/matrix.c new file mode 100644 index 0000000..a0772dc --- /dev/null +++ b/cyclone/sickle/matrix.c @@ -0,0 +1,563 @@ +/* Copyright (c) 2005 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include "m_pd.h" +#include "common/loud.h" +#include "common/fitter.h" +#include "unstable/fragile.h" +#include "sickle/sic.h" + +#ifdef KRZYSZCZ +#define MATRIX_DEBUG +#endif + +#define MATRIX_DEFGAIN 0. /* CHECKED */ +#define MATRIX_DEFRAMP 0. /* CHECKED */ + +#define MATRIX_GAINEPSILON 1e-20f +#define MATRIX_MINRAMP .001 /* LATER rethink */ + +typedef struct _matrix +{ + t_sic x_sic; + int x_ninlets; + int x_noutlets; + int x_nblock; + int x_maxblock; + t_float **x_ivecs; + t_float **x_ovecs; + t_float **x_osums; + int x_ncells; + int *x_cells; + t_outlet *x_dumpout; + /* The following fields are specific to nonbinary mode, i.e. we keep them + unallocated in binary mode. This is CHECKED to be incompatible: c74 + always accepts (and reports) gains and ramps, although they are actually + meaningless in binary mode, and switching modes is not supported. */ + float x_defgain; + float *x_gains; /* target gains */ + float x_deframp; + float *x_ramps; + float x_ksr; + float *x_coefs; /* current coefs */ + float *x_incrs; + float *x_bigincrs; + int *x_remains; +} t_matrix; + +typedef void (*t_matrix_cellfn)(t_matrix *x, int indx, int ondx, + int onoff, float gain); + +static t_class *matrix_class; +static t_symbol *matrixps_matrixtilde; + +/* called only in nonbinary mode; LATER deal with changing nblock/ksr */ +static void matrix_retarget(t_matrix *x, int cellndx) +{ + float target = (x->x_cells[cellndx] ? x->x_gains[cellndx] : 0.); + if (x->x_ramps[cellndx] < MATRIX_MINRAMP) + { + x->x_coefs[cellndx] = target; + x->x_remains[cellndx] = 0; + } + else + { + x->x_remains[cellndx] = + x->x_ramps[cellndx] * x->x_ksr + 0.5; /* LATER rethink */ + x->x_incrs[cellndx] = + (target - x->x_coefs[cellndx]) / (float)x->x_remains[cellndx]; + x->x_bigincrs[cellndx] = x->x_nblock * x->x_incrs[cellndx]; + } +} + +static void matrix_float(t_matrix *x, t_float f) +{ + loud_nomethod((t_pd *)x, &s_float); /* CHECKED */ +} + +static void matrix_list(t_matrix *x, t_symbol *s, int ac, t_atom *av) +{ + int indx, ondx, cellndx, onoff; + float gain; + if (ac < 3) + return; /* CHECKED list silently ignored if ac < 3 */ + /* CHECKED floats silently clipped, symbols converted to 0 */ + indx = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0); + if (indx < 0 || indx >= x->x_ninlets) + { /* CHECKED */ + loud_error((t_pd *)x, "invalid inlet number %d", indx); + return; + } + ac--; av++; + /* CHECKED floats silently clipped, symbols converted to 0 */ + ondx = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0); + if (ondx < 0 || ondx >= x->x_noutlets) + { /* CHECKED */ + loud_error((t_pd *)x, "invalid outlet number %d", ondx); + return; + } + cellndx = indx * x->x_noutlets + ondx; + ac--; av++; + /* CHECKED negative gain used in nonbinary mode, accepted as 1 in binary */ + gain = (av->a_type == A_FLOAT ? av->a_w.w_float : 0.); + onoff = (gain < -MATRIX_GAINEPSILON || gain > MATRIX_GAINEPSILON); + x->x_cells[cellndx] = onoff; + if (x->x_gains) + { + if (onoff) /* CHECKME */ + x->x_gains[cellndx] = gain; + ac--; av++; + if (ac) + { + float ramp = (av->a_type == A_FLOAT ? av->a_w.w_float : 0.); + x->x_ramps[cellndx] = (ramp < MATRIX_MINRAMP ? 0. : ramp); + } + matrix_retarget(x, cellndx); + } +} + +static void matrix_clear(t_matrix *x) +{ + int i; + for (i = 0; i < x->x_ncells; i++) + x->x_cells[i] = 0; +} + +/* CHECKED c74's refman and help patch are wrong about int pairs -- + the actual syntax is "[dis]connect indx ondx1 [ondx2 [ondx3..." */ +static void matrix_connect(t_matrix *x, t_symbol *s, int ac, t_atom *av) +{ + int onoff = (s == gensym("connect")), indx, celloffset; + if (ac < 2) + return; /* CHECKED */ + /* CHECKED floats silently clipped, symbols converted to 0 */ + indx = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0); + if (indx < 0 || indx >= x->x_ninlets) + { /* CHECKED */ + loud_error((t_pd *)x, "invalid inlet number %d", indx); + return; + } + celloffset = indx * x->x_noutlets; + ac--; av++; + while (ac) + { + /* CHECKED floats silently clipped, symbols converted to 0 */ + int cellndx, ondx = (av->a_type == A_FLOAT ? (int)av->a_w.w_float : 0); + if (ondx < 0 || ondx >= x->x_noutlets) + { /* CHECKED */ + loud_error((t_pd *)x, "invalid outlet number %d", ondx); + return; + } + cellndx = celloffset + ondx; + x->x_cells[cellndx] = onoff; + if (x->x_gains) + matrix_retarget(x, cellndx); + ac--; av++; + } +} + +/* CHECKED active ramps are not retargeted */ +static void matrix_ramp(t_matrix *x, t_floatarg f) +{ + if (x->x_ramps) + { + int i; + x->x_deframp = (f < MATRIX_MINRAMP ? 0. : f); + /* CHECKED cell-specific ramps are lost */ + for (i = 0; i < x->x_ncells; i++) + x->x_ramps[i] = x->x_deframp; + } +} + +static t_int *matrix01_perform(t_int *w) +{ + t_matrix *x = (t_matrix *)(w[1]); + int nblock = (int)(w[2]); + t_float **ivecs = x->x_ivecs; + t_float **ovecs = x->x_ovecs; + t_float **osums = x->x_osums; + int *cellp = x->x_cells; + int indx = x->x_ninlets; + while (indx--) + { + t_float *ivec = *ivecs++; + t_float **ovecp = osums; + int ondx = x->x_noutlets; + while (ondx--) + { + if (*cellp++) + { + t_float *in = ivec; + t_float *out = *ovecp; + int sndx = nblock; + while (sndx--) + *out++ += *in++; + } + ovecp++; + } + } + osums = x->x_osums; + indx = x->x_noutlets; + while (indx--) + { + t_float *in = *osums++; + t_float *out = *ovecs++; + int sndx = nblock; + while (sndx--) + { + *out++ = *in; + *in++ = 0.; + } + } + return (w + 3); +} + +static t_int *matrixnb_perform(t_int *w) +{ + t_matrix *x = (t_matrix *)(w[1]); + int nblock = (int)(w[2]); + t_float **ivecs = x->x_ivecs; + t_float **ovecs = x->x_ovecs; + t_float **osums = x->x_osums; + int *cellp = x->x_cells; + float *gainp = x->x_gains; + float *coefp = x->x_coefs; + float *incrp = x->x_incrs; + float *bigincrp = x->x_bigincrs; + int *nleftp = x->x_remains; + int indx = x->x_ninlets; + while (indx--) + { + t_float *ivec = *ivecs++; + t_float **ovecp = osums; + int ondx = x->x_noutlets; + while (ondx--) + { + t_float *in = ivec; + t_float *out = *ovecp; + float nleft = *nleftp; + int sndx = nblock; + if (nleft >= nblock) + { + float coef = *coefp; + float incr = *incrp; + if ((*nleftp -= nblock) == 0) + *coefp = (*cellp ? *gainp : 0.); + else + *coefp += *bigincrp; + while (sndx--) + *out++ += *in++ * coef, coef += incr; + } + else if (nleft > 0) + { + float coef = *coefp; + float incr = *incrp; + sndx -= nleft; + do + *out++ += *in++ * coef, coef += incr; + while (--nleft); + if (*cellp) + { + coef = *coefp = *gainp; + while (sndx--) + *out++ += *in++ * coef; + } + else *coefp = 0.; + *nleftp = 0; + } + else if (*cellp) + { + float coef = *coefp; + while (sndx--) + *out++ += *in++ * coef; + } + cellp++; + ovecp++; + gainp++; + coefp++; + incrp++; + bigincrp++; + nleftp++; + } + } + osums = x->x_osums; + indx = x->x_noutlets; + while (indx--) + { + t_float *in = *osums++; + t_float *out = *ovecs++; + int sndx = nblock; + while (sndx--) + { + *out++ = *in; + *in++ = 0.; + } + } + return (w + 3); +} + +static void matrix_dsp(t_matrix *x, t_signal **sp) +{ + int i, nblock = sp[0]->s_n; + t_float **vecp = x->x_ivecs; + t_signal **sigp = sp; + for (i = 0; i < x->x_ninlets; i++) + *vecp++ = (*sigp++)->s_vec; + vecp = x->x_ovecs; + for (i = 0; i < x->x_noutlets; i++) + *vecp++ = (*sigp++)->s_vec; + if (nblock != x->x_nblock) + { + if (nblock > x->x_maxblock) + { + size_t oldsize = x->x_maxblock * sizeof(*x->x_osums[i]), + newsize = nblock * sizeof(*x->x_osums[i]); + for (i = 0; i < x->x_noutlets; i++) + x->x_osums[i] = resizebytes(x->x_osums[i], oldsize, newsize); + x->x_maxblock = nblock; + } + x->x_nblock = nblock; + } + if (x->x_gains) + { + x->x_ksr = sp[0]->s_sr * .001; + dsp_add(matrixnb_perform, 2, x, nblock); + } + else dsp_add(matrix01_perform, 2, x, nblock); +} + +static void matrix_cellout(t_matrix *x, int indx, int ondx, + int onoff, float gain) +{ + t_atom atout[3]; + SETFLOAT(&atout[0], (t_float)indx); + SETFLOAT(&atout[1], (t_float)ondx); + if (onoff) + SETFLOAT(&atout[2], gain); + else + SETFLOAT(&atout[2], 0.); + outlet_list(x->x_dumpout, &s_list, 3, atout); +} + +static void matrix_cellprint(t_matrix *x, int indx, int ondx, + int onoff, float gain) +{ + post("%d %d %g", indx, ondx, (onoff ? gain : 0.)); +} + +#ifdef MATRIX_DEBUG +static void matrix_celldebug(t_matrix *x, int indx, int ondx, + int onoff, float gain) +{ + loudbug_post("%d %d %g", indx, ondx, gain); +} +#endif + +static void matrix_report(t_matrix *x, float *gains, float defgain, + t_matrix_cellfn cellfn) +{ + if (gains) + { + int *cellp = x->x_cells; + float *gp = gains; + int indx, ondx; + for (indx = 0; indx < x->x_ninlets; indx++) + for (ondx = 0; ondx < x->x_noutlets; ondx++, cellp++, gp++) + /* CHECKED all cells are printed */ + (*cellfn)(x, indx, ondx, *cellp, *gp); + } + else /* CHECKED incompatible: gains confusingly printed in binary mode */ + { + int *cellp = x->x_cells; + int indx, ondx; + for (indx = 0; indx < x->x_ninlets; indx++) + for (ondx = 0; ondx < x->x_noutlets; ondx++, cellp++) + /* CHECKED all cells are printed */ + (*cellfn)(x, indx, ondx, *cellp, defgain); + } +} + +static void matrix_dump(t_matrix *x) +{ + matrix_report(x, x->x_coefs, 1., matrix_cellout); +} + +static void matrix_dumptarget(t_matrix *x) +{ + matrix_report(x, x->x_gains, 1., matrix_cellout); +} + +static void matrix_print(t_matrix *x) +{ + /* CHECKED same output as 'dump' -> [matrix~] -> [print] */ + matrix_report(x, x->x_coefs, 1., matrix_cellprint); +} + +#ifdef MATRIX_DEBUG +static void matrix_debugramps(t_matrix *x) +{ + matrix_report(x, x->x_ramps, 0., matrix_celldebug); +} + +static void matrix_debugsums(t_matrix *x) +{ + int i; + loudbug_startpost("nblock %d (max %d), vectors:", + x->x_nblock, x->x_maxblock); + for (i = 0; i < x->x_noutlets; i++) + loudbug_startpost(" %x", (int)x->x_osums[i]); + loudbug_endpost(); +} + +static void matrix_debug(t_matrix *x, t_symbol *s) +{ + if (s == gensym("ramps")) + matrix_debugramps(x); + else if (s == gensym("sums")) + matrix_debugsums(x); + else + { + matrix_debugramps(x); + matrix_debugsums(x); + } +} +#endif + +static void matrix_free(t_matrix *x) +{ + if (x->x_ivecs) + freebytes(x->x_ivecs, x->x_ninlets * sizeof(*x->x_ivecs)); + if (x->x_ovecs) + freebytes(x->x_ovecs, x->x_noutlets * sizeof(*x->x_ovecs)); + if (x->x_osums) + { + int i; + for (i = 0; i < x->x_noutlets; i++) + freebytes(x->x_osums[i], x->x_maxblock * sizeof(*x->x_osums[i])); + freebytes(x->x_osums, x->x_noutlets * sizeof(*x->x_osums)); + } + if (x->x_cells) + freebytes(x->x_cells, x->x_ncells * sizeof(*x->x_cells)); + if (x->x_gains) + freebytes(x->x_gains, x->x_ncells * sizeof(*x->x_gains)); + if (x->x_ramps) + freebytes(x->x_ramps, x->x_ncells * sizeof(*x->x_ramps)); + if (x->x_coefs) + freebytes(x->x_coefs, x->x_ncells * sizeof(*x->x_coefs)); + if (x->x_incrs) + freebytes(x->x_incrs, x->x_ncells * sizeof(*x->x_incrs)); + if (x->x_bigincrs) + freebytes(x->x_bigincrs, x->x_ncells * sizeof(*x->x_bigincrs)); + if (x->x_remains) + freebytes(x->x_remains, x->x_ncells * sizeof(*x->x_remains)); +} + +static void *matrix_new(t_symbol *s, int ac, t_atom *av) +{ + t_pd *z; + if (!fittermax_get() && + (z = fragile_class_mutate(matrixps_matrixtilde, + (t_newmethod)matrix_new, ac, av))) + return (z); + else if (ac < 2) + { + loud_error(0, "bad creation arguments for class '%s'", + matrixps_matrixtilde->s_name); + loud_errand(0, "missing number of %s", (ac ? "outlets" : "inlets")); + return (0); /* CHECKED */ + } + else + { + t_matrix *x = (t_matrix *)pd_new(matrix_class); + int i; + if (av[0].a_type == A_FLOAT) + { + if ((x->x_ninlets = (int)av[0].a_w.w_float) < 1) + x->x_ninlets = 1; + } + else x->x_ninlets = 1; /* CHECKED */ + if (av[1].a_type == A_FLOAT) + { + if ((x->x_noutlets = (int)av[1].a_w.w_float) < 1) + x->x_noutlets = 1; + } + else x->x_noutlets = 1; /* CHECKED */ + x->x_ncells = x->x_ninlets * x->x_noutlets; + x->x_ivecs = getbytes(x->x_ninlets * sizeof(*x->x_ivecs)); + x->x_ovecs = getbytes(x->x_noutlets * sizeof(*x->x_ovecs)); + x->x_nblock = x->x_maxblock = sys_getblksize(); + x->x_osums = getbytes(x->x_noutlets * sizeof(*x->x_osums)); + for (i = 0; i < x->x_noutlets; i++) + x->x_osums[i] = getbytes(x->x_maxblock * sizeof(*x->x_osums[i])); + x->x_cells = getbytes(x->x_ncells * sizeof(*x->x_cells)); + matrix_clear(x); + if (ac >= 3) + { + if (av[2].a_type == A_FLOAT) + x->x_defgain = av[2].a_w.w_float; + else + x->x_defgain = MATRIX_DEFGAIN; + x->x_gains = getbytes(x->x_ncells * sizeof(*x->x_gains)); + for (i = 0; i < x->x_ncells; i++) + x->x_gains[i] = x->x_defgain; + x->x_ramps = getbytes(x->x_ncells * sizeof(*x->x_ramps)); + matrix_ramp(x, MATRIX_DEFRAMP); + x->x_coefs = getbytes(x->x_ncells * sizeof(*x->x_coefs)); + for (i = 0; i < x->x_ncells; i++) + x->x_coefs[i] = 0.; + x->x_ksr = sys_getsr() * .001; + x->x_incrs = getbytes(x->x_ncells * sizeof(*x->x_incrs)); + x->x_bigincrs = getbytes(x->x_ncells * sizeof(*x->x_bigincrs)); + x->x_remains = getbytes(x->x_ncells * sizeof(*x->x_remains)); + for (i = 0; i < x->x_ncells; i++) + x->x_remains[i] = 0; + } + else + { + x->x_gains = 0; + x->x_ramps = 0; + x->x_coefs = 0; + x->x_incrs = 0; + x->x_bigincrs = 0; + x->x_remains = 0; + } + for (i = 1; i < x->x_ninlets; i++) + sic_newinlet((t_sic *)x, 0.); + for (i = 0; i < x->x_noutlets; i++) + outlet_new((t_object *)x, &s_signal); + x->x_dumpout = outlet_new((t_object *)x, &s_list); + return (x); + } +} + +void matrix_tilde_setup(void) +{ + matrixps_matrixtilde = gensym("matrix~"); + matrix_class = class_new(matrixps_matrixtilde, + (t_newmethod)matrix_new, + (t_method)matrix_free, + sizeof(t_matrix), 0, A_GIMME, 0); + fragile_class_raise(matrixps_matrixtilde, (t_newmethod)matrix_new); + sic_setup(matrix_class, matrix_dsp, matrix_float); + class_addlist(matrix_class, matrix_list); + class_addmethod(matrix_class, (t_method)matrix_clear, + gensym("clear"), 0); + class_addmethod(matrix_class, (t_method)matrix_connect, + gensym("connect"), A_GIMME, 0); + class_addmethod(matrix_class, (t_method)matrix_connect, + gensym("disconnect"), A_GIMME, 0); + class_addmethod(matrix_class, (t_method)matrix_ramp, + gensym("ramp"), A_FLOAT, 0); + class_addmethod(matrix_class, (t_method)matrix_dump, + gensym("dump"), 0); + class_addmethod(matrix_class, (t_method)matrix_dumptarget, + gensym("dumptarget"), 0); + class_addmethod(matrix_class, (t_method)matrix_print, + gensym("print"), 0); +#ifdef MATRIX_DEBUG + class_addmethod(matrix_class, (t_method)matrix_debug, + gensym("debug"), A_DEFSYM, 0); +#endif + fitter_setup(matrix_class, 0); +} diff --git a/cyclone/sickle/sickle.c b/cyclone/sickle/sickle.c index 1d46050..c83f543 100644 --- a/cyclone/sickle/sickle.c +++ b/cyclone/sickle/sickle.c @@ -13,8 +13,6 @@ void allsickles_setup(void); typedef struct _sickle { t_object x_ob; - t_symbol *x_dir; - t_symbol *x_canvasdir; t_hammerfile *x_filehandle; } t_sickle; @@ -24,39 +22,43 @@ static int sickle_lastndx; static void sickle_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av) { - import_max(fn->s_name, ""); + int result = import_max(fn->s_name, ""); + outlet_float(((t_object *)z)->ob_outlet, (t_float)result); } -static void sickle_doimport(t_sickle *x, t_symbol *fn, t_symbol *dir) +static void sickle_doimport(t_sickle *x, t_symbol *fn) { - if (!dir || dir == &s_) - dir = x->x_dir; if (fn && fn != &s_) - import_max(fn->s_name, (dir && dir != &s_) ? dir->s_name : ""); - else - hammerpanel_open(x->x_filehandle, dir); + { + t_symbol *dir = hammerpanel_getopendir(x->x_filehandle); + int result = + import_max(fn->s_name, (dir && dir != &s_ ? dir->s_name : "")); + outlet_float(((t_object *)x)->ob_outlet, (t_float)result); + } + else hammerpanel_open(x->x_filehandle, 0); } static void sickle_click(t_sickle *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) { - sickle_doimport(x, 0, 0); + sickle_doimport(x, 0); } static void sickle_import(t_sickle *x, t_symbol *fn) { - sickle_doimport(x, fn, 0); + sickle_doimport(x, fn); } static void sickle_cd(t_sickle *x, t_symbol *dir) { - /* LATER hammerfile interface for relative jumps, etc. */ - x->x_dir = (dir && dir != &s_ ? dir : x->x_canvasdir); + hammerpanel_setopendir(x->x_filehandle, dir); } -static void sickle_pwd(t_sickle *x) +static void sickle_pwd(t_sickle *x, t_symbol *s) { - outlet_symbol(((t_object *)x)->ob_outlet, x->x_dir); + t_symbol *dir; + if (s && s->s_thing && (dir = hammerpanel_getopendir(x->x_filehandle))) + pd_symbol(s->s_thing, dir); } static void sickle_bang(t_sickle *x) @@ -74,9 +76,7 @@ static void *sickle_new(void) { t_sickle *x = (t_sickle *)pd_new(sickle_class); x->x_filehandle = hammerfile_new((t_pd *)x, 0, sickle_readhook, 0, 0); - x->x_canvasdir = canvas_getdir(x->x_filehandle->f_canvas); - x->x_dir = x->x_canvasdir; - outlet_new((t_object *)x, &s_symbol); + outlet_new((t_object *)x, &s_float); return (x); } @@ -106,7 +106,7 @@ void sickle_setup(void) class_addmethod(sickle_class, (t_method)sickle_cd, gensym("cd"), A_DEFSYM, 0); class_addmethod(sickle_class, (t_method)sickle_pwd, - gensym("pwd"), 0); + gensym("pwd"), A_SYMBOL, 0); class_addmethod(sickle_class, (t_method)sickle_import, gensym("import"), A_DEFSYM, 0); class_addmethod(sickle_class, (t_method)sickle_click, |