MIDI robustness.
[ardour.git] / libs / evoral / src / libsmf / smf_tempo.c
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  * Tempo map related part.
32  *
33  */
34
35 #include <stdlib.h>
36 #include <assert.h>
37 #include <math.h>
38 #include <string.h>
39 #include "smf.h"
40 #include "smf_private.h"
41
42 static double seconds_from_pulses(const smf_t *smf, int pulses);
43
44 /**
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".
48  */
49 static smf_tempo_t *
50 new_tempo(smf_t *smf, int pulses)
51 {
52         smf_tempo_t *tempo, *previous_tempo = NULL;
53
54         if (smf->tempo_array->len > 0) {
55                 previous_tempo = smf_get_last_tempo(smf);
56
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);
60         }
61
62         tempo = malloc(sizeof(smf_tempo_t));
63         if (tempo == NULL) {
64                 g_critical("Cannot allocate smf_tempo_t.");
65                 return (NULL);
66         }
67
68         tempo->time_pulses = pulses;
69
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;
76         } else {
77                 tempo->microseconds_per_quarter_note = 500000; /* Initial tempo is 120 BPM. */
78                 tempo->numerator = 4;
79                 tempo->denominator = 4;
80                 tempo->clocks_per_click = -1;
81                 tempo->notes_per_note = -1;
82         }
83
84         g_ptr_array_add(smf->tempo_array, tempo);
85
86         if (pulses == 0)
87                 tempo->time_seconds = 0.0;
88         else
89                 tempo->time_seconds = seconds_from_pulses(smf, pulses);
90
91         return (tempo);
92 }
93
94 static int
95 add_tempo(smf_t *smf, int pulses, int tempo)
96 {
97         smf_tempo_t *smf_tempo = new_tempo(smf, pulses);
98         if (smf_tempo == NULL)
99                 return (-1);
100
101         smf_tempo->microseconds_per_quarter_note = tempo;
102
103         return (0);
104 }
105
106 static int
107 add_time_signature(smf_t *smf, int pulses, int numerator, int denominator, int clocks_per_click, int notes_per_note)
108 {
109         smf_tempo_t *smf_tempo = new_tempo(smf, pulses);
110         if (smf_tempo == NULL)
111                 return (-1);
112
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;
117
118         return (0);
119 }
120
121 /**
122  * \internal
123  */
124 void
125 maybe_add_to_tempo_map(smf_event_t *event)
126 {
127         if (!smf_event_is_metadata(event))
128                 return;
129
130         assert(event->track != NULL);
131         assert(event->track->smf != NULL);
132         assert(event->midi_buffer_length >= 1);
133
134         /* Tempo Change? */
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.");
139                         return;
140                 }
141
142                 add_tempo(event->track->smf, event->time_pulses, new_tempo);
143         }
144
145         /* Time Signature? */
146         if (event->midi_buffer[1] == 0x58) {
147                 int numerator, denominator, clocks_per_click, notes_per_note;
148
149                 if (event->midi_buffer_length < 7) {
150                         g_critical("Time Signature event seems truncated.");
151                         return;
152                 }
153
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];
158
159                 add_time_signature(event->track->smf, event->time_pulses, numerator, denominator, clocks_per_click, notes_per_note);
160         }
161
162         return;
163 }
164
165 /**
166  * \internal
167  *
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
170  * after that one.
171  */
172 void
173 remove_last_tempo_with_pulses(smf_t *smf, int pulses)
174 {
175         smf_tempo_t *tempo;
176
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
180            to remove B. */
181         if (smf->tempo_array->len == 0)
182                 return;
183
184         tempo = smf_get_last_tempo(smf);
185
186         /* Workaround part two. */
187         if (tempo->time_pulses != pulses)
188                 return;
189
190         memset(tempo, 0, sizeof(smf_tempo_t));
191         free(tempo);
192
193         g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
194 }
195
196 static double
197 seconds_from_pulses(const smf_t *smf, int pulses)
198 {
199         double seconds;
200         smf_tempo_t *tempo;
201
202         tempo = smf_get_tempo_by_pulses(smf, pulses);
203         assert(tempo);
204         assert(tempo->time_pulses <= pulses);
205
206         seconds = tempo->time_seconds + (double)(pulses - tempo->time_pulses) *
207                 (tempo->microseconds_per_quarter_note / ((double)smf->ppqn * 1000000.0));
208
209         return (seconds);
210 }
211
212 static int
213 pulses_from_seconds(const smf_t *smf, double seconds)
214 {
215         int pulses = 0;
216         smf_tempo_t *tempo;
217
218         tempo = smf_get_tempo_by_seconds(smf, seconds);
219         assert(tempo);
220         assert(tempo->time_seconds <= seconds);
221
222         pulses = tempo->time_pulses + (seconds - tempo->time_seconds) *
223                 ((double)smf->ppqn * 1000000.0 / tempo->microseconds_per_quarter_note);
224
225         return (pulses);
226 }
227
228 /**
229  * \internal
230  *
231  * Computes value of event->time_seconds for all events in smf.
232  * Warning: rewinds the smf.
233  */
234 void
235 smf_create_tempo_map_and_compute_seconds(smf_t *smf)
236 {
237         smf_event_t *event;
238
239         smf_rewind(smf);
240         smf_init_tempo(smf);
241
242         for (;;) {
243                 event = smf_get_next_event(smf);
244                 
245                 if (event == NULL)
246                         return;
247
248                 maybe_add_to_tempo_map(event);
249
250                 event->time_seconds = seconds_from_pulses(smf, event->time_pulses);
251         }
252
253         /* Not reached. */
254 }
255
256 smf_tempo_t *
257 smf_get_tempo_by_number(const smf_t *smf, int number)
258 {
259         assert(number >= 0);
260
261         if (number >= smf->tempo_array->len)
262                 return (NULL);
263
264         return (g_ptr_array_index(smf->tempo_array, number));
265 }
266
267 /**
268  * Return last tempo (i.e. tempo with greatest time_pulses) that happens before "pulses".
269  */
270 smf_tempo_t *
271 smf_get_tempo_by_pulses(const smf_t *smf, int pulses)
272 {
273         int i;
274         smf_tempo_t *tempo;
275
276         assert(pulses >= 0);
277
278         if (pulses == 0)
279                 return (smf_get_tempo_by_number(smf, 0));
280
281         assert(smf->tempo_array != NULL);
282         
283         for (i = smf->tempo_array->len - 1; i >= 0; i--) {
284                 tempo = smf_get_tempo_by_number(smf, i);
285
286                 assert(tempo);
287                 if (tempo->time_pulses < pulses)
288                         return (tempo);
289         }
290
291         return (NULL);
292 }
293
294 /**
295  * Return last tempo (i.e. tempo with greatest time_seconds) that happens before "seconds".
296  */
297 smf_tempo_t *
298 smf_get_tempo_by_seconds(const smf_t *smf, double seconds)
299 {
300         int i;
301         smf_tempo_t *tempo;
302
303         assert(seconds >= 0.0);
304
305         if (seconds == 0.0)
306                 return (smf_get_tempo_by_number(smf, 0));
307
308         assert(smf->tempo_array != NULL);
309         
310         for (i = smf->tempo_array->len - 1; i >= 0; i--) {
311                 tempo = smf_get_tempo_by_number(smf, i);
312
313                 assert(tempo);
314                 if (tempo->time_seconds < seconds)
315                         return (tempo);
316         }
317
318         return (NULL);
319 }
320
321
322 /**
323  * Return last tempo.
324  */
325 smf_tempo_t *
326 smf_get_last_tempo(const smf_t *smf)
327 {
328         smf_tempo_t *tempo;
329
330         tempo = smf_get_tempo_by_number(smf, smf->tempo_array->len - 1);
331         assert(tempo);
332
333         return (tempo);
334 }
335
336 /**
337  * \internal 
338  *
339  * Remove all smf_tempo_t structures from SMF.
340  */
341 void
342 smf_fini_tempo(smf_t *smf)
343 {
344         smf_tempo_t *tempo;
345
346         while (smf->tempo_array->len > 0) {
347                 tempo = g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1);
348                 assert(tempo);
349
350                 memset(tempo, 0, sizeof(smf_tempo_t));
351                 free(tempo);
352
353                 g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
354         }
355
356         assert(smf->tempo_array->len == 0);
357 }
358
359 /**
360  * \internal
361  *
362  * Remove any existing tempos and add default one.
363  *
364  * \bug This will abort (by calling g_error) if new_tempo() (memory allocation there) fails.
365  */
366 void
367 smf_init_tempo(smf_t *smf)
368 {
369         smf_tempo_t *tempo;
370
371         smf_fini_tempo(smf);
372
373         tempo = new_tempo(smf, 0);
374         if (tempo == NULL)
375                 g_error("tempo_init failed, sorry.");
376 }
377
378 /**
379  * Returns ->time_pulses of last event on the given track, or 0, if track is empty.
380  */
381 static int
382 last_event_pulses(const smf_track_t *track)
383 {
384         /* Get time of last event on this track. */
385         if (track->number_of_events > 0) {
386                 smf_event_t *previous_event = smf_track_get_last_event(track);
387                 assert(previous_event);
388                 assert(previous_event->time_pulses >= 0);
389
390                 return (previous_event->time_pulses);
391         }
392
393         return (0);
394 }
395
396 /**
397  * Adds event to the track at the time "pulses" clocks from the previous event in this track.
398  * The remaining two time fields will be computed automatically based on the third argument
399  * and current tempo map.  Note that ->delta_pulses is computed by smf.c:smf_track_add_event,
400  * not here.
401  */
402 void
403 smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, int delta)
404 {
405         assert(delta >= 0);
406         assert(event->time_pulses == -1);
407         assert(event->time_seconds == -1.0);
408         assert(track->smf != NULL);
409
410         if (!smf_event_is_valid(event)) {
411                 g_critical("Added event is invalid");
412         }
413
414         smf_track_add_event_pulses(track, event, last_event_pulses(track) + delta);
415 }
416
417 /**
418  * Adds event to the track at the time "pulses" clocks from the start of song.
419  * The remaining two time fields will be computed automatically based on the third argument
420  * and current tempo map.
421  */
422 void
423 smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, int pulses)
424 {
425         assert(pulses >= 0);
426         assert(event->time_pulses == -1);
427         assert(event->time_seconds == -1.0);
428         assert(track->smf != NULL);
429
430         event->time_pulses = pulses;
431         event->time_seconds = seconds_from_pulses(track->smf, pulses);
432         smf_track_add_event(track, event);
433 }
434
435 /**
436  * Adds event to the track at the time "seconds" seconds from the start of song.
437  * The remaining two time fields will be computed automatically based on the third argument
438  * and current tempo map.
439  */
440 void
441 smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds)
442 {
443         assert(seconds >= 0.0);
444         assert(event->time_pulses == -1);
445         assert(event->time_seconds == -1.0);
446         assert(track->smf != NULL);
447
448         event->time_seconds = seconds;
449         event->time_pulses = pulses_from_seconds(track->smf, seconds);
450         smf_track_add_event(track, event);
451 }
452