From 184923d73fa67e4cfdd95caec49ed7cc7f73e8dd Mon Sep 17 00:00:00 2001 From: Sojourner Truth <jon.w.wilkes@gmail.com> Date: Fri, 29 Jul 2016 23:24:02 -0400 Subject: [PATCH] very rough fix to #92: Midi settings not accepted fixed up dialog, backported some code from Pd-Vanilla 0.46 --- pd/nw/dialog_prefs.html | 38 ++++++++-- pd/src/s_midi.c | 164 +++++++++++++++++++++++++++++++++------- pd/src/s_midi_alsa.c | 6 ++ pd/src/s_stuff.h | 3 + 4 files changed, 175 insertions(+), 36 deletions(-) diff --git a/pd/nw/dialog_prefs.html b/pd/nw/dialog_prefs.html index e73d01e8b..90362742c 100644 --- a/pd/nw/dialog_prefs.html +++ b/pd/nw/dialog_prefs.html @@ -221,14 +221,14 @@ <input type="text" id="alsa_in_ports" name="alsa_in_ports" - onchange="attr_change(this);"> + onchange="alsa_in_ports_change(this);"> </label> <label data-i18n="[title]prefs.midi.alsa_out_ports_tt"> <span data-i18n="prefs.midi.alsa_out_ports"></span> <input type="text" id="alsa_out_ports" name="alsa_out_ports" - onchange="attr_change(this);"> + onchange="alsa_out_ports_change(this);"> </label> </div> @@ -356,6 +356,28 @@ function attr_change(elem) { pdgui.post("value is " + elem.value); } +function alsa_ports_change(elem, type) { + var attr, dummy, i, len; + attr = pd_midi_attrs; + dummy = []; + len = Number(elem.value); + if (len.isNan) { + len = 0; + } + for (i = 0; i < len; i++) { + dummy.push("dummy"); + } + attr[attr.indexOf("midi-" + type + "dev-names") + 1] = dummy; +} + +function alsa_in_ports_change(elem) { + alsa_ports_change(elem, "in"); +} + +function alsa_out_ports_change(elem) { + alsa_ports_change(elem, "out"); +} + function get_input(name) { var val = document.getElementsByName(name)[0].value; return val === 0 ? "0" : val; @@ -386,7 +408,8 @@ function kludge_chans(type, attrs, index) { } function apply() { - var attrs = pd_audio_attrs; + var attrs = pd_audio_attrs, + midi_use_alsa; pdgui.post("applying preferences"); // Audio dialog @@ -415,6 +438,7 @@ function apply() { ); attrs = pd_midi_attrs; + midi_use_alsa = !!get_attr("use_alsa", attrs); // Midi dialog pdgui.pdsend( "pd midi-dialog", @@ -426,8 +450,8 @@ function apply() { get_attr("pd-outdevs", attrs)[1], get_attr("pd-outdevs", attrs)[2], get_attr("pd-outdevs", attrs)[3], - 0, // midi_alsain - 0 // midi_alsaout + midi_use_alsa ? get_attr("midi-indev-names", attrs).length : 0, + midi_use_alsa ? get_attr("midi-outdev-names", attrs).length : 0 ); } @@ -654,9 +678,9 @@ function midi_prefs_callback(attrs) { // the first of the "indevs" for this value, so (for now) // we repeat that mistake here... document.getElementById("alsa_in_ports").value = - +get_attr("pd-indevs", attrs)[0]; + get_attr("midi-indev-names", attrs).length; document.getElementById("alsa_out_ports").value = - +get_attr("pd-outdevs", attrs)[0]; + get_attr("midi-outdev-names", attrs).length; } else { document.getElementsByClassName("midi_devices")[0] .style.setProperty("display", "inherit"); diff --git a/pd/src/s_midi.c b/pd/src/s_midi.c index 35af15a45..3b719dc08 100644 --- a/pd/src/s_midi.c +++ b/pd/src/s_midi.c @@ -489,6 +489,12 @@ void sys_pollmidiqueue( void) /******************** dialog window and device listing ********************/ +#define MAXNDEV 20 +#define DEVDESCSIZE 80 + +#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */ + + #ifdef USEAPI_ALSA void midi_alsa_init( void); #endif @@ -499,9 +505,10 @@ void midi_oss_init( void); /* last requested parameters */ static int midi_nmidiindev; static int midi_midiindev[MAXMIDIINDEV]; +static char midi_indevnames[MAXMIDIINDEV * DEVDESCSIZE]; static int midi_nmidioutdev; static int midi_midioutdev[MAXMIDIOUTDEV]; - +static char midi_outdevnames[MAXMIDIINDEV * DEVDESCSIZE]; void sys_get_midi_apis(char *buf) { @@ -522,6 +529,8 @@ void sys_get_midi_apis(char *buf) } +/* replacement for sys_get_midi_apis, which uses annoying tcl list brackets. + Once it's stable we can switch to it and erase the old one. */ void sys_get_midi_apis2(t_binbuf *buf) { int n = 0; @@ -541,13 +550,23 @@ void sys_get_midi_apis2(t_binbuf *buf) void sys_get_midi_params(int *pnmidiindev, int *pmidiindev, int *pnmidioutdev, int *pmidioutdev) { - int i; + int i, devn; *pnmidiindev = midi_nmidiindev; - for (i = 0; i < MAXMIDIINDEV; i++) - pmidiindev[i] = midi_midiindev[i]; + for (i = 0; i < midi_nmidiindev; i++) + { + if ((devn = sys_mididevnametonumber(0, + &midi_indevnames[i * DEVDESCSIZE])) >= 0) + pmidiindev[i] = devn; + else pmidiindev[i] = midi_midiindev[i]; + } *pnmidioutdev = midi_nmidioutdev; - for (i = 0; i < MAXMIDIOUTDEV; i++) - pmidioutdev[i] = midi_midioutdev[i]; + for (i = 0; i < midi_nmidioutdev; i++) + { + if ((devn = sys_mididevnametonumber(1, + &midi_outdevnames[i * DEVDESCSIZE])) >= 0) + pmidioutdev[i] = devn; + else pmidioutdev[i] = midi_midioutdev[i]; + } } static void sys_save_midi_params( @@ -556,11 +575,19 @@ static void sys_save_midi_params( { int i; midi_nmidiindev = nmidiindev; - for (i = 0; i < MAXMIDIINDEV; i++) - midi_midiindev[i] = midiindev[i]; + for (i = 0; i < nmidiindev; i++) + { + midi_midiindev[i] = midiindev[i]; + sys_mididevnumbertoname(0, midiindev[i], + &midi_indevnames[i * DEVDESCSIZE], DEVDESCSIZE); + } midi_nmidioutdev = nmidioutdev; - for (i = 0; i < MAXMIDIOUTDEV; i++) - midi_midioutdev[i] = midioutdev[i]; + for (i = 0; i < nmidioutdev; i++) + { + midi_midioutdev[i] = midioutdev[i]; + sys_mididevnumbertoname(1, midioutdev[i], + &midi_outdevnames[i * DEVDESCSIZE], DEVDESCSIZE); + } } void sys_open_midi(int nmidiindev, int *midiindev, @@ -595,11 +622,6 @@ void sys_reopen_midi( void) sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 1); } -#define MAXNDEV 20 -#define DEVDESCSIZE 80 - -#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */ - void sys_listmididevs(void ) { char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; @@ -640,6 +662,7 @@ void sys_set_midi_api(int which) } void glob_midi_properties(t_pd *dummy, t_floatarg flongform); +void midi_alsa_setndevs(int in, int out); void glob_midi_setapi(void *dummy, t_floatarg f) { @@ -654,19 +677,21 @@ void glob_midi_setapi(void *dummy, t_floatarg f) else { #ifdef USEAPI_ALSA - if (sys_midiapi == API_ALSA) - sys_alsa_close_midi(); - else + if (sys_midiapi == API_ALSA) + sys_alsa_close_midi(); + else #endif - sys_close_midi(); - sys_midiapi = newapi; - /* bash device params back to default */ - midi_nmidiindev = midi_nmidioutdev = 1; - //midi_midiindev[0] = midi_midioutdev[0] = DEFAULTMIDIDEV; - //midi_midichindev[0] = midi_midichoutdev[0] = SYS_DEFAULTCH; - sys_reopen_midi(); + sys_close_midi(); + sys_midiapi = newapi; + /* bash device params back to default */ +// midi_nmidiindev = midi_nmidioutdev = 1; + //midi_midiindev[0] = midi_midioutdev[0] = DEFAULTMIDIDEV; + //midi_midichindev[0] = midi_midichoutdev[0] = SYS_DEFAULTCH; + sys_reopen_midi(); } - +#ifdef USEAPI_ALSA + midi_alsa_setndevs(midi_nmidiindev, midi_nmidioutdev); +#endif glob_midi_properties(0, 0); } else //if (midi_isopen()) @@ -692,17 +717,18 @@ void glob_midi_properties(t_pd *dummy, t_floatarg flongform) char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; int nindevs = 0, noutdevs = 0, i; - midi_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, + sys_get_midi_devs(indevlist, &nindevs, outdevlist, &noutdevs, MAXNDEV, DEVDESCSIZE); gui_start_vmess("gui_midi_properties", "s", gfxstub_new2(&glob_pdobject, (void *)glob_midi_properties)); //sys_gui("global midi_indevlist; set midi_indevlist {none}\n"); - +fprintf(stderr, "ndevs is %d", nindevs); gui_start_array(); for (i = 0; i < nindevs; i++) { +fprintf(stderr, "dev is %s", indevlist + i * DEVDESCSIZE); //sys_vgui("lappend midi_indevlist {%s}\n", // indevlist + i * DEVDESCSIZE); gui_s(indevlist + i * DEVDESCSIZE); @@ -817,6 +843,25 @@ void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) alsadevin = atom_getintarg(8, argc, argv); alsadevout = atom_getintarg(9, argc, argv); +fprintf(stderr, "devin is %d", alsadevin); +fprintf(stderr, "devout is %d", alsadevout); +#ifdef USEAPI_ALSA + /* invent a story so that saving/recalling "settings" will + be able to restore the number of devices. ALSA MIDI handling + uses its own set of variables. LATER figure out how to get + this to work coherently */ + if (sys_midiapi == API_ALSA) + { + nindev = alsadevin; + noutdev = alsadevout; + for (i = 0; i < nindev; i++) + newmidiindev[i] = i; + for (i = 0; i < noutdev; i++) + newmidioutdev[i] = i; + } +#endif + sys_save_midi_params(nindev, newmidiindev, + noutdev, newmidioutdev); #ifdef USEAPI_ALSA if (sys_midiapi == API_ALSA) { @@ -829,7 +874,6 @@ void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) sys_close_midi(); sys_open_midi(nindev, newmidiindev, noutdev, newmidioutdev, 1); } - } void sys_get_midi_devs(char *indevlist, int *nindevs, @@ -839,9 +883,71 @@ void sys_get_midi_devs(char *indevlist, int *nindevs, #ifdef USEAPI_ALSA if (sys_midiapi == API_ALSA) + { midi_alsa_getdevs(indevlist, nindevs, outdevlist, noutdevs, maxndevs, devdescsize); + fprintf(stderr, "nindevs areererer %d", *nindevs); + } else #endif /* ALSA */ midi_getdevs(indevlist, nindevs, outdevlist, noutdevs, maxndevs, devdescsize); } + +/* convert a device name to a (1-based) device number. (Output device if +'output' parameter is true, otherwise input device). Negative on failure. */ + +int sys_mididevnametonumber(int output, const char *name) +{ + char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; + int nindevs = 0, noutdevs = 0, i; + + sys_get_midi_devs(indevlist, &nindevs, outdevlist, &noutdevs, + MAXNDEV, DEVDESCSIZE); + + if (output) + { + for (i = 0; i < noutdevs; i++) + { + unsigned int comp = strlen(name); + if (comp > strlen(outdevlist + i * DEVDESCSIZE)) + comp = strlen(outdevlist + i * DEVDESCSIZE); + if (!strncmp(name, outdevlist + i * DEVDESCSIZE, comp)) + return (i); + } + } + else + { + for (i = 0; i < nindevs; i++) + { + unsigned int comp = strlen(name); + if (comp > strlen(indevlist + i * DEVDESCSIZE)) + comp = strlen(indevlist + i * DEVDESCSIZE); + if (!strncmp(name, indevlist + i * DEVDESCSIZE, comp)) + return (i); + } + } + return (-1); +} + +/* convert a (1-based) device number to a device name. (Output device if +'output' parameter is true, otherwise input device). Empty string on failure. +*/ + +void sys_mididevnumbertoname(int output, int devno, char *name, int namesize) +{ + char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; + int nindevs = 0, noutdevs = 0, i; + if (devno < 0) + { + *name = 0; + return; + } + sys_get_midi_devs(indevlist, &nindevs, outdevlist, &noutdevs, + MAXNDEV, DEVDESCSIZE); + if (output && (devno < noutdevs)) + strncpy(name, outdevlist + devno * DEVDESCSIZE, namesize); + else if (!output && (devno < nindevs)) + strncpy(name, indevlist + devno * DEVDESCSIZE, namesize); + else *name = 0; + name[namesize-1] = 0; +} diff --git a/pd/src/s_midi_alsa.c b/pd/src/s_midi_alsa.c index b25759985..b2905d49f 100644 --- a/pd/src/s_midi_alsa.c +++ b/pd/src/s_midi_alsa.c @@ -239,6 +239,12 @@ void midi_alsa_init(void) alsa_initted = 1; } +void midi_alsa_setndevs(int in, int out) +{ + alsa_nmidiindevs = in; + alsa_nmidioutdevs = out; +} + void midi_alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int maxndev, int devdescsize) { diff --git a/pd/src/s_stuff.h b/pd/src/s_stuff.h index 5575819b2..b271001c2 100644 --- a/pd/src/s_stuff.h +++ b/pd/src/s_stuff.h @@ -130,6 +130,9 @@ EXTERN void sys_get_midi_devs(char *indevlist, int *nindevs, int maxndev, int devdescsize); void sys_get_midi_params(int *pnmidiindev, int *pmidiindev, int *pnmidioutdev, int *pmidioutdev); +EXTERN int sys_mididevnametonumber(int output, const char *name); +EXTERN void sys_mididevnumbertoname(int output, int devno, char *name, + int namesize); void sys_get_midi_apis(char *buf); void sys_get_midi_apis2(t_binbuf *buf); -- GitLab