mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
Significantly speed up loading SMF tempo-maps
Files that have many tracks, each with tempo information
were near impossible to load (30+ mins on modern 4.2Ghz CPU!),
because tempo is parsed incrementally:
```
For each new track:
for each new tempo-event:
rewind()
for each loaded track so far:
for each event on this track so far
```
This reduces the complexity from O(tracks^2 * tempos^2)
to O(tracks * tempos).
"Come Thou Fount Tempo Map.mid" has 238 Tracks and 56168 total
Tempo Changes (236 per track). This now requires only 56168 iterations
in smf_create_tempo_map_and_compute_seconds, rather than 1.64e+9
iterations
This commit is contained in:
parent
3da54244ea
commit
cd53301d06
3 changed files with 8 additions and 1 deletions
|
|
@ -525,7 +525,7 @@ smf_track_add_event(smf_track_t *track, smf_event_t *event)
|
|||
if (smf_event_is_last(event))
|
||||
maybe_add_to_tempo_map(event);
|
||||
else
|
||||
smf_create_tempo_map_and_compute_seconds(event->track->smf);
|
||||
event->track->smf->need_tempo_map_compute = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,6 +709,7 @@ smf_track_get_next_event(smf_track_t *track)
|
|||
if (track->next_event_number < track->number_of_events) {
|
||||
next_event = smf_track_get_event_by_number(track, track->next_event_number + 1);
|
||||
assert(next_event);
|
||||
assert(next_event->time_pulses >= event->time_pulses);
|
||||
|
||||
track->time_of_next_event = next_event->time_pulses;
|
||||
track->next_event_number++;
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ struct smf_struct {
|
|||
/** Private, used by smf.c. */
|
||||
GPtrArray *tracks_array;
|
||||
double last_seek_position;
|
||||
int need_tempo_map_compute;
|
||||
|
||||
/** Private, used by smf_tempo.c. */
|
||||
/** Array of pointers to smf_tempo_struct. */
|
||||
|
|
|
|||
|
|
@ -972,6 +972,11 @@ smf_load_from_memory(void *buffer, const size_t buffer_length)
|
|||
smf->expected_number_of_tracks = smf->number_of_tracks;
|
||||
}
|
||||
|
||||
/* process tempo-map */
|
||||
if (smf->need_tempo_map_compute) {
|
||||
smf_create_tempo_map_and_compute_seconds(smf);
|
||||
}
|
||||
|
||||
smf->file_buffer = NULL;
|
||||
smf->file_buffer_length = 0;
|
||||
smf->next_chunk_offset = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue