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