take all tracks inside a midi-file into account when loading model
* fixes [region] length calculation, * prepare for auditioning midi files (one track plays it all)
This commit is contained in:
parent
9e799c6146
commit
1e3ad60eb6
@ -476,6 +476,12 @@ SMFSource::safe_midi_file_extension (const string& file)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool compare_eventlist (
|
||||
const std::pair< Evoral::Event<double>*, gint >& a,
|
||||
const std::pair< Evoral::Event<double>*, gint >& b) {
|
||||
return ( a.first->time() < b.first->time() );
|
||||
}
|
||||
|
||||
void
|
||||
SMFSource::load_model (bool lock, bool force_reload)
|
||||
{
|
||||
@ -514,34 +520,37 @@ SMFSource::load_model (bool lock, bool force_reload)
|
||||
uint8_t* buf = NULL;
|
||||
int ret;
|
||||
gint event_id;
|
||||
bool have_event_id = false;
|
||||
bool have_event_id;
|
||||
|
||||
// TODO simplify event allocation
|
||||
std::list< std::pair< Evoral::Event<double>*, gint > > eventlist;
|
||||
|
||||
for (unsigned i = 1; i <= num_tracks(); ++i) {
|
||||
if (seek_to_track(i)) continue;
|
||||
|
||||
time = 0;
|
||||
have_event_id = false;
|
||||
|
||||
while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
|
||||
|
||||
time += delta_t;
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
/* meta-event : did we get an event ID ?
|
||||
*/
|
||||
|
||||
/* meta-event : did we get an event ID ? */
|
||||
if (event_id >= 0) {
|
||||
have_event_id = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
|
||||
/* not a meta-event */
|
||||
|
||||
ev.set (buf, size, time / (double)ppqn());
|
||||
ev.set_event_type(EventTypeMap::instance().midi_event_type(buf[0]));
|
||||
|
||||
if (!have_event_id) {
|
||||
event_id = Evoral::next_event_id();
|
||||
}
|
||||
uint32_t event_type = EventTypeMap::instance().midi_event_type(buf[0]);
|
||||
double event_time = time / (double) ppqn();
|
||||
#ifndef NDEBUG
|
||||
std::string ss;
|
||||
|
||||
@ -552,23 +561,34 @@ SMFSource::load_model (bool lock, bool force_reload)
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
|
||||
delta_t, time, size, ss , ev.event_type(), name()));
|
||||
delta_t, time, size, ss , event_type, name()));
|
||||
#endif
|
||||
|
||||
_model->append (ev, event_id);
|
||||
eventlist.push_back(make_pair (
|
||||
new Evoral::Event<double> (
|
||||
event_type, event_time,
|
||||
size, buf, true)
|
||||
, event_id));
|
||||
|
||||
// Set size to max capacity to minimize allocs in read_event
|
||||
scratch_size = std::max(size, scratch_size);
|
||||
size = scratch_size;
|
||||
|
||||
_length_beats = max(_length_beats, ev.time());
|
||||
_length_beats = max(_length_beats, event_time);
|
||||
}
|
||||
|
||||
/* event ID's must immediately precede the event they are for
|
||||
*/
|
||||
|
||||
/* event ID's must immediately precede the event they are for */
|
||||
have_event_id = false;
|
||||
}
|
||||
}
|
||||
|
||||
eventlist.sort(compare_eventlist);
|
||||
|
||||
std::list< std::pair< Evoral::Event<double>*, gint > >::iterator it;
|
||||
for (it=eventlist.begin(); it!=eventlist.end(); ++it) {
|
||||
_model->append (*it->first, it->second);
|
||||
delete it->first;
|
||||
}
|
||||
|
||||
_model->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);
|
||||
_model->set_edited (false);
|
||||
|
Loading…
Reference in New Issue
Block a user