/*
 * aplaymidi.c - play Standard MIDI Files to sequencer port(s)
 *
 * Copyright (c) 2004-2006 Clemens Ladisch <clemens@ladisch.de>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

/* TODO: sequencer queue timer selection */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
#include "aconfig.h"
#include "version.h"

/*
 * 31.25 kbaud, one start bit, eight data bits, two stop bits.
 * (The MIDI spec says one stop bit, but every transmitter uses two, just to be
 * sure, so we better not exceed that to avoid overflowing the output buffer.)
 */
#define MIDI_BYTES_PER_SEC (31250 / (1 + 8 + 2))

/*
 * A MIDI event after being parsed/loaded from the file.
 * There could be made a case for using snd_seq_event_t instead.
 */
struct event {
	struct event *next;		/* linked list */

	unsigned char type;		/* SND_SEQ_EVENT_xxx */
	unsigned char port;		/* port index */
	unsigned int tick;
	union {
		unsigned char d[3];	/* channel and data bytes */
		int tempo;
		unsigned int length;	/* length of sysex data */
	} data;
	unsigned char sysex[0];
};

struct track {
	struct event *first_event;	/* list of all events in this track */
	int end_tick;			/* length of this track */

	struct event *current_event;	/* used while loading and playing */
};

static snd_seq_t *seq;
static int client;
static int port_count;
static snd_seq_addr_t *ports;
static int queue;
static int end_delay = 2;
static const char *file_name;
static FILE *file;
static int file_offset;		/* current offset in input file */
static int num_tracks;
static struct track *tracks;
static int smpte_timing;

/* prints an error message to stderr */
static void errormsg(const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	vfprintf(stderr, msg, ap);
	va_end(ap);
	fputc('\n', stderr);
}

/* prints an error message to stderr, and dies */
static void fatal(const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	vfprintf(stderr, msg, ap);
	va_end(ap);
	fputc('\n', stderr);
	exit(EXIT_FAILURE);
}

/* memory allocation error handling */
static void check_mem(void *p)
{
	if (!p)
		fatal("Out of memory");
}

/* error handling for ALSA functions */
static void check_snd(const char *operation, int err)
{
	if (err < 0)
		fatal("Cannot %s - %s", operation, snd_strerror(err));
}

static void init_seq(void)
{
	int err;

	/* open sequencer */
	err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
	check_snd("open sequencer", err);

	/* set our name (otherwise it's "Client-xxx") */
	err = snd_seq_set_client_name(seq, "aplaymidi");
	check_snd("set client name", err);

	/* find out who we actually are */
	client = snd_seq_client_id(seq);
	check_snd("get client id", client);
}

/* parses one or more port addresses from the string */
static void parse_ports(const char *arg)
{
	char *buf, *s, *port_name;
	int err;

	/* make a copy of the string because we're going to modify it */
	buf = strdup(arg);
	check_mem(buf);

	for (port_name = s = buf; s; port_name = s + 1) {
		/* Assume that ports are separated by commas.  We don't use
		 * spaces because those are valid in client names. */
		s = strchr(port_name, ',');
		if (s)
			*s = '\0';

		++port_count;
		ports = realloc(ports, port_count * sizeof(snd_seq_addr_t));
		check_mem(ports);

		err = snd_seq_parse_address(seq, &ports[port_count - 1], port_name);
		if (err < 0)
			fatal("Invalid port %s - %s", port_name, snd_strerror(err));
	}

	free(buf);
}

static void create_source_port(void)
{
	snd_seq_port_info_t *pinfo;
	int err;

	snd_seq_port_info_alloca(&pinfo);

	/* the first created port is 0 anyway, but let's make sure ... */
	snd_seq_port_info_set_port(pinfo, 0);
	snd_seq_port_info_set_port_specified(pinfo, 1);

	snd_seq_port_info_set_name(pinfo, "aplaymidi");

	snd_seq_port_info_set_capability(pinfo, 0); /* sic */
	snd_seq_port_info_set_type(pinfo,
				   SND_SEQ_PORT_TYPE_MIDI_GENERIC |
				   SND_SEQ_PORT_TYPE_APPLICATION);

	err = snd_seq_create_port(seq, pinfo);
	check_snd("create port", err);
}

