1 /*-
2  * Copyright (c) 2007, 2008 Edward Tomasz Napierała <trasz@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * ALTHOUGH THIS SOFTWARE IS MADE OF SCIENCE AND WIN, IT IS PROVIDED BY THE
15  * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
18  * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
20  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 /*
29  * This is jack-smf-player, Standard MIDI File player for JACK MIDI.
30  *
31  * For questions and comments, contact Edward Tomasz Napierala <trasz@FreeBSD.org>.
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37 #include <sys/time.h>
38 #include <unistd.h>
39 #include <assert.h>
40 #include <string.h>
41 #include <sysexits.h>
42 #include <errno.h>
43 #include <signal.h>
44 #include <jack/jack.h>
45 #include <jack/midiport.h>
46 #include <glib.h>
47 
48 #include "config.h"
49 #include "smf.h"
50 
51 #ifdef WITH_LASH
52 #include <lash/lash.h>
53 #endif
54 
55 #define PROGRAM_NAME		"jack-smf-player"
56 #define PROGRAM_VERSION		PACKAGE_VERSION
57 
58 #define MIDI_CONTROLLER         0xB0
59 #define MIDI_ALL_SOUND_OFF      120
60 
61 #define MAX_NUMBER_OF_TRACKS	128
62 
63 jack_port_t	*output_ports[MAX_NUMBER_OF_TRACKS];
64 int		drop_messages = 0;
65 jack_client_t	*jack_client = NULL;
66 double		rate_limit = 0;
67 int		just_one_output = 0;
68 int		start_stopped = 0;
69 int		use_transport = 1;
70 int		be_quiet = 0;
71 volatile int	playback_started = -1, song_position = 0, ctrl_c_pressed = 0;
72 smf_t		*smf = NULL;
73 
74 #ifdef WITH_LASH
75 lash_client_t	*lash_client;
76 #endif
77 
78 /* Will emit a warning if time between jack callbacks is longer than this. */
79 #define MAX_TIME_BETWEEN_CALLBACKS	0.1
80 
81 /* Will emit a warning if execution of jack callback takes longer than this. */
82 #define MAX_PROCESSING_TIME	0.01
83 
84 double
get_time(void)85 get_time(void)
86 {
87 	double		seconds;
88 	int		ret;
89 	struct timeval	tv;
90 
91 	ret = gettimeofday(&tv, NULL);
92 
93 	if (ret) {
94 		perror("gettimeofday");
95 		exit(EX_OSERR);
96 	}
97 
98 	seconds = tv.tv_sec + tv.tv_usec / 1000000.0;
99 
100 	return seconds;
101 }
102 
103 double
get_delta_time(void)104 get_delta_time(void)
105 {
106 	static double	previously = -1.0;
107 	double		now;
108 	double		delta;
109 
110 	now = get_time();
111 
112 	if (previously == -1.0) {
113 		previously = now;
114 
115 		return 0;
116 	}
117 
118 	delta = now - previously;
119 	previously = now;
120 
121 	assert(delta >= 0.0);
122 
123 	return delta;
124 }
125 
126 static gboolean
warning_async(gpointer s)127 warning_async(gpointer s)
128 {
129 	const char *str = (const char *)s;
130 
131 	g_warning(str);
132 
133 	return FALSE;
134 }
135 
136 static void
warn_from_jack_thread_context(const char * str)137 warn_from_jack_thread_context(const char *str)
138 {
139 	g_idle_add(warning_async, (gpointer)str);
140 }
141 
142 static double
nframes_to_ms(jack_nframes_t nframes)143 nframes_to_ms(jack_nframes_t nframes)
144 {
145 	jack_nframes_t sr;
146 
147 	sr = jack_get_sample_rate(jack_client);
148 
149 	assert(sr > 0);
150 
151 	return (nframes * 1000.0) / (double)sr;
152 }
153 
154 static double
nframes_to_seconds(jack_nframes_t nframes)155 nframes_to_seconds(jack_nframes_t nframes)
156 {
157 	return nframes_to_ms(nframes) / 1000.0;
158 }
159 
160 static jack_nframes_t
ms_to_nframes(double ms)161 ms_to_nframes(double ms)
162 {
163 	jack_nframes_t sr;
164 
165 	sr = jack_get_sample_rate(jack_client);
166 
167 	assert(sr > 0);
168 
169 	return ((double)sr * ms) / 1000.0;
170 }
171 
172 static jack_nframes_t
seconds_to_nframes(double seconds)173 seconds_to_nframes(double seconds)
174 {
175 	return ms_to_nframes(seconds * 1000.0);
176 }
177 
178 static void
send_all_sound_off(void * port_buffers[MAX_NUMBER_OF_TRACKS],jack_nframes_t nframes)179 send_all_sound_off(void *port_buffers[MAX_NUMBER_OF_TRACKS], jack_nframes_t nframes)
180 {
181 	int i, channel;
182 	unsigned char *buffer;
183 
184 	for (i = 0; i <= smf->number_of_tracks; i++) {
185 		for (channel = 0; channel < 16; channel++) {
186 #ifdef JACK_MIDI_NEEDS_NFRAMES
187 			buffer = jack_midi_event_reserve(port_buffers[i], 0, 3, nframes);
188 #else
189 			buffer = jack_midi_event_reserve(port_buffers[i], 0, 3);
190 #endif
191 			if (buffer == NULL) {
192 				warn_from_jack_thread_context("jack_midi_event_reserve failed, cannot send All Sound Off.");
193 				break;
194 			}
195 
196 			buffer[0] = MIDI_CONTROLLER | channel;
197 			buffer[1] = MIDI_ALL_SOUND_OFF;
198 			buffer[2] = 0;
199 		}
200 
201 		if (just_one_output)
202 			break;
203 	}
204 }
205 
206 static void
process_midi_output(jack_nframes_t nframes)207 process_midi_output(jack_nframes_t nframes)
208 {
209 	int		i, t, bytes_remaining, track_number;
210 	unsigned char  *buffer, tmp_status;
211 	void		*port_buffers[MAX_NUMBER_OF_TRACKS];
212 	jack_nframes_t	last_frame_time;
213 	jack_transport_state_t transport_state;
214 	static jack_transport_state_t previous_transport_state = JackTransportStopped;
215 
216 	for (i = 0; i <= smf->number_of_tracks; i++) {
217 		port_buffers[i] = jack_port_get_buffer(output_ports[i], nframes);
218 
219 		if (port_buffers[i] == NULL) {
220 			warn_from_jack_thread_context("jack_port_get_buffer failed, cannot send anything.");
221 			return;
222 		}
223 
224 #ifdef JACK_MIDI_NEEDS_NFRAMES
225 		jack_midi_clear_buffer(port_buffers[i], nframes);
226 #else
227 		jack_midi_clear_buffer(port_buffers[i]);
228 #endif
229 
230 		if (just_one_output)
231 			break;
232 	}
233 
234 	if (ctrl_c_pressed) {
235 		send_all_sound_off(port_buffers, nframes);
236 
237 		/* The idea here is to exit at the second time process_midi_output gets called.
238 		   Otherwise, All Sound Off won't be delivered. */
239 		ctrl_c_pressed++;
240 		if (ctrl_c_pressed >= 3)
241 			exit(0);
242 
243 		return;
244 	}
245 
246 	if (use_transport) {
247 		transport_state = jack_transport_query(jack_client, NULL);
248 		if (transport_state == JackTransportStopped) {
249 			if (previous_transport_state == JackTransportRolling)
250 				send_all_sound_off(port_buffers, nframes);
251 
252 			previous_transport_state = transport_state;
253 
254 			return;
255 		}
256 
257 		previous_transport_state = transport_state;
258 	}
259 
260 	last_frame_time = jack_last_frame_time(jack_client);
261 
262 	/* End of song already? */
263 	if (playback_started < 0)
264 		return;
265 
266 	/* We may push at most one byte per 0.32ms to stay below 31.25 Kbaud limit. */
267 	bytes_remaining = nframes_to_ms(nframes) * rate_limit;
268 
269 	for (;;) {
270 		smf_event_t *event = smf_peek_next_event(smf);
271 
272 		if (event == NULL) {
273 			if (!be_quiet)
274 				g_debug("End of song.");
275 			playback_started = -1;
276 
277 			if (!use_transport)
278 				ctrl_c_pressed = 1;
279 
280 			break;
281 		}
282 
283 		/* Skip over metadata events. */
284 		if (smf_event_is_metadata(event)) {
285 			char *decoded = smf_event_decode(event);
286 			if (decoded && !be_quiet)
287 				g_debug("Metadata: %s", decoded);
288 
289 			smf_get_next_event(smf);
290 			continue;
291 		}
292 
293 		bytes_remaining -= event->midi_buffer_length;
294 
295 		if (rate_limit > 0.0 && bytes_remaining <= 0) {
296 			warn_from_jack_thread_context("Rate limiting in effect.");
297 			break;
298 		}
299 
300 		t = seconds_to_nframes(event->time_seconds) + playback_started - song_position + nframes - last_frame_time;
301 
302 		/* If computed time is too much into the future, we'll need
303 		   to send it later. */
304 		if (t >= (int)nframes)
305 			break;
306 
307 		/* If computed time is < 0, we missed a cycle because of xrun. */
308 		if (t < 0)
309 			t = 0;
310 
311 		assert(event->track->track_number >= 0 && event->track->track_number <= MAX_NUMBER_OF_TRACKS);
312 
313 		/* We will send this event; remove it from the queue. */
314 		smf_get_next_event(smf);
315 
316 		/* First, send it via midi_out. */
317 		track_number = 0;
318 
319 #ifdef JACK_MIDI_NEEDS_NFRAMES
320 		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length, nframes);
321 #else
322 		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length);
323 #endif
324 
325 		if (buffer == NULL) {
326 			warn_from_jack_thread_context("jack_midi_event_reserve failed, NOTE LOST.");
327 			break;
328 		}
329 
330 		memcpy(buffer, event->midi_buffer, event->midi_buffer_length);
331 
332 		/* Ignore per-track outputs? */
333 		if (just_one_output)
334 			continue;
335 
336 		/* Send it via proper output port. */
337 		track_number = event->track->track_number;
338 
339 #ifdef JACK_MIDI_NEEDS_NFRAMES
340 		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length, nframes);
341 #else
342 		buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length);
343 #endif
344 
345 		if (buffer == NULL) {
346 			warn_from_jack_thread_context("jack_midi_event_reserve failed, NOTE LOST.");
347 			break;
348 		}
349 
350 		/* Before sending, reset channel to 0. XXX: Not very pretty. */
351 		assert(event->midi_buffer_length >= 1);
352 
353 		tmp_status = event->midi_buffer[0];
354 
355 		if (event->midi_buffer[0] >= 0x80 && event->midi_buffer[0] <= 0xEF)
356 			event->midi_buffer[0] &= 0xF0;
357 
358 		memcpy(buffer, event->midi_buffer, event->midi_buffer_length);
359 
360 		event->midi_buffer[0] = tmp_status;
361 	}
362 }
363 
364 static int
process_callback(jack_nframes_t nframes,void * notused)365 process_callback(jack_nframes_t nframes, void *notused)
366 {
367 #ifdef MEASURE_TIME
368 	if (get_delta_time() > MAX_TIME_BETWEEN_CALLBACKS) {
369 		warn_from_jack_thread_context("Had to wait too long for JACK callback; scheduling problem?");
370 	}
371 #endif
372 
373 	/* Check for impossible condition that actually happened to me, caused by some problem between jackd and OSS4. */
374 	if (nframes <= 0) {
375 		warn_from_jack_thread_context("Process callback called with nframes = 0; bug in JACK?");
376 		return 0;
377 	}
378 
379 	process_midi_output(nframes);
380 
381 #ifdef MEASURE_TIME
382 	if (get_delta_time() > MAX_PROCESSING_TIME) {
383 		warn_from_jack_thread_context("Processing took too long; scheduling problem?");
384 	}
385 #endif
386 
387 	return 0;
388 }
389 
390 static int
sync_callback(jack_transport_state_t state,jack_position_t * position,void * notused)391 sync_callback(jack_transport_state_t state, jack_position_t *position, void *notused)
392 {
393 	assert(jack_client);
394 
395 	/* XXX: We should probably adapt to external tempo changes. */
396 
397 	if (state == JackTransportStarting) {
398 		song_position = position->frame;
399 		smf_seek_to_seconds(smf, nframes_to_seconds(position->frame));
400 
401 		if (!be_quiet)
402 			g_debug("Seeking to %f seconds.", nframes_to_seconds(position->frame));
403 
404 		playback_started = jack_frame_time(jack_client);
405 
406 	} else if (state == JackTransportStopped) {
407 		playback_started = -1;
408 	}
409 
410 	return TRUE;
411 }
412 
timebase_callback(jack_transport_state_t state,jack_nframes_t nframes,jack_position_t * pos,int new_pos,void * notused)413 void timebase_callback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *notused)
414 {
415 	double min;		/* Minutes since frame 0. */
416 	long abs_tick;		/* Ticks since frame 0. */
417 	long abs_beat;		/* Beats since frame 0. */
418 	smf_tempo_t *tempo;
419 	static smf_tempo_t *previous_tempo = NULL;
420 
421 	smf_event_t *event = smf_peek_next_event(smf);
422 	if (event == NULL)
423 		return;
424 
425 	tempo = smf_get_tempo_by_pulses(smf, event->time_pulses);
426 
427 	assert(tempo);
428 
429 	if (new_pos || previous_tempo != tempo) {
430 		pos->valid = JackPositionBBT;
431 		pos->beats_per_bar = tempo->numerator;
432 		pos->beat_type = 1.0 / (double)tempo->denominator;
433 		pos->ticks_per_beat = event->track->smf->ppqn; /* XXX: Is this right? */
434 		pos->beats_per_minute = 60000000.0 / (double)tempo->microseconds_per_quarter_note;
435 
436 		min = pos->frame / ((double) pos->frame_rate * 60.0);
437 		abs_tick = min * pos->beats_per_minute * pos->ticks_per_beat;
438 		abs_beat = abs_tick / pos->ticks_per_beat;
439 
440 		pos->bar = abs_beat / pos->beats_per_bar;
441 		pos->beat = abs_beat - (pos->bar * pos->beats_per_bar) + 1;
442 		pos->tick = abs_tick - (abs_beat * pos->ticks_per_beat);
443 		pos->bar_start_tick = pos->bar * pos->beats_per_bar * pos->ticks_per_beat;
444 		pos->bar++; /* adjust start to bar 1 */
445 
446 		previous_tempo = tempo;
447 
448 	} else {
449 		/* Compute BBT info based on previous period. */
450 		pos->tick += nframes * pos->ticks_per_beat * pos->beats_per_minute / (pos->frame_rate * 60);
451 
452 		while (pos->tick >= pos->ticks_per_beat) {
453 			pos->tick -= pos->ticks_per_beat;
454 			if (++pos->beat > pos->beats_per_bar) {
455 				pos->beat = 1;
456 				++pos->bar;
457 				pos->bar_start_tick += pos->beats_per_bar * pos->ticks_per_beat;
458 			}
459 		}
460 	}
461 }
462 
463 /* Connects to the specified input port, disconnecting already connected ports. */
464 int
connect_to_input_port(const char * port)465 connect_to_input_port(const char *port)
466 {
467 	int ret;
468 
469 	ret = jack_port_disconnect(jack_client, output_ports[0]);
470 
471 	if (ret) {
472 		g_warning("Cannot disconnect MIDI port.");
473 
474 		return -3;
475 	}
476 
477 	ret = jack_connect(jack_client, jack_port_name(output_ports[0]), port);
478 
479 	if (ret) {
480 		g_warning("Cannot connect to %s.", port);
481 
482 		return -4;
483 	}
484 
485 	g_warning("Connected to %s.", port);
486 
487 	return 0;
488 }
489 
490 static void
init_jack(void)491 init_jack(void)
492 {
493 	int i, err;
494 
495 #ifdef WITH_LASH
496 	lash_event_t *event;
497 #endif
498 
499 	jack_client = jack_client_open(PROGRAM_NAME, JackNullOption, NULL);
500 
501 	if (jack_client == NULL) {
502 		g_critical("Could not connect to the JACK server; run jackd first?");
503 		exit(EX_UNAVAILABLE);
504 	}
505 
506 #ifdef WITH_LASH
507 	event = lash_event_new_with_type(LASH_Client_Name);
508 	assert (event); /* Documentation does not say anything about return value. */
509 	lash_event_set_string(event, jack_get_client_name(jack_client));
510 	lash_send_event(lash_client, event);
511 
512 	lash_jack_client_name(lash_client, jack_get_client_name(jack_client));
513 #endif
514 
515 	err = jack_set_process_callback(jack_client, process_callback, 0);
516 	if (err) {
517 		g_critical("Could not register JACK process callback.");
518 		exit(EX_UNAVAILABLE);
519 	}
520 
521 	if (use_transport) {
522 		err = jack_set_sync_callback(jack_client, sync_callback, 0);
523 		if (err) {
524 			g_critical("Could not register JACK sync callback.");
525 			exit(EX_UNAVAILABLE);
526 		}
527 #if 0
528 		err = jack_set_timebase_callback(jack_client, 1, timebase_callback, 0);
529 		if (err) {
530 			g_critical("Could not register JACK timebase callback.");
531 			exit(EX_UNAVAILABLE);
532 		}
533 #endif
534 	}
535 
536 	assert(smf->number_of_tracks >= 1);
537 
538 	/* We are allocating number_of_tracks + 1 output ports. */
539 	for (i = 0; i <= smf->number_of_tracks; i++) {
540 		char port_name[32];
541 
542 		if (i == 0)
543 			snprintf(port_name, sizeof(port_name), "midi_out");
544 		else
545 			snprintf(port_name, sizeof(port_name), "track_%d_midi_out", i);
546 
547 		output_ports[i] = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
548 
549 		if (output_ports[i] == NULL) {
550 			g_critical("Could not register JACK output port '%s'.", port_name);
551 			exit(EX_UNAVAILABLE);
552 		}
553 
554 		if (just_one_output)
555 			break;
556 	}
557 
558 	if (jack_activate(jack_client)) {
559 		g_critical("Cannot activate JACK client.");
560 		exit(EX_UNAVAILABLE);
561 	}
562 }
563 
564 #ifdef WITH_LASH
565 
566 static gboolean
lash_callback(gpointer notused)567 lash_callback(gpointer notused)
568 {
569 	lash_event_t	*event;
570 
571 	while ((event = lash_get_event(lash_client))) {
572 		switch (lash_event_get_type(event)) {
573 			case LASH_Restore_Data_Set:
574 			case LASH_Save_Data_Set:
575 				break;
576 
577 			case LASH_Quit:
578 				g_warning("Exiting due to LASH request.");
579 				ctrl_c_pressed = 1;
580 				break;
581 
582 			default:
583 				g_warning("Receieved unknown LASH event of type %d.", lash_event_get_type(event));
584 				lash_event_destroy(event);
585 		}
586 	}
587 
588 	return TRUE;
589 }
590 
591 static void
init_lash(lash_args_t * args)592 init_lash(lash_args_t *args)
593 {
594 	/* XXX: Am I doing the right thing wrt protocol version? */
595 	lash_client = lash_init(args, PROGRAM_NAME, LASH_Config_Data_Set, LASH_PROTOCOL(2, 0));
596 
597 	if (!lash_server_connected(lash_client)) {
598 		g_critical("Cannot initialize LASH.  Continuing anyway.");
599 		/* exit(EX_UNAVAILABLE); */
600 
601 		return;
602 	}
603 
604 	/* Schedule a function to process LASH events, ten times per second. */
605 	g_timeout_add(100, lash_callback, NULL);
606 }
607 
608 #endif /* WITH_LASH */
609 
610 /*
611  * This is neccessary for exiting due to jackd being killed, when exit(0)
612  * in process_callback won't get called for obvious reasons.
613  */
614 gboolean
emergency_exit_timeout(gpointer notused)615 emergency_exit_timeout(gpointer notused)
616 {
617 	if (ctrl_c_pressed == 0)
618 		return TRUE;
619 
620 	exit(0);
621 }
622 
623 void
ctrl_c_handler(int signum)624 ctrl_c_handler(int signum)
625 {
626 	ctrl_c_pressed = 1;
627 }
628 
629 static void
log_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer notused)630 log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer notused)
631 {
632 	fprintf(stderr, "%s: %s\n", log_domain, message);
633 }
634 
635 static void
show_version(void)636 show_version(void)
637 {
638 	fprintf(stdout, "%s %s, libsmf %s\n", PROGRAM_NAME, PROGRAM_VERSION, smf_get_version());
639 
640 	exit(EX_OK);
641 }
642 
643 static void
usage(void)644 usage(void)
645 {
646 	fprintf(stderr, "usage: jack-smf-player [-dnqstV] [ -a <input port>] [-r <rate>] file_name\n");
647 
648 	exit(EX_USAGE);
649 }
650 
651 int
main(int argc,char * argv[])652 main(int argc, char *argv[])
653 {
654 	int		ch;
655 	char		*file_name, *autoconnect_port_name = NULL;
656 
657 #ifdef WITH_LASH
658 	lash_args_t *lash_args;
659 #endif
660 
661 	g_thread_init(NULL);
662 
663 #ifdef WITH_LASH
664 	lash_args = lash_extract_args(&argc, &argv);
665 #endif
666 
667 	g_log_set_default_handler(log_handler, NULL);
668 
669 	while ((ch = getopt(argc, argv, "a:dnqr:stV")) != -1) {
670 		switch (ch) {
671 			case 'a':
672 				autoconnect_port_name = strdup(optarg);
673 				break;
674 
675 			case 'd':
676 				drop_messages = 1;
677 				break;
678 
679 			case 'n':
680 				start_stopped = 1;
681 				break;
682 
683 			case 'q':
684 				be_quiet = 1;
685 				break;
686 
687 			case 'r':
688 				rate_limit = strtod(optarg, NULL);
689 				if (rate_limit <= 0.0) {
690 					g_critical("Invalid rate limit specified.\n");
691 
692 					exit(EX_USAGE);
693 				}
694 
695 				break;
696 
697 			case 's':
698 				just_one_output = 1;
699 				break;
700 
701 			case 't':
702 				use_transport = 0;
703 				break;
704 
705 			case 'V':
706 				show_version();
707 				break;
708 
709 			case '?':
710 			default:
711 				usage();
712 		}
713 	}
714 
715 	argc -= optind;
716 	argv += optind;
717 
718 	if (argv[0] == NULL) {
719 		g_critical("No file name given.");
720 		usage();
721 	}
722 
723 	file_name = argv[0];
724 
725 	smf = smf_load(file_name);
726 
727 	if (smf == NULL) {
728 		g_critical("Loading SMF file failed.");
729 
730 		exit(-1);
731 	}
732 
733 	if (!be_quiet)
734 		g_message("%s.", smf_decode(smf));
735 
736 	if (smf->number_of_tracks > MAX_NUMBER_OF_TRACKS) {
737 		g_warning("Number of tracks (%d) exceeds maximum for per-track output; implying '-s' option.", smf->number_of_tracks);
738 		just_one_output = 1;
739 	}
740 
741 #ifdef WITH_LASH
742 	init_lash(lash_args);
743 #endif
744 
745 	g_timeout_add(1000, emergency_exit_timeout, (gpointer)0);
746 	signal(SIGINT, ctrl_c_handler);
747 
748 	init_jack();
749 
750 	if (autoconnect_port_name) {
751 		if (connect_to_input_port(autoconnect_port_name)) {
752 			g_critical("Couldn't connect to '%s', exiting.", autoconnect_port_name);
753 			exit(EX_UNAVAILABLE);
754 		}
755 	}
756 
757 	if (use_transport && !start_stopped) {
758 		jack_transport_locate(jack_client, 0);
759 		jack_transport_start(jack_client);
760 	}
761 
762 	if (!use_transport)
763 		playback_started = jack_frame_time(jack_client);
764 
765 	g_main_loop_run(g_main_loop_new(NULL, TRUE));
766 
767 	/* Not reached. */
768 
769 	return 0;
770 }
771 
772