Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preserve signal pointers #63

Merged
merged 3 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 40 additions & 32 deletions pdlua.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,14 +1071,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 +1087,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 +1105,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 +1132,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 +1173,34 @@ 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));

sigvec[0] = (t_int)x;
// Free existing sig_info if it exists, using the old sig_count
if (x->sig_info) {
freebytes(x->sig_info, x->sig_count * sizeof(t_pdlua_siginfo));
x->sig_info = NULL;
}

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));
x->sig_count = sum;

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_addv(pdlua_perform, sigvecsize, sigvec);
freebytes(sigvec, sigvecsize * sizeof(t_int));
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 +1444,8 @@ 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->sig_count = 0;

o->gfx.width = 80;
o->gfx.height = 80;
Expand Down Expand Up @@ -1929,6 +1931,12 @@ static int pdlua_object_free(lua_State *L)
free(o->out);
o->out = NULL;
}

if (o->sig_info)
{
freebytes(o->sig_info, o->sig_count * sizeof(t_pdlua_siginfo));
o->sig_info = NULL;
}
}
}
PDLUA_DEBUG("pdlua_object_free: end. stack top is %d", lua_gettop(L));
Expand Down
10 changes: 10 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
{
t_float *vec; // Signal vector
int nchans; // Number of channels
} t_pdlua_siginfo;

/** Pd object data. */
typedef struct pdlua
{
Expand All @@ -61,6 +69,8 @@ typedef struct pdlua
t_inlet **in;
int outlets; // Number of outlets.
t_outlet **out; // The outlets themselves.
t_pdlua_siginfo *sig_info; // Array of signal info structures for perform function.
int sig_count; // Total number of signal iolets for sig_info memory management.
int siginlets; // Number of signal inlets.
int sigoutlets; // Number of signal outlets.
int sig_warned; // Flag for perform signal errors.
Expand Down