From d117462cb9d7cc1b15379edca19cdca203826efb Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 3 Jan 2000 10:25:56 +0000 Subject: [PATCH] Takashi Iwai Mon, 03 Jan 2000 10:47:02 +0100 - bugfix: proper handling of exclusive subscription - bugfix and update: alsa-lib/test/seq* stuff - minor updates (long option support, etc) of aconnect and aseqnet - man pages for aconnect and aseqnet are added --- include/seq.h | 1 + src/seq/seq.c | 13 +- test/Makefile.am | 3 +- test/README.aconnect | 13 +- test/README.aseqnet | 4 +- test/aconnect.c | 94 +++++++---- test/aseqnet.c | 42 +++-- test/seq-decoder.c | 462 +++++++++++++++++++++++++-------------------------- test/seq-sender.c | 31 ++-- 9 files changed, 364 insertions(+), 299 deletions(-) diff --git a/include/seq.h b/include/seq.h index df3ada30..aac02d58 100644 --- a/include/seq.h +++ b/include/seq.h @@ -64,6 +64,7 @@ int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev); int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer); int snd_seq_event_input_selective(snd_seq_t *seq, snd_seq_event_t **ev, int type, int blocking); int snd_seq_flush_output(snd_seq_t *handle); +int snd_seq_event_output_pending(snd_seq_t *seq); int snd_seq_extract_output(snd_seq_t *handle, snd_seq_event_t **ev); int snd_seq_drain_output(snd_seq_t *handle); int snd_seq_drain_output_buffer(snd_seq_t *handle); diff --git a/src/seq/seq.c b/src/seq/seq.c index acb035e6..607cb5e7 100644 --- a/src/seq/seq.c +++ b/src/seq/seq.c @@ -773,6 +773,16 @@ int snd_seq_event_input_selective(snd_seq_t *seq, snd_seq_event_t **ev, int type } /* + * return the size of pending events + */ +int snd_seq_event_output_pending(snd_seq_t *seq) +{ + if (!seq) + return -EINVAL; + return seq->obufused; +} + +/* * flush output buffer to sequencer */ int snd_seq_flush_output(snd_seq_t *seq) @@ -842,6 +852,7 @@ int snd_seq_drain_output_buffer(snd_seq_t *seq) if (!seq) return -EINVAL; seq->obufused = 0; + return 0; } /* @@ -857,7 +868,7 @@ int snd_seq_drain_input_buffer(snd_seq_t *seq) } /* - * clear output buffer and and remove events in sequencer queue + * clear output buffer and remove events in sequencer queue */ int snd_seq_drain_output(snd_seq_t *seq) { diff --git a/test/Makefile.am b/test/Makefile.am index bfef0b81..4839d90c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -18,4 +18,5 @@ aseqnet_LDADD=../src/libasound.la INCLUDES=-I$(top_srcdir)/include CFLAGS=-static -Wall -pipe -g -EXTRA_DIST=seq-decoder.c seq-sender.c midifile.h midifile.c midifile.3 +EXTRA_DIST=seq-decoder.c seq-sender.c midifile.h midifile.c midifile.3 \ + aconnect.1 README.aconnect aseqnet.1 README.aseqnet diff --git a/test/README.aconnect b/test/README.aconnect index 7d3d071f..a2839ab0 100644 --- a/test/README.aconnect +++ b/test/README.aconnect @@ -1,7 +1,7 @@ ================================================================ aconnect - control subscriptions - ver.0.1.2 - Copyright (C) 1999 Takashi Iwai + ver.0.1.3 + Copyright (C) 1999-2000 Takashi Iwai ================================================================ aconnect is a utility to control subscriptions of two ports as the @@ -42,8 +42,9 @@ using -g option. The option -l together with -i or -o shows subscribers for each port. -The option -D specifies the sequencer device file (as default, -/dev/snd/seq). Usually, you don't have to change it. -The option -q specifies the queue number. The argument must be a -valid queue number, usually from 0 to 7. +Ports are connected exclusively when the option -e is specified. +For modifying time-stamp with a queue, use -r or -t option followed by +a queue index which updates the time-stamp. Former uses real-time queue, +while the latter uses tick queue. The queue must be used (not necessarily +owned) by the receiver client. diff --git a/test/README.aseqnet b/test/README.aseqnet index 7e005715..65d70671 100644 --- a/test/README.aseqnet +++ b/test/README.aseqnet @@ -1,7 +1,7 @@ ================================================================ - ALSA sequencer connectors + ALSA sequencer connectors over network ver.0.1 - Copyright (C) 1999 Takashi Iwai + Copyright (C) 1999-2000 Takashi Iwai ================================================================ * ASEQNET diff --git a/test/aconnect.c b/test/aconnect.c index 124afb91..935e88ca 100644 --- a/test/aconnect.c +++ b/test/aconnect.c @@ -1,6 +1,6 @@ /* * connect / disconnect two subscriber ports - * ver.0.1.2 + * ver.0.1.3 * * Copyright (C) 1999 Takashi Iwai * @@ -16,42 +16,50 @@ */ #include +#include #include #include #include #include -#include +#include #include #include -#define DEFAULT_QUEUE 0 - static void usage(void) { - fprintf(stderr, "connect / disconnect two subscriber ports\n"); - fprintf(stderr, "copyright (C) 1999 Takashi Iwai\n"); - fprintf(stderr, "usage: aconnect [-d] [-q queue] [-g group] sender receiver\n"); - fprintf(stderr, " -d = disconnect\n"); - fprintf(stderr, " sender, receiver = client:port\n"); - fprintf(stderr, " aconnect -i [-g group] [-l]\n"); - fprintf(stderr, " list input ports\n"); - fprintf(stderr, " aconnect -o [-g group] [-l]\n"); - fprintf(stderr, " list output ports\n"); - fprintf(stderr, " -l = list current connections\n"); + fprintf(stderr, "aconnect - ALSA sequencer connection manager\n"); + fprintf(stderr, "Copyright (C) 1999-2000 Takashi Iwai\n"); + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " * Connection/disconnection betwen two ports\n"); + fprintf(stderr, " aconnect [-options] sender receiver\n"); + fprintf(stderr, " sender, receiver = client:port pair\n"); + fprintf(stderr, " -d,--disconnect disconnect\n"); + fprintf(stderr, " -e,--exclusive exclusive connection\n"); + fprintf(stderr, " -r,--real # convert real-time-stamp on queue\n"); + fprintf(stderr, " -t,--tick # convert tick-time-stamp on queue\n"); + fprintf(stderr, " -g,--group name set the group name\n"); + fprintf(stderr, " * List connected ports (no subscription action)\n"); + fprintf(stderr, " aconnect -i|-o [-options]\n"); + fprintf(stderr, " -i,--input list input (readable) ports\n"); + fprintf(stderr, " -o,--output list output (writable) ports\n"); + fprintf(stderr, " -g,--group name specify the group name\n"); + fprintf(stderr, " -l,--list list current connections of each port\n"); } /* * parse command line to client:port */ -static void parse_address(snd_seq_addr_t *addr, char *arg) +static int parse_address(snd_seq_addr_t *addr, char *arg) { char *p; + if (! isdigit(*arg)) + return -1; + if ((p = strpbrk(arg, ":.")) == NULL) + return -1; addr->client = atoi(arg); - if ((p = strchr(arg, ':')) != NULL) - addr->port = atoi(p + 1); - else - addr->port = 0; + addr->port = atoi(p + 1); + return 0; } /* @@ -153,11 +161,23 @@ enum { SUBSCRIBE, UNSUBSCRIBE, LIST_INPUT, LIST_OUTPUT }; +static struct option long_option[] = { + {"disconnect", 0, NULL, 'd'}, + {"input", 0, NULL, 'i'}, + {"output", 0, NULL, 'o'}, + {"group", 1, NULL, 'g'}, + {"real", 1, NULL, 'r'}, + {"tick", 1, NULL, 't'}, + {"exclusive", 0, NULL, 'e'}, + {"list", 0, NULL, 'l'}, + {NULL, 0, NULL, 0}, +}; + int main(int argc, char **argv) { int c; snd_seq_t *seq; - int queue = DEFAULT_QUEUE; + int queue = 0, convert_time = 0, convert_real = 0, exclusive = 0; int command = SUBSCRIBE; char *group = ""; int client; @@ -165,7 +185,7 @@ int main(int argc, char **argv) snd_seq_client_info_t cinfo; snd_seq_port_subscribe_t subs; - while ((c = getopt(argc, argv, "diog:D:q:l")) != -1) { + while ((c = getopt_long(argc, argv, "diog:r:t:el", long_option, NULL)) != -1) { switch (c) { case 'd': command = UNSUBSCRIBE; @@ -179,8 +199,18 @@ int main(int argc, char **argv) case 'g': group = optarg; break; - case 'q': + case 'e': + exclusive = 1; + break; + case 'r': queue = atoi(optarg); + convert_time = 1; + convert_real = 1; + break; + case 't': + queue = atoi(optarg); + convert_time = 1; + convert_real = 0; break; case 'l': list_subs = 1; @@ -232,12 +262,18 @@ int main(int argc, char **argv) /* set subscription */ memset(&subs, 0, sizeof(subs)); - parse_address(&subs.sender, argv[optind]); - parse_address(&subs.dest, argv[optind + 1]); + if (parse_address(&subs.sender, argv[optind]) < 0) { + fprintf(stderr, "invalid sender address %s\n", argv[optind]); + return 1; + } + if (parse_address(&subs.dest, argv[optind + 1]) < 0) { + fprintf(stderr, "invalid destination address %s\n", argv[optind + 1]); + return 1; + } subs.queue = queue; - subs.exclusive = 0; - subs.convert_time = 0; - subs.realtime = 0; + subs.exclusive = exclusive; + subs.convert_time = convert_time; + subs.realtime = convert_real; if (command == UNSUBSCRIBE) { if (snd_seq_get_port_subscription(seq, &subs) < 0) { @@ -247,7 +283,7 @@ int main(int argc, char **argv) } if (snd_seq_unsubscribe_port(seq, &subs) < 0) { snd_seq_close(seq); - fprintf(stderr, "Disconnection failed (errno=%d)\n", errno); + fprintf(stderr, "Disconnection failed (%s)\n", snd_strerror(errno)); return 1; } } else { @@ -258,7 +294,7 @@ int main(int argc, char **argv) } if (snd_seq_subscribe_port(seq, &subs) < 0) { snd_seq_close(seq); - fprintf(stderr, "Connection failed (errno=%d)\n", errno); + fprintf(stderr, "Connection failed (%s)\n", snd_strerror(errno)); return 1; } } diff --git a/test/aseqnet.c b/test/aseqnet.c index d2f993dd..37ea64a8 100644 --- a/test/aseqnet.c +++ b/test/aseqnet.c @@ -2,7 +2,7 @@ * network server/client for ALSA sequencer * ver.0.1 * - * Copyright (C) 1999 Takashi Iwai + * Copyright (C) 1999-2000 Takashi Iwai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* @@ -69,13 +69,21 @@ static int server_mode; * main routine */ +static struct option long_option[] = { + {"port", 1, NULL, 'p'}, + {"source", 1, NULL, 's'}, + {"dest", 1, NULL, 'd'}, + {"help", 0, NULL, 'h'}, + {NULL, 0, NULL, 0}, +}; + int main(int argc, char **argv) { int c; int port = DEFAULT_PORT; char *source = NULL, *dest = NULL; - while ((c = getopt(argc, argv, "p:s:d:")) != -1) { + while ((c = getopt_long(argc, argv, "p:s:d:", long_option, NULL)) != -1) { switch (c) { case 'p': if (isdigit(*optarg)) @@ -130,9 +138,9 @@ static void usage(void) fprintf(stderr, " server mode: aseqnet [-options]\n"); fprintf(stderr, " client mode: aseqnet [-options] server_host\n"); fprintf(stderr, "options:\n"); - fprintf(stderr, " -p port : sepcify TCP port (digit or service name)\n"); - fprintf(stderr, " -s addr : read from given addr (client:port)\n"); - fprintf(stderr, " -d addr : write to given addr (client:port)\n"); + fprintf(stderr, " -p,--port # : sepcify TCP port (digit or service name)\n"); + fprintf(stderr, " -s,--source addr : read from given addr (client:port)\n"); + fprintf(stderr, " -d,--dest addr : write to given addr (client:port)\n"); } @@ -157,15 +165,17 @@ static void init_buf(void) /* * parse client:port argument */ -static void parse_addr(snd_seq_addr_t *addr, char *arg) +static int parse_addr(snd_seq_addr_t *addr, char *arg) { char *p; + if (! isdigit(*arg)) + return -1; + if ((p = strpbrk(arg, ":.")) == NULL) + return -1; addr->client = atoi(arg); - if ((p = strchr(arg, ':')) != NULL) - addr->port = atoi(p + 1); - else - addr->port = 0; + addr->port = atoi(p + 1); + return 0; } @@ -222,7 +232,10 @@ static void init_seq(char *source, char *dest) /* explicit subscriptions */ if (source) { /* read subscription */ - parse_addr(&addr, source); + if (parse_addr(&addr, source) < 0) { + fprintf(stderr, "invalid source address %s\n", source); + exit(1); + } if (snd_seq_connect_from(handle, seq_port, addr.client, addr.port)) { perror("read subscription"); exit(1); @@ -230,7 +243,10 @@ static void init_seq(char *source, char *dest) } if (dest) { /* write subscription */ - parse_addr(&addr, dest); + if (parse_addr(&addr, dest) < 0) { + fprintf(stderr, "invalid destination address %s\n", dest); + exit(1); + } if (snd_seq_connect_to(handle, seq_port, addr.client, addr.port)) { perror("write subscription"); exit(1); diff --git a/test/seq-decoder.c b/test/seq-decoder.c index c402d496..5377f991 100644 --- a/test/seq-decoder.c +++ b/test/seq-decoder.c @@ -4,48 +4,48 @@ static char *event_names[256] = { /* 0 */ "System", - /* 1 */ "Note", - /* 2 */ "Note On", - /* 3 */ "Note Off", + /* 1 */ "Result", + /* 2 */ "Reserved 2", + /* 3 */ "Reserved 3", /* 4 */ "Reserved 4", - /* 5 */ "Reserved 5", - /* 6 */ "Reserved 6", - /* 7 */ "Reserved 7", - /* 8 */ "Reserved 8", + /* 5 */ "Note", + /* 6 */ "Note On", + /* 7 */ "Note Off", + /* 8 */ "Key Pressure", /* 9 */ "Reserved 9", - /* 10 */ "KeyPress", - /* 11 */ "Controller", - /* 12 */ "Program Change", - /* 13 */ "Channel Pressure", - /* 14 */ "Pitchbend", - /* 15 */ "Control14", - /* 16 */ "Nonregparam", - /* 17 */ "Regparam", + /* 10 */ "Controller", + /* 11 */ "Program Change", + /* 12 */ "Channel Pressure", + /* 13 */ "Pitchbend", + /* 14 */ "Control14", + /* 15 */ "Nonregparam", + /* 16 */ "Regparam", + /* 17 */ "Reserved 17", /* 18 */ "Reserved 18", /* 19 */ "Reserved 19", /* 20 */ "Song Position", /* 21 */ "Song Select", - /* 22 */ "Clock", - /* 23 */ "Start", - /* 24 */ "Continue", - /* 25 */ "Stop", - /* 26 */ "Qframe", + /* 22 */ "Qframe", + /* 23 */ "SMF Time Signature", + /* 24 */ "SMF Key Signature", + /* 25 */ "Reserved 25", + /* 26 */ "Reserved 26", /* 27 */ "Reserved 27", /* 28 */ "Reserved 28", /* 29 */ "Reserved 29", - /* 30 */ "Tempo", - /* 31 */ "SMF Time Signature", - /* 32 */ "SMF Key Signature", - /* 33 */ "Reserved 33", - /* 34 */ "Reserved 34", - /* 35 */ "Reserved 35", - /* 36 */ "Reserved 36", - /* 37 */ "Reserved 37", + /* 30 */ "Start", + /* 31 */ "Continue", + /* 32 */ "Stop", + /* 33 */ "Set Position Tick", + /* 34 */ "Set Position Time", + /* 35 */ "Tempo", + /* 36 */ "Clock", + /* 37 */ "Tick", /* 38 */ "Reserved 38", /* 39 */ "Reserved 39", - /* 40 */ "System Exclusive", - /* 41 */ "Heart Beat", - /* 42 */ "Reserved 42", + /* 40 */ "Tune Request", + /* 41 */ "Reset", + /* 42 */ "Active Sensing", /* 43 */ "Reserved 43", /* 44 */ "Reserved 44", /* 45 */ "Reserved 45", @@ -53,8 +53,8 @@ static char *event_names[256] = { /* 47 */ "Reserved 47", /* 48 */ "Reserved 48", /* 49 */ "Reserved 49", - /* 50 */ "Heart Beat (Active sensing)", - /* 51 */ "Echo", + /* 50 */ "Echo", + /* 51 */ "OSS", /* 52 */ "Reserved 52", /* 53 */ "Reserved 53", /* 54 */ "Reserved 54", @@ -69,206 +69,196 @@ static char *event_names[256] = { /* 63 */ "Port Start", /* 64 */ "Port Exit", /* 65 */ "Port Change", - /* 66 */ "Reserved 66", - /* 67 */ "Reserved 67", - /* 68 */ "Reserved 68", - /* 69 */ "Reserved 69", - /* 70 */ "Reserved 70", - /* 71 */ "Reserved 71", - /* 72 */ "Reserved 72", - /* 73 */ "Reserved 73", - /* 74 */ "Reserved 74", - /* 75 */ "Reserved 75", - /* 76 */ "Reserved 76", - /* 77 */ "Reserved 77", - /* 78 */ "Reserved 78", + /* 66 */ "Port Subscribed", + /* 67 */ "Port Used", + /* 68 */ "Port Unsubscribed", + /* 69 */ "Port Unused", + /* 70 */ "Sample", + /* 71 */ "Sample Cluster", + /* 72 */ "Sample Start", + /* 73 */ "Sample Stop", + /* 74 */ "Sample Freq", + /* 75 */ "Sample Volume", + /* 76 */ "Sample Loop", + /* 77 */ "Sample Position", + /* 78 */ "Sample Private1", /* 79 */ "Reserved 79", - /* 80 */ "Sample Select", - /* 81 */ "Sample Start", - /* 82 */ "Sample Stop", - /* 83 */ "Sample Frequency", - /* 84 */ "Sample Volume", - /* 85 */ "Sample Loop", - /* 86 */ "Sample Position", - /* 87 */ "Reseved 87", - /* 88 */ "Reseved 88", - /* 89 */ "Reseved 89", - /* 90 */ "Reseved 90", - /* 91 */ "Reseved 91", - /* 92 */ "Reseved 92", - /* 93 */ "Reseved 93", - /* 94 */ "Reseved 94", - /* 95 */ "Reseved 95", - /* 96 */ "Reseved 96", - /* 97 */ "Reseved 97", - /* 98 */ "Reseved 98", - /* 99 */ "Reseved 99", - /* 100 */ "Reseved 100", - /* 101 */ "Reseved 101", - /* 102 */ "Reseved 102", - /* 103 */ "Reseved 103", - /* 104 */ "Reseved 104", - /* 105 */ "Reseved 105", - /* 106 */ "Reseved 106", - /* 107 */ "Reseved 107", - /* 108 */ "Reseved 108", - /* 109 */ "Reseved 109", - /* 100 */ "Reserved 100" - /* 101 */ "Reserved 101" - /* 102 */ "Reserved 102" - /* 103 */ "Reserved 103" - /* 104 */ "Reserved 104" - /* 105 */ "Reserved 105" - /* 106 */ "Reserved 106" - /* 107 */ "Reserved 107" - /* 108 */ "Reserved 108" - /* 109 */ "Reserved 109" - /* 110 */ "Reserved 110" - /* 111 */ "Reserved 111" - /* 112 */ "Reserved 112" - /* 113 */ "Reserved 113" - /* 114 */ "Reserved 114" - /* 115 */ "Reserved 115" - /* 116 */ "Reserved 116" - /* 117 */ "Reserved 117" - /* 118 */ "Reserved 118" - /* 119 */ "Reserved 119" - /* 120 */ "Reserved 120" - /* 121 */ "Reserved 121" - /* 122 */ "Reserved 122" - /* 123 */ "Reserved 123" - /* 124 */ "Reserved 124" - /* 125 */ "Reserved 125" - /* 126 */ "Reserved 126" - /* 127 */ "Reserved 127" - /* 128 */ "Reserved 128" - /* 129 */ "Reserved 129" - /* 130 */ "Reserved 130" - /* 131 */ "Reserved 131" - /* 132 */ "Reserved 132" - /* 133 */ "Reserved 133" - /* 134 */ "Reserved 134" - /* 135 */ "Reserved 135" - /* 136 */ "Reserved 136" - /* 137 */ "Reserved 137" - /* 138 */ "Reserved 138" - /* 139 */ "Reserved 139" - /* 140 */ "Reserved 140" - /* 141 */ "Reserved 141" - /* 142 */ "Reserved 142" - /* 143 */ "Reserved 143" - /* 144 */ "Reserved 144" - /* 145 */ "Reserved 145" - /* 146 */ "Reserved 146" - /* 147 */ "Reserved 147" - /* 148 */ "Reserved 148" - /* 149 */ "Reserved 149" - /* 150 */ "Reserved 150" - /* 151 */ "Reserved 151" - /* 152 */ "Reserved 152" - /* 153 */ "Reserved 153" - /* 154 */ "Reserved 154" - /* 155 */ "Reserved 155" - /* 156 */ "Reserved 156" - /* 157 */ "Reserved 157" - /* 158 */ "Reserved 158" - /* 159 */ "Reserved 159" - /* 160 */ "Reserved 160" - /* 161 */ "Reserved 161" - /* 162 */ "Reserved 162" - /* 163 */ "Reserved 163" - /* 164 */ "Reserved 164" - /* 165 */ "Reserved 165" - /* 166 */ "Reserved 166" - /* 167 */ "Reserved 167" - /* 168 */ "Reserved 168" - /* 169 */ "Reserved 169" - /* 170 */ "Reserved 170" - /* 171 */ "Reserved 171" - /* 172 */ "Reserved 172" - /* 173 */ "Reserved 173" - /* 174 */ "Reserved 174" - /* 175 */ "Reserved 175" - /* 176 */ "Reserved 176" - /* 177 */ "Reserved 177" - /* 178 */ "Reserved 178" - /* 179 */ "Reserved 179" - /* 180 */ "Reserved 180" - /* 181 */ "Reserved 181" - /* 182 */ "Reserved 182" - /* 183 */ "Reserved 183" - /* 184 */ "Reserved 184" - /* 185 */ "Reserved 185" - /* 186 */ "Reserved 186" - /* 187 */ "Reserved 187" - /* 188 */ "Reserved 188" - /* 189 */ "Reserved 189" - /* 190 */ "Reserved 190" - /* 191 */ "Reserved 191" - /* 192 */ "Reserved 192" - /* 193 */ "Reserved 193" - /* 194 */ "Reserved 194" - /* 195 */ "Reserved 195" - /* 196 */ "Reserved 196" - /* 197 */ "Reserved 197" - /* 198 */ "Reserved 198" - /* 199 */ "Reserved 199" - /* 200 */ "Reserved 200" - /* 201 */ "Reserved 201" - /* 202 */ "Reserved 202" - /* 203 */ "Reserved 203" - /* 204 */ "Reserved 204" - /* 205 */ "Reserved 205" - /* 206 */ "Reserved 206" - /* 207 */ "Reserved 207" - /* 208 */ "Reserved 208" - /* 209 */ "Reserved 209" - /* 210 */ "Reserved 210" - /* 211 */ "Reserved 211" - /* 212 */ "Reserved 212" - /* 213 */ "Reserved 213" - /* 214 */ "Reserved 214" - /* 215 */ "Reserved 215" - /* 216 */ "Reserved 216" - /* 217 */ "Reserved 217" - /* 218 */ "Reserved 218" - /* 219 */ "Reserved 219" - /* 220 */ "Reserved 220" - /* 221 */ "Reserved 221" - /* 222 */ "Reserved 222" - /* 223 */ "Reserved 223" - /* 224 */ "Reserved 224" - /* 225 */ "Reserved 225" - /* 226 */ "Reserved 226" - /* 227 */ "Reserved 227" - /* 228 */ "Reserved 228" - /* 229 */ "Reserved 229" - /* 230 */ "Reserved 230" - /* 231 */ "Reserved 231" - /* 232 */ "Reserved 232" - /* 233 */ "Reserved 233" - /* 234 */ "Reserved 234" - /* 235 */ "Reserved 235" - /* 236 */ "Reserved 236" - /* 237 */ "Reserved 237" - /* 238 */ "Reserved 238" - /* 239 */ "Reserved 239" - /* 240 */ "Reserved 240" - /* 241 */ "Reserved 241" - /* 242 */ "Reserved 242" - /* 243 */ "Reserved 243" - /* 244 */ "Reserved 244" - /* 245 */ "Reserved 245" - /* 246 */ "Reserved 246" - /* 247 */ "Reserved 247" - /* 248 */ "Reserved 248" - /* 249 */ "Reserved 249" - /* 250 */ "Reserved 250" - /* 251 */ "Reserved 251" - /* 252 */ "Reserved 252" - /* 253 */ "Reserved 253" - /* 254 */ "Reserved 254" - /* 255 */ "Reserved 255" + /* 80 */ "Reserved 80", + /* 81 */ "Reserved 81", + /* 82 */ "Reserved 82", + /* 83 */ "Reserved 83", + /* 84 */ "Reserved 84", + /* 85 */ "Reserved 85", + /* 86 */ "Reserved 86", + /* 87 */ "Reserved 87", + /* 88 */ "Reserved 88", + /* 89 */ "Reserved 89", + /* 90 */ "User 0", + /* 91 */ "User 1", + /* 92 */ "User 2", + /* 93 */ "User 3", + /* 94 */ "User 4", + /* 95 */ "User 5", + /* 96 */ "User 6", + /* 97 */ "User 7", + /* 98 */ "User 8", + /* 99 */ "User 9", + /* 100 */ "Instr Begin", + /* 101 */ "Instr End", + /* 102 */ "Instr Info", + /* 103 */ "Instr Info Result", + /* 104 */ "Instr Finfo", + /* 105 */ "Instr Finfo Result", + /* 106 */ "Instr Reset", + /* 107 */ "Instr Status", + /* 108 */ "Instr Status Result", + /* 109 */ "Instr Put", + /* 110 */ "Instr Get", + /* 111 */ "Instr Get Result", + /* 112 */ "Instr Free", + /* 113 */ "Instr List", + /* 114 */ "Instr List Result", + /* 115 */ "Instr Cluster", + /* 116 */ "Instr Cluster Get", + /* 117 */ "Instr Cluster Result", + /* 118 */ "Instr Change", + /* 119 */ "Reserved 119", + /* 120 */ "Reserved 120", + /* 121 */ "Reserved 121", + /* 122 */ "Reserved 122", + /* 123 */ "Reserved 123", + /* 124 */ "Reserved 124", + /* 125 */ "Reserved 125", + /* 126 */ "Reserved 126", + /* 127 */ "Reserved 127", + /* 128 */ "Reserved 128", + /* 129 */ "Reserved 129", + /* 130 */ "Sysex", + /* 131 */ "Bounce", + /* 132 */ "Reserved 132", + /* 133 */ "Reserved 133", + /* 134 */ "Reserved 134", + /* 135 */ "User Var0", + /* 136 */ "User Var1", + /* 137 */ "User Var2", + /* 138 */ "User Var3", + /* 139 */ "User Var4", + /* 140 */ "IPC Shm", + /* 141 */ "Reserved 141", + /* 142 */ "Reserved 142", + /* 143 */ "Reserved 143", + /* 144 */ "Reserved 144", + /* 145 */ "User IPC0", + /* 146 */ "User IPC1", + /* 147 */ "User IPC2", + /* 148 */ "User IPC3", + /* 149 */ "User IPC4", + /* 150 */ "Reserved 150", + /* 151 */ "Reserved 151", + /* 152 */ "Reserved 152", + /* 153 */ "Reserved 153", + /* 154 */ "Reserved 154", + /* 155 */ "Reserved 155", + /* 156 */ "Reserved 156", + /* 157 */ "Reserved 157", + /* 158 */ "Reserved 158", + /* 159 */ "Reserved 159", + /* 160 */ "Reserved 160", + /* 161 */ "Reserved 161", + /* 162 */ "Reserved 162", + /* 163 */ "Reserved 163", + /* 164 */ "Reserved 164", + /* 165 */ "Reserved 165", + /* 166 */ "Reserved 166", + /* 167 */ "Reserved 167", + /* 168 */ "Reserved 168", + /* 169 */ "Reserved 169", + /* 170 */ "Reserved 170", + /* 171 */ "Reserved 171", + /* 172 */ "Reserved 172", + /* 173 */ "Reserved 173", + /* 174 */ "Reserved 174", + /* 175 */ "Reserved 175", + /* 176 */ "Reserved 176", + /* 177 */ "Reserved 177", + /* 178 */ "Reserved 178", + /* 179 */ "Reserved 179", + /* 180 */ "Reserved 180", + /* 181 */ "Reserved 181", + /* 182 */ "Reserved 182", + /* 183 */ "Reserved 183", + /* 184 */ "Reserved 184", + /* 185 */ "Reserved 185", + /* 186 */ "Reserved 186", + /* 187 */ "Reserved 187", + /* 188 */ "Reserved 188", + /* 189 */ "Reserved 189", + /* 190 */ "Reserved 190", + /* 191 */ "Reserved 191", + /* 192 */ "Reserved 192", + /* 193 */ "Reserved 193", + /* 194 */ "Reserved 194", + /* 195 */ "Reserved 195", + /* 196 */ "Reserved 196", + /* 197 */ "Reserved 197", + /* 198 */ "Reserved 198", + /* 199 */ "Reserved 199", + /* 200 */ "Reserved 200", + /* 201 */ "Reserved 201", + /* 202 */ "Reserved 202", + /* 203 */ "Reserved 203", + /* 204 */ "Reserved 204", + /* 205 */ "Reserved 205", + /* 206 */ "Reserved 206", + /* 207 */ "Reserved 207", + /* 208 */ "Reserved 208", + /* 209 */ "Reserved 209", + /* 210 */ "Reserved 210", + /* 211 */ "Reserved 211", + /* 212 */ "Reserved 212", + /* 213 */ "Reserved 213", + /* 214 */ "Reserved 214", + /* 215 */ "Reserved 215", + /* 216 */ "Reserved 216", + /* 217 */ "Reserved 217", + /* 218 */ "Reserved 218", + /* 219 */ "Reserved 219", + /* 220 */ "Reserved 220", + /* 221 */ "Reserved 221", + /* 222 */ "Reserved 222", + /* 223 */ "Reserved 223", + /* 224 */ "Reserved 224", + /* 225 */ "Reserved 225", + /* 226 */ "Reserved 226", + /* 227 */ "Reserved 227", + /* 228 */ "Reserved 228", + /* 229 */ "Reserved 229", + /* 230 */ "Reserved 230", + /* 231 */ "Reserved 231", + /* 232 */ "Reserved 232", + /* 233 */ "Reserved 233", + /* 234 */ "Reserved 234", + /* 235 */ "Reserved 235", + /* 236 */ "Reserved 236", + /* 237 */ "Reserved 237", + /* 238 */ "Reserved 238", + /* 239 */ "Reserved 239", + /* 240 */ "Reserved 240", + /* 241 */ "Reserved 241", + /* 242 */ "Reserved 242", + /* 243 */ "Reserved 243", + /* 244 */ "Reserved 244", + /* 245 */ "Reserved 245", + /* 246 */ "Reserved 246", + /* 247 */ "Reserved 247", + /* 248 */ "Reserved 248", + /* 249 */ "Reserved 249", + /* 250 */ "Reserved 250", + /* 251 */ "Reserved 251", + /* 252 */ "Reserved 252", + /* 253 */ "Reserved 253", + /* 254 */ "Reserved 254", + /* 255 */ "None" }; int decode_event(snd_seq_event_t * ev) @@ -299,10 +289,11 @@ int decode_event(snd_seq_event_t * ev) /* decode actual event data... */ switch (ev->type) { case SND_SEQ_EVENT_NOTE: - printf("; ch=%d, note=%d, velocity=%d, duration=%d\n", + printf("; ch=%d, note=%d, velocity=%d, off_velocity=%d, duration=%d\n", ev->data.note.channel, ev->data.note.note, ev->data.note.velocity, + ev->data.note.off_velocity, ev->data.note.duration); break; @@ -384,6 +375,10 @@ int decode_event(snd_seq_event_t * ev) case SND_SEQ_EVENT_PORT_START: case SND_SEQ_EVENT_PORT_EXIT: case SND_SEQ_EVENT_PORT_CHANGE: + case SND_SEQ_EVENT_PORT_SUBSCRIBED: + case SND_SEQ_EVENT_PORT_USED: + case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: + case SND_SEQ_EVENT_PORT_UNUSED: printf("; client=%i, port = %i\n", ev->data.addr.client, ev->data.addr.port); break; @@ -437,6 +432,7 @@ void event_decoder(snd_seq_t *handle, int argc, char *argv[]) bzero(&port, sizeof(port)); strcpy(port.name, "Input"); port.capability = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ; + port.capability |= SND_SEQ_PORT_CAP_SUBS_WRITE; if ((err = snd_seq_create_port(handle, &port)) < 0) { fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err)); return; diff --git a/test/seq-sender.c b/test/seq-sender.c index 10dea180..0158df5e 100644 --- a/test/seq-sender.c +++ b/test/seq-sender.c @@ -83,9 +83,7 @@ void event_sender_start_timer(snd_seq_t *handle, int client, int queue, snd_pcm_ #endif if ((err = snd_seq_start_queue(handle, queue, NULL))<0) fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err)); - /* ugly, but working */ - while (snd_seq_flush_output(handle)>0) - sleep(1); + snd_seq_flush_output(handle); } void event_sender_filter(snd_seq_t *handle) @@ -123,6 +121,11 @@ void send_event(snd_seq_t *handle, int queue, int client, int port, fprintf(stderr, "Event output error: %s\n", snd_strerror(err)); ev.dest.client = sub->dest.client; ev.dest.port = sub->dest.port; + ev.type = SND_SEQ_EVENT_PGMCHANGE; + ev.data.control.channel = 0; + ev.data.control.value = 16; + if ((err = snd_seq_event_output(handle, &ev))<0) + fprintf(stderr, "Event output error: %s\n", snd_strerror(err)); ev.type = SND_SEQ_EVENT_NOTE; ev.data.note.channel = 0; ev.data.note.note = 64 + (queue*2); @@ -141,13 +144,13 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[]) snd_seq_port_info_t port; snd_seq_port_subscribe_t sub; fd_set out, in; - int client, queue, max, err, v1, v2, time = 0, first, pcm_flag = 0; + int client, queue, max, err, v1, v2, time = 0, pcm_flag = 0; char *ptr; snd_pcm_t *phandle = NULL; char *pbuf = NULL; if (argc < 1) { - fprintf(stderr, "Invalid destonation...\n"); + fprintf(stderr, "Invalid destination...\n"); return; } @@ -197,7 +200,7 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[]) } } - printf("Destonation client = %i, port = %i\n", sub.dest.client, sub.dest.port); + printf("Destination client = %i, port = %i\n", sub.dest.client, sub.dest.port); #ifdef USE_PCM if (pcm_flag) { @@ -217,13 +220,17 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[]) #endif event_sender_start_timer(handle, client, queue, phandle); - first = 1; + /* send the first event */ + send_event(handle, queue, client, port.port, &sub, &time); + while (1) { FD_ZERO(&out); FD_ZERO(&in); max = snd_seq_file_descriptor(handle); - FD_SET(snd_seq_file_descriptor(handle), &out); FD_SET(snd_seq_file_descriptor(handle), &in); + if (snd_seq_event_output_pending(handle)) { + FD_SET(snd_seq_file_descriptor(handle), &out); + } #ifdef USE_PCM if (phandle) { if (snd_pcm_file_descriptor(phandle) > max) @@ -241,12 +248,8 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[]) } } #endif - if (FD_ISSET(snd_seq_file_descriptor(handle), &out)) { - if (first) { - send_event(handle, queue, client, port.port, &sub, &time); - first = 0; - } - } + if (FD_ISSET(snd_seq_file_descriptor(handle), &out)) + snd_seq_flush_output(handle); if (FD_ISSET(snd_seq_file_descriptor(handle), &in)) { do { if ((err = snd_seq_event_input(handle, &ev))<0) -- 2.11.0