c24e7460c1e060fb21c7bdff1231979d90d8d8e4
[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, size_t 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, size_t 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, size_t 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, size_t 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, size_t number)
258 {
259         if (number >= smf->tempo_array->len)
260                 return (NULL);
261
262         return (g_ptr_array_index(smf->tempo_array, number));
263 }
264
265 /**
266  * Return last tempo (i.e. tempo with greatest time_pulses) that happens before "pulses".
267  */
268 smf_tempo_t *
269 smf_get_tempo_by_pulses(const smf_t *smf, size_t pulses)
270 {
271         size_t i;
272         smf_tempo_t *tempo;
273
274         if (pulses == 0)
275                 return (smf_get_tempo_by_number(smf, 0));
276
277         assert(smf->tempo_array != NULL);
278         
279         for (i = smf->tempo_array->len; i > 0; i--) {
280                 tempo = smf_get_tempo_by_number(smf, i - 1);
281
282                 assert(tempo);
283                 if (tempo->time_pulses < pulses)
284                         return (tempo);
285         }
286
287         return (NULL);
288 }
289
290 /**
291  * Return last tempo (i.e. tempo with greatest time_seconds) that happens before "seconds".
292  */
293 smf_tempo_t *
294 smf_get_tempo_by_seconds(const smf_t *smf, double seconds)
295 {
296         size_t i;
297         smf_tempo_t *tempo;
298
299         assert(seconds >= 0.0);
300
301         if (seconds == 0.0)
302                 return (smf_get_tempo_by_number(smf, 0));
303
304         assert(smf->tempo_array != NULL);
305         
306         for (i = smf->tempo_array->len; i > 0; i--) {
307                 tempo = smf_get_tempo_by_number(smf, i - 1);
308
309                 assert(tempo);
310                 if (tempo->time_seconds < seconds)
311                         return (tempo);
312         }
313
314         return (NULL);
315 }
316
317
318 /**
319  * Return last tempo.
320  */
321 smf_tempo_t *
322 smf_get_last_tempo(const smf_t *smf)
323 {
324         smf_tempo_t *tempo;
325
326         assert(smf->tempo_array->len > 0);
327         tempo = smf_get_tempo_by_number(smf, smf->tempo_array->len - 1);
328         assert(tempo);
329
330         return (tempo);
331 }
332
333 /**
334  * \internal 
335  *
336  * Remove all smf_tempo_t structures from SMF.
337  */
338 void
339 smf_fini_tempo(smf_t *smf)
340 {
341         smf_tempo_t *tempo;
342
343         while (smf->tempo_array->len > 0) {
344                 tempo = g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1);
345                 assert(tempo);
346
347                 memset(tempo, 0, sizeof(smf_tempo_t));
348                 free(tempo);
349
350                 g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
351         }
352
353         assert(smf->tempo_array->len == 0);
354 }
355
356 /**
357  * \internal
358  *
359  * Remove any existing tempos and add default one.
360  *
361  * \bug This will abort (by calling g_error) if new_tempo() (memory allocation there) fails.
362  */
363 void
364 smf_init_tempo(smf_t *smf)
365 {
366         smf_tempo_t *tempo;
367
368         smf_fini_tempo(smf);
369
370         tempo = new_tempo(smf, 0);
371         if (tempo == NULL) {
372                 g_error("tempo_init failed, sorry.");
373         }
374 }
375
376 /**
377  * Returns ->time_pulses of last event on the given track, or 0, if track is empty.
378  */
379 static int
380 last_event_pulses(const smf_track_t *track)
381 {
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);
386
387                 return (previous_event->time_pulses);
388         }
389
390         return (0);
391 }
392
393 /**
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,
397  * not here.
398  */
399 void
400 smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, uint32_t delta)
401 {
402         assert(event->time_seconds == -1.0);
403         assert(track->smf != NULL);
404
405         if (!smf_event_is_valid(event)) {
406                 g_critical("Added event is invalid");
407         }
408
409         smf_track_add_event_pulses(track, event, last_event_pulses(track) + delta);
410 }
411
412 /**
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.
416  */
417 void
418 smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, size_t pulses)
419 {
420         assert(event->time_seconds == -1.0);
421         assert(track->smf != NULL);
422
423         event->time_pulses = pulses;
424         event->time_seconds = seconds_from_pulses(track->smf, pulses);
425         smf_track_add_event(track, event);
426 }
427
428 /**
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.
432  */
433 void
434 smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds)
435 {
436         assert(seconds >= 0.0);
437         assert(event->time_seconds == -1.0);
438         assert(track->smf != NULL);
439
440         event->time_seconds = seconds;
441         event->time_pulses = pulses_from_seconds(track->smf, seconds);
442         smf_track_add_event(track, event);
443 }
444