1 #include "config.h"
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <ctype.h>
8 #include <getopt.h>
9 #include "../include/asoundlib.h"
10 
11 #include "seq-decoder.c"
12 #include "seq-sender.c"
13 
14 #define SEQ_VERSION "0.0.1"
15 
16 #define HELPID_HELP             1000
17 #define HELPID_DEBUG            1001
18 #define HELPID_VERBOSE		1002
19 #define HELPID_VERSION          1003
20 
21 int max_clients;
22 int max_ports;
23 int max_queues;
24 int debug = 0;
25 int verbose = 0;
26 
set_name(snd_seq_t *handle)27 void set_name(snd_seq_t *handle)
28 {
29 	int err;
30 	char name[64];
31 
32 	sprintf(name, "SeqUtil - %i", getpid());
33 	if ((err = snd_seq_set_client_name(handle, name)) < 0) {
34 		fprintf(stderr, "Set client info error: %s\n", snd_strerror(err));
35 		exit(0);
36 	}
37 }
38 
system_info(snd_seq_t *handle)39 void system_info(snd_seq_t *handle)
40 {
41 	int err;
42 	snd_seq_system_info_t *sysinfo;
43 
44 	snd_seq_system_info_alloca(&sysinfo);
45 	if ((err = snd_seq_system_info(handle, sysinfo))<0) {
46 		fprintf(stderr, "System info error: %s\n", snd_strerror(err));
47 		exit(0);
48 	}
49 	max_clients = snd_seq_system_info_get_clients(sysinfo);
50 	max_ports = snd_seq_system_info_get_ports(sysinfo);
51 	max_queues = snd_seq_system_info_get_ports(sysinfo);
52 }
53 
show_system_info(snd_seq_t *handle ATTRIBUTE_UNUSED)54 void show_system_info(snd_seq_t *handle ATTRIBUTE_UNUSED)
55 {
56 	printf("System info\n");
57 	printf("  Max queues    : %i\n", max_queues);
58 	printf("  Max clients   : %i\n", max_clients);
59 	printf("  Max ports     : %i\n", max_ports);
60 }
61 
show_queue_status(snd_seq_t *handle, int queue)62 void show_queue_status(snd_seq_t *handle, int queue)
63 {
64 	int err, idx, min, max;
65 	snd_seq_queue_status_t *status;
66 
67 	snd_seq_queue_status_alloca(&status);
68 	min = queue < 0 ? 0 : queue;
69 	max = queue < 0 ? max_queues : queue + 1;
70 	for (idx = min; idx < max; idx++) {
71 		if ((err = snd_seq_get_queue_status(handle, idx, status))<0) {
72 			if (err == -ENOENT)
73 				continue;
74 			fprintf(stderr, "Client %i info error: %s\n", idx, snd_strerror(err));
75 			exit(0);
76 		}
77 		printf("Queue %i info\n", snd_seq_queue_status_get_queue(status));
78 		printf("  Tick          : %u\n", snd_seq_queue_status_get_tick_time(status));
79 		printf("  Realtime      : %i.%i\n",
80 		       snd_seq_queue_status_get_real_time(status)->tv_sec,
81 		       snd_seq_queue_status_get_real_time(status)->tv_nsec);
82 		printf("  Flags         : 0x%x\n", snd_seq_queue_status_get_status(status));
83 	}
84 }
85 
show_port_info(snd_seq_t *handle, int client, int port)86 void show_port_info(snd_seq_t *handle, int client, int port)
87 {
88 	int err, idx, min, max;
89 	snd_seq_port_info_t *info;
90 
91 	snd_seq_port_info_alloca(&info);
92 	min = port < 0 ? 0 : port;
93 	max = port < 0 ? max_ports : port + 1;
94 	for (idx = min; idx < max; idx++) {
95 		if ((err = snd_seq_get_any_port_info(handle, client, idx, info))<0) {
96 			if (err == -ENOENT)
97 				continue;
98 			fprintf(stderr, "Port %i/%i info error: %s\n", client, idx, snd_strerror(err));
99 			exit(0);
100 		}
101 		printf("  Port %i info\n", idx);
102 		printf("    Client        : %i\n", snd_seq_port_info_get_client(info));
103 		printf("    Port          : %i\n", snd_seq_port_info_get_port(info));
104 		printf("    Name          : %s\n", snd_seq_port_info_get_name(info));
105 		printf("    Capability    : 0x%x\n", snd_seq_port_info_get_capability(info));
106 		printf("    Type          : 0x%x\n", snd_seq_port_info_get_type(info));
107 		//printf("    Midi channels : %i\n", info.midi_channels);
108 		//printf("    Synth voices  : %i\n", info.synth_voices);
109 		printf("    Output subs   : %i\n", snd_seq_port_info_get_write_use(info));
110 		printf("    Input subs    : %i\n", snd_seq_port_info_get_read_use(info));
111 	}
112 }
113 
show_client_info(snd_seq_t *handle, int client)114 void show_client_info(snd_seq_t *handle, int client)
115 {
116 	int err, idx, min, max;
117 	snd_seq_client_info_t *info;
118 
119 	snd_seq_client_info_alloca(&info);
120 	min = client < 0 ? 0 : client;
121 	max = client < 0 ? max_clients : client + 1;
122 	for (idx = min; idx < max; idx++) {
123 		if ((err = snd_seq_get_any_client_info(handle, idx, info))<0) {
124 			if (err == -ENOENT)
125 				continue;
126 			fprintf(stderr, "Client %i info error: %s\n", idx, snd_strerror(err));
127 			exit(0);
128 		}
129 		printf("Client %i info\n", idx);
130 		if (verbose)
131 			printf("  Client        : %i\n", snd_seq_client_info_get_client(info));
132 		printf("  Type          : %s\n", snd_seq_client_info_get_type(info) == SND_SEQ_KERNEL_CLIENT ? "kernel" : "user");
133 		printf("  Name          : %s\n", snd_seq_client_info_get_name(info));
134 	}
135 }
136 
help(void)137 static void help(void)
138 {
139 	printf("Usage: seq <options> command\n");
140 	printf("\nAvailable options:\n");
141 	printf("  -h,--help       this help\n");
142 	printf("  -d,--debug      debug mode\n");
143 	printf("  -v,--verbose    verbose mode\n");
144 	printf("  -V,--version    print version of this program\n");
145 	printf("\nAvailable commands:\n");
146 	printf("  system          show basic sequencer info\n");
147 	printf("  queue [#]       show all queues or specified queue\n");
148 	printf("  client [#]      show all clients or specified client\n");
149 	printf("  port <client> [#]  show all ports or specified port for specified client\n");
150 	printf("  decoder         event decoder\n");
151 	printf("  sender <client.port> [<client.port>] ...   event sender\n");
152 }
153 
main(int argc, char *argv[])154 int main(int argc, char *argv[])
155 {
156 	int morehelp, err, arg, arg1;
157 	snd_seq_t *handle;
158 	static struct option long_option[] =
159 	{
160 		{"help", 0, NULL, HELPID_HELP},
161 		{"debug", 0, NULL, HELPID_DEBUG},
162 		{"verbose", 0, NULL, HELPID_VERBOSE},
163 		{"version", 0, NULL, HELPID_VERSION},
164 		{NULL, 0, NULL, 0},
165         };
166 
167         morehelp = 0;
168 
169 	while (1) {
170 		int c;
171 
172 		if ((c = getopt_long(argc, argv, "hdvV", long_option, NULL)) < 0)
173 			break;
174 		switch (c) {
175 		case 'h':
176 		case HELPID_HELP:
177 			morehelp++;
178 			break;
179 		case 'd':
180 		case HELPID_DEBUG:
181 			debug = 1;
182 			break;
183 		case 'v':
184 		case HELPID_VERBOSE:
185 			verbose = 1;
186 			break;
187 		case 'V':
188 		case HELPID_VERSION:
189 			printf("alsactl version " SEQ_VERSION "\n");
190 			return 1;
191 		default:
192 			fprintf(stderr, "\07Invalid switch or option needs an argument.\n");
193 			morehelp++;
194 		}
195 	}
196         if (morehelp) {
197                 help();
198                 return 1;
199         }
200 	if (argc - optind <= 0) {
201 		fprintf(stderr, "seq: Specify command...\n");
202 		return 0;
203 	}
204 	if ((err = snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0))<0) {
205 		fprintf(stderr, "Open error: %s\n", snd_strerror(err));
206 		exit(0);
207 	}
208 	set_name(handle);
209 	system_info(handle);
210 
211         if (!strcmp(argv[optind], "system")) {
212 		show_system_info(handle);
213 	} else if (!strcmp(argv[optind], "queue")) {
214 		arg = argc - optind > 1 ? atoi(argv[optind + 1]) : -1;
215 		show_queue_status(handle, arg);
216 	} else if (!strcmp(argv[optind], "client")) {
217 		arg = argc - optind > 1 ? atoi(argv[optind + 1]) : -1;
218 		show_client_info(handle, arg);
219 	} else if (!strcmp(argv[optind], "port")) {
220 		arg = argc - optind > 1 ? atoi(argv[optind + 1]) : -1;
221 		if (arg < 0) {
222 			fprintf(stderr, "Specify port...\n");
223 			exit(0);
224 		}
225 		arg1 = argc - optind > 2 ? atoi(argv[optind + 2]) : -1;
226 		show_port_info(handle, arg, arg1);
227 	} else if (!strcmp(argv[optind], "decoder")) {
228 		event_decoder(handle, argc - optind - 1, argv + optind + 1);
229 	} else if (!strcmp(argv[optind], "sender")) {
230 		event_sender(handle, argc - optind - 1, argv + optind + 1);
231 	} else {
232 		help();
233 	}
234 	exit(1);
235 }
236