1d5ac70f0Sopenharmony_ci/* 2d5ac70f0Sopenharmony_ci * Simple event decoder 3d5ac70f0Sopenharmony_ci */ 4d5ac70f0Sopenharmony_ci 5d5ac70f0Sopenharmony_cistatic char *event_names[256] = { 6d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SYSTEM]= "System", 7d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_RESULT]= "Result", 8d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_NOTE]= "Note", 9d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_NOTEON]= "Note On", 10d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_NOTEOFF]= "Note Off", 11d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_KEYPRESS]= "Key Pressure", 12d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CONTROLLER]= "Controller", 13d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PGMCHANGE]= "Program Change", 14d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CHANPRESS]= "Channel Pressure", 15d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PITCHBEND]= "Pitchbend", 16d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CONTROL14]= "Control14", 17d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_NONREGPARAM]= "Nonregparam", 18d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_REGPARAM]= "Regparam", 19d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SONGPOS]= "Song Position", 20d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SONGSEL]= "Song Select", 21d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_QFRAME]= "Qframe", 22d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_TIMESIGN]= "SMF Time Signature", 23d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_KEYSIGN]= "SMF Key Signature", 24d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_START]= "Start", 25d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CONTINUE]= "Continue", 26d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_STOP]= "Stop", 27d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SETPOS_TICK]= "Set Position Tick", 28d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SETPOS_TIME]= "Set Position Time", 29d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_TEMPO]= "Tempo", 30d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CLOCK]= "Clock", 31d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_TICK]= "Tick", 32d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_TUNE_REQUEST]= "Tune Request", 33d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_RESET]= "Reset", 34d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SENSING]= "Active Sensing", 35d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_ECHO]= "Echo", 36d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_OSS]= "OSS", 37d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CLIENT_START]= "Client Start", 38d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CLIENT_EXIT]= "Client Exit", 39d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_CLIENT_CHANGE]= "Client Change", 40d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PORT_START]= "Port Start", 41d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PORT_EXIT]= "Port Exit", 42d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PORT_CHANGE]= "Port Change", 43d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PORT_SUBSCRIBED]= "Port Subscribed", 44d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_PORT_UNSUBSCRIBED]= "Port Unsubscribed", 45d5ac70f0Sopenharmony_ci#if 0 46d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE]= "Sample", 47d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_CLUSTER]= "Sample Cluster", 48d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_START]= "Sample Start", 49d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_STOP]= "Sample Stop", 50d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_FREQ]= "Sample Freq", 51d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_VOLUME]= "Sample Volume", 52d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_LOOP]= "Sample Loop", 53d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_POSITION]= "Sample Position", 54d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SAMPLE_PRIVATE1]= "Sample Private1", 55d5ac70f0Sopenharmony_ci#endif 56d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR0]= "User 0", 57d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR1]= "User 1", 58d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR2]= "User 2", 59d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR3]= "User 3", 60d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR4]= "User 4", 61d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR5]= "User 5", 62d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR6]= "User 6", 63d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR7]= "User 7", 64d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR8]= "User 8", 65d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR9]= "User 9", 66d5ac70f0Sopenharmony_ci#if 0 67d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_BEGIN]= "Instr Begin", 68d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_END]= "Instr End", 69d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_INFO]= "Instr Info", 70d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_INFO_RESULT]= "Instr Info Result", 71d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_FINFO]= "Instr Font Info", 72d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_FINFO_RESULT]= "Instr Font Info Result", 73d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_RESET]= "Instr Reset", 74d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_STATUS]= "Instr Status", 75d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_STATUS_RESULT]= "Instr Status Result", 76d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_PUT]= "Instr Put", 77d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_GET]= "Instr Get", 78d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_GET_RESULT]= "Instr Get Result", 79d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_FREE]= "Instr Free", 80d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_LIST]= "Instr List", 81d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_LIST_RESULT]= "Instr List Result", 82d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_CLUSTER]= "Instr Cluster", 83d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_CLUSTER_GET]= "Instr Cluster Get", 84d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_CLUSTER_RESULT]= "Instr Cluster Result", 85d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_INSTR_CHANGE]= "Instr Change", 86d5ac70f0Sopenharmony_ci#endif 87d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_SYSEX]= "Sysex", 88d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_BOUNCE]= "Bounce", 89d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VAR0]= "User Var0", 90d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VAR1]= "User Var1", 91d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VAR2]= "User Var2", 92d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VAR3]= "User Var3", 93d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VAR4]= "User Var4", 94d5ac70f0Sopenharmony_ci#if 0 95d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_IPCSHM]= "IPC Shm", 96d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VARIPC0]= "User IPC0", 97d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VARIPC1]= "User IPC1", 98d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VARIPC2]= "User IPC2", 99d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VARIPC3]= "User IPC3", 100d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_USR_VARIPC4]= "User IPC4", 101d5ac70f0Sopenharmony_ci#endif 102d5ac70f0Sopenharmony_ci [SND_SEQ_EVENT_NONE]= "None", 103d5ac70f0Sopenharmony_ci}; 104d5ac70f0Sopenharmony_ci 105d5ac70f0Sopenharmony_ciint decode_event(snd_seq_event_t * ev) 106d5ac70f0Sopenharmony_ci{ 107d5ac70f0Sopenharmony_ci char *space = " "; 108d5ac70f0Sopenharmony_ci 109d5ac70f0Sopenharmony_ci printf("EVENT>>> Type = %d, flags = 0x%x", ev->type, ev->flags); 110d5ac70f0Sopenharmony_ci switch (ev->flags & SND_SEQ_TIME_STAMP_MASK) { 111d5ac70f0Sopenharmony_ci case SND_SEQ_TIME_STAMP_TICK: 112d5ac70f0Sopenharmony_ci printf(", time = %d ticks", 113d5ac70f0Sopenharmony_ci ev->time.tick); 114d5ac70f0Sopenharmony_ci break; 115d5ac70f0Sopenharmony_ci case SND_SEQ_TIME_STAMP_REAL: 116d5ac70f0Sopenharmony_ci printf(", time = %d.%09d", 117d5ac70f0Sopenharmony_ci (int)ev->time.time.tv_sec, 118d5ac70f0Sopenharmony_ci (int)ev->time.time.tv_nsec); 119d5ac70f0Sopenharmony_ci break; 120d5ac70f0Sopenharmony_ci } 121d5ac70f0Sopenharmony_ci printf("\n%sSource = %d.%d, dest = %d.%d, queue = %d\n", 122d5ac70f0Sopenharmony_ci space, 123d5ac70f0Sopenharmony_ci ev->source.client, 124d5ac70f0Sopenharmony_ci ev->source.port, 125d5ac70f0Sopenharmony_ci ev->dest.client, 126d5ac70f0Sopenharmony_ci ev->dest.port, 127d5ac70f0Sopenharmony_ci ev->queue); 128d5ac70f0Sopenharmony_ci 129d5ac70f0Sopenharmony_ci if (event_names[ev->type]) 130d5ac70f0Sopenharmony_ci printf("%sEvent = %s", space, event_names[ev->type]); 131d5ac70f0Sopenharmony_ci else 132d5ac70f0Sopenharmony_ci printf("%sEvent = Reserved %d\n", space, ev->type); 133d5ac70f0Sopenharmony_ci /* decode the actual event data... */ 134d5ac70f0Sopenharmony_ci switch (ev->type) { 135d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_NOTE: 136d5ac70f0Sopenharmony_ci printf("; ch=%d, note=%d, velocity=%d, off_velocity=%d, duration=%d\n", 137d5ac70f0Sopenharmony_ci ev->data.note.channel, 138d5ac70f0Sopenharmony_ci ev->data.note.note, 139d5ac70f0Sopenharmony_ci ev->data.note.velocity, 140d5ac70f0Sopenharmony_ci ev->data.note.off_velocity, 141d5ac70f0Sopenharmony_ci ev->data.note.duration); 142d5ac70f0Sopenharmony_ci break; 143d5ac70f0Sopenharmony_ci 144d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_NOTEON: 145d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_NOTEOFF: 146d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_KEYPRESS: 147d5ac70f0Sopenharmony_ci printf("; ch=%d, note=%d, velocity=%d\n", 148d5ac70f0Sopenharmony_ci ev->data.note.channel, 149d5ac70f0Sopenharmony_ci ev->data.note.note, 150d5ac70f0Sopenharmony_ci ev->data.note.velocity); 151d5ac70f0Sopenharmony_ci break; 152d5ac70f0Sopenharmony_ci 153d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CONTROLLER: 154d5ac70f0Sopenharmony_ci printf("; ch=%d, param=%i, value=%i\n", 155d5ac70f0Sopenharmony_ci ev->data.control.channel, 156d5ac70f0Sopenharmony_ci ev->data.control.param, 157d5ac70f0Sopenharmony_ci ev->data.control.value); 158d5ac70f0Sopenharmony_ci break; 159d5ac70f0Sopenharmony_ci 160d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PGMCHANGE: 161d5ac70f0Sopenharmony_ci printf("; ch=%d, program=%i\n", 162d5ac70f0Sopenharmony_ci ev->data.control.channel, 163d5ac70f0Sopenharmony_ci ev->data.control.value); 164d5ac70f0Sopenharmony_ci break; 165d5ac70f0Sopenharmony_ci 166d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CHANPRESS: 167d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PITCHBEND: 168d5ac70f0Sopenharmony_ci printf("; ch=%d, value=%i\n", 169d5ac70f0Sopenharmony_ci ev->data.control.channel, 170d5ac70f0Sopenharmony_ci ev->data.control.value); 171d5ac70f0Sopenharmony_ci break; 172d5ac70f0Sopenharmony_ci 173d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_SYSEX: 174d5ac70f0Sopenharmony_ci { 175d5ac70f0Sopenharmony_ci unsigned char *sysex = (unsigned char *) ev + sizeof(snd_seq_event_t); 176d5ac70f0Sopenharmony_ci unsigned int c; 177d5ac70f0Sopenharmony_ci 178d5ac70f0Sopenharmony_ci printf("; len=%d [", ev->data.ext.len); 179d5ac70f0Sopenharmony_ci 180d5ac70f0Sopenharmony_ci for (c = 0; c < ev->data.ext.len; c++) { 181d5ac70f0Sopenharmony_ci printf("%02x%s", sysex[c], c < ev->data.ext.len - 1 ? ":" : ""); 182d5ac70f0Sopenharmony_ci } 183d5ac70f0Sopenharmony_ci printf("]\n"); 184d5ac70f0Sopenharmony_ci } 185d5ac70f0Sopenharmony_ci break; 186d5ac70f0Sopenharmony_ci 187d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_QFRAME: 188d5ac70f0Sopenharmony_ci printf("; frame=0x%02x\n", ev->data.control.value); 189d5ac70f0Sopenharmony_ci break; 190d5ac70f0Sopenharmony_ci 191d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CLOCK: 192d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_START: 193d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CONTINUE: 194d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_STOP: 195d5ac70f0Sopenharmony_ci printf("; queue = %i\n", ev->data.queue.queue); 196d5ac70f0Sopenharmony_ci break; 197d5ac70f0Sopenharmony_ci 198d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_SENSING: 199d5ac70f0Sopenharmony_ci printf("\n"); 200d5ac70f0Sopenharmony_ci break; 201d5ac70f0Sopenharmony_ci 202d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_ECHO: 203d5ac70f0Sopenharmony_ci { 204d5ac70f0Sopenharmony_ci int i; 205d5ac70f0Sopenharmony_ci 206d5ac70f0Sopenharmony_ci printf("; "); 207d5ac70f0Sopenharmony_ci for (i = 0; i < 8; i++) { 208d5ac70f0Sopenharmony_ci printf("%02i%s", ev->data.raw8.d[i], i < 7 ? ":" : "\n"); 209d5ac70f0Sopenharmony_ci } 210d5ac70f0Sopenharmony_ci } 211d5ac70f0Sopenharmony_ci break; 212d5ac70f0Sopenharmony_ci 213d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CLIENT_START: 214d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CLIENT_EXIT: 215d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_CLIENT_CHANGE: 216d5ac70f0Sopenharmony_ci printf("; client=%i\n", ev->data.addr.client); 217d5ac70f0Sopenharmony_ci break; 218d5ac70f0Sopenharmony_ci 219d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PORT_START: 220d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PORT_EXIT: 221d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PORT_CHANGE: 222d5ac70f0Sopenharmony_ci printf("; client=%i, port = %i\n", ev->data.addr.client, ev->data.addr.port); 223d5ac70f0Sopenharmony_ci break; 224d5ac70f0Sopenharmony_ci 225d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PORT_SUBSCRIBED: 226d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: 227d5ac70f0Sopenharmony_ci printf("; %i:%i -> %i:%i\n", 228d5ac70f0Sopenharmony_ci ev->data.connect.sender.client, ev->data.connect.sender.port, 229d5ac70f0Sopenharmony_ci ev->data.connect.dest.client, ev->data.connect.dest.port); 230d5ac70f0Sopenharmony_ci break; 231d5ac70f0Sopenharmony_ci 232d5ac70f0Sopenharmony_ci default: 233d5ac70f0Sopenharmony_ci printf("; not implemented\n"); 234d5ac70f0Sopenharmony_ci } 235d5ac70f0Sopenharmony_ci 236d5ac70f0Sopenharmony_ci 237d5ac70f0Sopenharmony_ci switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) { 238d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_LENGTH_FIXED: 239d5ac70f0Sopenharmony_ci return sizeof(snd_seq_event_t); 240d5ac70f0Sopenharmony_ci 241d5ac70f0Sopenharmony_ci case SND_SEQ_EVENT_LENGTH_VARIABLE: 242d5ac70f0Sopenharmony_ci return sizeof(snd_seq_event_t) + ev->data.ext.len; 243d5ac70f0Sopenharmony_ci } 244d5ac70f0Sopenharmony_ci 245d5ac70f0Sopenharmony_ci return 0; 246d5ac70f0Sopenharmony_ci} 247d5ac70f0Sopenharmony_ci 248d5ac70f0Sopenharmony_civoid event_decoder_start_timer(snd_seq_t *handle, int queue, 249d5ac70f0Sopenharmony_ci int client ATTRIBUTE_UNUSED, 250d5ac70f0Sopenharmony_ci int port ATTRIBUTE_UNUSED) 251d5ac70f0Sopenharmony_ci{ 252d5ac70f0Sopenharmony_ci int err; 253d5ac70f0Sopenharmony_ci 254d5ac70f0Sopenharmony_ci if ((err = snd_seq_start_queue(handle, queue, NULL))<0) 255d5ac70f0Sopenharmony_ci fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err)); 256d5ac70f0Sopenharmony_ci while (snd_seq_drain_output(handle)>0) 257d5ac70f0Sopenharmony_ci sleep(1); 258d5ac70f0Sopenharmony_ci} 259d5ac70f0Sopenharmony_ci 260d5ac70f0Sopenharmony_civoid event_decoder(snd_seq_t *handle, int argc, char *argv[]) 261d5ac70f0Sopenharmony_ci{ 262d5ac70f0Sopenharmony_ci snd_seq_event_t *ev; 263d5ac70f0Sopenharmony_ci snd_seq_port_info_t *pinfo; 264d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_t *sub; 265d5ac70f0Sopenharmony_ci snd_seq_addr_t addr; 266d5ac70f0Sopenharmony_ci int client, port, queue, max, err, v1, v2; 267d5ac70f0Sopenharmony_ci char *ptr; 268d5ac70f0Sopenharmony_ci struct pollfd *pfds; 269d5ac70f0Sopenharmony_ci 270d5ac70f0Sopenharmony_ci if ((client = snd_seq_client_id(handle))<0) { 271d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client)); 272d5ac70f0Sopenharmony_ci return; 273d5ac70f0Sopenharmony_ci } 274d5ac70f0Sopenharmony_ci printf("Client ID = %i\n", client); 275d5ac70f0Sopenharmony_ci if ((queue = snd_seq_alloc_queue(handle))<0) { 276d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot allocate queue: %s\n", snd_strerror(queue)); 277d5ac70f0Sopenharmony_ci return; 278d5ac70f0Sopenharmony_ci } 279d5ac70f0Sopenharmony_ci printf("Queue ID = %i\n", queue); 280d5ac70f0Sopenharmony_ci if ((err = snd_seq_nonblock(handle, 1))<0) 281d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err)); 282d5ac70f0Sopenharmony_ci snd_seq_port_info_alloca(&pinfo); 283d5ac70f0Sopenharmony_ci snd_seq_port_info_set_name(pinfo, "Input"); 284d5ac70f0Sopenharmony_ci snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC); 285d5ac70f0Sopenharmony_ci snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_WRITE); 286d5ac70f0Sopenharmony_ci 287d5ac70f0Sopenharmony_ci /* Enable timestamping for events sent by external subscribers. */ 288d5ac70f0Sopenharmony_ci snd_seq_port_info_set_timestamping(pinfo, 1); 289d5ac70f0Sopenharmony_ci snd_seq_port_info_set_timestamp_real(pinfo, 1); 290d5ac70f0Sopenharmony_ci snd_seq_port_info_set_timestamp_queue(pinfo, queue); 291d5ac70f0Sopenharmony_ci 292d5ac70f0Sopenharmony_ci if ((err = snd_seq_create_port(handle, pinfo)) < 0) { 293d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err)); 294d5ac70f0Sopenharmony_ci return; 295d5ac70f0Sopenharmony_ci } 296d5ac70f0Sopenharmony_ci port = snd_seq_port_info_get_port(pinfo); 297d5ac70f0Sopenharmony_ci event_decoder_start_timer(handle, queue, client, port); 298d5ac70f0Sopenharmony_ci 299d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_alloca(&sub); 300d5ac70f0Sopenharmony_ci addr.client = SND_SEQ_CLIENT_SYSTEM; 301d5ac70f0Sopenharmony_ci addr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; 302d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_sender(sub, &addr); 303d5ac70f0Sopenharmony_ci addr.client = client; 304d5ac70f0Sopenharmony_ci addr.port = port; 305d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_dest(sub, &addr); 306d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_queue(sub, queue); 307d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_time_update(sub, 1); 308d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_time_real(sub, 1); 309d5ac70f0Sopenharmony_ci if ((err = snd_seq_subscribe_port(handle, sub))<0) { 310d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot subscribe announce port: %s\n", snd_strerror(err)); 311d5ac70f0Sopenharmony_ci return; 312d5ac70f0Sopenharmony_ci } 313d5ac70f0Sopenharmony_ci 314d5ac70f0Sopenharmony_ci addr.client = SND_SEQ_CLIENT_SYSTEM; 315d5ac70f0Sopenharmony_ci addr.port = SND_SEQ_PORT_SYSTEM_TIMER; 316d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_sender(sub, &addr); 317d5ac70f0Sopenharmony_ci if ((err = snd_seq_subscribe_port(handle, sub))<0) { 318d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot subscribe timer port: %s\n", snd_strerror(err)); 319d5ac70f0Sopenharmony_ci return; 320d5ac70f0Sopenharmony_ci } 321d5ac70f0Sopenharmony_ci 322d5ac70f0Sopenharmony_ci for (max = 0; max < argc; max++) { 323d5ac70f0Sopenharmony_ci ptr = argv[max]; 324d5ac70f0Sopenharmony_ci if (!ptr) 325d5ac70f0Sopenharmony_ci continue; 326d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_time_real(sub, 0); 327d5ac70f0Sopenharmony_ci if (tolower(*ptr) == 'r') { 328d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_time_real(sub, 1); 329d5ac70f0Sopenharmony_ci ptr++; 330d5ac70f0Sopenharmony_ci } 331d5ac70f0Sopenharmony_ci if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) { 332d5ac70f0Sopenharmony_ci fprintf(stderr, "Wrong argument '%s'...\n", argv[max]); 333d5ac70f0Sopenharmony_ci return; 334d5ac70f0Sopenharmony_ci } 335d5ac70f0Sopenharmony_ci addr.client = v1; 336d5ac70f0Sopenharmony_ci addr.port = v2; 337d5ac70f0Sopenharmony_ci snd_seq_port_subscribe_set_sender(sub, &addr); 338d5ac70f0Sopenharmony_ci if ((err = snd_seq_subscribe_port(handle, sub))<0) { 339d5ac70f0Sopenharmony_ci fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err)); 340d5ac70f0Sopenharmony_ci return; 341d5ac70f0Sopenharmony_ci } 342d5ac70f0Sopenharmony_ci } 343d5ac70f0Sopenharmony_ci 344d5ac70f0Sopenharmony_ci max = snd_seq_poll_descriptors_count(handle, POLLIN); 345d5ac70f0Sopenharmony_ci pfds = alloca(sizeof(*pfds) * max); 346d5ac70f0Sopenharmony_ci while (1) { 347d5ac70f0Sopenharmony_ci snd_seq_poll_descriptors(handle, pfds, max, POLLIN); 348d5ac70f0Sopenharmony_ci if (poll(pfds, max, -1) < 0) 349d5ac70f0Sopenharmony_ci break; 350d5ac70f0Sopenharmony_ci do { 351d5ac70f0Sopenharmony_ci if ((err = snd_seq_event_input(handle, &ev))<0) 352d5ac70f0Sopenharmony_ci break; 353d5ac70f0Sopenharmony_ci if (!ev) 354d5ac70f0Sopenharmony_ci continue; 355d5ac70f0Sopenharmony_ci decode_event(ev); 356d5ac70f0Sopenharmony_ci snd_seq_free_event(ev); 357d5ac70f0Sopenharmony_ci } while (err > 0); 358d5ac70f0Sopenharmony_ci } 359d5ac70f0Sopenharmony_ci} 360