mirror of
https://gitee.com/openharmony/third_party_alsa-lib
synced 2024-11-30 11:10:49 +00:00
497 lines
13 KiB
C
497 lines
13 KiB
C
/*
|
|
* Simple event decoder
|
|
*/
|
|
|
|
static char *event_names[256] = {
|
|
/* 0 */ "System",
|
|
/* 1 */ "Result",
|
|
/* 2 */ "Reserved 2",
|
|
/* 3 */ "Reserved 3",
|
|
/* 4 */ "Reserved 4",
|
|
/* 5 */ "Note",
|
|
/* 6 */ "Note On",
|
|
/* 7 */ "Note Off",
|
|
/* 8 */ "Key Pressure",
|
|
/* 9 */ "Reserved 9",
|
|
/* 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 */ "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 */ "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 */ "Tune Request",
|
|
/* 41 */ "Reset",
|
|
/* 42 */ "Active Sensing",
|
|
/* 43 */ "Reserved 43",
|
|
/* 44 */ "Reserved 44",
|
|
/* 45 */ "Reserved 45",
|
|
/* 46 */ "Reserved 46",
|
|
/* 47 */ "Reserved 47",
|
|
/* 48 */ "Reserved 48",
|
|
/* 49 */ "Reserved 49",
|
|
/* 50 */ "Echo",
|
|
/* 51 */ "OSS",
|
|
/* 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 */ "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 */ "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)
|
|
{
|
|
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.time.tv_sec,
|
|
(int)ev->time.time.tv_nsec);
|
|
break;
|
|
}
|
|
printf("\n%sSource = %d.%d, dest = %d.%d, queue = %d\n",
|
|
space,
|
|
ev->source.client,
|
|
ev->source.port,
|
|
ev->dest.client,
|
|
ev->dest.port,
|
|
ev->queue);
|
|
|
|
printf("%sEvent = %s", space, event_names[ev->type]);
|
|
/* decode actual event data... */
|
|
switch (ev->type) {
|
|
case SND_SEQ_EVENT_NOTE:
|
|
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;
|
|
|
|
case SND_SEQ_EVENT_NOTEON:
|
|
case SND_SEQ_EVENT_NOTEOFF:
|
|
case SND_SEQ_EVENT_KEYPRESS:
|
|
printf("; ch=%d, note=%d, velocity=%d\n",
|
|
ev->data.note.channel,
|
|
ev->data.note.note,
|
|
ev->data.note.velocity);
|
|
break;
|
|
|
|
case SND_SEQ_EVENT_CONTROLLER:
|
|
printf("; ch=%d, param=%i, value=%i\n",
|
|
ev->data.control.channel,
|
|
ev->data.control.param,
|
|
ev->data.control.value);
|
|
break;
|
|
|
|
case SND_SEQ_EVENT_PGMCHANGE:
|
|
printf("; ch=%d, program=%i\n",
|
|
ev->data.control.channel,
|
|
ev->data.control.value);
|
|
break;
|
|
|
|
case SND_SEQ_EVENT_CHANPRESS:
|
|
case SND_SEQ_EVENT_PITCHBEND:
|
|
printf("; ch=%d, value=%i\n",
|
|
ev->data.control.channel,
|
|
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=0x%02x\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\n", ev->data.queue.queue);
|
|
break;
|
|
|
|
case SND_SEQ_EVENT_SENSING:
|
|
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:
|
|
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;
|
|
|
|
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(snd_seq_t *handle, int queue, int client, int port)
|
|
{
|
|
int err;
|
|
|
|
if ((err = snd_seq_start_queue(handle, queue, NULL))<0)
|
|
fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err));
|
|
while (snd_seq_drain_output(handle)>0)
|
|
sleep(1);
|
|
}
|
|
|
|
void event_decoder(snd_seq_t *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))<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");
|
|
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;
|
|
}
|
|
event_decoder_start_timer(handle, queue, client, port.port);
|
|
|
|
bzero(&sub, sizeof(sub));
|
|
sub.sender.client = SND_SEQ_CLIENT_SYSTEM;
|
|
sub.sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
|
|
sub.dest.client = client;
|
|
sub.dest.port = port.port;
|
|
sub.queue = queue;
|
|
sub.exclusive = 0;
|
|
sub.convert_time = 1;
|
|
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_poll_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);
|
|
}
|
|
}
|