Skip to content

Commit

Permalink
preserve signal pointers
Browse files Browse the repository at this point in the history
closes #62
  • Loading branch information
ben-wes committed Oct 17, 2024
1 parent e3dff62 commit 73ac4e4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 32 deletions.
71 changes: 39 additions & 32 deletions pdlua.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,13 @@ static void pdlua_free( t_pdlua *o /**< The object to destruct. */)
lua_pop(__L(), 1); /* pop the global "pd" */
PDLUA_DEBUG("pdlua_free: end. stack top %d", lua_gettop(__L()));

// Free sig_info if it exists
// FIXME: necessary?
if (o->sig_info) {
freebytes(o->sig_info, (o->siginlets + o->sigoutlets) * sizeof(t_pdlua_siginfo));
o->sig_info = NULL;
}

// Collect garbage
// If we don't do this here, it could potentially leak if no other pdlua objects are used afterwards
lua_gc(__L(), LUA_GCCOLLECT);
Expand Down Expand Up @@ -1071,14 +1078,10 @@ static t_int *pdlua_perform(t_int *w){
for (int i = 0; i < o->siginlets; i++)
{
lua_newtable(__L());
t_signal *sig = (t_signal *)(w[2 + i]);
t_float *in = sig->s_vec;
#if PD_MULTICHANNEL
int nchans = sig->s_nchans ? sig->s_nchans : 1;
#else
int nchans = 1;
#endif
int s_n_allchans = nblock * nchans; // sum of all inlet samples
t_float *in = o->sig_info[i].vec;
int nchans = o->sig_info[i].nchans;
int s_n_allchans = nblock * nchans;

for (int j = 0; j < s_n_allchans; j++)
{
lua_pushinteger(__L(), j + 1);
Expand All @@ -1091,7 +1094,7 @@ static t_int *pdlua_perform(t_int *w){
{
mylua_error(__L(), o, "perform");
lua_pop(__L(), 1); /* pop the global pd */
return w + o->siginlets + o->sigoutlets + 2;
return w + 2;
}

if (!lua_istable(__L(), -1))
Expand All @@ -1109,21 +1112,16 @@ static t_int *pdlua_perform(t_int *w){
}
}
lua_pop(__L(), 1 + o->sigoutlets);
return w + o->siginlets + o->sigoutlets + 2;
return w + 2;
}

for (int i = o->sigoutlets - 1; i >= 0; i--)
{
t_signal *sig = (t_signal *)(w[2 + o->siginlets + i]);
t_float *out = sig->s_vec;
#if PD_MULTICHANNEL
int nchans = sig->s_nchans ? sig->s_nchans : 1;
#else
int nchans = 1;
#endif
int s_n_allchans = nblock * nchans; // sum of all outlet samples
for (int j = 0; j < s_n_allchans; j++)
{
t_float *out = o->sig_info[o->siginlets + i].vec;
int nchans = o->sig_info[o->siginlets + i].nchans;
int s_n_allchans = nblock * nchans;

for (int j = 0; j < s_n_allchans; j++) {
lua_pushinteger(__L(), (lua_Integer)(j + 1));
lua_gettable(__L(), -2);
if (lua_isnumber(__L(), -1))
Expand All @@ -1141,14 +1139,14 @@ static t_int *pdlua_perform(t_int *w){

PDLUA_DEBUG("pdlua_perform: end. stack top %d", lua_gettop(__L()));

return w + o->siginlets + o->sigoutlets + 2;
return w + 2;
}

static void pdlua_dsp(t_pdlua *x, t_signal **sp){
int sum = x->siginlets + x->sigoutlets;
if(sum == 0) return;
x->sig_warned = 0;
x->blocksize = (int)sp[0]->s_n; // local block size instead of sys_getblksize();
x->blocksize = (int)sp[0]->s_n;
x->sp = sp; // prepare for Lua signal_setmultiout

PDLUA_DEBUG("pdlua_dsp: stack top %d", lua_gettop(__L()));
Expand Down Expand Up @@ -1182,25 +1180,33 @@ static void pdlua_dsp(t_pdlua *x, t_signal **sp){
}

if (lua_pcall(__L(), 4, 0, 0))
{
mylua_error(__L(), x, "dsp");
}

lua_pop(__L(), 1); /* pop the global "pd" */

PDLUA_DEBUG("pdlua_dsp: end. stack top %d", lua_gettop(__L()));

int sigvecsize = sum + 1;
t_int* sigvec = getbytes(sigvecsize * sizeof(t_int));
// Free existing sig_info if it exists
if (x->sig_info) {
freebytes(x->sig_info, sum * sizeof(t_pdlua_siginfo));
x->sig_info = NULL;
}

sigvec[0] = (t_int)x;

for (int i = 0; i < sum; i++)
sigvec[i + 1] = (t_int)sp[i];
x->sig_info = (t_pdlua_siginfo *)getbytes(sum * sizeof(t_pdlua_siginfo));

dsp_addv(pdlua_perform, sigvecsize, sigvec);
freebytes(sigvec, sigvecsize * sizeof(t_int));
for (int i = 0; i < sum; i++) {
x->sig_info[i].vec = sp[i]->s_vec;
#if PD_MULTICHANNEL
x->sig_info[i].nchans = sp[i]->s_nchans ? sp[i]->s_nchans : 1;
#else
x->sig_info[i].nchans = 1;
#endif
}

dsp_add(pdlua_perform, 1, x);
}


static int pdlua_get_arguments(lua_State *L)
{
// Check if the first argument is a valid user data pointer
Expand Down Expand Up @@ -1444,6 +1450,7 @@ static int pdlua_object_new(lua_State *L)
o->pdlua_class = c;
o->pdlua_class_gfx = c_gfx;
o->sp = NULL;
o->sig_info = NULL;

o->gfx.width = 80;
o->gfx.height = 80;
Expand Down
9 changes: 9 additions & 0 deletions pdlua.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ typedef struct _pdlua_gfx
#endif
} t_pdlua_gfx;

/** Structure to hold signal information. */
typedef struct pdlua_siginfo
{
t_float *vec; // Signal vector
int nchans; // Number of channels
} t_pdlua_siginfo;


/** Pd object data. */
typedef struct pdlua
{
Expand All @@ -70,6 +78,7 @@ typedef struct pdlua
t_pdlua_gfx gfx; // Holds state for graphics.
t_class *pdlua_class; // Holds our class pointer.
t_class *pdlua_class_gfx; // Holds our gfx class pointer.
t_pdlua_siginfo *sig_info; // Array of signal info structures
t_signal **sp; // Array of signal pointers for multichannel audio.
} t_pdlua;

Expand Down

0 comments on commit 73ac4e4

Please sign in to comment.