tarina

git clone https://git.tarina.org/tarina
Log | Files | Refs | README | LICENSE

aplaymidi.c (22515B)


      1 /*
      2  * aplaymidi.c - play Standard MIDI Files to sequencer port(s)
      3  *
      4  * Copyright (c) 2004-2006 Clemens Ladisch <clemens@ladisch.de>
      5  *
      6  *
      7  *  This program is free software; you can redistribute it and/or modify
      8  *  it under the terms of the GNU General Public License as published by
      9  *  the Free Software Foundation; either version 2 of the License, or
     10  *  (at your option) any later version.
     11  *
     12  *  This program is distributed in the hope that it will be useful,
     13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  *  GNU General Public License for more details.
     16  *
     17  *  You should have received a copy of the GNU General Public License
     18  *  along with this program; if not, write to the Free Software
     19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     20  */
     21 
     22 /* TODO: sequencer queue timer selection */
     23 
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <stdarg.h>
     27 #include <string.h>
     28 #include <getopt.h>
     29 #include <unistd.h>
     30 #include <alsa/asoundlib.h>
     31 #include "aconfig.h"
     32 #include "version.h"
     33 
     34 /*
     35  * 31.25 kbaud, one start bit, eight data bits, two stop bits.
     36  * (The MIDI spec says one stop bit, but every transmitter uses two, just to be
     37  * sure, so we better not exceed that to avoid overflowing the output buffer.)
     38  */
     39 #define MIDI_BYTES_PER_SEC (31250 / (1 + 8 + 2))
     40 
     41 /*
     42  * A MIDI event after being parsed/loaded from the file.
     43  * There could be made a case for using snd_seq_event_t instead.
     44  */
     45 struct event {
     46 	struct event *next;		/* linked list */
     47 
     48 	unsigned char type;		/* SND_SEQ_EVENT_xxx */
     49 	unsigned char port;		/* port index */
     50 	unsigned int tick;
     51 	union {
     52 		unsigned char d[3];	/* channel and data bytes */
     53 		int tempo;
     54 		unsigned int length;	/* length of sysex data */
     55 	} data;
     56 	unsigned char sysex[0];
     57 };
     58 
     59 struct track {
     60 	struct event *first_event;	/* list of all events in this track */
     61 	int end_tick;			/* length of this track */
     62 
     63 	struct event *current_event;	/* used while loading and playing */
     64 };
     65 
     66 static snd_seq_t *seq;
     67 static int client;
     68 static int port_count;
     69 static snd_seq_addr_t *ports;
     70 static int queue;
     71 static int end_delay = 2;
     72 static const char *file_name;
     73 static FILE *file;
     74 static int file_offset;		/* current offset in input file */
     75 static int num_tracks;
     76 static struct track *tracks;
     77 static int smpte_timing;
     78 
     79 /* prints an error message to stderr */
     80 static void errormsg(const char *msg, ...)
     81 {
     82 	va_list ap;
     83 
     84 	va_start(ap, msg);
     85 	vfprintf(stderr, msg, ap);
     86 	va_end(ap);
     87 	fputc('\n', stderr);
     88 }
     89 
     90 /* prints an error message to stderr, and dies */
     91 static void fatal(const char *msg, ...)
     92 {
     93 	va_list ap;
     94 
     95 	va_start(ap, msg);
     96 	vfprintf(stderr, msg, ap);
     97 	va_end(ap);
     98 	fputc('\n', stderr);
     99 	exit(EXIT_FAILURE);
    100 }
    101 
    102 /* memory allocation error handling */
    103 static void check_mem(void *p)
    104 {
    105 	if (!p)
    106 		fatal("Out of memory");
    107 }
    108 
    109 /* error handling for ALSA functions */
    110 static void check_snd(const char *operation, int err)
    111 {
    112 	if (err < 0)
    113 		fatal("Cannot %s - %s", operation, snd_strerror(err));
    114 }
    115 
    116 static void init_seq(void)
    117 {
    118 	int err;
    119 
    120 	/* open sequencer */
    121 	err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
    122 	check_snd("open sequencer", err);
    123 
    124 	/* set our name (otherwise it's "Client-xxx") */
    125 	err = snd_seq_set_client_name(seq, "aplaymidi");
    126 	check_snd("set client name", err);
    127 
    128 	/* find out who we actually are */
    129 	client = snd_seq_client_id(seq);
    130 	check_snd("get client id", client);
    131 }
    132 
    133 /* parses one or more port addresses from the string */
    134 static void parse_ports(const char *arg)
    135 {
    136 	char *buf, *s, *port_name;
    137 	int err;
    138 
    139 	/* make a copy of the string because we're going to modify it */
    140 	buf = strdup(arg);
    141 	check_mem(buf);
    142 
    143 	for (port_name = s = buf; s; port_name = s + 1) {
    144 		/* Assume that ports are separated by commas.  We don't use
    145 		 * spaces because those are valid in client names. */
    146 		s = strchr(port_name, ',');
    147 		if (s)
    148 			*s = '\0';
    149 
    150 		++port_count;
    151 		ports = realloc(ports, port_count * sizeof(snd_seq_addr_t));
    152 		check_mem(ports);
    153 
    154 		err = snd_seq_parse_address(seq, &ports[port_count - 1], port_name);
    155 		if (err < 0)
    156 			fatal("Invalid port %s - %s", port_name, snd_strerror(err));
    157 	}
    158 
    159 	free(buf);
    160 }
    161 
    162 static void create_source_port(void)
    163 {
    164 	snd_seq_port_info_t *pinfo;
    165 	int err;
    166 
    167 	snd_seq_port_info_alloca(&pinfo);
    168 
    169 	/* the first created port is 0 anyway, but let's make sure ... */
    170 	snd_seq_port_info_set_port(pinfo, 0);
    171 	snd_seq_port_info_set_port_specified(pinfo, 1);
    172 
    173 	snd_seq_port_info_set_name(pinfo, "aplaymidi");
    174 
    175 	snd_seq_port_info_set_capability(pinfo, 0); /* sic */
    176 	snd_seq_port_info_set_type(pinfo,
    177 				   SND_SEQ_PORT_TYPE_MIDI_GENERIC |
    178 				   SND_SEQ_PORT_TYPE_APPLICATION);
    179 
    180 	err = snd_seq_create_port(seq, pinfo);
    181 	check_snd("create port", err);
    182 }
    183 
    184 static void create_queue(void)
    185 {
    186 	queue = snd_seq_alloc_named_queue(seq, "aplaymidi");
    187 	check_snd("create queue", queue);
    188 	/* the queue is now locked, which is just fine */
    189 }
    190 
    191 static void connect_ports(void)
    192 {
    193 	int i, err;
    194 
    195 	/*
    196 	 * We send MIDI events with explicit destination addresses, so we don't
    197 	 * need any connections to the playback ports.  But we connect to those
    198 	 * anyway to force any underlying RawMIDI ports to remain open while
    199 	 * we're playing - otherwise, ALSA would reset the port after every
    200 	 * event.
    201 	 */
    202 	for (i = 0; i < port_count; ++i) {
    203 		err = snd_seq_connect_to(seq, 0, ports[i].client, ports[i].port);
    204 		if (err < 0)
    205 			fatal("Cannot connect to port %d:%d - %s",
    206 			      ports[i].client, ports[i].port, snd_strerror(err));
    207 	}
    208 }
    209 
    210 static int read_byte(void)
    211 {
    212 	++file_offset;
    213 	return getc(file);
    214 }
    215 
    216 /* reads a little-endian 32-bit integer */
    217 static int read_32_le(void)
    218 {
    219 	int value;
    220 	value = read_byte();
    221 	value |= read_byte() << 8;
    222 	value |= read_byte() << 16;
    223 	value |= read_byte() << 24;
    224 	return !feof(file) ? value : -1;
    225 }
    226 
    227 /* reads a 4-character identifier */
    228 static int read_id(void)
    229 {
    230 	return read_32_le();
    231 }
    232 #define MAKE_ID(c1, c2, c3, c4) ((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))
    233 
    234 /* reads a fixed-size big-endian number */
    235 static int read_int(int bytes)
    236 {
    237 	int c, value = 0;
    238 
    239 	do {
    240 		c = read_byte();
    241 		if (c == EOF)
    242 			return -1;
    243 		value = (value << 8) | c;
    244 	} while (--bytes);
    245 	return value;
    246 }
    247 
    248 /* reads a variable-length number */
    249 static int read_var(void)
    250 {
    251 	int value, c;
    252 
    253 	c = read_byte();
    254 	value = c & 0x7f;
    255 	if (c & 0x80) {
    256 		c = read_byte();
    257 		value = (value << 7) | (c & 0x7f);
    258 		if (c & 0x80) {
    259 			c = read_byte();
    260 			value = (value << 7) | (c & 0x7f);
    261 			if (c & 0x80) {
    262 				c = read_byte();
    263 				value = (value << 7) | c;
    264 				if (c & 0x80)
    265 					return -1;
    266 			}
    267 		}
    268 	}
    269 	return !feof(file) ? value : -1;
    270 }
    271 
    272 /* allocates a new event */
    273 static struct event *new_event(struct track *track, int sysex_length)
    274 {
    275 	struct event *event;
    276 
    277 	event = malloc(sizeof(struct event) + sysex_length);
    278 	check_mem(event);
    279 
    280 	event->next = NULL;
    281 
    282 	/* append at the end of the track's linked list */
    283 	if (track->current_event)
    284 		track->current_event->next = event;
    285 	else
    286 		track->first_event = event;
    287 	track->current_event = event;
    288 
    289 	return event;
    290 }
    291 
    292 static void skip(int bytes)
    293 {
    294 	while (bytes > 0)
    295 		read_byte(), --bytes;
    296 }
    297 
    298 /* reads one complete track from the file */
    299 static int read_track(struct track *track, int track_end)
    300 {
    301 	int tick = 0;
    302 	unsigned char last_cmd = 0;
    303 	unsigned char port = 0;
    304 
    305 	/* the current file position is after the track ID and length */
    306 	while (file_offset < track_end) {
    307 		unsigned char cmd;
    308 		struct event *event;
    309 		int delta_ticks, len, c;
    310 
    311 		delta_ticks = read_var();
    312 		if (delta_ticks < 0)
    313 			break;
    314 		tick += delta_ticks;
    315 
    316 		c = read_byte();
    317 		if (c < 0)
    318 			break;
    319 
    320 		if (c & 0x80) {
    321 			/* have command */
    322 			cmd = c;
    323 			if (cmd < 0xf0)
    324 				last_cmd = cmd;
    325 		} else {
    326 			/* running status */
    327 			ungetc(c, file);
    328 			file_offset--;
    329 			cmd = last_cmd;
    330 			if (!cmd)
    331 				goto _error;
    332 		}
    333 
    334 		switch (cmd >> 4) {
    335 			/* maps SMF events to ALSA sequencer events */
    336 			static const unsigned char cmd_type[] = {
    337 				[0x8] = SND_SEQ_EVENT_NOTEOFF,
    338 				[0x9] = SND_SEQ_EVENT_NOTEON,
    339 				[0xa] = SND_SEQ_EVENT_KEYPRESS,
    340 				[0xb] = SND_SEQ_EVENT_CONTROLLER,
    341 				[0xc] = SND_SEQ_EVENT_PGMCHANGE,
    342 				[0xd] = SND_SEQ_EVENT_CHANPRESS,
    343 				[0xe] = SND_SEQ_EVENT_PITCHBEND
    344 			};
    345 
    346 		case 0x8: /* channel msg with 2 parameter bytes */
    347 		case 0x9:
    348 		case 0xa:
    349 		case 0xb:
    350 		case 0xe:
    351 			event = new_event(track, 0);
    352 			event->type = cmd_type[cmd >> 4];
    353 			event->port = port;
    354 			event->tick = tick;
    355 			event->data.d[0] = cmd & 0x0f;
    356 			event->data.d[1] = read_byte() & 0x7f;
    357 			event->data.d[2] = read_byte() & 0x7f;
    358 			break;
    359 
    360 		case 0xc: /* channel msg with 1 parameter byte */
    361 		case 0xd:
    362 			event = new_event(track, 0);
    363 			event->type = cmd_type[cmd >> 4];
    364 			event->port = port;
    365 			event->tick = tick;
    366 			event->data.d[0] = cmd & 0x0f;
    367 			event->data.d[1] = read_byte() & 0x7f;
    368 			break;
    369 
    370 		case 0xf:
    371 			switch (cmd) {
    372 			case 0xf0: /* sysex */
    373 			case 0xf7: /* continued sysex, or escaped commands */
    374 				len = read_var();
    375 				if (len < 0)
    376 					goto _error;
    377 				if (cmd == 0xf0)
    378 					++len;
    379 				event = new_event(track, len);
    380 				event->type = SND_SEQ_EVENT_SYSEX;
    381 				event->port = port;
    382 				event->tick = tick;
    383 				event->data.length = len;
    384 				if (cmd == 0xf0) {
    385 					event->sysex[0] = 0xf0;
    386 					c = 1;
    387 				} else {
    388 					c = 0;
    389 				}
    390 				for (; c < len; ++c)
    391 					event->sysex[c] = read_byte();
    392 				break;
    393 
    394 			case 0xff: /* meta event */
    395 				c = read_byte();
    396 				len = read_var();
    397 				if (len < 0)
    398 					goto _error;
    399 
    400 				switch (c) {
    401 				case 0x21: /* port number */
    402 					if (len < 1)
    403 						goto _error;
    404 					port = read_byte() % port_count;
    405 					skip(len - 1);
    406 					break;
    407 
    408 				case 0x2f: /* end of track */
    409 					track->end_tick = tick;
    410 					skip(track_end - file_offset);
    411 					return 1;
    412 
    413 				case 0x51: /* tempo */
    414 					if (len < 3)
    415 						goto _error;
    416 					if (smpte_timing) {
    417 						/* SMPTE timing doesn't change */
    418 						skip(len);
    419 					} else {
    420 						event = new_event(track, 0);
    421 						event->type = SND_SEQ_EVENT_TEMPO;
    422 						event->port = port;
    423 						event->tick = tick;
    424 						event->data.tempo = read_byte() << 16;
    425 						event->data.tempo |= read_byte() << 8;
    426 						event->data.tempo |= read_byte();
    427 						skip(len - 3);
    428 					}
    429 					break;
    430 
    431 				default: /* ignore all other meta events */
    432 					skip(len);
    433 					break;
    434 				}
    435 				break;
    436 
    437 			default: /* invalid Fx command */
    438 				goto _error;
    439 			}
    440 			break;
    441 
    442 		default: /* cannot happen */
    443 			goto _error;
    444 		}
    445 	}
    446 _error:
    447 	errormsg("%s: invalid MIDI data (offset %#x)", file_name, file_offset);
    448 	return 0;
    449 }
    450 
    451 /* reads an entire MIDI file */
    452 static int read_smf(void)
    453 {
    454 	int header_len, type, time_division, i, err;
    455 	snd_seq_queue_tempo_t *queue_tempo;
    456 
    457 	/* the curren position is immediately after the "MThd" id */
    458 	header_len = read_int(4);
    459 	if (header_len < 6) {
    460 invalid_format:
    461 		errormsg("%s: invalid file format", file_name);
    462 		return 0;
    463 	}
    464 
    465 	type = read_int(2);
    466 	if (type != 0 && type != 1) {
    467 		errormsg("%s: type %d format is not supported", file_name, type);
    468 		return 0;
    469 	}
    470 
    471 	num_tracks = read_int(2);
    472 	if (num_tracks < 1 || num_tracks > 1000) {
    473 		errormsg("%s: invalid number of tracks (%d)", file_name, num_tracks);
    474 		num_tracks = 0;
    475 		return 0;
    476 	}
    477 	tracks = calloc(num_tracks, sizeof(struct track));
    478 	if (!tracks) {
    479 		errormsg("out of memory");
    480 		num_tracks = 0;
    481 		return 0;
    482 	}
    483 
    484 	time_division = read_int(2);
    485 	if (time_division < 0)
    486 		goto invalid_format;
    487 
    488 	/* interpret and set tempo */
    489 	snd_seq_queue_tempo_alloca(&queue_tempo);
    490 	smpte_timing = !!(time_division & 0x8000);
    491 	if (!smpte_timing) {
    492 		/* time_division is ticks per quarter */
    493 		snd_seq_queue_tempo_set_tempo(queue_tempo, 500000); /* default: 120 bpm */
    494 		snd_seq_queue_tempo_set_ppq(queue_tempo, time_division);
    495 	} else {
    496 		/* upper byte is negative frames per second */
    497 		i = 0x80 - ((time_division >> 8) & 0x7f);
    498 		/* lower byte is ticks per frame */
    499 		time_division &= 0xff;
    500 		/* now pretend that we have quarter-note based timing */
    501 		switch (i) {
    502 		case 24:
    503 			snd_seq_queue_tempo_set_tempo(queue_tempo, 500000);
    504 			snd_seq_queue_tempo_set_ppq(queue_tempo, 12 * time_division);
    505 			break;
    506 		case 25:
    507 			snd_seq_queue_tempo_set_tempo(queue_tempo, 400000);
    508 			snd_seq_queue_tempo_set_ppq(queue_tempo, 10 * time_division);
    509 			break;
    510 		case 29: /* 30 drop-frame */
    511 			snd_seq_queue_tempo_set_tempo(queue_tempo, 100000000);
    512 			snd_seq_queue_tempo_set_ppq(queue_tempo, 2997 * time_division);
    513 			break;
    514 		case 30:
    515 			snd_seq_queue_tempo_set_tempo(queue_tempo, 500000);
    516 			snd_seq_queue_tempo_set_ppq(queue_tempo, 15 * time_division);
    517 			break;
    518 		default:
    519 			errormsg("%s: invalid number of SMPTE frames per second (%d)",
    520 				 file_name, i);
    521 			return 0;
    522 		}
    523 	}
    524 	err = snd_seq_set_queue_tempo(seq, queue, queue_tempo);
    525 	if (err < 0) {
    526 		errormsg("Cannot set queue tempo (%u/%i)",
    527 			 snd_seq_queue_tempo_get_tempo(queue_tempo),
    528 			 snd_seq_queue_tempo_get_ppq(queue_tempo));
    529 		return 0;
    530 	}
    531 
    532 	/* read tracks */
    533 	for (i = 0; i < num_tracks; ++i) {
    534 		int len;
    535 
    536 		/* search for MTrk chunk */
    537 		for (;;) {
    538 			int id = read_id();
    539 			len = read_int(4);
    540 			if (feof(file)) {
    541 				errormsg("%s: unexpected end of file", file_name);
    542 				return 0;
    543 			}
    544 			if (len < 0 || len >= 0x10000000) {
    545 				errormsg("%s: invalid chunk length %d", file_name, len);
    546 				return 0;
    547 			}
    548 			if (id == MAKE_ID('M', 'T', 'r', 'k'))
    549 				break;
    550 			skip(len);
    551 		}
    552 		if (!read_track(&tracks[i], file_offset + len))
    553 			return 0;
    554 	}
    555 	return 1;
    556 }
    557 
    558 static int read_riff(void)
    559 {
    560 	/* skip file length */
    561 	read_byte();
    562 	read_byte();
    563 	read_byte();
    564 	read_byte();
    565 
    566 	/* check file type ("RMID" = RIFF MIDI) */
    567 	if (read_id() != MAKE_ID('R', 'M', 'I', 'D')) {
    568 invalid_format:
    569 		errormsg("%s: invalid file format", file_name);
    570 		return 0;
    571 	}
    572 	/* search for "data" chunk */
    573 	for (;;) {
    574 		int id = read_id();
    575 		int len = read_32_le();
    576 		if (feof(file)) {
    577 data_not_found:
    578 			errormsg("%s: data chunk not found", file_name);
    579 			return 0;
    580 		}
    581 		if (id == MAKE_ID('d', 'a', 't', 'a'))
    582 			break;
    583 		if (len < 0)
    584 			goto data_not_found;
    585 		skip((len + 1) & ~1);
    586 	}
    587 	/* the "data" chunk must contain data in SMF format */
    588 	if (read_id() != MAKE_ID('M', 'T', 'h', 'd'))
    589 		goto invalid_format;
    590 	return read_smf();
    591 }
    592 
    593 static void cleanup_file_data(void)
    594 {
    595 	int i;
    596 	struct event *event;
    597 
    598 	for (i = 0; i < num_tracks; ++i) {
    599 		event = tracks[i].first_event;
    600 		while (event) {
    601 			struct event *next = event->next;
    602 			free(event);
    603 			event = next;
    604 		}
    605 	}
    606 	num_tracks = 0;
    607 	free(tracks);
    608 	tracks = NULL;
    609 }
    610 
    611 static void handle_big_sysex(snd_seq_event_t *ev)
    612 {
    613 	unsigned int length;
    614 	ssize_t event_size;
    615 	int err;
    616 
    617 	length = ev->data.ext.len;
    618 	if (length > MIDI_BYTES_PER_SEC)
    619 		ev->data.ext.len = MIDI_BYTES_PER_SEC;
    620 	event_size = snd_seq_event_length(ev);
    621 	if (event_size + 1 > snd_seq_get_output_buffer_size(seq)) {
    622 		err = snd_seq_drain_output(seq);
    623 		check_snd("drain output", err);
    624 		err = snd_seq_set_output_buffer_size(seq, event_size + 1);
    625 		check_snd("set output buffer size", err);
    626 	}
    627 	while (length > MIDI_BYTES_PER_SEC) {
    628 		err = snd_seq_event_output(seq, ev);
    629 		check_snd("output event", err);
    630 		err = snd_seq_drain_output(seq);
    631 		check_snd("drain output", err);
    632 		err = snd_seq_sync_output_queue(seq);
    633 		check_snd("sync output", err);
    634 		if (sleep(1))
    635 			fatal("aborted");
    636 		ev->data.ext.ptr += MIDI_BYTES_PER_SEC;
    637 		length -= MIDI_BYTES_PER_SEC;
    638 	}
    639 	ev->data.ext.len = length;
    640 }
    641 
    642 static void play_midi(void)
    643 {
    644 	snd_seq_event_t ev;
    645 	int i, max_tick, err;
    646 
    647 	/* calculate length of the entire file */
    648 	max_tick = -1;
    649 	for (i = 0; i < num_tracks; ++i) {
    650 		if (tracks[i].end_tick > max_tick)
    651 			max_tick = tracks[i].end_tick;
    652 	}
    653 
    654 	/* initialize current position in each track */
    655 	for (i = 0; i < num_tracks; ++i)
    656 		tracks[i].current_event = tracks[i].first_event;
    657 
    658 	/* common settings for all our events */
    659 	snd_seq_ev_clear(&ev);
    660 	ev.queue = queue;
    661 	ev.source.port = 0;
    662 	ev.flags = SND_SEQ_TIME_STAMP_TICK;
    663 
    664 	err = snd_seq_start_queue(seq, queue, NULL);
    665 	check_snd("start queue", err);
    666 	/* The queue won't be started until the START_QUEUE event is
    667 	 * actually drained to the kernel, which is exactly what we want. */
    668 
    669 	for (;;) {
    670 		struct event* event = NULL;
    671 		struct track* event_track = NULL;
    672 		int i, min_tick = max_tick + 1;
    673 
    674 		/* search next event */
    675 		for (i = 0; i < num_tracks; ++i) {
    676 			struct track *track = &tracks[i];
    677 			struct event *e2 = track->current_event;
    678 			if (e2 && e2->tick < min_tick) {
    679 				min_tick = e2->tick;
    680 				event = e2;
    681 				event_track = track;
    682 			}
    683 		}
    684 		if (!event)
    685 			break; /* end of song reached */
    686 
    687 		/* advance pointer to next event */
    688 		event_track->current_event = event->next;
    689 
    690 		/* output the event */
    691 		ev.type = event->type;
    692 		ev.time.tick = event->tick;
    693 		ev.dest = ports[event->port];
    694 		switch (ev.type) {
    695 		case SND_SEQ_EVENT_NOTEON:
    696 		case SND_SEQ_EVENT_NOTEOFF:
    697 		case SND_SEQ_EVENT_KEYPRESS:
    698 			snd_seq_ev_set_fixed(&ev);
    699 			ev.data.note.channel = event->data.d[0];
    700 			ev.data.note.note = event->data.d[1];
    701 			ev.data.note.velocity = event->data.d[2];
    702 			break;
    703 		case SND_SEQ_EVENT_CONTROLLER:
    704 			snd_seq_ev_set_fixed(&ev);
    705 			ev.data.control.channel = event->data.d[0];
    706 			ev.data.control.param = event->data.d[1];
    707 			ev.data.control.value = event->data.d[2];
    708 			break;
    709 		case SND_SEQ_EVENT_PGMCHANGE:
    710 		case SND_SEQ_EVENT_CHANPRESS:
    711 			snd_seq_ev_set_fixed(&ev);
    712 			ev.data.control.channel = event->data.d[0];
    713 			ev.data.control.value = event->data.d[1];
    714 			break;
    715 		case SND_SEQ_EVENT_PITCHBEND:
    716 			snd_seq_ev_set_fixed(&ev);
    717 			ev.data.control.channel = event->data.d[0];
    718 			ev.data.control.value =
    719 				((event->data.d[1]) |
    720 				 ((event->data.d[2]) << 7)) - 0x2000;
    721 			break;
    722 		case SND_SEQ_EVENT_SYSEX:
    723 			snd_seq_ev_set_variable(&ev, event->data.length,
    724 						event->sysex);
    725 			handle_big_sysex(&ev);
    726 			break;
    727 		case SND_SEQ_EVENT_TEMPO:
    728 			snd_seq_ev_set_fixed(&ev);
    729 			ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
    730 			ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
    731 			ev.data.queue.queue = queue;
    732 			ev.data.queue.param.value = event->data.tempo;
    733 			break;
    734 		default:
    735 			fatal("Invalid event type %d!", ev.type);
    736 		}
    737 
    738 		/* this blocks when the output pool has been filled */
    739 		err = snd_seq_event_output(seq, &ev);
    740 		check_snd("output event", err);
    741 	}
    742 
    743 	/* schedule queue stop at end of song */
    744 	snd_seq_ev_set_fixed(&ev);
    745 	ev.type = SND_SEQ_EVENT_STOP;
    746 	ev.time.tick = max_tick;
    747 	ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
    748 	ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
    749 	ev.data.queue.queue = queue;
    750 	err = snd_seq_event_output(seq, &ev);
    751 	check_snd("output event", err);
    752 
    753 	/* make sure that the sequencer sees all our events */
    754 	err = snd_seq_drain_output(seq);
    755 	check_snd("drain output", err);
    756 
    757 	/*
    758 	 * There are three possibilities how to wait until all events have
    759 	 * been played:
    760 	 * 1) send an event back to us (like pmidi does), and wait for it;
    761 	 * 2) wait for the EVENT_STOP notification for our queue which is sent
    762 	 *    by the system timer port (this would require a subscription);
    763 	 * 3) wait until the output pool is empty.
    764 	 * The last is the simplest.
    765 	 */
    766 	err = snd_seq_sync_output_queue(seq);
    767 	check_snd("sync output", err);
    768 
    769 	/* give the last notes time to die away */
    770 	if (end_delay > 0)
    771 		sleep(end_delay);
    772 }
    773 
    774 static void play_file(void)
    775 {
    776 	int ok;
    777 
    778 	if (!strcmp(file_name, "-"))
    779 		file = stdin;
    780 	else
    781 		file = fopen(file_name, "rb");
    782 	if (!file) {
    783 		errormsg("Cannot open %s - %s", file_name, strerror(errno));
    784 		return;
    785 	}
    786 
    787 	file_offset = 0;
    788 	ok = 0;
    789 
    790 	switch (read_id()) {
    791 	case MAKE_ID('M', 'T', 'h', 'd'):
    792 		ok = read_smf();
    793 		break;
    794 	case MAKE_ID('R', 'I', 'F', 'F'):
    795 		ok = read_riff();
    796 		break;
    797 	default:
    798 		errormsg("%s is not a Standard MIDI File", file_name);
    799 		break;
    800 	}
    801 
    802 	if (file != stdin)
    803 		fclose(file);
    804 
    805 	if (ok)
    806 		play_midi();
    807 
    808 	cleanup_file_data();
    809 }
    810 
    811 static void list_ports(void)
    812 {
    813 	snd_seq_client_info_t *cinfo;
    814 	snd_seq_port_info_t *pinfo;
    815 
    816 	snd_seq_client_info_alloca(&cinfo);
    817 	snd_seq_port_info_alloca(&pinfo);
    818 
    819 	puts(" Port    Client name                      Port name");
    820 
    821 	snd_seq_client_info_set_client(cinfo, -1);
    822 	while (snd_seq_query_next_client(seq, cinfo) >= 0) {
    823 		int client = snd_seq_client_info_get_client(cinfo);
    824 
    825 		snd_seq_port_info_set_client(pinfo, client);
    826 		snd_seq_port_info_set_port(pinfo, -1);
    827 		while (snd_seq_query_next_port(seq, pinfo) >= 0) {
    828 			/* port must understand MIDI messages */
    829 			if (!(snd_seq_port_info_get_type(pinfo)
    830 			      & SND_SEQ_PORT_TYPE_MIDI_GENERIC))
    831 				continue;
    832 			/* we need both WRITE and SUBS_WRITE */
    833 			if ((snd_seq_port_info_get_capability(pinfo)
    834 			     & (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE))
    835 			    != (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE))
    836 				continue;
    837 			printf("%3d:%-3d  %-32.32s %s\n",
    838 			       snd_seq_port_info_get_client(pinfo),
    839 			       snd_seq_port_info_get_port(pinfo),
    840 			       snd_seq_client_info_get_name(cinfo),
    841 			       snd_seq_port_info_get_name(pinfo));
    842 		}
    843 	}
    844 }
    845 
    846 static void usage(const char *argv0)
    847 {
    848 	printf(
    849 		"Usage: %s -p client:port[,...] [-d delay] midifile ...\n"
    850 		"-h, --help                  this help\n"
    851 		"-V, --version               print current version\n"
    852 		"-l, --list                  list all possible output ports\n"
    853 		"-p, --port=client:port,...  set port(s) to play to\n"
    854 		"-d, --delay=seconds         delay after song ends\n",
    855 		argv0);
    856 }
    857 
    858 static void version(void)
    859 {
    860 	puts("aplaymidi version " SND_UTIL_VERSION_STR);
    861 }
    862 
    863 int main(int argc, char *argv[])
    864 {
    865 	static const char short_options[] = "hVlp:d:";
    866 	static const struct option long_options[] = {
    867 		{"help", 0, NULL, 'h'},
    868 		{"version", 0, NULL, 'V'},
    869 		{"list", 0, NULL, 'l'},
    870 		{"port", 1, NULL, 'p'},
    871 		{"delay", 1, NULL, 'd'},
    872 		{}
    873 	};
    874 	int c;
    875 	int do_list = 0;
    876 
    877 	init_seq();
    878 
    879 	while ((c = getopt_long(argc, argv, short_options,
    880 				long_options, NULL)) != -1) {
    881 		switch (c) {
    882 		case 'h':
    883 			usage(argv[0]);
    884 			return 0;
    885 		case 'V':
    886 			version();
    887 			return 0;
    888 		case 'l':
    889 			do_list = 1;
    890 			break;
    891 		case 'p':
    892 			parse_ports(optarg);
    893 			break;
    894 		case 'd':
    895 			end_delay = atoi(optarg);
    896 			break;
    897 		default:
    898 			usage(argv[0]);
    899 			return 1;
    900 		}
    901 	}
    902 
    903 	if (do_list) {
    904 		list_ports();
    905 	} else {
    906 		if (port_count < 1) {
    907 			/* use env var for compatibility with pmidi */
    908 			const char *ports_str = getenv("ALSA_OUTPUT_PORTS");
    909 			if (ports_str)
    910 				parse_ports(ports_str);
    911 			if (port_count < 1) {
    912 				errormsg("Please specify at least one port with --port.");
    913 				return 1;
    914 			}
    915 		}
    916 		if (optind >= argc) {
    917 			errormsg("Please specify a file to play.");
    918 			return 1;
    919 		}
    920 
    921 		create_source_port();
    922 		create_queue();
    923 		connect_ports();
    924 
    925 		for (; optind < argc; ++optind) {
    926 			file_name = argv[optind];
    927 			play_file();
    928 		}
    929 	}
    930 	snd_seq_close(seq);
    931 	return 0;
    932 }