From 0d4b66c7bc77f6a2fafb1debe548f8621d21cf70 Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Sun, 21 Aug 2005 14:46:18 +0000 Subject: Improved samplerate~ implementation. svn path=/trunk/; revision=3438 --- pd/src/d_misc.c | 43 ------------------------------- pd/src/d_ugen.c | 77 ++++++++++++++++++++++++++++++++++++++++--------------- pd/src/g_canvas.c | 26 ++++++++++++++----- pd/src/g_editor.c | 18 +++++++++++-- pd/src/notes.txt | 44 +++---------------------------- 5 files changed, 97 insertions(+), 111 deletions(-) (limited to 'pd/src') diff --git a/pd/src/d_misc.c b/pd/src/d_misc.c index 1056f0cb..3a327dc5 100644 --- a/pd/src/d_misc.c +++ b/pd/src/d_misc.c @@ -127,48 +127,6 @@ static void bang_tilde_setup(void) gensym("dsp"), 0); } -/* ------------------------ samplerate~~ -------------------------- */ - -static t_class *samplerate_tilde_class; - -typedef struct _samplerate -{ - t_object x_obj; - float x_sr; -} t_samplerate; - -static void samplerate_tilde_bang(t_samplerate *x) -{ - if (!canvas_dspstate) - { - post( - "NB: samplerate~ momentarily started DSP to learn sample rate"); - canvas_resume_dsp(1); - canvas_suspend_dsp(); - } - outlet_float(x->x_obj.ob_outlet, x->x_sr); -} - -static void samplerate_tilde_dsp(t_samplerate *x, t_signal **sp) -{ - x->x_sr = sp[0]->s_sr; -} - -static void *samplerate_tilde_new(t_symbol *s) -{ - t_samplerate *x = (t_samplerate *)pd_new(samplerate_tilde_class); - outlet_new(&x->x_obj, &s_float); - return (x); -} - -static void samplerate_tilde_setup(void) -{ - samplerate_tilde_class = class_new(gensym("samplerate~"), - (t_newmethod)samplerate_tilde_new, 0, sizeof(t_samplerate), 0, 0); - class_addbang(samplerate_tilde_class, samplerate_tilde_bang); - class_addmethod(samplerate_tilde_class, (t_method)samplerate_tilde_dsp, - gensym("dsp"), A_CANT, 0); -} /* ------------------------ global setup routine ------------------------- */ @@ -176,7 +134,6 @@ void d_misc_setup(void) { print_setup(); bang_tilde_setup(); - samplerate_tilde_setup(); } diff --git a/pd/src/d_ugen.c b/pd/src/d_ugen.c index 17a4ecc3..c1dcbffc 100644 --- a/pd/src/d_ugen.c +++ b/pd/src/d_ugen.c @@ -247,6 +247,18 @@ static void block_dsp(t_block *x, t_signal **sp) /* do nothing here */ } +void block_tilde_setup(void) +{ + block_class = class_new(gensym("block~"), (t_newmethod)block_new, 0, + sizeof(t_block), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)switch_new, gensym("switch~"), + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(block_class, (t_method)block_set, gensym("set"), + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(block_class, (t_method)block_dsp, gensym("dsp"), 0); + class_addfloat(block_class, block_float); +} + /* ------------------ DSP call list ----------------------- */ static t_int *dsp_chain; @@ -660,7 +672,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) t_siginlet *uin; t_sigoutconnect *oc, *oc2; t_class *class = pd_class(&u->u_obj->ob_pd); - int i, n, totnsig; + int i, n; /* suppress creating new signals for the outputs of signal inlets and subpatchs; except in the case we're an inlet and "blocking" is set. We don't yet know if a subcanvas will be "blocking" so there @@ -695,8 +707,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) s3->s_refcount = 1; } } - totnsig = u->u_nin + u->u_nout; - insig = (t_signal **)getbytes((totnsig ? totnsig : 1) * sizeof(t_signal *)); + insig = (t_signal **)getbytes((u->u_nin + u->u_nout) * sizeof(t_signal *)); outsig = insig + u->u_nin; for (sig = insig, uin = u->u_in, i = u->u_nin; i--; sig++, uin++) { @@ -731,11 +742,6 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) *sig = uout->o_signal = signal_new(dc->dc_vecsize, dc->dc_srate); (*sig)->s_refcount = uout->o_nconnect; } - /* if thre are no input or output signals, supply one fake signal so - the object can learn the sample rate and block size. Used by the - samplerate~ object. */ - if (!totnsig) - insig[0] = signal_new(dc->dc_vecsize, dc->dc_srate); /* now call the DSP scheduling routine for the ugen. This routine must fill in "borrowed" signal outputs in case it's either a subcanvas or a signal inlet. */ @@ -750,9 +756,6 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u) if (!(*sig)->s_refcount) signal_makereusable(*sig); } - /* special case: no inputs or outputs: free the fake signal we made */ - if (!totnsig) - signal_makereusable(insig[0]); if (ugen_loud) { if (u->u_nin + u->u_nout == 0) post("put %s %d", @@ -1099,18 +1102,52 @@ t_signal *ugen_getiosig(int index, int inout) return (ugen_currentcontext->dc_iosigs[index]); } +/* ------------------------ samplerate~~ -------------------------- */ + +static t_class *samplerate_tilde_class; + +typedef struct _samplerate +{ + t_object x_obj; + float x_sr; + t_canvas *x_canvas; +} t_samplerate; + +void *canvas_getblock(t_class *blockclass, t_canvas **canvasp); + +static void samplerate_tilde_bang(t_samplerate *x) +{ + float srate = sys_getsr(); + t_canvas *canvas = x->x_canvas; + while (canvas) + { + t_block *b = (t_block *)canvas_getblock(block_class, &canvas); + if (b) + srate *= (float)(b->x_upsample) / (float)(b->x_downsample); + } + outlet_float(x->x_obj.ob_outlet, srate); +} + +static void *samplerate_tilde_new(t_symbol *s) +{ + t_samplerate *x = (t_samplerate *)pd_new(samplerate_tilde_class); + outlet_new(&x->x_obj, &s_float); + x->x_canvas = canvas_getcurrent(); + return (x); +} + +static void samplerate_tilde_setup(void) +{ + samplerate_tilde_class = class_new(gensym("samplerate~"), + (t_newmethod)samplerate_tilde_new, 0, sizeof(t_samplerate), 0, 0); + class_addbang(samplerate_tilde_class, samplerate_tilde_bang); +} /* -------------------- setup routine -------------------------- */ -void d_ugen_setup(void) /* really just block_setup */ +void d_ugen_setup(void) { - block_class = class_new(gensym("block~"), (t_newmethod)block_new, 0, - sizeof(t_block), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)switch_new, gensym("switch~"), - A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(block_class, (t_method)block_set, gensym("set"), - A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(block_class, (t_method)block_dsp, gensym("dsp"), 0); - class_addfloat(block_class, block_float); + block_tilde_setup(); + samplerate_tilde_setup(); } diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index 4019807f..dd8e6467 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -1224,12 +1224,6 @@ int canvas_showtext(t_canvas *x) return (!isarray); } -static void canvas_dodsp(t_canvas *x, int toplevel, t_signal **sp); -static void canvas_dsp(t_canvas *x, t_signal **sp) -{ - canvas_dodsp(x, 0, sp); -} - /* get the document containing this canvas */ t_canvas *canvas_getrootfor(t_canvas *x) { @@ -1289,6 +1283,11 @@ static void canvas_dodsp(t_canvas *x, int toplevel, t_signal **sp) ugen_done_graph(dc); } +static void canvas_dsp(t_canvas *x, t_signal **sp) +{ + canvas_dodsp(x, 0, sp); +} + /* this routine starts DSP for all root canvases. */ static void canvas_start_dsp(void) { @@ -1356,6 +1355,21 @@ void glob_dsp(void *dummy, t_symbol *s, int argc, t_atom *argv) else post("dsp state %d", canvas_dspstate); } +void *canvas_getblock(t_class *blockclass, t_canvas **canvasp) +{ + t_canvas *canvas = *canvasp; + t_gobj *g; + void *ret = 0; + for (g = canvas->gl_list; g; g = g->g_next) + { + if (g->g_pd == blockclass) + ret = g; + } + *canvasp = canvas->gl_owner; + return(ret); +} + +/******************* redrawing data *********************/ /* redraw all "scalars" (do this if a drawing command is changed.) LATER we'll use the "template" information to select which ones we diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 938842a6..c621d299 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -1686,7 +1686,12 @@ void canvas_menuclose(t_canvas *x, t_floatarg fforce) g); return; } - else pd_free(&x->gl_pd); + else + { + sys_vgui( +"pdtk_check {Close this window??} {.x%lx menuclose 1;\n} yes\n", + x); + } } else if (force == 1) pd_free(&x->gl_pd); @@ -1695,7 +1700,16 @@ void canvas_menuclose(t_canvas *x, t_floatarg fforce) canvas_dirty(x, 0); while (x->gl_owner) x = x->gl_owner; - canvas_menuclose(x, 0); + g = glist_finddirty(x); + if (g) + { + canvas_vis(g, 1); + sys_vgui( +"pdtk_check {Discard changes to this window??} {.x%lx menuclose 2;\n} no\n", + g); + return; + } + else pd_free(&x->gl_pd); } else if (force == 3) { diff --git a/pd/src/notes.txt b/pd/src/notes.txt index 49f5a90c..257e24ca 100644 --- a/pd/src/notes.txt +++ b/pd/src/notes.txt @@ -1,46 +1,12 @@ ---------------- dolist -------------------- -done for 0.39: -At the source level, "regular" arrays and arrays withing data structures -are now the same thing. The main user-visible effect of this is that now -"arrays" may be graphed as "bezier curves". -array elements can be clicked on, etc -fixed array onset bug -rfft bug fix -bug fix in d_soundfile.c -bugfix in number2 -plot drawing instructions turn on and off -ranges in drawing instructions -select/deselect hook -unify graph properties dialogs -GOP font depends on abstraction, not parent -bug fixes, stale pointers -message "addcomma" etc -"list" object -Mac to tcl/tk 8.4.5; pd extension added automatically -bug fix writing aiff gfiles -bug fix (tcl error messages when starting open dialogs) -pointer rewind (also check if send-window documented?) -stop vis-ing subpatches of abstractions -save dirty abstractions on close -close dirty patches on quit -"find" fixed to open GOPs correctly -cheat to speed up mouse motion over arrays -fix samplerate~ to figure out blocking -thread-unsafe callbacks from sys_microsleep() -writesf -- "open" without "0" misses closing the previous file. - ------------- 0.39 --------- +test: +compile on various versions of linux windows: modal dialogs confuse watchdog check the right-click-on-empty-canvas -mac: - load libraries first before opening patches on drag-and-drop + MIDI I/O (inc. sysex) -check: -MIDI I/O for windows -blechman patch for s_inter.c -check what happens when going back and forth between graph-on-parent doc: object list @@ -76,6 +42,7 @@ check if _vsnprintf with zero argument in windows works any better... detect adc~ and dac~ reblocking features: +integrate video into tilde objects flag to suppress printing array name above graph flag to suppress scrollbars in canvases fix copyright notices @@ -109,7 +76,6 @@ editing: data: data copy/paste doesn't check templates aren't changed -figure out why Pd sometimes crashes when you close example after adding fields arrays of non-existent templates crash vget, vset traversal objects cursor to show (x, y) location @@ -119,8 +85,6 @@ sublists should display on parent if desired? (new drawing instruction) sublists seem not to handle canvas allocation right (get.pd->pointer.pd bug) scalar hook to catch the mouse protect against "plots" going away while you drag on them -when last drawing instruction leaves, glist_redrawitem() fails to erase it; - perhaps scalar_vis(...0) should just delete for the tag, itself? more features: -- cgit v1.2.1