From 39ccb5b6170dc997873460e64f7a2ac933233fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Wed, 12 Jan 2011 18:14:18 +0000 Subject: simplistic external for reading audio/midi settings svn path=/trunk/externals/iem/mediasettings/; revision=14718 --- Makefile | 13 +-- audiosettings.c | 247 +++++++++++++++++++++++++++++++++++++---- midisettings.c | 338 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 568 insertions(+), 30 deletions(-) create mode 100644 midisettings.c diff --git a/Makefile b/Makefile index f7f2ca1..24a1fae 100644 --- a/Makefile +++ b/Makefile @@ -5,16 +5,7 @@ LIBRARY_NAME = audiosettings # add your .c source files to the SOURCES variable, help files will be # included automatically -SOURCES = audiosettings.c - -# For objects that only build on certain platforms, add those to the SOURCES -# line for the right platforms. -SOURCES_android = -SOURCES_cygwin = -SOURCES_macosx = -SOURCES_iphoneos = -SOURCES_linux = -SOURCES_windows = +SOURCES = audiosettings.c midisettings.c # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will # be included automatically @@ -56,7 +47,7 @@ INSTALL = install INSTALL_FILE = $(INSTALL) -p -m 644 INSTALL_DIR = $(INSTALL) -p -m 755 -d -CFLAGS = -DPD -I$(PD_PATH)/src -Wall -W -g +CFLAGS = -DPD -I$(PD_PATH)/src -I$(prefix)/include/pd -Wall -W -g LDFLAGS = LIBS = ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ diff --git a/audiosettings.c b/audiosettings.c index e5eb2c6..7232eec 100644 --- a/audiosettings.c +++ b/audiosettings.c @@ -15,19 +15,16 @@ * ******************************************************/ #include "m_pd.h" +#include "s_stuff.h" #include - -void sys_get_audio_apis(char*buf); - -#ifdef _WIN32 -/* we have to implement the not exported functions for w32... */ -#endif - +#define MAXNDEV 20 +#define DEVDESCSIZE 80 +#define MAXAUDIOINDEV 4 +#define MAXAUDIOOUTDEV 4 static t_class *audiosettings_class; - typedef struct _as_apis { t_symbol*name; int id; @@ -44,6 +41,14 @@ t_as_apis*as_findapi(t_as_apis*apis, const t_symbol*name) { 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; + } + 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); @@ -63,9 +68,7 @@ t_as_apis*as_addapi(t_as_apis*apis, t_symbol*name, int id, int overwrite) { return api; } - - -t_as_apis*as_apiparse_42(t_as_apis*apis, const char*buf) { +t_as_apis*as_apiparse(t_as_apis*apis, const char*buf) { t_as_apis*api=apis; int start=-1; @@ -106,12 +109,24 @@ t_as_apis*as_apiparse_42(t_as_apis*apis, const char*buf) { return apis; } +static t_as_apis*APIS=NULL; -t_as_apis*as_apiparse(t_as_apis*apis, const char*buf) { - return as_apiparse_42(apis, buf); +static t_symbol*as_getapiname(const int id) { + t_as_apis*api=as_findapiid(APIS, id); + if(api) { + return api->name; + } else { + return gensym(""); + } } -static t_as_apis*APIS=NULL; +static int as_getapiid(const t_symbol*id) { + t_as_apis*api=as_findapi(APIS, id); + if(api) { + return api->id; + } + return -1; /* unknown */ +} typedef struct _audiosettings { @@ -120,14 +135,185 @@ typedef struct _audiosettings } t_audiosettings; -static void audiosettings_listdevices(t_audiosettings *x, t_symbol *s) +static void audiosettings_listparams(t_audiosettings *x); +static void audiosettings_listdevices(t_audiosettings *x) { + int i; + + char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE]; + int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0; + + t_atom atoms[3]; + + sys_get_audio_devs((char*)indevlist, &indevs, + (char*)outdevlist, &outdevs, + &canmulti, &cancallback, + MAXNDEV, DEVDESCSIZE); + + SETSYMBOL (atoms+0, gensym("api")); + SETSYMBOL (atoms+1, as_getapiname(sys_audioapi)); + outlet_anything(x->x_info, gensym("device"), 2, atoms); + + SETSYMBOL (atoms+0, gensym("multi")); + SETFLOAT (atoms+1, (t_float)canmulti); + outlet_anything(x->x_info, gensym("device"), 2, atoms); + + SETSYMBOL (atoms+0, gensym("callback")); + SETFLOAT (atoms+1, (t_float)cancallback); + outlet_anything(x->x_info, gensym("device"), 2, atoms); + + SETSYMBOL(atoms+0, gensym("in")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)indevs); + outlet_anything(x->x_info, gensym("device"), 3, atoms); + + for(i=0; ix_info, gensym("device"), 3, atoms); + } + + SETSYMBOL(atoms+0, gensym("out")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)outdevs); + outlet_anything(x->x_info, gensym("device"), 2, atoms); + for(i=0; ix_info, gensym("device"), 3, atoms); + } +} +static void audiosettings_listparams(t_audiosettings *x) { + int i; + t_atom atoms[4]; + + int naudioindev=1, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; + int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; + int rate, advance, callback; + sys_get_audio_params(&naudioindev, audioindev, chindev, + &naudiooutdev, audiooutdev, choutdev, + &rate, &advance, &callback); + + + SETSYMBOL (atoms+0, gensym("rate")); + SETFLOAT (atoms+1, (t_float)rate); + outlet_anything(x->x_info, gensym("params"), 2, atoms); + + SETSYMBOL (atoms+0, gensym("advance")); + SETFLOAT (atoms+1, (t_float)advance); + outlet_anything(x->x_info, gensym("params"), 2, atoms); + + SETSYMBOL (atoms+0, gensym("callback")); + SETFLOAT (atoms+1, (t_float)callback); + outlet_anything(x->x_info, gensym("params"), 2, atoms); + + SETSYMBOL(atoms+0, gensym("in")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)naudioindev); + outlet_anything(x->x_info, gensym("params"), 3, atoms); + + for(i=0; ix_info, gensym("params"), 3, atoms); + } + + SETSYMBOL(atoms+0, gensym("out")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)naudiooutdev); + outlet_anything(x->x_info, gensym("params"), 3, atoms); + + for(i=0; ix_info, gensym("params"), 3, atoms); + } } /* + * TODO: provide a nicer interface than the "pd audio-dialog" */ -static void audiosettings_bang(t_audiosettings *x) +static void audiosettings_set(t_audiosettings *x, t_symbol*s, int argc, t_atom*argv) { +/* + "pd audio-dialog ..." + #00: indev[0] + #01: indev[1] + #02: indev[2] + #03: indev[3] + #04: inchan[0] + #05: inchan[1] + #06: inchan[2] + #07: inchan[3] + #08: outdev[0] + #09: outdev[1] + #10: outdev[2] + #11: outdev[3] + #12: outchan[0] + #13: outchan[1] + #14: outchan[2] + #15: outchan[3] + #16: rate + #17: advance + #18: callback +*/ +/* + PLAN: + several messages that accumulate to a certain settings, and then "apply" them +*/ + + +} + + + +static void audiosettings_testdevices(t_audiosettings *x) +{ + int i; + + char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE]; + int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0; + + sys_get_audio_devs((char*)indevlist, &indevs, (char*)outdevlist, &outdevs, &canmulti, + &cancallback, MAXNDEV, DEVDESCSIZE); + + post("%d indevs", indevs); + for(i=0; iname); outlet_anything(x->x_info, gensym("driver"), 1, ap); } +} + +static void audiosettings_setapi(t_audiosettings *x, t_symbol*s) { + int id=as_getapiid(s); + if(id<0) { + pd_error(x, "invalid API: '%s'", s->s_name); + } + verbose(1, "setting API: %d", id); + sys_set_audio_api(id); + sys_reopen_audio(); +} +static void audiosettings_bang(t_audiosettings *x) { + audiosettings_listapis(x); + audiosettings_listdevices(x); + audiosettings_listparams(x); } + static void audiosettings_free(t_audiosettings *x){ } @@ -155,8 +357,6 @@ static void *audiosettings_new(void) APIS=as_apiparse(APIS, buf); - - return (x); } @@ -177,6 +377,15 @@ void audiosettings_setup(void) sizeof(t_audiosettings), 0, 0); class_addbang(audiosettings_class, (t_method)audiosettings_bang); - class_addmethod(audiosettings_class, (t_method)audiosettings_listdevices, gensym("listdevices"), A_GIMME); + class_addmethod(audiosettings_class, (t_method)audiosettings_listapis, gensym("listapis"), A_NULL); + class_addmethod(audiosettings_class, (t_method)audiosettings_listdevices, gensym("listdevices"), A_NULL); + class_addmethod(audiosettings_class, (t_method)audiosettings_listparams, gensym("listparams"), A_NULL); + + + class_addmethod(audiosettings_class, (t_method)audiosettings_setapi, gensym("setapi"), A_SYMBOL); + + + class_addmethod(audiosettings_class, (t_method)audiosettings_testdevices, gensym("testdevices"), A_NULL); + } diff --git a/midisettings.c b/midisettings.c new file mode 100644 index 0000000..b6bf728 --- /dev/null +++ b/midisettings.c @@ -0,0 +1,338 @@ +/****************************************************** + * + * midisettings - get/set midi preferences from within Pd-patches + * Copyright (C) 2010 IOhannes m zmölnig + * + * forum::für::umläute + * + * institute of electronic music and acoustics (iem) + * university of music and dramatic arts, graz (kug) + * + * + ****************************************************** + * + * license: GNU General Public License v.3 or later + * + ******************************************************/ +#include "m_pd.h" +#include "s_stuff.h" +#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 { + t_symbol*name; + int id; + + struct _as_apis *next; +} t_as_apis; + + +t_as_apis*as_findapi(t_as_apis*apis, const t_symbol*name) { + while(apis) { + if(name==apis->name)return apis; + apis=apis->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; + } + 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); + + if(api) { + if(overwrite) { + api->name=name; + api->id =id; + } + return apis; + } + + api=(t_as_apis*)getbytes(sizeof(t_as_apis)); + api->name=name; + api->id=id; + api->next=apis; + + return api; +} + +t_as_apis*as_apiparse(t_as_apis*apis, const char*buf) { + t_as_apis*api=apis; + + int start=-1; + int stop =-1; + + unsigned int index=0; + int depth=0; + const char*s; + char substring[MAXPDSTRING]; + + for(index=0, s=buf; 0!=*s; s++, index++) { + if('{'==*s) { + start=index; + depth++; + } + if('}'==*s) { + depth--; + 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); + } else { + post("unparseable: '%s'", substring); + } + } + start=-1; + stop=-1; + } + } + + return apis; +} + +static t_as_apis*APIS=NULL; + +static t_symbol*as_getapiname(const int id) { + t_as_apis*api=as_findapiid(APIS, id); + if(api) { + return api->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; + } + return -1; /* unknown */ +} + +typedef struct _midisettings +{ + t_object x_obj; + t_outlet*x_info; +} t_midisettings; + + +static void midisettings_listdevices(t_midisettings *x) +{ + int i; + + char indevlist[MAXNDEV][DEVDESCSIZE], outdevlist[MAXNDEV][DEVDESCSIZE]; + int indevs = 0, outdevs = 0; + + t_atom atoms[3]; + + sys_get_midi_devs((char*)indevlist, &indevs, + (char*)outdevlist, &outdevs, + MAXNDEV, DEVDESCSIZE); + + SETSYMBOL (atoms+0, gensym("api")); + SETSYMBOL (atoms+1, as_getapiname(sys_midiapi)); + outlet_anything(x->x_info, gensym("device"), 2, atoms); + + SETSYMBOL(atoms+0, gensym("in")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)indevs); + outlet_anything(x->x_info, gensym("device"), 3, atoms); + + for(i=0; ix_info, gensym("device"), 3, atoms); + } + + SETSYMBOL(atoms+0, gensym("out")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)outdevs); + outlet_anything(x->x_info, gensym("device"), 2, atoms); + + for(i=0; ix_info, gensym("device"), 3, atoms); + } +} + +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); + + SETSYMBOL(atoms+0, gensym("in")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)nmidiindev); + outlet_anything(x->x_info, gensym("params"), 3, atoms); + + for(i=0; ix_info, gensym("params"), 2, atoms); + } + + SETSYMBOL(atoms+0, gensym("out")); + + SETSYMBOL(atoms+1, gensym("devices")); + SETFLOAT (atoms+2, (t_float)nmidioutdev); + outlet_anything(x->x_info, gensym("params"), 3, atoms); + + for(i=0; ix_info, gensym("params"), 2, atoms); + } +} + +/* + * TODO: provide a nicer interface than the "pd audio-dialog" + */ +static void midisettings_set(t_midisettings *x, + t_symbol*s, + int argc, t_atom*argv) { +/* + "pd audio-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 +*/ +/* + PLAN: + several messages that accumulate to a certain settings, and then "apply" them +*/ + + +} + + + +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; inext) { + t_atom ap[1]; + SETSYMBOL(ap, api->name); + outlet_anything(x->x_info, gensym("driver"), 1, ap); + } +} + +static void midisettings_free(t_midisettings *x){ + +} + + +static void *midisettings_new(void) +{ + t_midisettings *x = (t_midisettings *)pd_new(midisettings_class); + x->x_info=outlet_new(&x->x_obj, 0); + + char buf[MAXPDSTRING]; + sys_get_midi_apis(buf); + + APIS=as_apiparse(APIS, buf); + + // sys_get_midi_apis(buf); + // APIS=as_apiparse(APIS, buf); + + + return (x); +} + + +void midisettings_setup(void) +{ + post("midisettings: midi settings manager"); + post(" Copyright (C) 2010 IOhannes m zmoelnig"); + post(" for the IntegraLive project"); + post(" institute of electronic music and acoustics (iem)"); + post(" published under the GNU General Public License version 3 or later"); +#ifdef MIDISETTINGS_VERSION + startpost(" version:"MIDISETTINGS_VERSION); +#endif + post("\tcompiled: "__DATE__""); + + 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_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_testdevices, gensym("testdevices"), A_NULL); + +} + -- cgit v1.2.1