Added sequencer test program..

This commit is contained in:
Jaroslav Kysela 1998-12-27 01:02:59 +00:00
parent 11eaf4d61b
commit 6f5e7d4d00
4 changed files with 884 additions and 2 deletions

View file

@ -1,4 +1,4 @@
check_PROGRAMS=control mixer switches pause pcm latency
check_PROGRAMS=control mixer switches pause pcm latency seq
control_LDADD=../src/libasound.la
mixer_LDADD=../src/libasound.la
@ -6,6 +6,8 @@ switches_LDADD=../src/libasound.la
pause_LDADD=../src/libasound.la
pcm_LDADD=../src/libasound.la
latency_LDADD=../src/libasound.la
seq_LDADD=../src/libasound.la
INCLUDES=-I$(top_srcdir)/include
CFLAGS=-static -Wall -pipe -g

505
test/seq-decoder.c Normal file
View file

@ -0,0 +1,505 @@
/*
* Simple event decoder
*/
static char *event_names[256] = {
/* 0 */ "System",
/* 1 */ "Note",
/* 2 */ "Note On",
/* 3 */ "Note Off",
/* 4 */ "Reserved 4",
/* 5 */ "Reserved 5",
/* 6 */ "Reserved 6",
/* 7 */ "Reserved 7",
/* 8 */ "Reserved 8",
/* 9 */ "Reserved 9",
/* 10 */ "KeyPress",
/* 11 */ "Controller",
/* 12 */ "Program Change",
/* 13 */ "Channel Pressure",
/* 14 */ "Pitchbend",
/* 15 */ "Control14",
/* 16 */ "Nonregparam",
/* 17 */ "Regparam",
/* 18 */ "Reserved 18",
/* 19 */ "Reserved 19",
/* 20 */ "Song Position",
/* 21 */ "Song Select",
/* 22 */ "Clock",
/* 23 */ "Start",
/* 24 */ "Continue",
/* 25 */ "Stop",
/* 26 */ "Qframe",
/* 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",
/* 38 */ "Reserved 38",
/* 39 */ "Reserved 39",
/* 40 */ "System Exclusive",
/* 41 */ "Heart Beat",
/* 42 */ "Reserved 42",
/* 43 */ "Reserved 43",
/* 44 */ "Reserved 44",
/* 45 */ "Reserved 45",
/* 46 */ "Reserved 46",
/* 47 */ "Reserved 47",
/* 48 */ "Reserved 48",
/* 49 */ "Reserved 49",
/* 50 */ "Heart Beat (Active sensing)",
/* 51 */ "Echo",
/* 52 */ "Reserved 52",
/* 53 */ "Reserved 53",
/* 54 */ "Reserved 54",
/* 55 */ "Reserved 55",
/* 56 */ "Reserved 56",
/* 57 */ "Reserved 57",
/* 58 */ "Reserved 58",
/* 59 */ "Reserved 59",
/* 60 */ "Client Start",
/* 61 */ "Client Exit",
/* 62 */ "Client Change",
/* 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",
/* 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"
};
int decode_event(snd_seq_event_t * ev)
{
char *space = " ";
printf("EVENT>>> Type = %d, flags = 0x%x", ev->type, ev->flags);
switch (ev->flags & SND_SEQ_TIME_STAMP_MASK) {
case SND_SEQ_TIME_STAMP_TICK:
printf(", time = %d ticks",
ev->time.tick);
break;
case SND_SEQ_TIME_STAMP_REAL:
printf(", time = %d.%09d",
(int)ev->time.real.tv_sec,
(int)ev->time.real.tv_nsec);
break;
}
printf("\n%sSource = %d.%d.%d.%d, dest = %d.%d.%d.%d\n",
space,
ev->source.queue,
ev->source.client,
ev->source.port,
ev->source.channel,
ev->dest.queue,
ev->dest.client,
ev->dest.port,
ev->dest.channel);
printf("%sEvent = %s", space, event_names[ev->type]);
/* decode actual event data... */
switch (ev->type) {
case SND_SEQ_EVENT_NOTE:
printf("; note=%d, velocity=%d, duration=%d\n",
ev->data.note.note,
ev->data.note.velocity,
ev->data.note.duration);
break;
case SND_SEQ_EVENT_NOTEON:
case SND_SEQ_EVENT_NOTEOFF:
printf("; note=%d, velocity=%d\n",
ev->data.note.note,
ev->data.note.velocity);
break;
case SND_SEQ_EVENT_KEYPRESS:
case SND_SEQ_EVENT_CONTROLLER:
printf("; param=%i, value=%i\n",
ev->data.control.param,
ev->data.control.value);
break;
case SND_SEQ_EVENT_PGMCHANGE:
printf("; program=%i\n", ev->data.control.value);
break;
case SND_SEQ_EVENT_CHANPRESS:
case SND_SEQ_EVENT_PITCHBEND:
printf("; value=%i\n", ev->data.control.value);
break;
case SND_SEQ_EVENT_SYSEX:
{
unsigned char *sysex = (unsigned char *) ev + sizeof(snd_seq_event_t);
int c;
printf("; len=%d [", ev->data.ext.len);
for (c = 0; c < ev->data.ext.len; c++) {
printf("%02x%s", sysex[c], c < ev->data.ext.len - 1 ? ":" : "");
}
printf("]\n");
}
break;
case SND_SEQ_EVENT_QFRAME:
printf("; frame=%i\n", ev->data.control.value);
break;
case SND_SEQ_EVENT_CLOCK:
case SND_SEQ_EVENT_START:
case SND_SEQ_EVENT_CONTINUE:
case SND_SEQ_EVENT_STOP:
printf("; queue = %i, client = %i\n", ev->data.addr.queue, ev->data.addr.client);
break;
case SND_SEQ_EVENT_HEARTBEAT:
printf("\n");
break;
case SND_SEQ_EVENT_ECHO:
{
int i;
printf("; ");
for (i = 0; i < 8; i++) {
printf("%02i%s", ev->data.raw8.d[i], i < 7 ? ":" : "\n");
}
}
break;
case SND_SEQ_EVENT_CLIENT_START:
case SND_SEQ_EVENT_CLIENT_EXIT:
case SND_SEQ_EVENT_CLIENT_CHANGE:
printf("; client=%i\n", ev->data.addr.client);
break;
case SND_SEQ_EVENT_PORT_START:
case SND_SEQ_EVENT_PORT_EXIT:
case SND_SEQ_EVENT_PORT_CHANGE:
printf("; client=%i, port = %i\n", ev->data.addr.client, ev->data.addr.port);
break;
default:
printf("; not implemented\n");
}
switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) {
case SND_SEQ_EVENT_LENGTH_FIXED:
return sizeof(snd_seq_event_t);
case SND_SEQ_EVENT_LENGTH_VARIABLE:
return sizeof(snd_seq_event_t) + ev->data.ext.len;
}
return 0;
}
void event_decoder_start_timer(void *handle, int queue, int client, int port)
{
int err;
snd_seq_event_t ev;
bzero(&ev, sizeof(ev));
ev.source.queue = queue;
ev.source.client = client;
ev.source.port = 0;
ev.dest.queue = queue;
ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_REL;
ev.type = SND_SEQ_EVENT_START;
if ((err = snd_seq_event_output(handle, &ev))<0)
fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err));
while (snd_seq_flush_output(handle)>0)
sleep(1);
}
void event_decoder(void *handle, int argc, char *argv[])
{
snd_seq_event_t *ev;
snd_seq_port_info_t port;
snd_seq_port_subscribe_t sub;
fd_set in;
int client, queue, max, err, v1, v2;
char *ptr;
if ((client = snd_seq_client_id(handle))<0) {
fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client));
return;
}
printf("Client ID = %i\n", client);
if ((queue = snd_seq_alloc_queue(handle, NULL))<0) {
fprintf(stderr, "Cannot allocate queue: %s\n", snd_strerror(queue));
return;
}
printf("Queue ID = %i\n", queue);
if ((err = snd_seq_block_mode(handle, 0))<0)
fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err));
bzero(&port, sizeof(port));
strcpy(port.name, "Input");
if ((err = snd_seq_create_port(handle, &port)) < 0) {
fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err));
return;
}
event_decoder_start_timer(handle, queue, client, port.port);
bzero(&sub, sizeof(sub));
sub.sender.queue = queue;
sub.sender.client = SND_SEQ_CLIENT_SYSTEM;
sub.sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
sub.dest.queue = queue;
sub.dest.client = client;
sub.dest.port = port.port;
sub.exclusive = 0;
sub.realtime = 1;
if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
fprintf(stderr, "Cannot subscribe announce port: %s\n", snd_strerror(err));
return;
}
sub.sender.port = SND_SEQ_PORT_SYSTEM_TIMER;
if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
fprintf(stderr, "Cannot subscribe timer port: %s\n", snd_strerror(err));
return;
}
for (max = 0; max < argc; max++) {
ptr = argv[max];
if (!ptr)
continue;
sub.realtime = 0;
if (tolower(*ptr) == 'r') {
sub.realtime = 1;
ptr++;
}
if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) {
fprintf(stderr, "Wrong argument '%s'...\n", argv[max]);
return;
}
sub.sender.client = v1;
sub.sender.port = v2;
if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err));
return;
}
}
while (1) {
FD_ZERO(&in);
FD_SET(max = snd_seq_file_descriptor(handle), &in);
if (select(max + 1, &in, NULL, NULL, NULL) < 0)
break;
do {
if ((err = snd_seq_event_input(handle, &ev))<0)
break;
if (!ev)
continue;
decode_event(ev);
snd_seq_free_event(ev);
} while (err > 0);
}
}

