From 7ed00adf7a1d30fbbb35b80f4915c8d778b4f9cc Mon Sep 17 00:00:00 2001 From: Gerard van Dongen Date: Sat, 18 Oct 2003 13:38:48 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r1106, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/jackx/; revision=1107 --- jackx.c | 396 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 jackx.c (limited to 'jackx.c') diff --git a/jackx.c b/jackx.c new file mode 100644 index 0000000..9c04bd6 --- /dev/null +++ b/jackx.c @@ -0,0 +1,396 @@ +/* jack utility externals for linux pd + * copyright 2003 Gerard van Dongen gml@xs4all.nl + +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + + +* objects: +* jack-connect +* this can query and set the port connections on the jack system +* methods: +* jack-ports +* this can query jack ports with regex's + + + + + */ + + + + +#include "m_pd.h" + +#include +#include +#include +#include +#include +#include + + +static t_class *jackports_class; +static t_class *jackconnect_class; + +typedef struct _jackports { + t_object x_obj; + t_outlet *input_ports, *output_ports; + char expression[128]; + char *buffer; //used internally it doesn't have to be reserved every time + t_atom *a_outlist; + +} t_jackports; + +typedef struct _jackconnect { + t_object x_obj; + t_symbol *input_client,*input_port, *output_client,*output_port; + char source[128],destination[128]; //ought to be enough for most names + int connected; +} t_jackconnect; + +static jack_client_t * jc; + + + +/******************************************************************************************************** + +methods for jack-ports + +*********************************************************************************************************/ + +void jackports_input(t_jackports *x, t_symbol *s,int argc, t_atom *argv) +{ + if (jc){ + char ** ports; + + int l = 0; + int n = 0; + int keyflag = 0; + int expflag =0; + int portflags = 0; + t_symbol *s_client; + t_symbol *s_port; + char *t; + + if (!strcmp(s->s_name,"bang")) { + strcpy(x->expression,""); + expflag = 1; + } else { + + //parse symbol s and all arguments for keywords: + //physical,virtual,input and output + + if (!strcmp(s->s_name,"physical")) { + portflags = portflags | JackPortIsPhysical; + keyflag = 1; + } + if (!strcmp(s->s_name,"virtual")) { + portflags = portflags & (~JackPortIsPhysical); + keyflag = 1; + } + if (!strcmp(s->s_name,"input")) { + portflags = portflags | JackPortIsInput; + keyflag = 1; + } + + if (!strcmp(s->s_name,"output")) { + portflags = portflags | JackPortIsOutput; + keyflag = 1; + } + if (!keyflag) { + strcpy(x->expression,s->s_name); + expflag = 1; + } + for (n=0;nbuffer,128); + if (!strcmp(x->buffer,"physical")) { + portflags = portflags | JackPortIsPhysical; + keyflag = 1; + } + if (!strcmp(x->buffer,"virtual")) { + portflags = portflags & (~JackPortIsPhysical); + keyflag = 1; + } + if (!strcmp(x->buffer,"input")) { + portflags = portflags | JackPortIsInput; + keyflag = 1; + } + + if (!strcmp(x->buffer,"output")) { + portflags = portflags | JackPortIsOutput; + keyflag = 1; + } + if (!keyflag && !expflag) { + strcpy(x->expression,x->buffer); + expflag = 1; + } + + + } + + + } + + + ports = jack_get_ports (jc,x->expression,NULL,portflags|JackPortIsOutput); + n=0; + if (ports) { + while (ports[n]) { + //seperate port and client + + l = strlen(ports[n]); + t = strchr(ports[n],':'); + + if (t) { + s_port=gensym(strchr(ports[n],':')+1); + + + snprintf(x->buffer,l-strlen(s_port->s_name),ports[n]); + s_client = gensym(x->buffer); + + SETSYMBOL(x->a_outlist,s_client); + SETSYMBOL(x->a_outlist+1,s_port); + + // output in output-outlet + outlet_list(x->output_ports,&s_list,2,x->a_outlist); + } + + n++; + } + } + free(ports); + + ports = jack_get_ports (jc,x->expression,NULL,portflags|JackPortIsInput); + n=0; + if (ports) { + while (ports[n]) { + l = strlen(ports[n]); + t = strchr(ports[n],':'); + + if (t) { + s_port=gensym(strchr(ports[n],':')+1); + + + snprintf(x->buffer,l-strlen(s_port->s_name),ports[n]); + s_client = gensym(x->buffer); + + SETSYMBOL(x->a_outlist,s_client); + SETSYMBOL(x->a_outlist+1,s_port); + + // output in output-outlet + outlet_list(x->input_ports,&s_list,2,x->a_outlist); + } + + + n++; + } + } + free(ports); + + strcpy(x->expression,"");//reset regex + } + +} + + + + +void *jackports_new(void) +{ + t_jackports * x = (t_jackports *)pd_new(jackports_class); + x->output_ports = outlet_new(&x->x_obj, &s_list); + x->input_ports = outlet_new(&x->x_obj, &s_list); + x->a_outlist = getbytes(3 * sizeof(t_atom)); + x->buffer = getbytes(128); + + return (void*)x; +} + + + +/******************************************************************************************************** + +methods for jack-connect + +*********************************************************************************************************/ +void jackconnect_getnames(t_jackconnect *x) +{ + char* to = x->source; + to = (char*)stpcpy( to,x->output_client->s_name); + to = (char*)stpcpy(to,":"); + to = (char*)stpcpy(to,x->output_port->s_name); + to = x->destination; + to = (char*)stpcpy(to,x->input_client->s_name); + to = (char*)stpcpy(to,":"); + to = (char*)stpcpy(to,x->input_port->s_name); + +} +void jackconnect_connect(t_jackconnect *x) +{ + + if (jc) { + + jackconnect_getnames(x); + post("connecting %s with %s",x->source,x->destination); + if (!jack_connect(jc,x->source,x->destination)) { + x->connected = 1; + outlet_float(x->x_obj.ob_outlet,x->connected); + } + } + +} + +void jackconnect_disconnect(t_jackconnect *x) +{ + if (jc) { + + jackconnect_getnames(x); + if (!jack_disconnect(jc,x->source,x->destination)) { + x->connected = 0; + outlet_float(x->x_obj.ob_outlet,x->connected); + } + post("disconnecting %s with %s",x->source,x->destination); + } + +} + +void jackconnect_toggle(t_jackconnect *x) +{ + if (jc) { + + jackconnect_getnames(x); + post("toggling connection %s with %s",x->source,x->destination); + if (jack_disconnect(jc,x->source,x->destination)) { + jack_connect(jc,x->source,x->destination); + x->connected = 1; + } else { + x->connected = 0; + } + outlet_float(x->x_obj.ob_outlet,x->connected); + } +} + + +void jackconnect_query(t_jackconnect *x) +{ + if (jc) { + + char **ports; + int n=0; + jackconnect_getnames(x); + + post("querying connection %s with %s",x->source,x->destination); + + ports = jack_port_get_all_connections(jc,(jack_port_t *)jack_port_by_name(jc,x->source)); + x->connected = 0; + + if(ports){ + while (ports[n]){ + post("n = %i",n); + if (!strcmp(ports[n],x->destination)){ + x->connected = 1; + break; + } + n++; + + } + free(ports); + } + outlet_float(x->x_obj.ob_outlet,x->connected); + } + + + +} + + + + + + + +void *jackconnect_new(void) +{ + t_jackconnect * x = (t_jackconnect *)pd_new(jackconnect_class); + + outlet_new(&x->x_obj, &s_float); + symbolinlet_new(&x->x_obj,&x->output_client); + symbolinlet_new(&x->x_obj,&x->output_port); + symbolinlet_new(&x->x_obj,&x->input_client); + symbolinlet_new(&x->x_obj,&x->input_port); + + /* to prevent segfaults put default names in the client/port variables */ + x->input_client = gensym("none"); + x->input_port = gensym("none"); + x->output_client = gensym("none"); + x->output_port = gensym("none"); + x->connected = 0; + jackconnect_getnames(x); + + return (void*)x; +} + + +/******************************************************************************************************** + +setup for jack-connect and jack-ports + +*********************************************************************************************************/ + + + +void jackx_setup(void) +{ + + post("//////////////////////////////////////////\n" + "/////Jack utility external library///////\n" + "////Gerard van Dongen, gml@xs4all.nl////\n" + "///testing for jack////////////////////\n" + "//////////////////////////////////////"); + + + jc = jack_client_new("jacky-x"); + + + + + /*jack ports setup */ + + jackports_class = class_new(gensym("jack-ports"),(t_newmethod)jackports_new,0,sizeof(t_jackports),CLASS_DEFAULT,0); + + + + + class_addanything(jackports_class,jackports_input); + + class_sethelpsymbol(jackports_class,gensym("jack-ports")); + + /*jack-connect setup */ + + + + jackconnect_class = class_new(gensym("jack-connect"),(t_newmethod)jackconnect_new,0,sizeof(t_jackconnect),CLASS_DEFAULT,0); + + class_addmethod(jackconnect_class, (t_method)jackconnect_connect, gensym("connect"),0); + class_addmethod(jackconnect_class, (t_method)jackconnect_disconnect, gensym("disconnect"),0); + class_addmethod(jackconnect_class, (t_method)jackconnect_toggle, gensym("toggle"),0); + class_addmethod(jackconnect_class, (t_method)jackconnect_query, gensym("query"),0); + class_addbang(jackconnect_class, (t_method)jackconnect_toggle); + class_sethelpsymbol(jackports_class,gensym("jack-connect")); +} + + + + -- cgit v1.2.1