aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2005-07-25 10:14:13 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2005-07-25 10:14:13 +0000
commit2c9e51ad6c49f6f412ff1ba045d6b2ebf0f17023 (patch)
treeee6cbdfa96a1eff027c634c84b4762ab57f3c064
parent2b487f5ee15706f432109a1dd8905b29e1b046a6 (diff)
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
-rw-r--r--aconnect-help.pd56
-rw-r--r--aconnect.c69
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 <sender_client> <sender_port> <receiver_client> <receiver_port>"
@@ -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);