static void create_queue(void)
{
	queue = snd_seq_alloc_named_queue(seq, "aplaymidi");
	check_snd("create queue", queue);
	/* the queue is now locked, which is just fine */
}

static void connect_ports(void)
{
	int i, err;

	/*
	 * We send MIDI events with explicit destination addresses, so we don't
	 * need any connections to the playback ports.  But we connect to those
	 * anyway to force any underlying RawMIDI ports to remain open while
	 * we're playing - otherwise, ALSA would reset the port after every
	 * event.
	 */
	for (i = 0; i < port_count; ++i) {
		err = snd_seq_connect_to(seq, 0, ports[i].client, ports[i].port);
		if (err < 0)
			fatal("Cannot connect to port %d:%d - %s",
			      ports[i].client, ports[i].port, snd_strerror(err));
	}
}

static int read_byte(void)
{
	++file_offset;
	return getc(file);
}

/* reads a little-endian 32-bit integer */
static int read_32_le(void)
{
	int value;
	value = read_byte();
	value |= read_byte() << 8;
	value |= read_byte() << 16;
	value |= read_byte() << 24;
	return !feof(file) ? value : -1;
}

/* reads a 4-character identifier */
static int read_id(void)
{
	return read_32_le();
}
#define MAKE_ID(c1, c2, c3, c4) ((c1) | ((c2) << 8) | ((c3) << 16) | ((c4) << 24))

/* reads a fixed-size big-endian number */
static int read_int(int bytes)
{
	int c, value = 0;

	do {
		c = read_byte();
		if (c == EOF)
			return -1;
		value = (value << 8) | c;
	} while (--bytes);
	return value;
}

/* reads a variable-length number */
static int read_var(void)
{
	int value, c;

	c = read_byte();
	value = c & 0x7f;
	if (c & 0x80) {
		c = read_byte();
		value = (value << 7) | (c & 0x7f);
		if (c & 0x80) {
			c = read_byte();
			value = (value << 7) | (c & 0x7f);
			if (c & 0x80) {
				c = read_byte();
				value = (value << 7) | c;
				if (c & 0x80)
					return -1;
			}
		}
	}
	return !feof(file) ? value : -1;
}

/* allocates a new event */
static struct event *new_event(struct track *track, int sysex_length)
{
	struct event *event;

	event = malloc(sizeof(struct event) + sysex_length);
	check_mem(event);

	event->next = NULL;

	/* append at the end of the track's linked list */
	if (track->current_event)
		track->current_event->next = event;
	else
		track->first_event = event;
	track->current_event = event;

	return event;
}

static void skip(int bytes)
{
	while (bytes > 0)
		read_byte(), --bytes;
}

