Commit 16ffe950 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Vanilla 0.47 backport 4: d_ugen.c, g_array.c, and g_canvas.c

parent ddd99b87
......@@ -11,17 +11,14 @@
interconnections.
*/
#include "m_pd.h"
#include "m_imp.h"
#include <stdlib.h>
#include <stdarg.h>
extern t_class *vinlet_class, *voutlet_class, *canvas_class;
extern t_class *vinlet_class, *voutlet_class, *canvas_class, *text_class;
t_float *obj_findsignalscalar(t_object *x, int m);
static int ugen_loud;
static t_int *dsp_chain;
static int dsp_chainsize;
EXTERN_STRUCT _vinlet;
EXTERN_STRUCT _voutlet;
......@@ -219,11 +216,11 @@ static void block_float(t_block *x, t_floatarg f)
static void block_bang(t_block *x)
{
if (x->x_switched && !x->x_switchon)
if (x->x_switched && !x->x_switchon && pd_this->pd_dspchain)
{
t_int *ip;
x->x_return = 1;
for (ip = dsp_chain + x->x_chainonset; ip; )
for (ip = pd_this->pd_dspchain + x->x_chainonset; ip; )
ip = (*(t_perfroutine)(*ip))(ip);
x->x_return = 0;
}
......@@ -300,40 +297,48 @@ static t_int dsp_done(t_int *w)
void dsp_add(t_perfroutine f, int n, ...)
{
int newsize = dsp_chainsize + n+1, i;
int newsize = pd_this->pd_dspchainsize + n+1, i;
va_list ap;
dsp_chain = t_resizebytes(dsp_chain, dsp_chainsize * sizeof (t_int),
newsize * sizeof (t_int));
dsp_chain[dsp_chainsize-1] = (t_int)f;
pd_this->pd_dspchain = t_resizebytes(pd_this->pd_dspchain,
pd_this->pd_dspchainsize * sizeof (t_int), newsize * sizeof (t_int));
pd_this->pd_dspchain[pd_this->pd_dspchainsize-1] = (t_int)f;
if (ugen_loud)
post("add to chain: %lx",
pd_this->pd_dspchain[pd_this->pd_dspchainsize-1]);
va_start(ap, n);
for (i = 0; i < n; i++)
dsp_chain[dsp_chainsize + i] = va_arg(ap, t_int);
{
pd_this->pd_dspchain[pd_this->pd_dspchainsize + i] = va_arg(ap, t_int);
if (ugen_loud)
post("add to chain: %lx",
pd_this->pd_dspchain[pd_this->pd_dspchainsize + i]);
}
va_end(ap);
dsp_chain[newsize-1] = (t_int)dsp_done;
dsp_chainsize = newsize;
pd_this->pd_dspchain[newsize-1] = (t_int)dsp_done;
pd_this->pd_dspchainsize = newsize;
}
/* at Guenter's suggestion, here's a vectorized version */
void dsp_addv(t_perfroutine f, int n, t_int *vec)
{
int newsize = dsp_chainsize + n+1, i;
int newsize = pd_this->pd_dspchainsize + n+1, i;
dsp_chain = t_resizebytes(dsp_chain, dsp_chainsize * sizeof (t_int),
newsize * sizeof (t_int));
dsp_chain[dsp_chainsize-1] = (t_int)f;
pd_this->pd_dspchain = t_resizebytes(pd_this->pd_dspchain,
pd_this->pd_dspchainsize * sizeof (t_int), newsize * sizeof (t_int));
pd_this->pd_dspchain[pd_this->pd_dspchainsize-1] = (t_int)f;
for (i = 0; i < n; i++)
dsp_chain[dsp_chainsize + i] = vec[i];
dsp_chain[newsize-1] = (t_int)dsp_done;
dsp_chainsize = newsize;
pd_this->pd_dspchain[pd_this->pd_dspchainsize + i] = vec[i];
pd_this->pd_dspchain[newsize-1] = (t_int)dsp_done;
pd_this->pd_dspchainsize = newsize;
}
void dsp_tick(void)
{
if (dsp_chain)
if (pd_this->pd_dspchain)
{
t_int *ip;
for (ip = dsp_chain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
for (ip = pd_this->pd_dspchain; ip; ) ip = (*(t_perfroutine)(*ip))(ip);
dsp_phase++;
}
}
......@@ -356,17 +361,15 @@ int ilog2(int n)
static t_signal *signal_freelist[MAXLOGSIG+1];
/* list of reusable "borrowed" signals (which don't own sample buffers) */
static t_signal *signal_freeborrowed;
/* list of all signals allocated (not including "borrowed" ones) */
static t_signal *signal_usedlist;
/* call this when DSP is stopped to free all the signals */
void signal_cleanup(void)
{
t_signal *sig;
t_signal **svec, *sig, *sig2;
int i;
while (sig = signal_usedlist)
while ((sig = pd_this->pd_signals))
{
signal_usedlist = sig->s_nextused;
pd_this->pd_signals = sig->s_nextused;
if (!sig->s_isborrowed)
t_freebytes(sig->s_vec, sig->s_vecsize * sizeof (*sig->s_vec));
t_freebytes(sig, sizeof *sig);
......@@ -429,8 +432,9 @@ void signal_makereusable(t_signal *sig)
t_signal *signal_new(int n, t_float sr)
{
int logn, vecsize = 0;
int logn, n2, vecsize = 0;
t_signal *ret, **whichlist;
t_sample *fp;
logn = ilog2(n);
if (n)
{
......@@ -444,7 +448,7 @@ t_signal *signal_new(int n, t_float sr)
whichlist = &signal_freeborrowed;
/* first try to reclaim one from the free list */
if (ret = *whichlist)
if ((ret = *whichlist))
*whichlist = ret->s_nextfree;
else
{
......@@ -460,15 +464,15 @@ t_signal *signal_new(int n, t_float sr)
ret->s_vec = 0;
ret->s_isborrowed = 1;
}
ret->s_nextused = signal_usedlist;
signal_usedlist = ret;
ret->s_nextused = pd_this->pd_signals;
pd_this->pd_signals = ret;
}
ret->s_n = n;
ret->s_vecsize = vecsize;
ret->s_sr = sr;
ret->s_refcount = 0;
ret->s_borrowedfrom = 0;
if (ugen_loud) post("new %lx: %d", ret, ret->s_isborrowed);
if (ugen_loud) post("new %lx: %lx", ret, ret->s_vec);
return (ret);
}
......@@ -487,6 +491,7 @@ void signal_setborrowed(t_signal *sig, t_signal *sig2)
sig->s_vec = sig2->s_vec;
sig->s_n = sig2->s_n;
sig->s_vecsize = sig2->s_vecsize;
if (ugen_loud) post("set borrowed %lx: %lx", sig, sig->s_vec);
}
int signal_compatible(t_signal *s1, t_signal *s2)
......@@ -552,12 +557,22 @@ struct _dspcontext
static int ugen_sortno = 0;
static t_dspcontext *ugen_currentcontext;
/* get a new signal for the current context - used by clone~ object */
t_signal *signal_newfromcontext(int borrowed)
{
return (signal_new((borrowed? 0 : ugen_currentcontext->dc_calcsize),
ugen_currentcontext->dc_srate));
}
void ugen_stop(void)
{
if (dsp_chain)
t_signal *s;
int i;
if (pd_this->pd_dspchain)
{
freebytes(dsp_chain, dsp_chainsize * sizeof (t_int));
dsp_chain = 0;
freebytes(pd_this->pd_dspchain,
pd_this->pd_dspchainsize * sizeof (t_int));
pd_this->pd_dspchain = 0;
}
signal_cleanup();
......@@ -567,9 +582,9 @@ void ugen_start(void)
{
ugen_stop();
ugen_sortno++;
dsp_chain = (t_int *)getbytes(sizeof(*dsp_chain));
dsp_chain[0] = (t_int)dsp_done;
dsp_chainsize = 1;
pd_this->pd_dspchain = (t_int *)getbytes(sizeof(*pd_this->pd_dspchain));
pd_this->pd_dspchain[0] = (t_int)dsp_done;
pd_this->pd_dspchainsize = 1;
if (ugen_currentcontext) bug("ugen_start");
}
......@@ -578,12 +593,12 @@ int ugen_getsortno(void)
return (ugen_sortno);
}
#if 0
#if 1
void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv)
{
int i, count;
t_signal *sig;
for (count = 0, sig = signal_usedlist; sig;
for (count = 0, sig = pd_this->pd_signals; sig;
count++, sig = sig->s_nextused)
;
post("used signals %d", count);
......@@ -609,9 +624,15 @@ t_dspcontext *ugen_start_graph(int toplevel, t_signal **sp,
int ninlets, int noutlets)
{
t_dspcontext *dc = (t_dspcontext *)getbytes(sizeof(*dc));
int parent_vecsize, vecsize;
if (ugen_loud) post("ugen_start_graph...");
/* protect against invalid numsignals. This might happen if we have
an abstraction with inlet~/outlet~ opened as a toplevel patch */
if (toplevel)
ninlets = noutlets = 0;
dc->dc_ugenlist = 0;
dc->dc_toplevel = toplevel;
dc->dc_iosigs = sp;
......@@ -643,9 +664,6 @@ void ugen_add(t_dspcontext *dc, t_object *obj)
uout->o_connections = 0, uout->o_nconnect = 0;
}
extern t_class *text_class;
#include <stdio.h>
/* and then this to make all the connections. */
void ugen_connect(t_dspcontext *dc, t_object *x1, int outno, t_object *x2,
int inno)
......@@ -664,6 +682,10 @@ void ugen_connect(t_dspcontext *dc, t_object *x1, int outno, t_object *x2,
for (u2 = dc->dc_ugenlist; u2 && u2->u_obj != x2; u2 = u2->u_next);
if (!u1 || !u2 || siginno < 0)
{
if (!u1)
error("object with signal outlets but no DSP method?");
/* check if it's a "text" (i.e., object wasn't created) -
if so fail silently */
t_text *t2 = (t_text *)x2;
// The following only happens if the DAC is on while connecting
// objects. If this is not yet initialized object we don't
......@@ -705,6 +727,7 @@ static int ugen_index(t_dspcontext *dc, t_ugenbox *x)
if (u == x) return (ret);
return (-1);
}
extern t_class *clone_class;
/* put a ugenbox on the chain, recursively putting any others on that
this one might uncover. */
......@@ -712,7 +735,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
{
t_sigoutlet *uout;
t_siginlet *uin;
t_sigoutconnect *oc;
t_sigoutconnect *oc, *oc2;
t_class *class = pd_class(&u->u_obj->ob_pd);
int i, n;
/* suppress creating new signals for the outputs of signal
......@@ -721,13 +744,13 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
we delay new signal creation, which will be handled by calling
signal_setborrowed in the ugen_done_graph routine below. */
int nonewsigs = (class == canvas_class ||
(class == vinlet_class) && !(dc->dc_reblock));
((class == vinlet_class) && !(dc->dc_reblock)));
/* when we encounter a subcanvas or a signal outlet, suppress freeing
the input signals as they may be "borrowed" for the super or sub
patch; same exception as above, but also if we're "switched" we
have to do a copy rather than a borrow. */
int nofreesigs = (class == canvas_class ||
(class == voutlet_class) && !(dc->dc_reblock || dc->dc_switched));
int nofreesigs = (class == canvas_class || class == clone_class ||
((class == voutlet_class) && !(dc->dc_reblock || dc->dc_switched)));
t_signal **insig, **outsig, **sig, *s1, *s2, *s3;
t_ugenbox *u2;
......@@ -738,10 +761,10 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
if (!uin->i_nconnect)
{
t_float *scalar;
s3 = signal_new(dc->dc_vecsize, dc->dc_srate);
s3 = signal_new(dc->dc_calcsize, dc->dc_srate);
/* post("%s: unconnected signal inlet set to zero",
class_getname(u->u_obj->ob_pd)); */
if (scalar = obj_findsignalscalar(u->u_obj, i))
if ((scalar = obj_findsignalscalar(u->u_obj, i)))
dsp_add_scalarcopy(scalar, s3->s_vec, s3->s_n);
else
dsp_add_zero(s3->s_vec, s3->s_n);
......@@ -781,7 +804,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
signal_new(0, dc->dc_srate);
}
else
*sig = uout->o_signal = signal_new(dc->dc_vecsize, dc->dc_srate);
*sig = uout->o_signal = signal_new(dc->dc_calcsize, dc->dc_srate);
(*sig)->s_refcount = uout->o_nconnect;
}
/* now call the DSP scheduling routine for the ugen. This
......@@ -821,7 +844,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
u2 = oc->oc_who;
uin = &u2->u_in[oc->oc_inno];
/* if there's already someone here, sum the two */
if (s2 = uin->i_signal)
if ((s2 = uin->i_signal))
{
s1->s_refcount--;
s2->s_refcount--;
......@@ -865,7 +888,7 @@ static void ugen_doit(t_dspcontext *dc, t_ugenbox *u)
void ugen_done_graph(t_dspcontext *dc)
{
t_ugenbox *u;
t_ugenbox *u, *u2;
t_sigoutlet *uout;
t_siginlet *uin;
t_sigoutconnect *oc, *oc2;
......@@ -874,7 +897,7 @@ void ugen_done_graph(t_dspcontext *dc)
t_dspcontext *parent_context = dc->dc_parentcontext;
t_float parent_srate;
int parent_vecsize;
int period, frequency, vecsize, calcsize;
int period, frequency, phase, vecsize, calcsize;
t_float srate;
int chainblockbegin; /* DSP chain onset before block prolog code */
int chainblockend; /* and after block epilog code */
......@@ -941,6 +964,7 @@ void ugen_done_graph(t_dspcontext *dc)
(parent_vecsize * realoverlap * upsample);
frequency = (parent_vecsize * realoverlap * upsample)/
(vecsize * downsample);
phase = blk->x_phase;
srate = parent_srate * realoverlap * upsample / downsample;
if (period < 1) period = 1;
if (frequency < 1) frequency = 1;
......@@ -960,6 +984,7 @@ void ugen_done_graph(t_dspcontext *dc)
calcsize = (parent_context ? parent_context->dc_calcsize : vecsize);
downsample = upsample = 1;
period = frequency = 1;
phase = 0;
if (!parent_context) reblock = 1;
switched = 0;
}
......@@ -1007,7 +1032,7 @@ void ugen_done_graph(t_dspcontext *dc)
for (u = dc->dc_ugenlist; u; u = u->u_next)
{
t_pd *zz = &u->u_obj->ob_pd;
t_signal **outsigs = dc->dc_iosigs;
t_signal **insigs = dc->dc_iosigs, **outsigs = dc->dc_iosigs;
if (outsigs) outsigs += dc->dc_ninlets;
if (pd_class(zz) == vinlet_class)
......@@ -1019,12 +1044,12 @@ void ugen_done_graph(t_dspcontext *dc)
outsigs, vecsize, calcsize, dsp_phase, period, frequency,
downsample, upsample, reblock, switched);
}
chainblockbegin = dsp_chainsize;
chainblockbegin = pd_this->pd_dspchainsize;
if (blk && (reblock || switched)) /* add the block DSP prolog */
{
dsp_add(block_prolog, 1, blk);
blk->x_chainonset = dsp_chainsize - 1;
blk->x_chainonset = pd_this->pd_dspchainsize - 1;
}
/* Initialize for sorting */
for (u = dc->dc_ugenlist; u; u = u->u_next)
......@@ -1079,7 +1104,7 @@ void ugen_done_graph(t_dspcontext *dc)
if (blk && (reblock || switched)) /* add block DSP epilog */
dsp_add(block_epilog, 1, blk);
chainblockend = dsp_chainsize;
chainblockend = pd_this->pd_dspchainsize;
/* add epilogs for outlets. */
......@@ -1096,7 +1121,7 @@ void ugen_done_graph(t_dspcontext *dc)
}
}
chainafterall = dsp_chainsize;
chainafterall = pd_this->pd_dspchainsize;
if (blk)
{
blk->x_blocklength = chainblockend - chainblockbegin;
......@@ -1108,7 +1133,8 @@ void ugen_done_graph(t_dspcontext *dc)
{
t_int *ip;
if (!dc->dc_parentcontext)
for (i = dsp_chainsize, ip = dsp_chain; i--; ip++)
for (i = pd_this->pd_dspchainsize, ip = pd_this->pd_dspchain;
i--; ip++)
post("chain %lx", *ip);
post("... ugen_done_graph done.");
}
......
......@@ -22,7 +22,7 @@ two, but how? */
which can't send symbols starting with '$' (because the Pd message
interpreter would change them!) */
static t_symbol *sharptodollar(t_symbol *s)
t_symbol *sharptodollar(t_symbol *s)
{
if (*s->s_name == '#')
{
......@@ -85,7 +85,7 @@ void array_resize(t_array *x, int n)
x->a_valid = ++glist_valid;
}
static void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
{
//fprintf(stderr,"array_resize_and_redraw\n");
t_array *a2 = array;
......@@ -93,10 +93,10 @@ static void array_resize_and_redraw(t_array *array, t_glist *glist, int n)
while (a2->a_gp.gp_stub->gs_which == GP_ARRAY)
a2 = a2->a_gp.gp_stub->gs_un.gs_array;
if (vis)
gobj_vis(a2->a_gp.gp_un.gp_gobj, glist, 0);
gobj_vis(&a2->a_gp.gp_un.gp_gobj, glist, 0);
array_resize(array, n);
if (vis)
gobj_vis(a2->a_gp.gp_un.gp_gobj, glist, 1);
gobj_vis(&a2->a_gp.gp_un.gp_gobj, glist, 1);
}
void word_free(t_word *wp, t_template *template);
......@@ -264,6 +264,18 @@ int garray_joc(t_garray *x)
return (x->x_joc);
}
/* get a garray's containing glist */
t_glist *garray_getglist(t_garray *x)
{
return (x->x_glist);
}
/* get a garray's associated scalar */
t_scalar *garray_getscalar(t_garray *x)
{
return (x->x_scalar);
}
/* helper function for fittograph to see if the same GOP has multiple
arrays in which case take length of the largest one */
static int garray_get_largest_array(t_garray *x)
......@@ -1403,7 +1415,7 @@ static int garray_click(t_gobj *z, t_glist *glist,
#define ARRAYWRITECHUNKSIZE 1000
static void garray_save(t_gobj *z, t_binbuf *b)
void garray_save(t_gobj *z, t_binbuf *b)
{
int filestyle;
t_garray *x = (t_garray *)z;
......
......@@ -59,6 +59,7 @@ static void canvas_pop(t_canvas *x, t_floatarg fvis);
static int canvas_should_bind(t_canvas *x);
static void canvas_bind(t_canvas *x);
static void canvas_unbind(t_canvas *x);
void canvas_declare(t_canvas *x, t_symbol *s, int argc, t_atom *argv);
/* --------- functions to handle the canvas environment ----------- */
......@@ -94,19 +95,19 @@ void canvas_updatewindowlist( void)
/* add a glist the list of "root" canvases (toplevels without parents.) */
static void canvas_addtolist(t_canvas *x)
{
x->gl_next = canvas_list;
canvas_list = x;
x->gl_next = pd_this->pd_canvaslist;
pd_this->pd_canvaslist = x;
}
static void canvas_takeofflist(t_canvas *x)
{
/* take it off the window list */
if (x == canvas_list) canvas_list = x->gl_next;
if (x == pd_this->pd_canvaslist) pd_this->pd_canvaslist = x->gl_next;
else
{
t_canvas *z;
for (z = canvas_list; z->gl_next != x; z = z->gl_next)
;
for (z = pd_this->pd_canvaslist; z->gl_next != x; z = z->gl_next)
if (!z->gl_next) return;
z->gl_next = x->gl_next;
}
}
......@@ -424,6 +425,7 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
x->gl_y2 = 1;
canvas_setbounds(x, xloc, yloc, xloc + width, yloc + height);
x->gl_owner = owner;
x->gl_isclone = 0;
x->gl_name = (*s->s_name ? s :
(canvas_newfilename ? canvas_newfilename : gensym("Pd")));
canvas_bind(x);
......@@ -929,7 +931,7 @@ void canvas_free(t_canvas *x)
freebytes(x->gl_ylabel, x->gl_nylabels * sizeof(*(x->gl_ylabel)));
gstub_cutoff(x->gl_stub);
gfxstub_deleteforkey(x); /* probably unnecessary */
if (!x->gl_owner)
if (!x->gl_owner && !x->gl_isclone)
canvas_takeofflist(x);
if (x->gl_svg) /* for groups, free the data */
canvas_group_free(x->gl_svg);
......@@ -1117,7 +1119,7 @@ void canvas_loadbangsubpatches(t_canvas *x, t_symbol *s)
zgetfn(&y->g_pd, s))
{
//fprintf(stderr,"%lx s:obj_loadbang %s\n",x,s->s_name);
pd_vmess(&y->g_pd, s, "");
pd_vmess(&y->g_pd, s, "f", (t_floatarg)LB_LOAD);
}
}
......@@ -1167,18 +1169,20 @@ void canvas_initbang(t_canvas *x)
t_symbol *s = gensym("initbang");
/* run "initbang" for all subpatches, but NOT for the child abstractions */
for (y = x->gl_list; y; y = y->g_next)
{
if (pd_class(&y->g_pd) == canvas_class)
{
if (!canvas_isabstraction((t_canvas *)y))
canvas_initbang((t_canvas *)y);
}
}
/* call the initbang()-method for objects that have one */
for (y = x->gl_list; y; y = y->g_next)
{
if ((pd_class(&y->g_pd) != canvas_class) && zgetfn(&y->g_pd, s))
{
pd_vmess(&y->g_pd, s, "");
pd_vmess(&y->g_pd, s, "f", (t_floatarg)LB_INIT);
}
}
}
......@@ -1199,7 +1203,7 @@ void canvas_closebang(t_canvas *x)
{
if ((pd_class(&y->g_pd) != canvas_class) && zgetfn(&y->g_pd, s))
{
pd_vmess(&y->g_pd, s, "");
pd_vmess(&y->g_pd, s, "f", (t_floatarg)LB_CLOSE);
}
}
}
......@@ -1443,16 +1447,6 @@ static void canvas_unbind(t_canvas *x)
pd_unbind(&x->gl_pd, canvas_makebindsym(x->gl_name));
}
/* return true if the "canvas" object is a "table". */
int canvas_istable(t_canvas *x)
{
t_atom *argv = (x->gl_obj.te_binbuf? binbuf_getvec(x->gl_obj.te_binbuf):0);
int argc = (x->gl_obj.te_binbuf? binbuf_getnatom(x->gl_obj.te_binbuf) : 0);
int istable = (argc && argv[0].a_type == A_SYMBOL &&
argv[0].a_w.w_symbol == gensym("table"));
return (istable);
}
/* return true if the "canvas" object should be treated as a text
object. This is true for abstractions but also for "table"s... */
/* JMZ: add a flag to gop-abstractions to hide the title */
......@@ -1495,7 +1489,7 @@ void ugen_done_graph(t_dspcontext *dc);
canvases, but is also called from the "dsp" method for sub-
canvases, which are treated almost like any other tilde object. */
static void canvas_dodsp(t_canvas *x, int toplevel, t_signal **sp)
void canvas_dodsp(t_canvas *x, int toplevel, t_signal **sp)
{
t_linetraverser t;
t_outconnect *oc;
......@@ -1548,25 +1542,29 @@ static void canvas_dsp(t_canvas *x, t_signal **sp)
static void canvas_start_dsp(void)
{
t_canvas *x;
if (canvas_dspstate)
if (pd_this->pd_dspstate)
ugen_stop();
else
gui_vmess("gui_pd_dsp", "i", 1);
ugen_start();
for (x = canvas_list; x; x = x->gl_next)
for (x = pd_getcanvaslist(); x; x = x->gl_next)
canvas_dodsp(x, 1, 0);
canvas_dspstate = 1;
canvas_dspstate = pd_this->pd_dspstate = 1;
if (gensym("pd-dsp-started")->s_thing)
pd_bang(gensym("pd-dsp-started")->s_thing);
}
static void canvas_stop_dsp(void)
{
if (canvas_dspstate)
if (pd_this->pd_dspstate)
{
ugen_stop();
gui_vmess("gui_pd_dsp", "i", 0);
canvas_dspstate = 0;
canvas_dspstate = pd_this->pd_dspstate = 0;
if (gensym("pd-dsp-stopped")->s_thing)
pd_bang(gensym("pd-dsp-stopped")->s_thing);
}
}
......@@ -1577,8 +1575,8 @@ static void canvas_stop_dsp(void)
int canvas_suspend_dsp(void)
{
int rval = canvas_dspstate;
//fprintf(stderr,"canvas_suspend_dsp %d\n", rval);
int rval = pd_this->pd_dspstate;
if (rval) canvas_stop_dsp();
return (rval);
}
......@@ -1592,27 +1590,36 @@ void canvas_resume_dsp(int oldstate)
/* this is equivalent to suspending and resuming in one step. */
void canvas_update_dsp(void)
{
if (canvas_dspstate) canvas_start_dsp();
if (pd_this->pd_dspstate) canvas_start_dsp();
}
/* the "dsp" message to pd starts and stops DSP computation, and, if
appropriate, also opens and closes the audio device. On exclusive-access
APIs such as ALSA, MMIO, and ASIO (I think) it's appropriate to close the
audio devices when not using them; but jack behaves better if audio I/O