mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-11 00:56:33 +01:00
Fix corrupt MIDI file writing when meta events are present (fixes missing first note issue on some imported files).
Reduce number of buffer allocations on MIDI read/write. git-svn-id: svn://localhost/ardour2/branches/3.0@3395 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
39b2e2b572
commit
54bec37b5a
3 changed files with 18 additions and 11 deletions
|
|
@ -545,6 +545,7 @@ void MidiModel::append_note_on_unlocked(uint8_t chan, double time,
|
||||||
/*cerr << "MidiModel " << this << " chan " << (int)chan <<
|
/*cerr << "MidiModel " << this << " chan " << (int)chan <<
|
||||||
" note " << (int)note_num << " on @ " << time << endl;*/
|
" note " << (int)note_num << " on @ " << time << endl;*/
|
||||||
|
|
||||||
|
assert(note_num <= 127);
|
||||||
assert(chan < 16);
|
assert(chan < 16);
|
||||||
assert(_writing);
|
assert(_writing);
|
||||||
_edited = true;
|
_edited = true;
|
||||||
|
|
@ -565,6 +566,7 @@ void MidiModel::append_note_off_unlocked(uint8_t chan, double time,
|
||||||
/*cerr << "MidiModel " << this << " chan " << (int)chan <<
|
/*cerr << "MidiModel " << this << " chan " << (int)chan <<
|
||||||
" note " << (int)note_num << " off @ " << time << endl;*/
|
" note " << (int)note_num << " off @ " << time << endl;*/
|
||||||
|
|
||||||
|
assert(note_num <= 127);
|
||||||
assert(chan < 16);
|
assert(chan < 16);
|
||||||
assert(_writing);
|
assert(_writing);
|
||||||
_edited = true;
|
_edited = true;
|
||||||
|
|
|
||||||
|
|
@ -406,15 +406,14 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n
|
||||||
//cerr << "SMF - EOF\n";
|
//cerr << "SMF - EOF\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time += ev_delta_t; // accumulate delta time
|
||||||
|
|
||||||
if (ret == 0) { // meta-event (skipped)
|
if (ret == 0) { // meta-event (skipped, just accumulate time)
|
||||||
//cerr << "SMF - META\n";
|
//cerr << "SMF - META\n";
|
||||||
time += ev_delta_t; // just accumulate delta time and ignore event
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
time += ev_delta_t; // accumulate delta time
|
|
||||||
|
|
||||||
if (time >= start_ticks) {
|
if (time >= start_ticks) {
|
||||||
const nframes_t ev_frame_time = (nframes_t)(
|
const nframes_t ev_frame_time = (nframes_t)(
|
||||||
((time / (double)_ppqn) * frames_per_beat)) + stamp_offset;
|
((time / (double)_ppqn) * frames_per_beat)) + stamp_offset;
|
||||||
|
|
@ -451,6 +450,8 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
|
||||||
if (_model && ! _model->writing())
|
if (_model && ! _model->writing())
|
||||||
_model->start_write();
|
_model->start_write();
|
||||||
|
|
||||||
|
MIDI::Event ev(0.0, 4, NULL, true);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool ret = src.full_peek(sizeof(double), (Byte*)&time);
|
bool ret = src.full_peek(sizeof(double), (Byte*)&time);
|
||||||
if (!ret || time - _timeline_position > _length + cnt)
|
if (!ret || time - _timeline_position > _length + cnt)
|
||||||
|
|
@ -474,7 +475,7 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
|
||||||
assert(time >= _timeline_position);
|
assert(time >= _timeline_position);
|
||||||
time -= _timeline_position;
|
time -= _timeline_position;
|
||||||
|
|
||||||
const MIDI::Event ev(time, size, buf);
|
ev.set(buf, size, time);
|
||||||
if (! (ev.is_channel_event() || ev.is_smf_meta_event() || ev.is_sysex()) ) {
|
if (! (ev.is_channel_event() || ev.is_smf_meta_event() || ev.is_sysex()) ) {
|
||||||
//cerr << "SMFSource: WARNING: caller tried to write non SMF-Event of type " << std::hex << int(ev.buffer()[0]) << endl;
|
//cerr << "SMFSource: WARNING: caller tried to write non SMF-Event of type " << std::hex << int(ev.buffer()[0]) << endl;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -501,6 +502,9 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
|
||||||
void
|
void
|
||||||
SMFSource::append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev)
|
SMFSource::append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev)
|
||||||
{
|
{
|
||||||
|
if (ev.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/*printf("SMFSource: %s - append_event_unlocked chan = %u, time = %lf, size = %u, data = ",
|
/*printf("SMFSource: %s - append_event_unlocked chan = %u, time = %lf, size = %u, data = ",
|
||||||
name().c_str(), (unsigned)ev.channel(), ev.time(), ev.size());
|
name().c_str(), (unsigned)ev.channel(), ev.time(), ev.size());
|
||||||
for (size_t i=0; i < ev.size(); ++i) {
|
for (size_t i=0; i < ev.size(); ++i) {
|
||||||
|
|
@ -931,15 +935,17 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||||
_session.tempo_map().meter_at(_timeline_position));
|
_session.tempo_map().meter_at(_timeline_position));
|
||||||
|
|
||||||
uint32_t delta_t = 0;
|
uint32_t delta_t = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
|
uint8_t* buf = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
while ((ret = read_event(&delta_t, &ev.size(), &ev.buffer())) >= 0) {
|
while ((ret = read_event(&delta_t, &size, &buf)) >= 0) {
|
||||||
|
|
||||||
|
ev.set(buf, size, 0.0);
|
||||||
time += delta_t;
|
time += delta_t;
|
||||||
|
|
||||||
if (ret > 0) { // didn't skip (meta) event
|
if (ret > 0) { // didn't skip (meta) event
|
||||||
// make ev.time absolute time in frames
|
// make ev.time absolute time in frames
|
||||||
ev.time() = (double)time * frames_per_beat / (double)_ppqn;
|
ev.time() = (double)time * frames_per_beat / (double)_ppqn;
|
||||||
|
|
||||||
_model->append(ev);
|
_model->append(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -952,7 +958,7 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||||
_model->end_write(false);
|
_model->end_write(false);
|
||||||
_model->set_edited(false);
|
_model->set_edited(false);
|
||||||
|
|
||||||
free(ev.buffer());
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,13 +125,12 @@ struct Event {
|
||||||
if (_size < size) {
|
if (_size < size) {
|
||||||
_buffer = (uint8_t*) ::realloc(_buffer, size);
|
_buffer = (uint8_t*) ::realloc(_buffer, size);
|
||||||
}
|
}
|
||||||
|
memcpy (_buffer, buf, size);
|
||||||
} else {
|
} else {
|
||||||
_buffer = (uint8_t*) malloc(size);
|
_buffer = buf;
|
||||||
_owns_buffer = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_size = size;
|
_size = size;
|
||||||
memcpy (_buffer, buf, size);
|
|
||||||
_time = t;
|
_time = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue