Commit 9fc5a523 authored by Miller Puckette's avatar Miller Puckette
Browse files

updates to pd~

parent 5e3a3a8f
#N canvas 193 43 967 599 10;
#N canvas 304 143 967 599 10;
#X obj 370 524 spigot;
#X msg 442 397 bang;
#X obj 429 488 bonk~;
......@@ -131,6 +131,8 @@ set" in memory.;
the high one and then fall to the low one to make an attack. The unit
is the sum of the proportional growth in the 11 filter bands. Proportional
growth is essentially the logarithmic time derivative.;
#X text 238 27 (NOTE: this documentation does not yet describe new
features for Pd 0.42).;
#X connect 0 0 40 0;
#X connect 1 0 2 0;
#X connect 2 0 8 0;
......
This diff is collapsed.
pd -schedlib `pwd`/pdsched
problems:
confusion about file extent (l_ia64 / pd_linux)
Pd dies silently if scheduler doesn't load
dolist:
pd~ to delay starting subproc until asked
figure out about setting nchannels from command line
maximum nchannels in and out
fix maximum nchannels in and out
......@@ -33,6 +33,7 @@ int pd_extern_sched(char *flags)
fprintf(stderr, "Pd plug-in scheduler called, chans %d %d, sr %d\n",
chin, chout, (int)rate);
sys_setchsr(chin, chout, rate);
sys_audioapi = API_NONE;
while ((c = getchar()) != EOF)
{
if (c == ';')
......@@ -63,6 +64,7 @@ int pd_extern_sched(char *flags)
*fp = 0;
}
printf(";\n");
fflush(stdout);
}
else if (n > 1 && ap[0].a_type == A_SYMBOL)
{
......
......@@ -18,7 +18,7 @@
#ifdef NT
#pragma warning (disable: 4305 4244)
#endif
#ifdef MSP
#include "ext.h"
#include "z_dsp.h"
......@@ -28,10 +28,12 @@
#include "ext_obex.h"
typedef double t_floatarg;
void *pd_tilde_class;
#define getbytes t_getbytes
#define freebytes t_freebytes
#define ERROR error(
void *pd_tilde_class;
#define MAXPDSTRING 4096
#define DEFDACBLKSIZE 64
#endif /* MSP */
#ifdef PD
......@@ -39,6 +41,8 @@ void *pd_tilde_class;
#include "s_stuff.h"
static t_class *pd_tilde_class;
char *class_gethelpdir(t_class *c);
#define ERROR pd_error(x,
#endif
#ifdef __linux__
......@@ -93,8 +97,7 @@ static void pd_tilde_dsp(t_pd_tilde *x, t_signal **sp);
void pd_tilde_assist(t_pd_tilde *x, void *b, long m, long a, char *s);
static void pd_tilde_free(t_pd_tilde *x);
void pd_tilde_setup(void);
void main();
static void pd_tilde_thresh(t_pd_tilde *x, t_floatarg f1, t_floatarg f2);
int main();
void pd_tilde_minvel_set(t_pd_tilde *x, void *attr, long ac, t_atom *av);
char *strcpy(char *s1, const char *s2);
#endif
......@@ -125,7 +128,7 @@ static void pd_tilde_readmessages(t_pd_tilde *x)
int c = getc(infd);
if (c == EOF)
{
pd_error(x, "pd~: %s", strerror(errno));
ERROR "pd~: %s", strerror(errno));
pd_tilde_close(x);
break;
}
......@@ -134,7 +137,7 @@ static void pd_tilde_readmessages(t_pd_tilde *x)
char *z = realloc(x->x_msgbuf, x->x_msgbufsize+MSGBUFSIZE);
if (!z)
{
pd_error(x, "pd~: failed to grow input buffer");
ERROR "pd~: failed to grow input buffer");
pd_tilde_close(x);
break;
}
......@@ -162,15 +165,13 @@ static void pd_tilde_donew(t_pd_tilde *x, char *pddir, char *schedlibdir,
{
int i, pid, pipe1[2], pipe2[2];
char cmdbuf[MAXPDSTRING], pdexecbuf[MAXPDSTRING], schedbuf[MAXPDSTRING];
float *fp;
t_sample **g;
struct stat statbuf;
x->x_infd = x->x_outfd = 0;
x->x_childpid = -1;
snprintf(pdexecbuf, MAXPDSTRING, "%s/bin/pd", pddir);
if (stat(pdexecbuf, &statbuf) < 0)
{
pd_error(x, "pd~: can't stat %s", pdexecbuf);
ERROR "pd~: can't stat %s", pdexecbuf);
goto fail1;
}
snprintf(schedbuf, MAXPDSTRING, "%s/pdsched%s", schedlibdir,
......@@ -181,26 +182,30 @@ static void pd_tilde_donew(t_pd_tilde *x, char *pddir, char *schedlibdir,
pd_tilde_dllextent2);
if (stat(schedbuf, &statbuf) < 0)
{
pd_error(x, "pd~: can't stat %s", schedbuf);
ERROR "pd~: can't stat %s", schedbuf);
goto fail1;
}
}
}
snprintf(cmdbuf, MAXPDSTRING, "%s -schedlib %s/pdsched %s\n",
pdexecbuf, schedlibdir, pdargs);
#ifdef PD
fprintf(stderr, "%s", cmdbuf);
#else
post("cmd: %s", cmdbuf);
#endif
if (pipe(pipe1) < 0)
{
pd_error(x, "pd~: can't create pipe");
ERROR "pd~: can't create pipe");
goto fail1;
}
if (pipe(pipe2) < 0)
{
pd_error(x, "pd~: can't create pipe");
ERROR "pd~: can't create pipe");
goto fail2;
}
if ((pid = fork()) < 0)
{
pd_error(x, "pd~: can't fork");
ERROR "pd~: can't fork");
goto fail3;
}
else if (pid == 0)
......@@ -236,14 +241,14 @@ static void pd_tilde_donew(t_pd_tilde *x, char *pddir, char *schedlibdir,
fflush(x->x_outfd);
if (!(x->x_msgbuf = calloc(MSGBUFSIZE, 1)))
{
pd_error(x, "pd~: can't allocate message buffer");
ERROR "pd~: can't allocate message buffer");
goto fail3;
}
x->x_msgbufsize = MSGBUFSIZE;
x->x_infill = 0;
fprintf(stderr, "read...\n");
/* fprintf(stderr, "read...\n"); */
pd_tilde_readmessages(x);
fprintf(stderr, "... done.\n");
/* fprintf(stderr, "... done.\n"); */
return;
fail3:
close(pipe2[0]);
......@@ -262,8 +267,7 @@ fail1:
static t_int *pd_tilde_perform(t_int *w)
{
t_pd_tilde *x = (t_pd_tilde *)(w[1]);
int n = (int)(w[2]), i, j, gotsomething = 0, setclock = 0,
numbuffill = 0, c;
int n = (int)(w[2]), i, j, numbuffill = 0, c;
char numbuf[80];
FILE *infd = x->x_infd;
if (!infd)
......@@ -288,8 +292,8 @@ static t_int *pd_tilde_perform(t_int *w)
if (c == EOF)
{
if (errno)
pd_error(x, "pd~: %s", strerror(errno));
else pd_error(x, "pd~: subprocess exited");
ERROR "pd~: %s", strerror(errno));
else ERROR "pd~: subprocess exited");
pd_tilde_close(x);
goto zeroit;
}
......@@ -379,7 +383,7 @@ static void pd_tilde_tick(t_pd_tilde *x)
if (vec[messstart].a_type != A_SYMBOL)
bug("pd_tilde_tick");
else if (!(whom = vec[messstart].a_w.w_symbol->s_thing))
pd_error(x, "%s: no such object",
ERROR "%s: no such object",
vec[messstart].a_w.w_symbol->s_name);
else if (vec[messstart+1].a_type == A_SYMBOL)
typedmess(whom, vec[messstart+1].a_w.w_symbol,
......@@ -416,7 +420,7 @@ static void pd_tilde_anything(t_pd_tilde *x, t_symbol *s,
static void *pd_tilde_new(t_symbol *s, int argc, t_atom *argv)
{
t_pd_tilde *x = (t_pd_tilde *)pd_new(pd_tilde_class);
int ninsig = 2, noutsig = 2, j, arglength, fifo = 5;
int ninsig = 2, noutsig = 2, j, fifo = 5;
float sr = sys_getsr();
t_sample **g;
t_symbol *pddir = gensym("."),
......@@ -484,7 +488,7 @@ static void *pd_tilde_new(t_symbol *s, int argc, t_atom *argv)
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
for (j = 0, g = x->x_outsig; j < noutsig; j++, g++)
outlet_new(&x->x_obj, &s_signal);
signal(SIGPIPE, SIG_IGN);
pd_tilde_donew(x, pddir->s_name, scheddir->s_name, pdargstring,
ninsig, noutsig, fifo, sr);
......@@ -506,92 +510,172 @@ void pd_tilde_setup(void)
/* -------------------------- MSP glue ------------------------- */
#ifdef MSP
void main()
#define LOTS 10000
static void pd_tilde_tick(t_pd_tilde *x)
{
int messstart = 0, i, n = 0;
t_atom vec[LOTS];
void *b = binbuf_new();
long z1 = 0, z2 = 0;
binbuf_text(b, &x->x_msgbuf, x->x_infill);
/* binbuf_print(b); */
while (!binbuf_getatom(b, &z1, &z2, vec+n))
if (++n >= LOTS)
break;
for (i = 0; i < n; i++)
{
if (vec[i].a_type == A_SEMI)
{
if (i > messstart + 1)
{
void *whom;
if (vec[messstart].a_type != A_SYM)
ERROR "pd_tilde_tick got non-symbol?");
else if (!(whom = vec[messstart].a_w.w_sym->s_thing))
ERROR "%s: no such object",
vec[messstart].a_w.w_sym->s_name);
else if (vec[messstart+1].a_type == A_SYM)
typedmess(whom, vec[messstart+1].a_w.w_sym,
i-messstart-2, vec+(messstart+2));
else if (vec[messstart+1].a_type == A_FLOAT && i == messstart+2)
typedmess(whom, gensym("float"), 1, vec+(messstart+1));
else if (vec[messstart+1].a_type == A_LONG && i == messstart+2)
typedmess(whom, gensym("int"), 1, vec+(messstart+1));
else typedmess(whom, gensym("list"),
i-messstart-1, vec+(messstart+1));
}
messstart = i+1;
}
}
binbuf_free(b);
x->x_infill = 0;
}
static void pd_tilde_anything(t_pd_tilde *x, t_symbol *s,
long ac, t_atom *av)
{
char msgbuf[MAXPDSTRING], *sp, *ep = msgbuf+MAXPDSTRING;
if (!x->x_outfd)
return;
msgbuf[0] = 0;
strncpy(msgbuf, s->s_name, MAXPDSTRING);
msgbuf[MAXPDSTRING-1] = 0;
sp = msgbuf + strlen(msgbuf);
while (ac--)
{
if (sp < ep-1)
sp[0] = ' ', sp[1] = 0, sp++;
if (sp < ep - 80)
{
if (av->a_type == A_SYM && strlen(av->a_w.w_sym->s_name) < ep - sp-20)
strcpy(sp, av->a_w.w_sym->s_name);
else if (av->a_type == A_LONG)
sprintf(sp, "%ld" ,av->a_w.w_long);
else if (av->a_type == A_FLOAT)
sprintf(sp, "%g" ,av->a_w.w_float);
}
sp += strlen(sp);
av++;
}
fprintf(x->x_outfd, "%s;\n", msgbuf);
}
int main()
{
t_class *c;
t_object *attr;
long attrflags = 0;
t_symbol *sym_long = gensym("long"), *sym_float32 = gensym("float32");
c = class_new("pd_tilde~", (method)pd_tilde_new, (method)pd_tilde_free, sizeof(t_pd_tilde), (method)0L, A_GIMME, 0);
class_obexoffset_set(c, calcoffset(t_pd_tilde, obex));
attr = attr_offset_new("npoints", sym_long, attrflags, (method)0L, (method)0L, calcoffset(t_pd_tilde, x_npoints));
class_addattr(c, attr);
class_addmethod(c, (method)pd_tilde_dsp, "dsp", A_CANT, 0);
class_addmethod(c, (method)pd_tilde_bang, "bang", A_CANT, 0);
class_addmethod(c, (method)pd_tilde_forget, "forget", 0);
class_addmethod(c, (method)pd_tilde_thresh, "thresh", A_FLOAT, A_FLOAT, 0);
class_addmethod(c, (method)pd_tilde_print, "print", A_DEFFLOAT, 0);
class_addmethod(c, (method)pd_tilde_read, "read", A_DEFSYM, 0);
class_addmethod(c, (method)pd_tilde_write, "write", A_DEFSYM, 0);
class_addmethod(c, (method)pd_tilde_assist, "assist", A_CANT, 0);
class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
class_addmethod(c, (method)pd_tilde_anything, "anything", A_GIMME, 0);
class_dspinit(c);
class_register(CLASS_BOX, c);
pd_tilde_class = c;
return (0);
}
static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av)
{
short j;
int ninsig = 2, noutsig = 2, fifo = 5, j;
float sr = sys_getsr();
t_symbol *pddir = gensym("."), *scheddir = gensym(".");
char pdargstring[MAXPDSTRING];
t_pd_tilde *x;
if (x = (t_pd_tilde *)object_alloc(pd_tilde_class)) {
t_insig *g;
if (ac) {
switch (av[0].a_type) {
case A_LONG:
x->x_nsig = av[0].a_w.w_long;
break;
}
}
attr_args_process(x, ac, av);
x->x_insig = (t_insig *)getbytes(x->x_nsig * sizeof(*x->x_insig));
x->x_ninsig = x->x_nsig;
dsp_setup((t_pxobject *)x, x->x_nsig);
object_obex_store(x, gensym("dumpout"), outlet_new(x, NULL));
x->x_cookedout = listout((t_object *)x);
for (j = 0, g = x->x_insig + x->x_nsig-1; j < x->x_nsig; j++, g--)
{
g->g_outlet = listout((t_object *)x);
}
if (x = (t_pd_tilde *)object_alloc(pd_tilde_class))
{
while (ac > 0 && av[0].a_type == A_SYM)
{
char *flag = av[0].a_w.w_sym->s_name;
if (!strcmp(flag, "-sr") && ac > 1)
{
sr = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float :
(av[1].a_type == A_LONG ? av[1].a_w.w_long : 0));
ac -= 2; av += 2;
}
else if (!strcmp(flag, "-ninsig") && ac > 1)
{
ninsig = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float :
(av[1].a_type == A_LONG ? av[1].a_w.w_long : 0));
ac -= 2; av += 2;
}
else if (!strcmp(flag, "-noutsig") && ac > 1)
{
noutsig = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float :
(av[1].a_type == A_LONG ? av[1].a_w.w_long : 0));
ac -= 2; av += 2;
}
else if (!strcmp(flag, "-fifo") && ac > 1)
{
fifo = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float :
(av[1].a_type == A_LONG ? av[1].a_w.w_long : 0));
ac -= 2; av += 2;
}
else if (!strcmp(flag, "-pddir") && ac > 1)
{
pddir = (av[1].a_type == A_SYM ? av[1].a_w.w_sym : gensym("."));
ac -= 2; av += 2;
}
else if (!strcmp(flag, "-scheddir") && ac > 1)
{
scheddir = (av[1].a_type == A_SYM ? av[1].a_w.w_sym : gensym("."));
ac -= 2; av += 2;
}
else break;
}
pdargstring[0] = 0;
while (ac--)
{
char buf[80];
if (av->a_type == A_SYM)
strcat(pdargstring, av->a_w.w_sym->s_name);
else if (av->a_type == A_LONG)
sprintf(buf+strlen(buf), "%ld", av->a_w.w_long);
else if (av->a_type == A_FLOAT)
sprintf(buf+strlen(buf), "%f", av->a_w.w_float);
strcat(buf, " ");
av++;
}
post("pd~: pddir %s scheddir %s args %s",
pddir->s_name, scheddir->s_name, pdargstring);
dsp_setup((t_pxobject *)x, ninsig);
for (j = 0; j < noutsig; j++)
outlet_new((t_pxobject *)x, "signal");
x->x_clock = clock_new(x, (method)pd_tilde_tick);
x->x_insig = (t_sample **)getbytes(ninsig * sizeof(*x->x_insig));
x->x_outsig = (t_sample **)getbytes(noutsig * sizeof(*x->x_outsig));
x->x_ninsig = ninsig;
x->x_noutsig = noutsig;
pd_tilde_donew(x, x->x_npoints, x->x_period, x->x_nsig, x->x_nfilters,
x->x_halftones, x->x_overlap, x->x_firstbin, sys_getsr());
pd_tilde_donew(x, pddir->s_name, scheddir->s_name, pdargstring,
ninsig, noutsig, fifo, sr);
}
return (x);
}
/* Attribute setters. */
void pd_tilde_minvel_set(t_pd_tilde *x, void *attr, long ac, t_atom *av)
{
if (ac && av) {
float f = atom_getfloat(av);
if (f < 0) f = 0;
x->x_minvel = f;
}
}
/* end attr setters */
void pd_tilde_assist(t_pd_tilde *x, void *b, long m, long a, char *s)
{
}
......
......@@ -11,7 +11,7 @@ extern "C" {
#define PD_MAJOR_VERSION 0
#define PD_MINOR_VERSION 42
#define PD_BUGFIX_VERSION 0
#define PD_TEST_VERSION "test1"
#define PD_TEST_VERSION "test2"
/* old name for "MSW" flag -- we have to take it for the sake of many old
"nmakefiles" for externs, which will define NT and not MSW */
......
......@@ -426,7 +426,9 @@ void sys_reopen_audio( void)
chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate);
else
#endif
post("unknown audio API specified");
if (sys_audioapi == API_NONE)
;
else post("unknown audio API specified");
if (outcome) /* failed */
{
audio_state = 0;
......
......@@ -8,6 +8,8 @@
#ifdef UNISTD
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif
#ifdef MSW
#include <io.h>
......@@ -256,18 +258,28 @@ int sys_run_scheduler(const char *externalschedlibname,
if (!ntdll)
{
post("%s: couldn't load external scheduler lib ", filename);
return (0);
return (1);
}
externalmainfunc =
(t_externalschedlibmain)GetProcAddress(ntdll, "main");
}
#else
{
void *dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
void *dlobj;
struct stat statbuf;
/* if first-choice file extent can't 'stat', go for second */
if (stat(filename, &statbuf) < 0)
{
snprintf(filename, sizeof(filename), "%s%s", externalschedlibname,
sys_dllextent2);
sys_bashfilename(filename, filename);
}
dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
if (!dlobj)
{
post("%s: %s", filename, dlerror());
return (0);
fprintf(stderr, "dlopen failed for %s: %s\n", filename, dlerror());
return (1);
}
externalmainfunc = (t_externalschedlibmain)dlsym(dlobj,
"pd_extern_sched");
......
......@@ -172,6 +172,7 @@ void sys_setalarm(int microsec);
void sys_setvirtualalarm( void);
#endif
#define API_NONE 0
#define API_ALSA 1
#define API_OSS 2
#define API_MMIO 3
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment