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 Standard MIDI File format implementation.
30  *
31  * For questions and comments, contact Edward Tomasz Napierala <trasz@FreeBSD.org>.
32  */
33 
34 /* Reference: http://www.borg.com/~jglatt/tech/midifile.htm */
35 
36 #include <stdlib.h>
37 #include <string.h>
38 #include <assert.h>
39 #include <math.h>
40 #include <errno.h>
41 #include <arpa/inet.h>
42 #include "smf.h"
43 #include "smf_private.h"
44 
45 /**
46  * Allocates new smf_t structure.
47  * \return pointer to smf_t or NULL.
48  */
49 smf_t *
smf_new(void)50 smf_new(void)
51 {
52 	smf_t *smf = malloc(sizeof(smf_t));
53 	if (smf == NULL) {
54 		g_critical("Cannot allocate smf_t structure: %s", strerror(errno));
55 		return NULL;
56 	}
57 
58 	memset(smf, 0, sizeof(smf_t));
59 
60 	smf->tracks_array = g_ptr_array_new();
61 	assert(smf->tracks_array);
62 
63 	smf->tempo_array = g_ptr_array_new();
64 	assert(smf->tempo_array);
65 
66 	smf_set_ppqn(smf, 120);
67 	smf_set_format(smf, 0);
68 	smf_init_tempo(smf);
69 
70 	return smf;
71 }
72 
73 /**
74  * Frees smf and all it's descendant structures.
75  */
76 void
smf_delete(smf_t * smf)77 smf_delete(smf_t *smf)
78 {
79 	/* Remove all the tracks, from last to first. */
80 	while (smf->tracks_array->len > 0)
81 		smf_track_delete(g_ptr_array_index(smf->tracks_array, smf->tracks_array->len - 1));
82 
83 	assert(smf->tracks_array->len == 0);
84 	assert(smf->number_of_tracks == 0);
85 	g_ptr_array_free(smf->tracks_array, TRUE);
86 	g_ptr_array_free(smf->tempo_array, TRUE);
87 
88 	memset(smf, 0, sizeof(smf_t));
89 	free(smf);
90 }
91 
92 /**
93  * Allocates new smf_track_t structure.
94  * \return pointer to smf_track_t or NULL.
95  */
96 smf_track_t *
smf_track_new(void)97 smf_track_new(void)
98 {
99 	smf_track_t *track = malloc(sizeof(smf_track_t));
100 	if (track == NULL) {
101 		g_critical("Cannot allocate smf_track_t structure: %s", strerror(errno));
102 		return NULL;
103 	}
104 
105 	memset(track, 0, sizeof(smf_track_t));
106 	track->next_event_number = -1;
107 
108 	track->events_array = g_ptr_array_new();
109 	assert(track->events_array);
110 
111 	return track;
112 }
113 
114 /**
115  * Detaches track from its smf and frees it.
116  */
117 void
smf_track_delete(smf_track_t * track)118 smf_track_delete(smf_track_t *track)
119 {
120 	assert(track);
121 	assert(track->events_array);
122 
123 	/* Remove all the events, from last to first. */
124 	while (track->events_array->len > 0)
125 		smf_event_delete(g_ptr_array_index(track->events_array, track->events_array->len - 1));
126 
127 	if (track->smf)
128 		smf_remove_track(track);
129 
130 	assert(track->events_array->len == 0);
131 	assert(track->number_of_events == 0);
132 	g_ptr_array_free(track->events_array, TRUE);
133 
134 	memset(track, 0, sizeof(smf_track_t));
135 	free(track);
136 }
137 
138 
139 /**
140  * Appends smf_track_t to smf.
141  */
142 void
smf_add_track(smf_t * smf,smf_track_t * track)143 smf_add_track(smf_t *smf, smf_track_t *track)
144 {
145 	assert(track->smf == NULL);
146 
147 	track->smf = smf;
148 	g_ptr_array_add(smf->tracks_array, track);
149 
150 	smf->number_of_tracks++;
151 	track->track_number = smf->number_of_tracks;
152 
153 	if (smf->number_of_tracks > 1)
154 		smf_set_format(smf, 1);
155 }
156 
157 /**
158  * Detaches track from the smf.
159  */
160 void
smf_remove_track(smf_track_t * track)161 smf_remove_track(smf_track_t *track)
162 {
163 	int i;
164 	smf_track_t *tmp;
165 
166 	assert(track->smf != NULL);
167 
168 	track->smf->number_of_tracks--;
169 
170 	assert(track->smf->tracks_array);
171 	g_ptr_array_remove(track->smf->tracks_array, track);
172 
173 	/* Renumber the rest of the tracks, so they are consecutively numbered. */
174 	for (i = track->track_number; i <= track->smf->number_of_tracks; i++) {
175 		tmp = smf_get_track_by_number(track->smf, i);
176 		tmp->track_number = i;
177 	}
178 
179 	track->track_number = -1;
180 	track->smf = NULL;
181 }
182 
183 /**
184  * Allocates new smf_event_t structure.  The caller is responsible for allocating
185  * event->midi_buffer, filling it with MIDI data and setting event->midi_buffer_length properly.
186  * Note that event->midi_buffer will be freed by smf_event_delete.
187  * \return pointer to smf_event_t or NULL.
188  */
189 smf_event_t *
smf_event_new(void)190 smf_event_new(void)
191 {
192 	smf_event_t *event = malloc(sizeof(smf_event_t));
193 	if (event == NULL) {
194 		g_critical("Cannot allocate smf_event_t structure: %s", strerror(errno));
195 		return NULL;
196 	}
197 
198 	memset(event, 0, sizeof(smf_event_t));
199 
200 	event->delta_time_pulses = -1;
201 	event->time_pulses = -1;
202 	event->time_seconds = -1.0;
203 	event->track_number = -1;
204 
205 	return event;
206 }
207 
208 /**
209  * Allocates an smf_event_t structure and fills it with "len" bytes copied
210  * from "midi_data".
211  * \param midi_data Pointer to MIDI data.  It sill be copied to the newly allocated event->midi_buffer.
212  * \param len Length of the buffer.  It must be proper MIDI event length, e.g. 3 for Note On event.
213  * \return Event containing MIDI data or NULL.
214  */
215 smf_event_t *
smf_event_new_from_pointer(void * midi_data,int len)216 smf_event_new_from_pointer(void *midi_data, int len)
217 {
218 	smf_event_t *event;
219 
220 	event = smf_event_new();
221 	if (event == NULL)
222 		return NULL;
223 
224 	event->midi_buffer_length = len;
225 	event->midi_buffer = malloc(event->midi_buffer_length);
226 	if (event->midi_buffer == NULL) {
227 		g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
228 		smf_event_delete(event);
229 
230 		return NULL;
231 	}
232 
233 	memcpy(event->midi_buffer, midi_data, len);
234 
235 	return event;
236 }
237 
238 /**
239  * Allocates an smf_event_t structure and fills it with at most three bytes of data.
240  * For example, if you need to create Note On event, do something like this:
241  *
242  * smf_event_new_from_bytes(0x90, 0x3C, 0x7f);
243  *
244  * To create event for MIDI message that is shorter than three bytes, do something
245  * like this:
246  *
247  * smf_event_new_from_bytes(0xC0, 0x42, -1);
248  *
249  * \param first_byte First byte of MIDI message.  Must be valid status byte.
250  * \param second_byte Second byte of MIDI message or -1, if message is one byte long.
251  * \param third_byte Third byte of MIDI message or -1, if message is two bytes long.
252  * \return Event containing MIDI data or NULL.
253  */
254 smf_event_t *
smf_event_new_from_bytes(int first_byte,int second_byte,int third_byte)255 smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte)
256 {
257 	int len;
258 
259 	smf_event_t *event;
260 
261 	event = smf_event_new();
262 	if (event == NULL)
263 		return NULL;
264 
265 	if (first_byte < 0) {
266 		g_critical("First byte of MIDI message cannot be < 0");
267 		smf_event_delete(event);
268 
269 		return NULL;
270 	}
271 
272 	if (first_byte > 255) {
273 		g_critical("smf_event_new_from_bytes: first byte is %d, which is larger than 255.", first_byte);
274 		return NULL;
275 	}
276 
277 	if (!is_status_byte(first_byte)) {
278 		g_critical("smf_event_new_from_bytes: first byte is not a valid status byte.");
279 		return NULL;
280 	}
281 
282 
283 	if (second_byte < 0)
284 		len = 1;
285 	else if (third_byte < 0)
286 		len = 2;
287 	else
288 		len = 3;
289 
290 	if (len > 1) {
291 		if (second_byte > 255) {
292 			g_critical("smf_event_new_from_bytes: second byte is %d, which is larger than 255.", second_byte);
293 			return NULL;
294 		}
295 
296 		if (is_status_byte(second_byte)) {
297 			g_critical("smf_event_new_from_bytes: second byte cannot be a status byte.");
298 			return NULL;
299 		}
300 	}
301 
302 	if (len > 2) {
303 		if (third_byte > 255) {
304 			g_critical("smf_event_new_from_bytes: third byte is %d, which is larger than 255.", third_byte);
305 			return NULL;
306 		}
307 
308 		if (is_status_byte(third_byte)) {
309 			g_critical("smf_event_new_from_bytes: third byte cannot be a status byte.");
310 			return NULL;
311 		}
312 	}
313 
314 	event->midi_buffer_length = len;
315 	event->midi_buffer = malloc(event->midi_buffer_length);
316 	if (event->midi_buffer == NULL) {
317 		g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
318 		smf_event_delete(event);
319 
320 		return NULL;
321 	}
322 
323 	event->midi_buffer[0] = first_byte;
324 	if (len > 1)
325 		event->midi_buffer[1] = second_byte;
326 	if (len > 2)
327 		event->midi_buffer[2] = third_byte;
328 
329 	return event;
330 }
331 
332 /**
333  * Detaches event from its track and frees it.
334  */
335 void
smf_event_delete(smf_event_t * event)336 smf_event_delete(smf_event_t *event)
337 {
338 	if (event->track != NULL)
339 		smf_track_remove_event(event);
340 
341 	if (event->midi_buffer != NULL)
342 		free(event->midi_buffer);
343 
344 	memset(event, 0, sizeof(smf_event_t));
345 	free(event);
346 }
347 
348 /**
349  * Used for sorting track->events_array.
350  */
351 static gint
events_array_compare_function(gconstpointer aa,gconstpointer bb)352 events_array_compare_function(gconstpointer aa, gconstpointer bb)
353 {
354 	smf_event_t *a, *b;
355 
356 	/* "The comparison function for g_ptr_array_sort() doesn't take the pointers
357 	    from the array as arguments, it takes pointers to the pointers in the array." */
358 	a = (smf_event_t *)*(gpointer *)aa;
359 	b = (smf_event_t *)*(gpointer *)bb;
360 
361 	if (a->time_pulses < b->time_pulses)
362 		return -1;
363 
364 	if (a->time_pulses > b->time_pulses)
365 		return 1;
366 
367 	return 0;
368 }
369 
370 /*
371  * An assumption here is that if there is an EOT event, it will be at the end of the track.
372  */
373 static void
remove_eot_if_before_pulses(smf_track_t * track,int pulses)374 remove_eot_if_before_pulses(smf_track_t *track, int pulses)
375 {
376 	smf_event_t *event;
377 
378 	event = smf_track_get_last_event(track);
379 
380 	if (event == NULL)
381 		return;
382 
383 	if (!smf_event_is_eot(event))
384 		return;
385 
386 	if (event->time_pulses > pulses)
387 		return;
388 
389 	smf_track_remove_event(event);
390 }
391 
392 /**
393  * Adds the event to the track and computes ->delta_pulses.  Note that it is faster
394  * to append events to the end of the track than to insert them in the middle.
395  * Usually you want to use smf_track_add_event_seconds or smf_track_add_event_pulses
396  * instead of this one.  Event needs to have ->time_pulses and ->time_seconds already set.
397  * If you try to add event after an EOT, EOT event will be automatically deleted.
398  */
399 void
smf_track_add_event(smf_track_t * track,smf_event_t * event)400 smf_track_add_event(smf_track_t *track, smf_event_t *event)
401 {
402 	int i;
403 	int last_pulses = 0;
404 
405 	assert(track->smf != NULL);
406 	assert(event->track == NULL);
407 	assert(event->delta_time_pulses == -1);
408 	assert(event->time_pulses >= 0);
409 	assert(event->time_seconds >= 0.0);
410 
411 	remove_eot_if_before_pulses(track, event->time_pulses);
412 
413 	event->track = track;
414 	event->track_number = track->track_number;
415 
416 	if (track->number_of_events == 0) {
417 		assert(track->next_event_number == -1);
418 		track->next_event_number = 1;
419 	}
420 
421 	if (track->number_of_events > 0)
422 		last_pulses = smf_track_get_last_event(track)->time_pulses;
423 
424 	track->number_of_events++;
425 
426 	/* Are we just appending element at the end of the track? */
427 	if (last_pulses <= event->time_pulses) {
428 		event->delta_time_pulses = event->time_pulses - last_pulses;
429 		assert(event->delta_time_pulses >= 0);
430 		g_ptr_array_add(track->events_array, event);
431 		event->event_number = track->number_of_events;
432 
433 	/* We need to insert in the middle of the track.  XXX: This is slow. */
434 	} else {
435 		/* Append, then sort according to ->time_pulses. */
436 		g_ptr_array_add(track->events_array, event);
437 		g_ptr_array_sort(track->events_array, events_array_compare_function);
438 
439 		/* Renumber entries and fix their ->delta_pulses. */
440 		for (i = 1; i <= track->number_of_events; i++) {
441 			smf_event_t *tmp = smf_track_get_event_by_number(track, i);
442 			tmp->event_number = i;
443 
444 			if (tmp->delta_time_pulses != -1)
445 				continue;
446 
447 			if (i == 1) {
448 				tmp->delta_time_pulses = tmp->time_pulses;
449 			} else {
450 				tmp->delta_time_pulses = tmp->time_pulses -
451 					smf_track_get_event_by_number(track, i - 1)->time_pulses;
452 				assert(tmp->delta_time_pulses >= 0);
453 			}
454 		}
455 	}
456 
457 	if (smf_event_is_tempo_change_or_time_signature(event)) {
458 		if (smf_event_is_last(event))
459 			maybe_add_to_tempo_map(event);
460 		else
461 			smf_create_tempo_map_and_compute_seconds(event->track->smf);
462 	}
463 }
464 
465 /**
466  * Add End Of Track metaevent.  Using it is optional, libsmf will automatically
467  * add EOT to the tracks during smf_save, with delta_pulses 0.  If you try to add EOT
468  * in the middle of the track, it will fail and nonzero value will be returned.
469  * If you try to add EOT after another EOT event, it will be added, but the existing
470  * EOT event will be removed.
471  *
472  * \return 0 if everything went ok, nonzero otherwise.
473  */
474 int
smf_track_add_eot_delta_pulses(smf_track_t * track,int delta)475 smf_track_add_eot_delta_pulses(smf_track_t *track, int delta)
476 {
477 	smf_event_t *event;
478 
479 	event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00);
480 	if (event == NULL)
481 		return -1;
482 
483 	smf_track_add_event_delta_pulses(track, event, delta);
484 
485 	return 0;
486 }
487 
488 int
smf_track_add_eot_pulses(smf_track_t * track,int pulses)489 smf_track_add_eot_pulses(smf_track_t *track, int pulses)
490 {
491 	smf_event_t *event, *last_event;
492 
493 	last_event = smf_track_get_last_event(track);
494 	if (last_event != NULL) {
495 		if (last_event->time_pulses > pulses)
496 			return -2;
497 	}
498 
499 	event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00);
500 	if (event == NULL)
501 		return -3;
502 
503 	smf_track_add_event_pulses(track, event, pulses);
504 
505 	return 0;
506 }
507 
508 int
smf_track_add_eot_seconds(smf_track_t * track,double seconds)509 smf_track_add_eot_seconds(smf_track_t *track, double seconds)
510 {
511 	smf_event_t *event, *last_event;
512 
513 	last_event = smf_track_get_last_event(track);
514 	if (last_event != NULL) {
515 		if (last_event->time_seconds > seconds)
516 			return -2;
517 	}
518 
519 	event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00);
520 	if (event == NULL)
521 		return -1;
522 
523 	smf_track_add_event_seconds(track, event, seconds);
524 
525 	return 0;
526 }
527 
528 /**
529  * Detaches event from its track.
530  */
531 void
smf_track_remove_event(smf_event_t * event)532 smf_track_remove_event(smf_event_t *event)
533 {
534 	int i, was_last;
535 	smf_event_t *tmp;
536 	smf_track_t *track;
537 
538 	assert(event->track != NULL);
539 	assert(event->track->smf != NULL);
540 
541 	track = event->track;
542 	was_last = smf_event_is_last(event);
543 
544 	/* Adjust ->delta_time_pulses of the next event. */
545 	if (event->event_number < track->number_of_events) {
546 		tmp = smf_track_get_event_by_number(track, event->event_number + 1);
547 		assert(tmp);
548 		tmp->delta_time_pulses += event->delta_time_pulses;
549 	}
550 
551 	track->number_of_events--;
552 	g_ptr_array_remove(track->events_array, event);
553 
554 	if (track->number_of_events == 0)
555 		track->next_event_number = -1;
556 
557 	/* Renumber the rest of the events, so they are consecutively numbered. */
558 	for (i = event->event_number; i <= track->number_of_events; i++) {
559 		tmp = smf_track_get_event_by_number(track, i);
560 		tmp->event_number = i;
561 	}
562 
563 	if (smf_event_is_tempo_change_or_time_signature(event)) {
564 		/* XXX: This will cause problems, when there is more than one Tempo Change event at a given time. */
565 		if (was_last)
566 			remove_last_tempo_with_pulses(event->track->smf, event->time_pulses);
567 		else
568 			smf_create_tempo_map_and_compute_seconds(track->smf);
569 	}
570 
571 	event->track = NULL;
572 	event->event_number = -1;
573 	event->delta_time_pulses = -1;
574 	event->time_pulses = -1;
575 	event->time_seconds = -1.0;
576 }
577 
578 /**
579   * \return Nonzero if event is Tempo Change or Time Signature metaevent.
580   */
581 int
smf_event_is_tempo_change_or_time_signature(const smf_event_t * event)582 smf_event_is_tempo_change_or_time_signature(const smf_event_t *event)
583 {
584 	if (!smf_event_is_metadata(event))
585 		return 0;
586 
587 	assert(event->midi_buffer_length >= 2);
588 
589 	if (event->midi_buffer[1] == 0x51 || event->midi_buffer[1] == 0x58)
590 		return 1;
591 
592 	return 0;
593 }
594 
595 /**
596   * Sets "Format" field of MThd header to the specified value.  Note that you
597   * don't really need to use this, as libsmf will automatically change format
598   * from 0 to 1 when you add the second track.
599   * \param smf SMF.
600   * \param format 0 for one track per file, 1 for several tracks per file.
601   */
602 int
smf_set_format(smf_t * smf,int format)603 smf_set_format(smf_t *smf, int format)
604 {
605 	assert(format == 0 || format == 1);
606 
607 	if (smf->number_of_tracks > 1 && format == 0) {
608 		g_critical("There is more than one track, cannot set format to 0.");
609 		return -1;
610 	}
611 
612 	smf->format = format;
613 
614 	return 0;
615 }
616 
617 /**
618   * Sets the PPQN ("Division") field of MThd header.  This is mandatory, you
619   * should call it right after smf_new.  Note that changing PPQN will change time_seconds
620   * of all the events.
621   * \param smf SMF.
622   * \param ppqn New PPQN.
623   */
624 int
smf_set_ppqn(smf_t * smf,int ppqn)625 smf_set_ppqn(smf_t *smf, int ppqn)
626 {
627 	assert(ppqn > 0);
628 
629 	smf->ppqn = ppqn;
630 
631 	return 0;
632 }
633 
634 /**
635   * Returns next event from the track given and advances next event counter.
636   * Do not depend on End Of Track event being the last event on the track - it
637   * is possible that the track will not end with EOT if you haven't added it
638   * yet.  EOTs are added automatically during smf_save().
639   *
640   * \return Event or NULL, if there are no more events left in this track.
641   */
642 smf_event_t *
smf_track_get_next_event(smf_track_t * track)643 smf_track_get_next_event(smf_track_t *track)
644 {
645 	smf_event_t *event, *next_event;
646 
647 	/* End of track? */
648 	if (track->next_event_number == -1)
649 		return NULL;
650 
651 	assert(track->next_event_number >= 1);
652 	assert(track->number_of_events > 0);
653 
654 	event = smf_track_get_event_by_number(track, track->next_event_number);
655 
656 	assert(event != NULL);
657 
658 	/* Is this the last event in the track? */
659 	if (track->next_event_number < track->number_of_events) {
660 		next_event = smf_track_get_event_by_number(track, track->next_event_number + 1);
661 		assert(next_event);
662 
663 		track->time_of_next_event = next_event->time_pulses;
664 		track->next_event_number++;
665 	} else {
666 		track->next_event_number = -1;
667 	}
668 
669 	return event;
670 }
671 
672 /**
673   * Returns next event from the track given.  Does not change next event counter,
674   * so repeatedly calling this routine will return the same event.
675   * \return Event or NULL, if there are no more events left in this track.
676   */
677 static smf_event_t *
smf_peek_next_event_from_track(smf_track_t * track)678 smf_peek_next_event_from_track(smf_track_t *track)
679 {
680 	smf_event_t *event;
681 
682 	/* End of track? */
683 	if (track->next_event_number == -1)
684 		return NULL;
685 
686 	assert(track->next_event_number >= 1);
687 	assert(track->events_array->len != 0);
688 
689 	event = smf_track_get_event_by_number(track, track->next_event_number);
690 
691 	return event;
692 }
693 
694 /**
695  * \return Track with a given number or NULL, if there is no such track.
696  * Tracks are numbered consecutively starting from one.
697  */
698 smf_track_t *
smf_get_track_by_number(const smf_t * smf,int track_number)699 smf_get_track_by_number(const smf_t *smf, int track_number)
700 {
701 	smf_track_t *track;
702 
703 	assert(track_number >= 1);
704 
705 	if (track_number > smf->number_of_tracks)
706 		return NULL;
707 
708 	track = (smf_track_t *)g_ptr_array_index(smf->tracks_array, track_number - 1);
709 
710 	assert(track);
711 
712 	return track;
713 }
714 
715 /**
716  * \return Event with a given number or NULL, if there is no such event.
717  * Events are numbered consecutively starting from one.
718  */
719 smf_event_t *
smf_track_get_event_by_number(const smf_track_t * track,int event_number)720 smf_track_get_event_by_number(const smf_track_t *track, int event_number)
721 {
722 	smf_event_t *event;
723 
724 	assert(event_number >= 1);
725 
726 	if (event_number > track->number_of_events)
727 		return NULL;
728 
729 	event = g_ptr_array_index(track->events_array, event_number - 1);
730 
731 	assert(event);
732 
733 	return event;
734 }
735 
736 /**
737  * \return Last event on the track or NULL, if track is empty.
738  */
739 smf_event_t *
smf_track_get_last_event(const smf_track_t * track)740 smf_track_get_last_event(const smf_track_t *track)
741 {
742 	smf_event_t *event;
743 
744 	if (track->number_of_events == 0)
745 		return NULL;
746 
747 	event = smf_track_get_event_by_number(track, track->number_of_events);
748 
749 	return event;
750 }
751 
752 /**
753  * Searches for track that contains next event, in time order.  In other words,
754  * returns the track that contains event that should be played next.
755  * \return Track with next event or NULL, if there are no events left.
756  */
757 smf_track_t *
smf_find_track_with_next_event(smf_t * smf)758 smf_find_track_with_next_event(smf_t *smf)
759 {
760 	int i, min_time = 0;
761 	smf_track_t *track = NULL, *min_time_track = NULL;
762 
763 	/* Find track with event that should be played next. */
764 	for (i = 1; i <= smf->number_of_tracks; i++) {
765 		track = smf_get_track_by_number(smf, i);
766 
767 		assert(track);
768 
769 		/* No more events in this track? */
770 		if (track->next_event_number == -1)
771 			continue;
772 
773 		if (track->time_of_next_event < min_time || min_time_track == NULL) {
774 			min_time = track->time_of_next_event;
775 			min_time_track = track;
776 		}
777 	}
778 
779 	return min_time_track;
780 }
781 
782 /**
783   * \return Next event, in time order, or NULL, if there are none left.
784   */
785 smf_event_t *
smf_get_next_event(smf_t * smf)786 smf_get_next_event(smf_t *smf)
787 {
788 	smf_event_t *event;
789 	smf_track_t *track = smf_find_track_with_next_event(smf);
790 
791 	if (track == NULL) {
792 #if 0
793 		g_debug("End of the song.");
794 #endif
795 
796 		return NULL;
797 	}
798 
799 	event = smf_track_get_next_event(track);
800 
801 	assert(event != NULL);
802 
803 	event->track->smf->last_seek_position = -1.0;
804 
805 	return event;
806 }
807 
808 /**
809   * \return Next event, in time order, or NULL, if there are none left.  Does
810   * not advance position in song.
811   */
812 smf_event_t *
smf_peek_next_event(smf_t * smf)813 smf_peek_next_event(smf_t *smf)
814 {
815 	smf_event_t *event;
816 	smf_track_t *track = smf_find_track_with_next_event(smf);
817 
818 	if (track == NULL) {
819 #if 0
820 		g_debug("End of the song.");
821 #endif
822 
823 		return NULL;
824 	}
825 
826 	event = smf_peek_next_event_from_track(track);
827 
828 	assert(event != NULL);
829 
830 	return event;
831 }
832 
833 /**
834   * Rewinds the SMF.  What that means is, after calling this routine, smf_get_next_event
835   * will return first event in the song.
836   */
837 void
smf_rewind(smf_t * smf)838 smf_rewind(smf_t *smf)
839 {
840 	int i;
841 	smf_track_t *track = NULL;
842 	smf_event_t *event;
843 
844 	assert(smf);
845 
846 	smf->last_seek_position = 0.0;
847 
848 	for (i = 1; i <= smf->number_of_tracks; i++) {
849 		track = smf_get_track_by_number(smf, i);
850 
851 		assert(track != NULL);
852 
853 		if (track->number_of_events > 0) {
854 			track->next_event_number = 1;
855 			event = smf_peek_next_event_from_track(track);
856 			assert(event);
857 			track->time_of_next_event = event->time_pulses;
858 		} else {
859 			track->next_event_number = -1;
860 			track->time_of_next_event = 0;
861 #if 0
862 			g_warning("Warning: empty track.");
863 #endif
864 		}
865 	}
866 }
867 
868 /**
869   * Seeks the SMF to the given event.  After calling this routine, smf_get_next_event
870   * will return the event that was the second argument of this call.
871   */
872 int
smf_seek_to_event(smf_t * smf,const smf_event_t * target)873 smf_seek_to_event(smf_t *smf, const smf_event_t *target)
874 {
875 	smf_event_t *event;
876 
877 	smf_rewind(smf);
878 
879 #if 0
880 	g_debug("Seeking to event %d, track %d.", target->event_number, target->track->track_number);
881 #endif
882 
883 	for (;;) {
884 		event = smf_peek_next_event(smf);
885 
886 		/* There can't be NULL here, unless "target" is not in this smf. */
887 		assert(event);
888 
889 		if (event != target)
890 			smf_get_next_event(smf);
891 		else
892 			break;
893 	}
894 
895 	smf->last_seek_position = event->time_seconds;
896 
897 	return 0;
898 }
899 
900 /**
901   * Seeks the SMF to the given position.  For example, after seeking to 1.0 seconds,
902   * smf_get_next_event will return first event that happens after the first second of song.
903   */
904 int
smf_seek_to_seconds(smf_t * smf,double seconds)905 smf_seek_to_seconds(smf_t *smf, double seconds)
906 {
907 	smf_event_t *event;
908 
909 	assert(seconds >= 0.0);
910 
911 	if (seconds == smf->last_seek_position) {
912 #if 0
913 		g_debug("Avoiding seek to %f seconds.", seconds);
914 #endif
915 		return 0;
916 	}
917 
918 	smf_rewind(smf);
919 
920 #if 0
921 	g_debug("Seeking to %f seconds.", seconds);
922 #endif
923 
924 	for (;;) {
925 		event = smf_peek_next_event(smf);
926 
927 		if (event == NULL) {
928 			g_critical("Trying to seek past the end of song.");
929 			return -1;
930 		}
931 
932 		if (event->time_seconds < seconds)
933 			smf_get_next_event(smf);
934 		else
935 			break;
936 	}
937 
938 	smf->last_seek_position = seconds;
939 
940 	return 0;
941 }
942 
943 /**
944   * Seeks the SMF to the given position.  For example, after seeking to 10 pulses,
945   * smf_get_next_event will return first event that happens after the first ten pulses.
946   */
947 int
smf_seek_to_pulses(smf_t * smf,int pulses)948 smf_seek_to_pulses(smf_t *smf, int pulses)
949 {
950 	smf_event_t *event;
951 
952 	assert(pulses >= 0);
953 
954 	smf_rewind(smf);
955 
956 #if 0
957 	g_debug("Seeking to %d pulses.", pulses);
958 #endif
959 
960 	for (;;) {
961 		event = smf_peek_next_event(smf);
962 
963 		if (event == NULL) {
964 			g_critical("Trying to seek past the end of song.");
965 			return -1;
966 		}
967 
968 		if (event->time_pulses < pulses)
969 			smf_get_next_event(smf);
970 		else
971 			break;
972 	}
973 
974 	smf->last_seek_position = event->time_seconds;
975 
976 	return 0;
977 }
978 
979 /**
980   * \return Length of SMF, in pulses.
981   */
982 int
smf_get_length_pulses(const smf_t * smf)983 smf_get_length_pulses(const smf_t *smf)
984 {
985 	int pulses = 0, i;
986 
987 	for (i = 1; i <= smf->number_of_tracks; i++) {
988 		smf_track_t *track;
989 		smf_event_t *event;
990 
991 	       	track = smf_get_track_by_number(smf, i);
992 		assert(track);
993 
994 		event = smf_track_get_last_event(track);
995 		/* Empty track? */
996 		if (event == NULL)
997 			continue;
998 
999 		if (event->time_pulses > pulses)
1000 			pulses = event->time_pulses;
1001 	}
1002 
1003 	return pulses;
1004 }
1005 
1006 /**
1007   * \return Length of SMF, in seconds.
1008   */
1009 double
smf_get_length_seconds(const smf_t * smf)1010 smf_get_length_seconds(const smf_t *smf)
1011 {
1012 	int i;
1013 	double seconds = 0.0;
1014 
1015 	for (i = 1; i <= smf->number_of_tracks; i++) {
1016 		smf_track_t *track;
1017 		smf_event_t *event;
1018 
1019 	       	track = smf_get_track_by_number(smf, i);
1020 		assert(track);
1021 
1022 		event = smf_track_get_last_event(track);
1023 		/* Empty track? */
1024 		if (event == NULL)
1025 			continue;
1026 
1027 		if (event->time_seconds > seconds)
1028 			seconds = event->time_seconds;
1029 	}
1030 
1031 	return seconds;
1032 }
1033 
1034 /**
1035   * \return Nonzero, if there are no events in the SMF after this one.
1036   * Note that may be more than one "last event", if they occur at the same time.
1037   */
1038 int
smf_event_is_last(const smf_event_t * event)1039 smf_event_is_last(const smf_event_t *event)
1040 {
1041 	if (smf_get_length_pulses(event->track->smf) <= event->time_pulses)
1042 		return 1;
1043 
1044 	return 0;
1045 }
1046 
1047 /**
1048   * \return Version of libsmf.
1049   */
1050 const char *
smf_get_version(void)1051 smf_get_version(void)
1052 {
1053 	return SMF_VERSION;
1054 }
1055 
1056