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;
|
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
|
void
|
||||||
SMFSource::load_model (bool lock, bool force_reload)
|
SMFSource::load_model (bool lock, bool force_reload)
|
||||||
{
|
{
|
||||||
|
@ -514,60 +520,74 @@ SMFSource::load_model (bool lock, bool force_reload)
|
||||||
uint8_t* buf = NULL;
|
uint8_t* buf = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
gint event_id;
|
gint event_id;
|
||||||
bool have_event_id = false;
|
bool have_event_id;
|
||||||
|
|
||||||
while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
|
// TODO simplify event allocation
|
||||||
|
std::list< std::pair< Evoral::Event<double>*, gint > > eventlist;
|
||||||
|
|
||||||
time += delta_t;
|
for (unsigned i = 1; i <= num_tracks(); ++i) {
|
||||||
|
if (seek_to_track(i)) continue;
|
||||||
|
|
||||||
if (ret == 0) {
|
time = 0;
|
||||||
|
have_event_id = false;
|
||||||
|
|
||||||
/* meta-event : did we get an event ID ?
|
while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
|
||||||
*/
|
|
||||||
|
|
||||||
if (event_id >= 0) {
|
time += delta_t;
|
||||||
have_event_id = true;
|
|
||||||
|
if (ret == 0) {
|
||||||
|
/* meta-event : did we get an event ID ? */
|
||||||
|
if (event_id >= 0) {
|
||||||
|
have_event_id = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
if (ret > 0) {
|
||||||
}
|
/* not a meta-event */
|
||||||
|
|
||||||
if (ret > 0) {
|
if (!have_event_id) {
|
||||||
|
event_id = Evoral::next_event_id();
|
||||||
/* not a meta-event */
|
}
|
||||||
|
uint32_t event_type = EventTypeMap::instance().midi_event_type(buf[0]);
|
||||||
ev.set (buf, size, time / (double)ppqn());
|
double event_time = time / (double) ppqn();
|
||||||
ev.set_event_type(EventTypeMap::instance().midi_event_type(buf[0]));
|
|
||||||
|
|
||||||
if (!have_event_id) {
|
|
||||||
event_id = Evoral::next_event_id();
|
|
||||||
}
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::string ss;
|
std::string ss;
|
||||||
|
|
||||||
for (uint32_t xx = 0; xx < size; ++xx) {
|
for (uint32_t xx = 0; xx < size; ++xx) {
|
||||||
char b[8];
|
char b[8];
|
||||||
snprintf (b, sizeof (b), "0x%x ", buf[xx]);
|
snprintf (b, sizeof (b), "0x%x ", buf[xx]);
|
||||||
ss += b;
|
ss += b;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
|
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
|
#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
|
// Set size to max capacity to minimize allocs in read_event
|
||||||
scratch_size = std::max(size, scratch_size);
|
scratch_size = std::max(size, scratch_size);
|
||||||
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 */
|
||||||
|
have_event_id = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* event ID's must immediately precede the event they are for
|
eventlist.sort(compare_eventlist);
|
||||||
*/
|
|
||||||
|
|
||||||
have_event_id = false;
|
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->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user