From 2c9e51ad6c49f6f412ff1ba045d6b2ebf0f17023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Mon, 25 Jul 2005 10:14:13 +0000 Subject: fixed a bug that didn't enumerate all connections when one sender was connected to multiple receivers introduced BUG: the above bug-fix keeps aconnectgui.pd from working (LATER fix this) statically connect to the alsa-sequencer (if possible): this makes a parallel aconnectgui instance crash less often (aconnectgui doesn't like the "default"-sequencer to be closed); LATER look at qjackctl how they manage to keep aconnectgui alive svn path=/trunk/externals/iem/aconnect/; revision=3372 --- aconnect-help.pd | 56 +++++++++++++++++++++++++++++++++------------ aconnect.c | 69 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 88 insertions(+), 37 deletions(-) diff --git a/aconnect-help.pd b/aconnect-help.pd index 0262925..0b02dd2 100644 --- a/aconnect-help.pd +++ b/aconnect-help.pd @@ -1,4 +1,4 @@ -#N canvas 83 42 744 737 10; +#N canvas 211 47 891 733 10; #X obj 145 275 aconnect; #X text 51 10 aconnect:: ALSA sequencer connection manager; #X text 70 43 allows you to (dis)connect different alsa-sequencer clients @@ -24,15 +24,13 @@ the clients; #X floatatom 452 446 3 0 0 1 dest# - -; #X floatatom 483 426 3 0 0 1 destport# - -; #X obj 390 355 t l l; -#X text 389 249 disconnect output of client#0:port#0 to input of client#72:port#1 -; #X msg 244 223 connect 74 0 72 0; #X text 371 213 connect output of client#74:port#0 to input of client#72:port#0 ; -#X obj 146 669 aconnect; -#X msg 146 644 bang; -#X msg 209 669 disconnect \$1 \$2 \$3 \$4; -#X text 188 643 disconnect all; +#X obj 502 563 aconnect; +#X msg 502 538 bang; +#X msg 568 564 disconnect \$1 \$2 \$3 \$4; +#X text 544 537 disconnect all; #N canvas 0 0 829 380 return 0; #X msg 78 163 sucess; #X obj 78 185 print retval; @@ -55,9 +53,38 @@ the clients; #X connect 9 0 1 0; #X connect 10 0 1 0; #X restore 196 297 pd return value; -#X msg 244 251 disconnect 0 0 72 1; +#N canvas 0 0 299 212 pipe 0; +#X obj 83 36 inlet; +#X obj 83 140 outlet; +#X obj 83 64 unpack 0 0 0 0; +#X obj 83 104 pack 0 0 0 0; +#X obj 83 84 pipe 0 0 0 0 0; +#X connect 0 0 2 0; +#X connect 2 0 4 0; +#X connect 2 1 4 1; +#X connect 2 2 4 2; +#X connect 2 3 4 3; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 4 1 3 1; +#X connect 4 2 3 2; +#X connect 4 3 3 3; +#X restore 502 586 pd pipe; +#X text 459 608 note: we need to detach the "disconnect" message from +querying the connections \, in order to be able to disconnect all listeners +from a sender with multiple listeners. this might change in future +versions; +#X text 532 12 updated for aconnect-0.3; +#X msg 244 251 disconnect 64 0 72 1; +#X text 393 248 disconnect output of client#64:port#0 to input of client#72:port#1 +; +#X text 51 655 insitute for electronic music and acoustics \, iem; +#X text 52 669 university of music and dramatic arts \, graz \, aut +; +#X text 50 621 copyleft (c) 2005 IOhannes m zmoelnig; +#X text 52 637 published under the GnuGPL v2.0; #X connect 0 0 5 0; -#X connect 0 1 30 0; +#X connect 0 1 29 0; #X connect 4 0 0 0; #X connect 5 0 6 0; #X connect 5 0 9 0; @@ -74,8 +101,9 @@ the clients; #X connect 17 3 21 0; #X connect 22 0 17 0; #X connect 22 1 16 0; -#X connect 24 0 0 0; -#X connect 26 0 28 0; -#X connect 27 0 26 0; -#X connect 28 0 26 0; -#X connect 31 0 0 0; +#X connect 23 0 0 0; +#X connect 25 0 30 0; +#X connect 26 0 25 0; +#X connect 27 0 25 0; +#X connect 30 0 27 0; +#X connect 33 0 0 0; diff --git a/aconnect.c b/aconnect.c index 0bce411..d69b6d1 100644 --- a/aconnect.c +++ b/aconnect.c @@ -37,11 +37,12 @@ typedef struct _aconnect #define LIST_INPUT 1 #define LIST_OUTPUT 2 -#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) - -static snd_seq_t* ac_seq; +#define ACONNECT_SEQ_NAME "default" +#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) +static int ac_count=0; +static snd_seq_t* ac_seq=0; static int check_permission(snd_seq_port_info_t *pinfo, int perm) { @@ -73,19 +74,21 @@ static void do_search_port(t_aconnect *x, snd_seq_t *seq, int perm, action_func_ snd_seq_client_info_t *cinfo; snd_seq_port_info_t *pinfo; int count; - snd_seq_client_info_alloca(&cinfo); snd_seq_port_info_alloca(&pinfo); snd_seq_client_info_set_client(cinfo, -1); while (snd_seq_query_next_client(seq, cinfo) >= 0) { /* reset query info */ - snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); - snd_seq_port_info_set_port(pinfo, -1); - count = 0; - while (snd_seq_query_next_port(seq, pinfo) >= 0) { - if (check_permission(pinfo, perm)) { - do_action(x, seq, cinfo, pinfo); - count++; + int senderport=snd_seq_client_info_get_client(cinfo); + if(SND_SEQ_CLIENT_SYSTEM != senderport){ /* skipping port 0 */ + snd_seq_port_info_set_client(pinfo, senderport); + snd_seq_port_info_set_port(pinfo, -1); + count = 0; + while (snd_seq_query_next_port(seq, pinfo) >= 0) { + if (check_permission(pinfo, perm)) { + do_action(x, seq, cinfo, pinfo); + count++; + } } } } @@ -127,13 +130,13 @@ static void print_connections(t_aconnect *x, snd_seq_t *seq, snd_seq_client_info int sender_port =snd_seq_port_info_get_port(pinfo); int receiver_id =-1; int receiver_port =-1; + snd_seq_query_subscribe_t *subs; t_atom ap[4]; SETFLOAT (ap+0, sender_id); SETFLOAT (ap+1, sender_port); - snd_seq_query_subscribe_t *subs; snd_seq_query_subscribe_alloca(&subs); snd_seq_query_subscribe_set_root(subs, snd_seq_port_info_get_addr(pinfo)); @@ -224,19 +227,18 @@ static void remove_all_connections(t_aconnect *x, snd_seq_t *seq) static void aconnect_listdevices(t_aconnect *x, t_symbol *s) { snd_seq_t *seq; - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { + if (((seq=ac_seq)==0) && snd_seq_open(&seq, ACONNECT_SEQ_NAME, SND_SEQ_OPEN_DUPLEX, 0) < 0) { error("aconnect: can't open sequencer"); outlet_float(x->x_error, (float)(-2)); return; } - if(&s_==s || gensym("input")==s) do_search_port(x, seq, LIST_INPUT, print_input); if(&s_==s || gensym("output")==s) do_search_port(x, seq, LIST_OUTPUT, print_output); - snd_seq_close(seq); + if(!ac_seq)snd_seq_close(seq); outlet_float(x->x_error, 0.); } @@ -248,15 +250,15 @@ static void aconnect_listdevices(t_aconnect *x, t_symbol *s) static void aconnect_bang(t_aconnect *x) { snd_seq_t *seq; - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { + if (((seq=ac_seq)==0) && snd_seq_open(&seq, ACONNECT_SEQ_NAME, SND_SEQ_OPEN_DUPLEX, 0) < 0) { error("aconnect: can't open sequencer"); outlet_float(x->x_error, (float)(-2)); return; } - do_search_port(x, seq, LIST_OUTPUT, print_connections); + do_search_port(x, seq, LIST_INPUT, print_connections); - snd_seq_close(seq); + if(!ac_seq)snd_seq_close(seq); outlet_float(x->x_error, 0.); } @@ -320,7 +322,7 @@ static void aconnect_connect(t_aconnect *x, t_symbol *s, int argc, t_atom *argv) return; } - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { + if (((seq=ac_seq)==0) && snd_seq_open(&seq, ACONNECT_SEQ_NAME, SND_SEQ_OPEN_DUPLEX, 0) < 0) { error("aconnect: can't open sequencer"); outlet_float(x->x_error, (float)(-2)); return; @@ -334,7 +336,7 @@ static void aconnect_connect(t_aconnect *x, t_symbol *s, int argc, t_atom *argv) err=aconnect_subscribe(seq, 1, sender_id, sender_port, dest_id, dest_port); - snd_seq_close(seq); + if(!ac_seq)snd_seq_close(seq); outlet_float(x->x_error, (float)err); } /* a list like "disconnect " @@ -351,7 +353,7 @@ static void aconnect_disconnect(t_aconnect *x, t_symbol *s, int argc, t_atom *ar return; } - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { + if (((seq=ac_seq)==0) && snd_seq_open(&seq, ACONNECT_SEQ_NAME, SND_SEQ_OPEN_DUPLEX, 0) < 0) { error("aconnect: can't open sequencer"); outlet_float(x->x_error, (float)(-2)); return; @@ -366,10 +368,21 @@ static void aconnect_disconnect(t_aconnect *x, t_symbol *s, int argc, t_atom *ar err=aconnect_subscribe(seq, 0, sender_id, sender_port, dest_id, dest_port); outlet_float(x->x_error, (float)err); - snd_seq_close(seq); + if(!ac_seq)snd_seq_close(seq); } #endif /* ALSA */ +static void aconnect_free(t_aconnect *x){ +#ifdef HAVE_ALSA + ac_count--; + if(ac_count<=0){ + if(ac_seq)snd_seq_close(ac_seq); + ac_seq=0; + } +#endif /* ALSA */ +} + + static void *aconnect_new(void) { t_aconnect *x = (t_aconnect *)pd_new(aconnect_class); @@ -379,6 +392,16 @@ static void *aconnect_new(void) #ifndef HAVE_ALSA error("aconnect: compiled without ALSA-suppor !!"); error("aconnect: no functionality enabled!"); +#else + if(ac_count<=0){ + ac_count=0; + if (snd_seq_open(&ac_seq, ACONNECT_SEQ_NAME, SND_SEQ_OPEN_DUPLEX, 0) < 0){ + error("aconnect: can't open sequencer"); + ac_seq=0; + } + } + ac_count++; + #endif /* !ALSA */ return (x); @@ -397,7 +420,7 @@ void aconnect_setup(void) #endif post("\tcompiled: "__DATE__""); - aconnect_class = class_new(gensym("aconnect"), (t_newmethod)aconnect_new, 0, + aconnect_class = class_new(gensym("aconnect"), (t_newmethod)aconnect_new, (t_method)aconnect_free, sizeof(t_aconnect), 0, 0); #ifdef HAVE_ALSA class_addmethod(aconnect_class, (t_method)aconnect_connect,gensym("connect"), A_GIMME, 0); -- cgit v1.2.1