/* reads one complete track from the file */
static int read_track(struct track *track, int track_end)
{
	int tick = 0;
	unsigned char last_cmd = 0;
	unsigned char port = 0;

	/* the current file position is after the track ID and length */
	while (file_offset < track_end) {
		unsigned char cmd;
		struct event *event;
		int delta_ticks, len, c;

		delta_ticks = read_var();
		if (delta_ticks < 0)
			break;
		tick += delta_ticks;

		c = read_byte();
		if (c < 0)
			break;

		if (c & 0x80) {
			/* have command */
			cmd = c;
			if (cmd < 0xf0)
				last_cmd = cmd;
		} else {
			/* running status */
			ungetc(c, file);
			file_offset--;
			cmd = last_cmd;
			if (!cmd)
				goto _error;
		}

		switch (cmd >> 4) {
			/* maps SMF events to ALSA sequencer events */
			static const unsigned char cmd_type[] = {
				[0x8] = SND_SEQ_EVENT_NOTEOFF,
				[0x9] = SND_SEQ_EVENT_NOTEON,
				[0xa] = SND_SEQ_EVENT_KEYPRESS,
				[0xb] = SND_SEQ_EVENT_CONTROLLER,
				[0xc] = SND_SEQ_EVENT_PGMCHANGE,
				[0xd] = SND_SEQ_EVENT_CHANPRESS,
				[0xe] = SND_SEQ_EVENT_PITCHBEND
			};

		case 0x8: /* channel msg with 2 parameter bytes */
		case 0x9:
		case 0xa:
		case 0xb:
		case 0xe:
			event = new_event(track, 0);
			event->type = cmd_type[cmd >> 4];
			event->port = port;
			event->tick = tick;
			event->data.d[0] = cmd & 0x0f;
			event->data.d[1] = read_byte() & 0x7f;
			event->data.d[2] = read_byte() & 0x7f;
			break;

		case 0xc: /* channel msg with 1 parameter byte */
		case 0xd:
			event = new_event(track, 0);
			event->type = cmd_type[cmd >> 4];
			event->port = port;
			event->tick = tick;
			event->data.d[0] = cmd & 0x0f;
			event->data.d[1] = read_byte() & 0x7f;
			break;

		case 0xf:
			switch (cmd) {
			case 0xf0: /* sysex */
			case 0xf7: /* continued sysex, or escaped commands */
				len = read_var();
				if (len < 0)
					goto _error;
				if (cmd == 0xf0)
					++len;
				event = new_event(track, len);
				event->type = SND_SEQ_EVENT_SYSEX;
				event->port = port;
				event->tick = tick;
				event->data.length = len;
				if (cmd == 0xf0) {
					event->sysex[0] = 0xf0;
					c = 1;
				} else {
					c = 0;
				}
				for (; c < len; ++c)
					event->sysex[c] = read_byte();
				break;

			case 0xff: /* meta event */
				c = read_byte();
				len = read_var();
				if (len < 0)
					goto _error;

				switch (c) {
				case 0x21: /* port number */
					if (len < 1)
						goto _error;
					port = read_byte() % port_count;
					skip(len - 1);
					break;

				case 0x2f: /* end of track */
					track->end_tick = tick;
					skip(track_end - file_offset);
					return 1;

				case 0x51: /* tempo */
					if (len < 3)
						goto _error;
					if (smpte_timing) {
						/* SMPTE timing doesn't change */
						skip(len);
					} else {
						event = new_event(track, 0);
						event->type = SND_SEQ_EVENT_TEMPO;
						event->port = port;
						event->tick = tick;
						event->data.tempo = read_byte() << 16;
						event->data.tempo |= read_byte() << 8;
						event->data.tempo |= read_byte();
						skip(len - 3);
					}
					break;

				default: /* ignore all other meta events */
					skip(len);
					break;
				}
				break;

			default: /* invalid Fx command */
				goto _error;
			}
			break;

		default: /* cannot happen */
			goto _error;
		}
	}
_error:
	errormsg("%s: invalid MIDI data (offset %#x)", file_name, file_offset);
	return 0;
}

/* reads an entire MIDI file */
static int read_smf(void)
{
	int header_len, type, time_division, i, err;
	snd_seq_queue_tempo_t *queue_tempo;

	/* the curren position is immediately after the "MThd" id */
	header_len = read_int(4);
	if (header_len < 6) {
invalid_format:
		errormsg("%s: invalid file format", file_name);
		return 0;
	}

	type = read_int(2);
	if (type != 0 && type != 1) {
		errormsg("%s: type %d format is not supported", file_name, type);
		return 0;
	}

	num_tracks = read_int(2);
	if (num_tracks < 1 || num_tracks > 1000) {
		errormsg("%s: invalid number of tracks (%d)", file_name, num_tracks);
		num_tracks = 0;
		return 0;
	}
	tracks = calloc(num_tracks, sizeof(struct track));
	if (!tracks) {
		errormsg("out of memory");
		num_tracks = 0;
		return 0;
	}

	time_division = read_int(2);
	if (time_division < 0)
		goto invalid_format;

	/* interpret and set tempo */
	snd_seq_queue_tempo_alloca(&queue_tempo);
	smpte_timing = !!(time_division & 0x8000);
	if (!smpte_timing) {
		/* time_division is ticks per quarter */
		snd_seq_queue_tempo_set_tempo(queue_tempo, 500000); /* default: 120 bpm */
		snd_seq_queue_tempo_set_ppq(queue_tempo, time_division);
	} else {
		/* upper byte is negative frames per second */
		i = 0x80 - ((time_division >> 8) & 0x7f);
		/* lower byte is ticks per frame */
		time_division &= 0xff;
		/* now pretend that we have quarter-note based timing */
		switch (i) {
		case 24:
			snd_seq_queue_tempo_set_tempo(queue_tempo, 500000);
			snd_seq_queue_tempo_set_ppq(queue_tempo, 12 * time_division);
			break;
		case 25:
			snd_seq_queue_tempo_set_tempo(queue_tempo, 400000);
			snd_seq_queue_tempo_set_ppq(queue_tempo, 10 * time_division);
			break;
		case 29: /* 30 drop-frame */
			snd_seq_queue_tempo_set_tempo(queue_tempo, 100000000);
			snd_seq_queue_tempo_set_ppq(queue_tempo, 2997 * time_division);
			break;
		case 30:
			snd_seq_queue_tempo_set_tempo(queue_tempo, 500000);
			snd_seq_queue_tempo_set_ppq(queue_tempo, 15 * time_division);
			break;
		default:
			errormsg("%s: invalid number of SMPTE frames per second (%d)",
				 file_name, i);
			return 0;
		}
	}
	err = snd_seq_set_queue_tempo(seq, queue, queue_tempo);
	if (err < 0) {
		errormsg("Cannot set queue tempo (%u/%i)",
			 snd_seq_queue_tempo_get_tempo(queue_tempo),
			 snd_seq_queue_tempo_get_ppq(queue_tempo));
		return 0;
	}

	/* read tracks */
	for (i = 0; i < num_tracks; ++i) {
		int len;

		/* search for MTrk chunk */
		for (;;) {
			int id = read_id();
			len = read_int(4);
			if (feof(file)) {
				errormsg("%s: unexpected end of file", file_name);
				return 0;
			}
			if (len < 0 || len >= 0x10000000) {
				errormsg("%s: invalid chunk length %d", file_name, len);
				return 0;
			}
			if (id == MAKE_ID('M', 'T', 'r', 'k'))
				break;
			skip(len);
		}
		if (!read_track(&tracks[i], file_offset + len))
			return 0;
	}
	return 1;
}

