00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include <stdlib.h>
00036 #include <assert.h>
00037 #include <math.h>
00038 #include <string.h>
00039 #include "smf.h"
00040 #include "smf_private.h"
00041
00042 static double seconds_from_pulses(const smf_t *smf, int pulses);
00043
00049 static smf_tempo_t *
00050 new_tempo(smf_t *smf, int pulses)
00051 {
00052 smf_tempo_t *tempo, *previous_tempo = NULL;
00053
00054 if (smf->tempo_array->len > 0) {
00055 previous_tempo = smf_get_last_tempo(smf);
00056
00057
00058 if (previous_tempo->time_pulses == pulses)
00059 return (previous_tempo);
00060 }
00061
00062 tempo = malloc(sizeof(smf_tempo_t));
00063 if (tempo == NULL) {
00064 g_critical("Cannot allocate smf_tempo_t.");
00065 return (NULL);
00066 }
00067
00068 tempo->time_pulses = pulses;
00069
00070 if (previous_tempo != NULL) {
00071 tempo->microseconds_per_quarter_note = previous_tempo->microseconds_per_quarter_note;
00072 tempo->numerator = previous_tempo->numerator;
00073 tempo->denominator = previous_tempo->denominator;
00074 tempo->clocks_per_click = previous_tempo->clocks_per_click;
00075 tempo->notes_per_note = previous_tempo->notes_per_note;
00076 } else {
00077 tempo->microseconds_per_quarter_note = 500000;
00078 tempo->numerator = 4;
00079 tempo->denominator = 4;
00080 tempo->clocks_per_click = -1;
00081 tempo->notes_per_note = -1;
00082 }
00083
00084 g_ptr_array_add(smf->tempo_array, tempo);
00085
00086 if (pulses == 0)
00087 tempo->time_seconds = 0.0;
00088 else
00089 tempo->time_seconds = seconds_from_pulses(smf, pulses);
00090
00091 return (tempo);
00092 }
00093
00094 static int
00095 add_tempo(smf_t *smf, int pulses, int tempo)
00096 {
00097 smf_tempo_t *smf_tempo = new_tempo(smf, pulses);
00098 if (smf_tempo == NULL)
00099 return (-1);
00100
00101 smf_tempo->microseconds_per_quarter_note = tempo;
00102
00103 return (0);
00104 }
00105
00106 static int
00107 add_time_signature(smf_t *smf, int pulses, int numerator, int denominator, int clocks_per_click, int notes_per_note)
00108 {
00109 smf_tempo_t *smf_tempo = new_tempo(smf, pulses);
00110 if (smf_tempo == NULL)
00111 return (-1);
00112
00113 smf_tempo->numerator = numerator;
00114 smf_tempo->denominator = denominator;
00115 smf_tempo->clocks_per_click = clocks_per_click;
00116 smf_tempo->notes_per_note = notes_per_note;
00117
00118 return (0);
00119 }
00120
00124 void
00125 maybe_add_to_tempo_map(smf_event_t *event)
00126 {
00127 if (!smf_event_is_metadata(event))
00128 return;
00129
00130 assert(event->track != NULL);
00131 assert(event->track->smf != NULL);
00132 assert(event->midi_buffer_length >= 1);
00133
00134
00135 if (event->midi_buffer[1] == 0x51) {
00136 int new_tempo = (event->midi_buffer[3] << 16) + (event->midi_buffer[4] << 8) + event->midi_buffer[5];
00137 if (new_tempo <= 0) {
00138 g_critical("Ignoring invalid tempo change.");
00139 return;
00140 }
00141
00142 add_tempo(event->track->smf, event->time_pulses, new_tempo);
00143 }
00144
00145
00146 if (event->midi_buffer[1] == 0x58) {
00147 int numerator, denominator, clocks_per_click, notes_per_note;
00148
00149 if (event->midi_buffer_length < 7) {
00150 g_critical("Time Signature event seems truncated.");
00151 return;
00152 }
00153
00154 numerator = event->midi_buffer[3];
00155 denominator = (int)pow(2, event->midi_buffer[4]);
00156 clocks_per_click = event->midi_buffer[5];
00157 notes_per_note = event->midi_buffer[6];
00158
00159 add_time_signature(event->track->smf, event->time_pulses, numerator, denominator, clocks_per_click, notes_per_note);
00160 }
00161
00162 return;
00163 }
00164
00172 void
00173 remove_last_tempo_with_pulses(smf_t *smf, int pulses)
00174 {
00175 smf_tempo_t *tempo;
00176
00177
00178
00179
00180
00181 if (smf->tempo_array->len == 0)
00182 return;
00183
00184 tempo = smf_get_last_tempo(smf);
00185
00186
00187 if (tempo->time_pulses != pulses)
00188 return;
00189
00190 memset(tempo, 0, sizeof(smf_tempo_t));
00191 free(tempo);
00192
00193 g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
00194 }
00195
00196 static double
00197 seconds_from_pulses(const smf_t *smf, int pulses)
00198 {
00199 double seconds;
00200 smf_tempo_t *tempo;
00201
00202 tempo = smf_get_tempo_by_pulses(smf, pulses);
00203 assert(tempo);
00204 assert(tempo->time_pulses <= pulses);
00205
00206 seconds = tempo->time_seconds + (double)(pulses - tempo->time_pulses) *
00207 (tempo->microseconds_per_quarter_note / ((double)smf->ppqn * 1000000.0));
00208
00209 return (seconds);
00210 }
00211
00212 static int
00213 pulses_from_seconds(const smf_t *smf, double seconds)
00214 {
00215 int pulses = 0;
00216 smf_tempo_t *tempo;
00217
00218 tempo = smf_get_tempo_by_seconds(smf, seconds);
00219 assert(tempo);
00220 assert(tempo->time_seconds <= seconds);
00221
00222 pulses = tempo->time_pulses + (seconds - tempo->time_seconds) *
00223 ((double)smf->ppqn * 1000000.0 / tempo->microseconds_per_quarter_note);
00224
00225 return (pulses);
00226 }
00227
00234 void
00235 smf_create_tempo_map_and_compute_seconds(smf_t *smf)
00236 {
00237 smf_event_t *event;
00238
00239 smf_rewind(smf);
00240 smf_init_tempo(smf);
00241
00242 for (;;) {
00243 event = smf_get_next_event(smf);
00244
00245 if (event == NULL)
00246 return;
00247
00248 maybe_add_to_tempo_map(event);
00249
00250 event->time_seconds = seconds_from_pulses(smf, event->time_pulses);
00251 }
00252
00253
00254 }
00255
00256 smf_tempo_t *
00257 smf_get_tempo_by_number(const smf_t *smf, int number)
00258 {
00259 assert(number >= 0);
00260
00261 if (number >= smf->tempo_array->len)
00262 return (NULL);
00263
00264 return (g_ptr_array_index(smf->tempo_array, number));
00265 }
00266
00270 smf_tempo_t *
00271 smf_get_tempo_by_pulses(const smf_t *smf, int pulses)
00272 {
00273 int i;
00274 smf_tempo_t *tempo;
00275
00276 assert(pulses >= 0);
00277
00278 if (pulses == 0)
00279 return (smf_get_tempo_by_number(smf, 0));
00280
00281 assert(smf->tempo_array != NULL);
00282
00283 for (i = smf->tempo_array->len - 1; i >= 0; i--) {
00284 tempo = smf_get_tempo_by_number(smf, i);
00285
00286 assert(tempo);
00287 if (tempo->time_pulses < pulses)
00288 return (tempo);
00289 }
00290
00291 return (NULL);
00292 }
00293
00297 smf_tempo_t *
00298 smf_get_tempo_by_seconds(const smf_t *smf, double seconds)
00299 {
00300 int i;
00301 smf_tempo_t *tempo;
00302
00303 assert(seconds >= 0.0);
00304
00305 if (seconds == 0.0)
00306 return (smf_get_tempo_by_number(smf, 0));
00307
00308 assert(smf->tempo_array != NULL);
00309
00310 for (i = smf->tempo_array->len - 1; i >= 0; i--) {
00311 tempo = smf_get_tempo_by_number(smf, i);
00312
00313 assert(tempo);
00314 if (tempo->time_seconds < seconds)
00315 return (tempo);
00316 }
00317
00318 return (NULL);
00319 }
00320
00321
00325 smf_tempo_t *
00326 smf_get_last_tempo(const smf_t *smf)
00327 {
00328 smf_tempo_t *tempo;
00329
00330 tempo = smf_get_tempo_by_number(smf, smf->tempo_array->len - 1);
00331 assert(tempo);
00332
00333 return (tempo);
00334 }
00335
00341 void
00342 smf_fini_tempo(smf_t *smf)
00343 {
00344 smf_tempo_t *tempo;
00345
00346 while (smf->tempo_array->len > 0) {
00347 tempo = g_ptr_array_index(smf->tempo_array, smf->tempo_array->len - 1);
00348 assert(tempo);
00349
00350 memset(tempo, 0, sizeof(smf_tempo_t));
00351 free(tempo);
00352
00353 g_ptr_array_remove_index(smf->tempo_array, smf->tempo_array->len - 1);
00354 }
00355
00356 assert(smf->tempo_array->len == 0);
00357 }
00358
00366 void
00367 smf_init_tempo(smf_t *smf)
00368 {
00369 smf_tempo_t *tempo;
00370
00371 smf_fini_tempo(smf);
00372
00373 tempo = new_tempo(smf, 0);
00374 if (tempo == NULL)
00375 g_error("tempo_init failed, sorry.");
00376 }
00377
00381 static int
00382 last_event_pulses(const smf_track_t *track)
00383 {
00384
00385 if (track->number_of_events > 0) {
00386 smf_event_t *previous_event = smf_track_get_last_event(track);
00387 assert(previous_event);
00388 assert(previous_event->time_pulses >= 0);
00389
00390 return (previous_event->time_pulses);
00391 }
00392
00393 return (0);
00394 }
00395
00402 void
00403 smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, int delta)
00404 {
00405 assert(delta >= 0);
00406 assert(event->time_pulses == -1);
00407 assert(event->time_seconds == -1.0);
00408 assert(track->smf != NULL);
00409
00410 smf_track_add_event_pulses(track, event, last_event_pulses(track) + delta);
00411 }
00412
00418 void
00419 smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, int pulses)
00420 {
00421 assert(pulses >= 0);
00422 assert(event->time_pulses == -1);
00423 assert(event->time_seconds == -1.0);
00424 assert(track->smf != NULL);
00425
00426 event->time_pulses = pulses;
00427 event->time_seconds = seconds_from_pulses(track->smf, pulses);
00428 smf_track_add_event(track, event);
00429 }
00430
00436 void
00437 smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds)
00438 {
00439 assert(seconds >= 0.0);
00440 assert(event->time_pulses == -1);
00441 assert(event->time_seconds == -1.0);
00442 assert(track->smf != NULL);
00443
00444 event->time_seconds = seconds;
00445 event->time_pulses = pulses_from_seconds(track->smf, seconds);
00446 smf_track_add_event(track, event);
00447 }
00448