2 * Copyright (c) 2007, 2008 Edward Tomasz NapieraĆa <trasz@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
31 * Tempo map related part.
40 #include "smf_private.h"
42 static double seconds_from_pulses(const smf_t *smf, size_t pulses);
45 * If there is tempo starting at "pulses" already, return it. Otherwise,
46 * allocate new one, fill it with values from previous one (or default ones,
47 * if there is no previous one) and attach it to "smf".
50 new_tempo(smf_t *smf, size_t pulses)
52 smf_tempo_t *tempo, *previous_tempo = NULL;
54 if (smf->tempo_array->len > 0) {
55 previous_tempo = smf_get_last_tempo(smf);
57 /* If previous tempo starts at the same time as new one, reuse it, updating in place. */
58 if (previous_tempo->time_pulses == pulses)
59 return (previous_tempo);
62 tempo = malloc(sizeof(smf_tempo_t));
64 g_critical("Cannot allocate smf_tempo_t.");
68 tempo->time_pulses = pulses;
70 if (previous_tempo != NULL) {
71 tempo->microseconds_per_quarter_note = previous_tempo->microseconds_per_quarter_note;
72 tempo->numerator = previous_tempo->numerator;
73 tempo->denominator = previous_tempo->denominator;
74 tempo->clocks_per_click = previous_tempo->clocks_per_click;
75 tempo->notes_per_note = previous_tempo->notes_per_note;
77 tempo->microseconds_per_quarter_note = 500000; /* Initial tempo is 120 BPM. */
79 tempo->denominator = 4;
80 tempo->clocks_per_click = -1;
81 tempo->notes_per_note = -1;
84 g_ptr_array_add(smf->tempo_array, tempo);
87 tempo->time_seconds = 0.0;
89 tempo->time_seconds = seconds_from_pulses(smf, pulses);
95 add_tempo(smf_t *smf, int pulses, int tempo)
97 smf_tempo_t *smf_tempo = new_tempo(smf, pulses);
98 if (smf_tempo == NULL)
101 smf_tempo->microseconds_per_quarter_note = tempo;
107 add_time_signature(smf_t *smf, int pulses, int numerator, int denominator, int clocks_per_click, int notes_per_note)
109 smf_tempo_t *smf_tempo = new_tempo(smf, pulses);
110 if (smf_tempo == NULL)
113 smf_tempo->numerator = numerator;
114 smf_tempo->denominator = denominator;
115 smf_tempo->clocks_per_click = clocks_per_click;
116 smf_tempo->notes_per_note = notes_per_note;
125 maybe_add_to_tempo_map(smf_event_t *event)
127 if (!smf_event_is_metadata(event))
130 assert(event->track != NULL);
131 assert(event->track->smf != NULL);
132 assert(event->midi_buffer_length >= 1);
135 if (event->midi_buffer[1] == 0x51) {
136 int new_tempo = (event->midi_buffer[3] << 16) + (event->midi_buffer[4] << 8) + event->midi_buffer[5];
137 if (new_tempo <= 0) {
138 g_critical("Ignoring invalid tempo change.");
142 add_tempo(event->track->smf, event->time_pulses, new_tempo);
145 /* Time Signature? */
146 if (event->midi_buffer[1] == 0x58) {
147 int numerator, denominator, clocks_per_click, notes_per_note;
149 if (event->midi_buffer_length < 7) {
150 g_critical("Time Signature event seems truncated.");
154 numerator = event->midi_buffer[3];
155 denominator = (int)pow(2, event->midi_buffer[4]);
156 clocks_per_click = event->midi_buffer[5];
157 notes_per_note = event->midi_buffer[6];
159 add_time_signature(event->track->smf, event->time_pulses, numerator, denominator, clocks_per_click, notes_per_note);
168 * This is an internal function, called from smf_track_remove_event when tempo-related
169 * event being removed does not require recreation of tempo map, i.e. there are no events
173 remove_last_tempo_with_pulses(smf_t *smf, size_t pulses)
177 /* XXX: This is a partial workaround for the following problem: we have two tempo-related
178 events, A and B, that occur at the same time. We remove B, then try to remove
179 A. However, both tempo changes got coalesced in new_tempo(), so it is impossible
181 if (smf->tempo_array->len == 0)
184 tempo = smf_get_last_tempo(smf);
186 /* Workaround part two. */
187 if (tempo->time_pulses != pulses)
190 memset(tempo, 0, sizeof(smf_tempo_t));
193 g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
197 seconds_from_pulses(const smf_t *smf, size_t pulses)
202 tempo = smf_get_tempo_by_pulses(smf, pulses);
204 assert(tempo->time_pulses <= pulses);
206 seconds = tempo->time_seconds + (double)(pulses - tempo->time_pulses) *
207 (tempo->microseconds_per_quarter_note / ((double)smf->ppqn * 1000000.0));
213 pulses_from_seconds(const smf_t *smf, double seconds)
218 tempo = smf_get_tempo_by_seconds(smf, seconds);
220 assert(tempo->time_seconds <= seconds);
222 pulses = tempo->time_pulses + (seconds - tempo->time_seconds) *
223 ((double)smf->ppqn * 1000000.0 / tempo->microseconds_per_quarter_note);
231 * Computes value of event->time_seconds for all events in smf.
232 * Warning: rewinds the smf.
235 smf_create_tempo_map_and_compute_seconds(smf_t *smf)
243 event = smf_get_next_event(smf);
248 maybe_add_to_tempo_map(event);
250 event->time_seconds = seconds_from_pulses(smf, event->time_pulses);
257 smf_get_tempo_by_number(const smf_t *smf, size_t number)
259 if (number >= smf->tempo_array->len)
262 return (g_ptr_array_index(smf->tempo_array, number));
266 * Return last tempo (i.e. tempo with greatest time_pulses) that happens before "pulses".
269 smf_get_tempo_by_pulses(const smf_t *smf, size_t pulses)
275 return (smf_get_tempo_by_number(smf, 0));
277 assert(smf->tempo_array != NULL);
279 for (i = smf->tempo_array->len; i > 0; i--) {
280 tempo = smf_get_tempo_by_number(smf, i - 1);
283 if (tempo->time_pulses < pulses)
291 * Return last tempo (i.e. tempo with greatest time_seconds) that happens before "seconds".
294 smf_get_tempo_by_seconds(const smf_t *smf, double seconds)
299 assert(seconds >= 0.0);
302 return (smf_get_tempo_by_number(smf, 0));
304 assert(smf->tempo_array != NULL);
306 for (i = smf->tempo_array->len; i > 0; i--) {
307 tempo = smf_get_tempo_by_number(smf, i - 1);
310 if (tempo->time_seconds < seconds)
322 smf_get_last_tempo(const smf_t *smf)
326 assert(smf->tempo_array->len > 0);
327 tempo = smf_get_tempo_by_number(smf, smf->tempo_array->len - 1);
336 * Remove all smf_tempo_t structures from SMF.
339 smf_fini_tempo(smf_t *smf)
343 while (smf->tempo_array->len > 0) {
344 tempo = g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1);
347 memset(tempo, 0, sizeof(smf_tempo_t));
350 g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
353 assert(smf->tempo_array->len == 0);
359 * Remove any existing tempos and add default one.
361 * \bug This will abort (by calling g_error) if new_tempo() (memory allocation there) fails.
364 smf_init_tempo(smf_t *smf)
370 tempo = new_tempo(smf, 0);
372 g_error("tempo_init failed, sorry.");
377 * Returns ->time_pulses of last event on the given track, or 0, if track is empty.
380 last_event_pulses(const smf_track_t *track)
382 /* Get time of last event on this track. */
383 if (track->number_of_events > 0) {
384 smf_event_t *previous_event = smf_track_get_last_event(track);
385 assert(previous_event);
387 return (previous_event->time_pulses);
394 * Adds event to the track at the time "pulses" clocks from the previous event in this track.
395 * The remaining two time fields will be computed automatically based on the third argument
396 * and current tempo map. Note that ->delta_pulses is computed by smf.c:smf_track_add_event,
400 smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, uint32_t delta)
402 assert(event->time_seconds == -1.0);
403 assert(track->smf != NULL);
405 if (!smf_event_is_valid(event)) {
406 g_critical("Added event is invalid");
409 smf_track_add_event_pulses(track, event, last_event_pulses(track) + delta);
413 * Adds event to the track at the time "pulses" clocks from the start of song.
414 * The remaining two time fields will be computed automatically based on the third argument
415 * and current tempo map.
418 smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, size_t pulses)
420 assert(event->time_seconds == -1.0);
421 assert(track->smf != NULL);
423 event->time_pulses = pulses;
424 event->time_seconds = seconds_from_pulses(track->smf, pulses);
425 smf_track_add_event(track, event);
429 * Adds event to the track at the time "seconds" seconds from the start of song.
430 * The remaining two time fields will be computed automatically based on the third argument
431 * and current tempo map.
434 smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds)
436 assert(seconds >= 0.0);
437 assert(event->time_seconds == -1.0);
438 assert(track->smf != NULL);
440 event->time_seconds = seconds;
441 event->time_pulses = pulses_from_seconds(track->smf, seconds);
442 smf_track_add_event(track, event);