static int read_riff(void)
{
	/* skip file length */
	read_byte();
	read_byte();
	read_byte();
	read_byte();

	/* check file type ("RMID" = RIFF MIDI) */
	if (read_id() != MAKE_ID('R', 'M', 'I', 'D')) {
invalid_format:
		errormsg("%s: invalid file format", file_name);
		return 0;
	}
	/* search for "data" chunk */
	for (;;) {
		int id = read_id();
		int len = read_32_le();
		if (feof(file)) {
data_not_found:
			errormsg("%s: data chunk not found", file_name);
			return 0;
		}
		if (id == MAKE_ID('d', 'a', 't', 'a'))
			break;
		if (len < 0)
			goto data_not_found;
		skip((len + 1) & ~1);
	}
	/* the "data" chunk must contain data in SMF format */
	if (read_id() != MAKE_ID('M', 'T', 'h', 'd'))
		goto invalid_format;
	return read_smf();
}

static void cleanup_file_data(void)
{
	int i;
	struct event *event;

	for (i = 0; i < num_tracks; ++i) {
		event = tracks[i].first_event;
		while (event) {
			struct event *next = event->next;
			free(event);
			event = next;
		}
	}
	num_tracks = 0;
	free(tracks);
	tracks = NULL;
}

static void handle_big_sysex(snd_seq_event_t *ev)
{
	unsigned int length;
	ssize_t event_size;
	int err;

	length = ev->data.ext.len;
	if (length > MIDI_BYTES_PER_SEC)
		ev->data.ext.len = MIDI_BYTES_PER_SEC;
	event_size = snd_seq_event_length(ev);
	if (event_size + 1 > snd_seq_get_output_buffer_size(seq)) {
		err = snd_seq_drain_output(seq);
		check_snd("drain output", err);
		err = snd_seq_set_output_buffer_size(seq, event_size + 1);
		check_snd("set output buffer size", err);
	}
	while (length > MIDI_BYTES_PER_SEC) {
		err = snd_seq_event_output(seq, ev);
		check_snd("output event", err);
		err = snd_seq_drain_output(seq);
		check_snd("drain output", err);
		err = snd_seq_sync_output_queue(seq);
		check_snd("sync output", err);
		if (sleep(1))
			fatal("aborted");
		ev->data.ext.ptr += MIDI_BYTES_PER_SEC;
		length -= MIDI_BYTES_PER_SEC;
	}
	ev->data.ext.len = length;
}

static void play_midi(void)
{
	snd_seq_event_t ev;
	int i, max_tick, err;

	/* calculate length of the entire file */
	max_tick = -1;
	for (i = 0; i < num_tracks; ++i) {
		if (tracks[i].end_tick > max_tick)
			max_tick = tracks[i].end_tick;
	}

	/* initialize current position in each track */
	for (i = 0; i < num_tracks; ++i)
		tracks[i].current_event = tracks[i].first_event;

	/* common settings for all our events */
	snd_seq_ev_clear(&ev);
	ev.queue = queue;
	ev.source.port = 0;
	ev.flags = SND_SEQ_TIME_STAMP_TICK;

	err = snd_seq_start_queue(seq, queue, NULL);
	check_snd("start queue", err);
	/* The queue won't be started until the START_QUEUE event is
	 * actually drained to the kernel, which is exactly what we want. */

	for (;;) {
		struct event* event = NULL;
		struct track* event_track = NULL;
		int i, min_tick = max_tick + 1;

		/* search next event */
		for (i = 0; i < num_tracks; ++i) {
			struct track *track = &tracks[i];
			struct event *e2 = track->current_event;
			if (e2 && e2->tick < min_tick) {
				min_tick = e2->tick;
				event = e2;
				event_track = track;
			}
		}
		if (!event)
			break; /* end of song reached */

		/* advance pointer to next event */
		event_track->current_event = event->next;

		/* output the event */
		ev.type = event->type;
		ev.time.tick = event->tick;
		ev.dest = ports[event->port];
		switch (ev.type) {
		case SND_SEQ_EVENT_NOTEON:
		case SND_SEQ_EVENT_NOTEOFF:
		case SND_SEQ_EVENT_KEYPRESS:
			snd_seq_ev_set_fixed(&ev);
			ev.data.note.channel = event->data.d[0];
			ev.data.note.note = event->data.d[1];
			ev.data.note.velocity = event->data.d[2];
			break;
		case SND_SEQ_EVENT_CONTROLLER:
			snd_seq_ev_set_fixed(&ev);
			ev.data.control.channel = event->data.d[0];
			ev.data.control.param = event->data.d[1];
			ev.data.control.value = event->data.d[2];
			break;
		case SND_SEQ_EVENT_PGMCHANGE:
		case SND_SEQ_EVENT_CHANPRESS:
			snd_seq_ev_set_fixed(&ev);
			ev.data.control.channel = event->data.d[0];
			ev.data.control.value = event->data.d[1];
			break;
		case SND_SEQ_EVENT_PITCHBEND:
			snd_seq_ev_set_fixed(&ev);
			ev.data.control.channel = event->data.d[0];
			ev.data.control.value =
				((event->data.d[1]) |
				 ((event->data.d[2]) << 7)) - 0x2000;
			break;
		case SND_SEQ_EVENT_SYSEX:
			snd_seq_ev_set_variable(&ev, event->data.length,
						event->sysex);
			handle_big_sysex(&ev);
			break;
		case SND_SEQ_EVENT_TEMPO:
			snd_seq_ev_set_fixed(&ev);
			ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
			ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
			ev.data.queue.queue = queue;
			ev.data.queue.param.value = event->data.tempo;
			break;
		default:
			fatal("Invalid event type %d!", ev.type);
		}

		/* this blocks when the output pool has been filled */
		err = snd_seq_event_output(seq, &ev);
		check_snd("output event", err);
	}

	/* schedule queue stop at end of song */
	snd_seq_ev_set_fixed(&ev);
	ev.type = SND_SEQ_EVENT_STOP;
	ev.time.tick = max_tick;
	ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
	ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
	ev.data.queue.queue = queue;
	err = snd_seq_event_output(seq, &ev);
	check_snd("output event", err);

	/* make sure that the sequencer sees all our events */
	err = snd_seq_drain_output(seq);
	check_snd("drain output", err);

	/*
	 * There are three possibilities how to wait until all events have
	 * been played:
	 * 1) send an event back to us (like pmidi does), and wait for it;
	 * 2) wait for the EVENT_STOP notification for our queue which is sent
	 *    by the system timer port (this would require a subscription);
	 * 3) wait until the output pool is empty.
	 * The last is the simplest.
	 */
	err = snd_seq_sync_output_queue(seq);
	check_snd("sync output", err);

	/* give the last notes time to die away */
	if (end_delay > 0)
		sleep(end_delay);
}

static void play_file(void)
{
	int ok;

	if (!strcmp(file_name, "-"))
		file = stdin;
	else
		file = fopen(file_name, "rb");
	if (!file) {
		errormsg("Cannot open %s - %s", file_name, strerror(errno));
		return;
	}

	file_offset = 0;
	ok = 0;

	switch (read_id()) {
	case MAKE_ID('M', 'T', 'h', 'd'):
		ok = read_smf();
		break;
	case MAKE_ID('R', 'I', 'F', 'F'):
		ok = read_riff();
		break;
	default:
		errormsg("%s is not a Standard MIDI File", file_name);
		break;
	}

	if (file != stdin)
		fclose(file);

	if (ok)
		play_midi();

	cleanup_file_data();
}

static void list_ports(void)
{
	snd_seq_client_info_t *cinfo;
	snd_seq_port_info_t *pinfo;

	snd_seq_client_info_alloca(&cinfo);
	snd_seq_port_info_alloca(&pinfo);

	puts(" Port    Client name                      Port name");

	snd_seq_client_info_set_client(cinfo, -1);
	while (snd_seq_query_next_client(seq, cinfo) >= 0) {
		int client = snd_seq_client_info_get_client(cinfo);

		snd_seq_port_info_set_client(pinfo, client);
		snd_seq_port_info_set_port(pinfo, -1);
		while (snd_seq_query_next_port(seq, pinfo) >= 0) {
			/* port must understand MIDI messages */
			if (!(snd_seq_port_info_get_type(pinfo)
			      & SND_SEQ_PORT_TYPE_MIDI_GENERIC))
				continue;
			/* we need both WRITE and SUBS_WRITE */
			if ((snd_seq_port_info_get_capability(pinfo)
			     & (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE))
			    != (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE))
				continue;
			printf("%3d:%-3d  %-32.32s %s\n",
			       snd_seq_port_info_get_client(pinfo),
			       snd_seq_port_info_get_port(pinfo),
			       snd_seq_client_info_get_name(cinfo),
			       snd_seq_port_info_get_name(pinfo));
		}
	}
}

static void usage(const char *argv0)
{
	printf(
		"Usage: %s -p client:port[,...] [-d delay] midifile ...\n"
		"-h, --help                  this help\n"
		"-V, --version               print current version\n"
		"-l, --list                  list all possible output ports\n"
		"-p, --port=client:port,...  set port(s) to play to\n"
		"-d, --delay=seconds         delay after song ends\n",
		argv0);
}

static void version(void)
{
	puts("aplaymidi version " SND_UTIL_VERSION_STR);
}

int main(int argc, char *argv[])
{
	static const char short_options[] = "hVlp:d:";
	static const struct option long_options[] = {
		{"help", 0, NULL, 'h'},
		{"version", 0, NULL, 'V'},
		{"list", 0, NULL, 'l'},
		{"port", 1, NULL, 'p'},
		{"delay", 1, NULL, 'd'},
		{}
	};
	int c;
	int do_list = 0;

	init_seq();

	while ((c = getopt_long(argc, argv, short_options,
				long_options, NULL)) != -1) {
		switch (c) {
		case 'h':
			usage(argv[0]);
			return 0;
		case 'V':
			version();
			return 0;
		case 'l':
			do_list = 1;
			break;
		case 'p':
			parse_ports(optarg);
			break;
		case 'd':
			end_delay = atoi(optarg);
			break;
		default:
			usage(argv[0]);
			return 1;
		}
	}

	if (do_list) {
		list_ports();
	} else {
		if (port_count < 1) {
			/* use env var for compatibility with pmidi */
			const char *ports_str = getenv("ALSA_OUTPUT_PORTS");
			if (ports_str)
				parse_ports(ports_str);
			if (port_count < 1) {
				errormsg("Please specify at least one port with --port.");
				return 1;
			}
		}
		if (optind >= argc) {
			errormsg("Please specify a file to play.");
			return 1;
		}

		create_source_port();
		create_queue();
		connect_ports();

		for (; optind < argc; ++optind) {
			file_name = argv[optind];
			play_file();
		}
	}
	snd_seq_close(seq);
	return 0;
}