152
test/seq-sender.c Normal file
View file

@ -0,0 +1,152 @@
/*
* Simple event sender
*/
void event_sender_start_timer(void *handle, int client, int queue)
{
int err;
snd_seq_event_t ev;
bzero(&ev, sizeof(ev));
ev.source.queue = queue;
ev.source.client = client;
ev.source.port = 0;
ev.dest.queue = queue;
ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_REL;
ev.type = SND_SEQ_EVENT_START;
if ((err = snd_seq_event_output(handle, &ev))<0)
fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err));
while (snd_seq_flush_output(handle)>0)
sleep(1);
}
void event_sender_filter(void *handle)
{
int err;
snd_seq_client_info_t info;
if ((err = snd_seq_get_client_info(handle, &info)) < 0) {
fprintf(stderr, "Unable to get client info: %s\n", snd_strerror(err));
return;
}
info.filter = SND_SEQ_FILTER_USE_EVENT;
memset(&info.event_filter, 0, sizeof(info.event_filter));
snd_seq_set_bit(SND_SEQ_EVENT_ECHO, info.event_filter);
if ((err = snd_seq_set_client_info(handle, &info)) < 0) {
fprintf(stderr, "Unable to set client info: %s\n", snd_strerror(err));
return;
}
}
void send_event(void *handle, int queue, int client, int port,
snd_seq_port_subscribe_t *sub, int *time)
{
int err;
snd_seq_event_t ev;
bzero(&ev, sizeof(ev));
ev.source.queue = ev.dest.queue = queue;
ev.source.client = ev.dest.client = client;
ev.source.port = ev.dest.port = port;
ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_ABS;
ev.time.real.tv_sec = *time; (*time)++;
ev.type = SND_SEQ_EVENT_ECHO;
if ((err = snd_seq_event_output(handle, &ev))<0)
fprintf(stderr, "Event output error: %s\n", snd_strerror(err));
ev.dest.client = sub->dest.client;
ev.dest.port = sub->dest.port;
ev.dest.channel = 0;
ev.type = SND_SEQ_EVENT_NOTE;
ev.data.note.note = 64 + (queue*2);
ev.data.note.velocity = 127;
ev.data.note.duration = 500; /* 0.5sec */
if ((err = snd_seq_event_output(handle, &ev))<0)
fprintf(stderr, "Event output error: %s\n", snd_strerror(err));
if ((err = snd_seq_flush_output(handle))<0)
fprintf(stderr, "Event flush error: %s\n", snd_strerror(err));
}
void event_sender(void *handle, int argc, char *argv[])
{
snd_seq_event_t *ev;
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;
char *ptr;
if (argc != 1) {
fprintf(stderr, "Invalid destonation...\n");
return;
}
if ((client = snd_seq_client_id(handle))<0) {
fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client));
return;
}
printf("Client ID = %i\n", client);
if ((queue = snd_seq_alloc_queue(handle, NULL))<0) {
fprintf(stderr, "Cannot allocate queue: %s\n", snd_strerror(queue));
return;
}
printf("Queue ID = %i\n", queue);
event_sender_filter(handle);
if ((err = snd_seq_block_mode(handle, 0))<0)
fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err));
event_sender_start_timer(handle, client, queue);
bzero(&port, sizeof(port));
strcpy(port.name, "Output");
if ((err = snd_seq_create_port(handle, &port)) < 0) {
fprintf(stderr, "Cannot create output port: %s\n", snd_strerror(err));
return;
}
bzero(&sub, sizeof(sub));
sub.sender.queue = queue;
sub.sender.client = client;
sub.sender.port = port.port;
sub.dest.queue = queue;
sub.exclusive = 0;
for (max = 0; max < argc; max++) {
ptr = argv[max];
if (!ptr)
continue;
if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) {
fprintf(stderr, "Wrong argument '%s'...\n", argv[max]);
return;
}
sub.dest.client = v1;
sub.dest.port = v2;
if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err));
return;
}
}
printf("Destonation client = %i, port = %i\n", sub.dest.client, sub.dest.port);
while (1) {
FD_ZERO(&out);
FD_ZERO(&in);
FD_SET(max = snd_seq_file_descriptor(handle), &out);
FD_SET(max = snd_seq_file_descriptor(handle), &in);
if (select(max + 1, &in, &out, NULL, NULL) < 0)
break;
if (FD_ISSET(max, &out)) {
send_event(handle, queue, client, port.port, &sub, &time);
}
if (FD_ISSET(max, &in)) {
do {
if ((err = snd_seq_event_input(handle, &ev))<0)
break;
if (!ev)
continue;
decode_event(ev);
snd_seq_free_event(ev);
} while (err > 0);
}
}
}

223
test/seq.c Normal file
View file

@ -0,0 +1,223 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <getopt.h>
#include "../include/asoundlib.h"
#include "seq-decoder.c"
#include "seq-sender.c"
#define SEQ_VERSION "0.0.1"
#define HELPID_HELP 1000
#define HELPID_DEBUG 1001
#define HELPID_VERBOSE 1002
#define HELPID_VERSION 1003
snd_seq_system_info_t sysinfo;
int debug = 0;
int verbose = 0;
void set_name(void *handle)
{
int err;
snd_seq_client_info_t info;
bzero(&info, sizeof(info));
snprintf(info.name, sizeof(info.name), "SeqUtil - %i", getpid());
if ((err = snd_seq_set_client_info(handle, &info)) < 0) {
fprintf(stderr, "Set client info error: %s\n", snd_strerror(err));
exit(0);
}
}
void system_info(void *handle)
{
int err;
if ((err = snd_seq_system_info(handle, &sysinfo))<0) {
fprintf(stderr, "System info error: %s\n", snd_strerror(err));
exit(0);
}
}
void show_system_info(void *handle)
{
printf("System info\n");
printf(" Max queues : %i\n", sysinfo.queues);
printf(" Max clients : %i\n", sysinfo.clients);
printf(" Max ports : %i\n", sysinfo.ports);
}
void show_queue_info(void *handle, int queue)
{
int err, idx, min, max;
snd_seq_queue_info_t info;
min = queue < 0 ? 0 : queue;
max = queue < 0 ? sysinfo.queues : queue + 1;
for (idx = min; idx < max; idx++) {
if ((err = snd_seq_get_queue_info(handle, idx, &info))<0) {
if (err == -ENOENT)
continue;
fprintf(stderr, "Client %i info error: %s\n", idx, snd_strerror(err));
exit(0);
}
printf("Queue %i info\n", info.queue);
printf(" Tick : %u\n", info.tick);
printf(" Realtime : %i.%i\n", info.time.tv_sec, info.time.tv_nsec);
printf(" Running : %i\n", info.running);
printf(" Tempo : %i\n", info.tempo);
printf(" PPQ : %i\n", info.ppq);
printf(" Flags : 0x%x\n", info.flags);
printf(" Owner : %i\n", info.owner);
printf(" Locked : %i\n", info.locked);
}
}
void show_port_info(void *handle, int client, int port)
{
int err, idx, min, max;
snd_seq_port_info_t info;
min = port < 0 ? 0 : port;
max = port < 0 ? sysinfo.ports : port + 1;
for (idx = min; idx < max; idx++) {
if ((err = snd_seq_get_any_port_info(handle, client, idx, &info))<0) {
if (err == -ENOENT)
continue;
fprintf(stderr, "Port %i/%i info error: %s\n", client, idx, snd_strerror(err));
exit(0);
}
printf(" Port %i info\n", idx);
printf(" Client : %i\n", info.client);
printf(" Port : %i\n", info.port);
printf(" Name : %s\n", info.name);
printf(" Capability : 0x%x\n", info.capability);
printf(" Type : 0x%x\n", info.type);
printf(" Midi channels : %i\n", info.midi_channels);
printf(" Synth voices : %i\n", info.synth_voices);
printf(" Subscribers : %i\n", info.subscribers);
printf(" Use : %i\n", info.use);
}
}
void show_client_info(void *handle, int client)
{
int err, idx, min, max;
snd_seq_client_info_t info;
min = client < 0 ? 0 : client;
max = client < 0 ? sysinfo.clients : client + 1;
for (idx = min; idx < max; idx++) {
if ((err = snd_seq_get_any_client_info(handle, idx, &info))<0) {
if (err == -ENOENT)
continue;
fprintf(stderr, "Client %i info error: %s\n", idx, snd_strerror(err));
exit(0);
}
printf("Client %i info\n", idx);
if (verbose)
printf(" Client : %i\n", info.client);
printf(" Type : %s\n", info.type == KERNEL_CLIENT ? "kernel" : "user");
printf(" Name : %s\n", info.name);
}
}
static void help(void)
{
printf("Usage: seq <options> command\n");
printf("\nAvailable options:\n");
printf(" -h,--help this help\n");
printf(" -d,--debug debug mode\n");
printf(" -v,--verbose verbose mode\n");
printf(" -V,--version print version of this program\n");
printf("\nAvailable commands:\n");
printf(" system show basic sequencer info\n");
printf(" queue [#] show all queues or specified queue\n");
printf(" client [#] show all clients or specified client\n");
printf(" port <client> [#] show all ports or specified port for specified client\n");
printf(" decoder event decoder\n");
}
int main(int argc, char *argv[])
{
int morehelp, err, arg, arg1;
void *handle;
static struct option long_option[] =
{
{"help", 0, NULL, HELPID_HELP},
{"debug", 0, NULL, HELPID_DEBUG},
{"verbose", 0, NULL, HELPID_VERBOSE},
{"version", 0, NULL, HELPID_VERSION},
{NULL, 0, NULL, 0},
};
while (1) {
int c;
if ((c = getopt_long(argc, argv, "hdvV", long_option, NULL)) < 0)
break;
switch (c) {
case 'h':
case HELPID_HELP:
morehelp++;
break;
case 'd':
case HELPID_DEBUG:
debug = 1;
break;
case 'v':
case HELPID_VERBOSE:
verbose = 1;
break;
case 'V':
case HELPID_VERSION:
printf("alsactl version " SEQ_VERSION "\n");
return 1;
default:
fprintf(stderr, "\07Invalid switch or option needs an argument.\n");
morehelp++;
}
}
if (morehelp) {
help();
return 1;
}
if (argc - optind <= 0) {
fprintf(stderr, "seq: Specify command...\n");
return 0;
}
if ((err = snd_seq_open(&handle, SND_SEQ_OPEN))<0) {
fprintf(stderr, "Open error: %s\n", snd_strerror(err));
exit(0);
}
set_name(handle);
system_info(handle);
if (!strcmp(argv[optind], "system")) {
show_system_info(handle);
} else if (!strcmp(argv[optind], "queue")) {
arg = argc - optind > 1 ? atoi(argv[optind + 1]) : -1;
show_queue_info(handle, arg);
} else if (!strcmp(argv[optind], "client")) {
arg = argc - optind > 1 ? atoi(argv[optind + 1]) : -1;
show_client_info(handle, arg);
} else if (!strcmp(argv[optind], "port")) {
arg = argc - optind > 1 ? atoi(argv[optind + 1]) : -1;
if (arg < 0) {
fprintf(stderr, "Specify port...\n");
exit(0);
}
arg1 = argc - optind > 2 ? atoi(argv[optind + 2]) : -1;
show_port_info(handle, arg, arg1);
} else if (!strcmp(argv[optind], "decoder")) {
event_decoder(handle, argc - optind - 1, argv + optind + 1);
} else if (!strcmp(argv[optind], "sender")) {
event_sender(handle, argc - optind - 1, argv + optind + 1);
} else {
help();
}
exit(1);
}