mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-10-29 05:40:25 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			505 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			505 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  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);
 | |
| 	}
 | |
| }
 | 
