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