From 2e92db24585041a49a66517e231b4ac850654d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Wed, 12 Jan 2011 18:14:56 +0000 Subject: working on th midi-part svn path=/trunk/externals/iem/mediasettings/; revision=14722 --- midisettings.c | 424 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 336 insertions(+), 88 deletions(-) diff --git a/midisettings.c b/midisettings.c index b6bf728..bc3c0a5 100644 --- a/midisettings.c +++ b/midisettings.c @@ -17,64 +17,67 @@ #include "m_pd.h" #include "s_stuff.h" #include +#include #define MAXNDEV 20 #define DEVDESCSIZE 80 + #ifndef MAXMIDIINDEV # define MAXMIDIINDEV 4 #endif #ifndef MAXMIDIOUTDEV # define MAXMIDIOUTDEV 4 #endif + extern int sys_midiapi; static t_class *midisettings_class; -typedef struct _as_apis { +static t_symbol*s_pdsym=NULL; + +typedef struct _as_drivers { t_symbol*name; int id; - struct _as_apis *next; -} t_as_apis; + struct _as_drivers *next; +} t_as_drivers; -t_as_apis*as_findapi(t_as_apis*apis, const t_symbol*name) { - while(apis) { - if(name==apis->name)return apis; - apis=apis->next; +t_as_drivers*as_finddriver(t_as_drivers*drivers, const t_symbol*name) { + while(drivers) { + if(name==drivers->name)return drivers; + drivers=drivers->next; } return NULL; } -t_as_apis*as_findapiid(t_as_apis*apis, const int id) { - while(apis) { - if(id==apis->id)return apis; - apis=apis->next; +t_as_drivers*as_finddriverid(t_as_drivers*drivers, const int id) { + while(drivers) { + if(id==drivers->id)return drivers; + drivers=drivers->next; } return NULL; } -t_as_apis*as_addapi(t_as_apis*apis, t_symbol*name, int id, int overwrite) { - t_as_apis*api=as_findapi(apis, name); +t_as_drivers*as_adddriver(t_as_drivers*drivers, t_symbol*name, int id, int overwrite) { + t_as_drivers*driver=as_finddriver(drivers, name); - if(api) { + if(driver) { if(overwrite) { - api->name=name; - api->id =id; + driver->name=name; + driver->id =id; } - return apis; + return drivers; } - api=(t_as_apis*)getbytes(sizeof(t_as_apis)); - api->name=name; - api->id=id; - api->next=apis; + driver=(t_as_drivers*)getbytes(sizeof(t_as_drivers)); + driver->name=name; + driver->id=id; + driver->next=drivers; - return api; + return driver; } -t_as_apis*as_apiparse(t_as_apis*apis, const char*buf) { - t_as_apis*api=apis; - +t_as_drivers*as_driverparse(t_as_drivers*drivers, const char*buf) { int start=-1; int stop =-1; @@ -93,14 +96,14 @@ t_as_apis*as_apiparse(t_as_apis*apis, const char*buf) { stop=index; if(start>=0 && start=MAXPDSTRING)length=MAXPDSTRING-1; snprintf(substring, length, "%s", buf+start+1); - if(2==sscanf(substring, "%s %d", apiname, &apiid)) { - apis=as_addapi(apis, gensym(apiname), apiid, 0); + if(2==sscanf(substring, "%s %d", drivername, &driverid)) { + drivers=as_adddriver(drivers, gensym(drivername), driverid, 0); } else { post("unparseable: '%s'", substring); } @@ -110,34 +113,86 @@ t_as_apis*as_apiparse(t_as_apis*apis, const char*buf) { } } - return apis; + return drivers; } -static t_as_apis*APIS=NULL; +static t_as_drivers*DRIVERS=NULL; -static t_symbol*as_getapiname(const int id) { - t_as_apis*api=as_findapiid(APIS, id); - if(api) { - return api->name; +static t_symbol*as_getdrivername(const int id) { + t_as_drivers*driver=as_finddriverid(DRIVERS, id); + if(driver) { + return driver->name; } else { return gensym(""); } } -static int as_getapiid(const t_symbol*id) { - t_as_apis*api=as_findapi(APIS, id); - if(api) { - return api->id; +static int as_getdriverid(const t_symbol*id) { + t_as_drivers*driver=as_finddriver(DRIVERS, id); + if(driver) { + return driver->id; } return -1; /* unknown */ } + + +typedef struct _as_params { + int indev[MAXMIDIINDEV], outdev[MAXMIDIOUTDEV]; + int inchannels, outchannels; +} t_as_params; +static void as_params_print(t_as_params*parms) { + int i=0; + post("\n=================================<"); + + for(i=0; iindev[i]); + } + for(i=0; ioutdev[i]); + } + + post("alsamidi: %d %d", parms->inchannels, parms->outchannels); + + post(">=================================\n"); + +} +static void as_params_get(t_as_params*parms) { + int i=0; + memset(parms, 0, sizeof(t_as_params)); + + sys_get_midi_params(&parms->inchannels, parms->indev, + &parms->outchannels, parms->outdev); +#if 0 + for(i=parms->naudioindev; iaudioindev[i]=0; + parms->chindev[i]=0; + } + for(i=parms->naudiooutdev; iaudiooutdev[i]=0; + parms->choutdev[i]=0; + } +#endif + + as_params_print(parms); +} + + + + + typedef struct _midisettings { t_object x_obj; t_outlet*x_info; + + t_as_params x_params; } t_midisettings; +static void midisettings_params_init(t_midisettings*x) { + as_params_get(&x->x_params); +} + static void midisettings_listdevices(t_midisettings *x) { @@ -152,8 +207,8 @@ static void midisettings_listdevices(t_midisettings *x) (char*)outdevlist, &outdevs, MAXNDEV, DEVDESCSIZE); - SETSYMBOL (atoms+0, gensym("api")); - SETSYMBOL (atoms+1, as_getapiname(sys_midiapi)); + SETSYMBOL (atoms+0, gensym("driver")); + SETSYMBOL (atoms+1, as_getdrivername(sys_midiapi)); outlet_anything(x->x_info, gensym("device"), 2, atoms); SETSYMBOL(atoms+0, gensym("in")); @@ -185,30 +240,27 @@ static void midisettings_listparams(t_midisettings *x) { int i; t_atom atoms[4]; - int nmidiindev=1, midiindev[MAXMIDIINDEV]; - int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; - sys_get_midi_params(&nmidiindev, midiindev, - &nmidioutdev, midioutdev); - + midisettings_params_init(x); + SETSYMBOL(atoms+0, gensym("in")); SETSYMBOL(atoms+1, gensym("devices")); - SETFLOAT (atoms+2, (t_float)nmidiindev); + SETFLOAT (atoms+2, (t_float)x->x_params.inchannels); outlet_anything(x->x_info, gensym("params"), 3, atoms); - for(i=0; ix_params.inchannels; i++) { + SETFLOAT (atoms+1, (t_float)x->x_params.indev[i]); outlet_anything(x->x_info, gensym("params"), 2, atoms); } SETSYMBOL(atoms+0, gensym("out")); SETSYMBOL(atoms+1, gensym("devices")); - SETFLOAT (atoms+2, (t_float)nmidioutdev); + SETFLOAT (atoms+2, (t_float)x->x_params.outchannels); outlet_anything(x->x_info, gensym("params"), 3, atoms); - for(i=0; ix_params.outchannels; i++) { + SETFLOAT (atoms+1, (t_float)x->x_params.outdev[i]); outlet_anything(x->x_info, gensym("params"), 2, atoms); } } @@ -220,7 +272,7 @@ static void midisettings_set(t_midisettings *x, t_symbol*s, int argc, t_atom*argv) { /* - "pd audio-dialog ..." + "pd midi-dialog ..." #00: indev[0] #01: indev[1] #02: indev[2] @@ -242,52 +294,207 @@ static void midisettings_set(t_midisettings *x, -static void midisettings_testdevices(t_midisettings *x) -{ - int i; - char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE]; - int indevs = 0, outdevs = 0; - - sys_get_midi_devs((char*)indevlist, &indevs, (char*)outdevlist, &outdevs, MAXNDEV, DEVDESCSIZE); +static void midisettings_params_apply(t_midisettings*x) { +/* + "pd midi-dialog ..." + #00: indev[0] + #01: indev[1] + #02: indev[2] + #03: indev[3] + #04: outdev[0] + #05: outdev[1] + #06: outdev[2] + #07: outdev[3] + #08: alsadevin + #09: alsadevout +*/ - post("%d midi indevs", indevs); - for(i=0; ix_params); + + + for(i=0; ix_params.indev[i])); + } + for(i=0; ix_params.outdev[i])); + } - endpost(); - int nmidiindev, midiindev[MAXMIDIINDEV]; - int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; - sys_get_midi_params(&nmidiindev, midiindev, - &nmidioutdev, midioutdev); - post("%d midiindev (parms)", nmidiindev); - for(i=0; ix_params.inchannels:0)); + SETFLOAT(argv+2*MAXMIDIINDEV+2*MAXMIDIOUTDEV+1,(t_float)(alsamidi?x->x_params.outchannels:0)); + + if (s_pdsym->s_thing) typedmess(s_pdsym->s_thing, + gensym("midi-dialog"), + argc, + argv); +} + + +/* find the beginning of the next parameter in the list */ +typedef enum { + PARAM_INPUT, + PARAM_OUTPUT, + PARAM_INVALID +} t_paramtype; +static t_paramtype midisettings_setparams_id(t_symbol*s) { + if(gensym("@input")==s) { + return PARAM_INPUT; + } else if(gensym("@output")==s) { + return PARAM_OUTPUT; } - post("%d midioutdev (parms)", nmidioutdev); - for(i=0; is_name[0]) + return i; + } + } + return i; +} + +/* [ ]* ... */ +static int midisettings_setparams_input(t_midisettings*x, int argc, t_atom*argv) { + int length=midisettings_setparams_next(argc, argv); + int i; + int numpairs=length/2; + + if(length%2)return length; + + if(numpairs>MAXMIDIINDEV) + numpairs=MAXMIDIINDEV; + + for(i=0; ix_params.indev[i]=dev; } + + return length; } + +static int midisettings_setparams_output(t_midisettings*x, int argc, t_atom*argv) { + int length=midisettings_setparams_next(argc, argv); + int i; + int numpairs=length/2; + + if(length%2)return length; + + if(numpairs>MAXMIDIOUTDEV) + numpairs=MAXMIDIOUTDEV; + + for(i=0; ix_params.outdev[i]=dev; + } + + return length; +} + +static void midisettings_setparams(t_midisettings *x, t_symbol*s, int argc, t_atom*argv) { +/* + * PLAN: + * several messages that accumulate to a certain settings, and then "apply" them + * + * normal midi: list up to four devices (each direction) + * alsa midi: choose number of ports (each direction) + +*/ + int apply=1; + int advance=0; + t_paramtype param=PARAM_INVALID; + + advance=midisettings_setparams_next(argc, argv); + while((argc-=advance)>0) { + argv+=advance; + s=atom_getsymbol(argv); + param=midisettings_setparams_id(s); + + argv++; + argc--; + + switch(param) { + case PARAM_INPUT: + advance=midisettings_setparams_input(x, argc, argv); + break; + case PARAM_OUTPUT: + advance=midisettings_setparams_output(x, argc, argv); + break; + default: + pd_error(x, "unknown parameter"); postatom(1, argv);endpost(); + break; + } + + argc-=advance; + argv+=advance; + advance=midisettings_setparams_next(argc, argv); + } + if(apply) { + // midisettings_params_apply(x); + midisettings_params_init (x); /* re-initialize to what we got */ + } +} + + + + /* */ -static void midisettings_listapis(t_midisettings *x) +static void midisettings_listdrivers(t_midisettings *x) { - t_as_apis*api=NULL; + t_as_drivers*driver=NULL; - for(api=APIS; api; api=api->next) { + for(driver=DRIVERS; driver; driver=driver->next) { t_atom ap[1]; - SETSYMBOL(ap, api->name); + SETSYMBOL(ap, driver->name); outlet_anything(x->x_info, gensym("driver"), 1, ap); } } +static void midisettings_bang(t_midisettings *x) { + midisettings_listdrivers(x); + midisettings_listdevices(x); + midisettings_listparams(x); +} + + static void midisettings_free(t_midisettings *x){ } @@ -301,18 +508,23 @@ static void *midisettings_new(void) char buf[MAXPDSTRING]; sys_get_midi_apis(buf); - APIS=as_apiparse(APIS, buf); + midisettings_params_init (x); /* re-initialize to what we got */ - // sys_get_midi_apis(buf); - // APIS=as_apiparse(APIS, buf); + DRIVERS=as_driverparse(DRIVERS, buf); + + // sys_get_midi_drivers(buf); + // DRIVERS=as_driverparse(DRIVERS, buf); return (x); } +static void midisettings_testdevices(t_midisettings *x); void midisettings_setup(void) { + s_pdsym=gensym("pd"); + post("midisettings: midi settings manager"); post(" Copyright (C) 2010 IOhannes m zmoelnig"); post(" for the IntegraLive project"); @@ -326,13 +538,49 @@ void midisettings_setup(void) midisettings_class = class_new(gensym("midisettings"), (t_newmethod)midisettings_new, (t_method)midisettings_free, sizeof(t_midisettings), 0, 0); - class_addbang(midisettings_class, (t_method)midisettings_listapis); - class_addmethod(midisettings_class, (t_method)midisettings_listapis, gensym("listapis"), A_NULL); + class_addbang(midisettings_class, (t_method)midisettings_bang); + class_addmethod(midisettings_class, (t_method)midisettings_listdrivers, gensym("listdrivers"), A_NULL); class_addmethod(midisettings_class, (t_method)midisettings_listdevices, gensym("listdevices"), A_NULL); - class_addmethod(midisettings_class, (t_method)midisettings_listparams, gensym("listparams"), A_NULL); + class_addmethod(midisettings_class, (t_method)midisettings_listparams, gensym("listparams"), A_NULL); - class_addmethod(midisettings_class, (t_method)midisettings_testdevices, gensym("testdevices"), A_NULL); + class_addmethod(midisettings_class, (t_method)midisettings_setparams, gensym("params"), A_GIMME); + + class_addmethod(midisettings_class, (t_method)midisettings_testdevices, gensym("testdevices"), A_NULL); } + + +static void midisettings_testdevices(t_midisettings *x) +{ + int i; + + char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE]; + int indevs = 0, outdevs = 0; + + sys_get_midi_devs((char*)indevlist, &indevs, (char*)outdevlist, &outdevs, MAXNDEV, DEVDESCSIZE); + + post("%d midi indevs", indevs); + for(i=0; i