Fix absolutely atrocious memory leak on MIDI recording. I meeean... move along now, nothing to see here.
Fix SMFSource to realloc a scratch read buffer as necessary, removing upper limit on single raw event size. Remove public exposure of MidiBuffer::max_event_size (though it still exists internally). Fix crash bug on MIDI record completion (transport stop). git-svn-id: svn://localhost/ardour2/trunk@2157 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
6a4bd8e926
commit
f9717abf01
@ -46,8 +46,6 @@ public:
|
||||
const MidiEvent& operator[](size_t i) const { assert(i < _size); return _events[i]; }
|
||||
MidiEvent& operator[](size_t i) { assert(i < _size); return _events[i]; }
|
||||
|
||||
static size_t max_event_size() { return MAX_EVENT_SIZE; }
|
||||
|
||||
bool merge(const MidiBuffer& a, const MidiBuffer& b);
|
||||
|
||||
private:
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
void append(const MidiBuffer& data);
|
||||
|
||||
/** Resizes vector if necessary (NOT realtime safe) */
|
||||
void append(double time, size_t size, Byte* in_buffer);
|
||||
void append(double time, size_t size, const Byte* in_buffer);
|
||||
|
||||
inline const Note& note_at(unsigned i) const { return _notes[i]; }
|
||||
|
||||
|
@ -104,7 +104,7 @@ MidiModel::append(const MidiBuffer& buf)
|
||||
* and MUST be >= the latest event currently in the model.
|
||||
*/
|
||||
void
|
||||
MidiModel::append(double time, size_t size, Byte* buf)
|
||||
MidiModel::append(double time, size_t size, const Byte* buf)
|
||||
{
|
||||
assert(_notes.empty() || time >= _notes.back().start);
|
||||
|
||||
|
@ -275,11 +275,17 @@ SMFSource::read_event(jack_midi_event_t& ev) const
|
||||
}
|
||||
}
|
||||
|
||||
size_t event_size = midi_event_size((unsigned char)status) + 1;
|
||||
|
||||
// Make sure we have enough scratch buffer
|
||||
if (ev.size < event_size)
|
||||
ev.buffer = (Byte*)realloc(ev.buffer, event_size);
|
||||
|
||||
ev.time = delta_time;
|
||||
ev.size = midi_event_size((unsigned char)status) + 1;
|
||||
ev.size = event_size;
|
||||
|
||||
if (ev.buffer == NULL)
|
||||
ev.buffer = (Byte*)malloc(sizeof(Byte) * ev.size);
|
||||
/*if (ev.buffer == NULL)
|
||||
ev.buffer = (Byte*)malloc(sizeof(Byte) * ev.size);*/
|
||||
|
||||
ev.buffer[0] = (unsigned char)status;
|
||||
fread(ev.buffer+1, 1, ev.size - 1, _fd);
|
||||
@ -305,12 +311,12 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n
|
||||
|
||||
_read_data_count = 0;
|
||||
|
||||
// FIXME: ugh
|
||||
unsigned char ev_buf[MidiBuffer::max_event_size()];
|
||||
jack_midi_event_t ev; // time in SMF ticks
|
||||
ev.time = 0;
|
||||
ev.size = MidiBuffer::max_event_size();
|
||||
ev.buffer = ev_buf;
|
||||
ev.size = 0;
|
||||
ev.buffer = NULL; // read_event will allocate scratch as needed
|
||||
|
||||
size_t scratch_size = 0; // keep track of scratch and minimize reallocs
|
||||
|
||||
// FIXME: don't seek to start every read
|
||||
fseek(_fd, _header_size, 0);
|
||||
@ -348,6 +354,11 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n
|
||||
}
|
||||
|
||||
_read_data_count += ev.size;
|
||||
|
||||
if (ev.size > scratch_size)
|
||||
scratch_size = ev.size;
|
||||
else
|
||||
ev.size = scratch_size;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
@ -786,8 +797,12 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||
return;
|
||||
}
|
||||
|
||||
if (! _model)
|
||||
if (! _model) {
|
||||
_model = new MidiModel(_session);
|
||||
} else {
|
||||
cerr << "SMFSource: Reloading model." << endl;
|
||||
_model->clear();
|
||||
}
|
||||
|
||||
_model->start_write();
|
||||
|
||||
@ -799,12 +814,15 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||
ev.size = 0;
|
||||
ev.buffer = NULL;
|
||||
|
||||
size_t scratch_size = 0; // keep track of scratch and minimize reallocs
|
||||
|
||||
// FIXME: assumes tempo never changes after start
|
||||
const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
|
||||
_session.engine().frame_rate());
|
||||
|
||||
int ret;
|
||||
while ((ret = read_event(ev)) >= 0) {
|
||||
|
||||
time += ev.time;
|
||||
|
||||
const double ev_time = (double)(time * frames_per_beat / (double)_ppqn); // in frames
|
||||
@ -813,10 +831,17 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||
//cerr << "ADDING EVENT TO MODEL: " << ev.time << endl;
|
||||
_model->append(ev_time, ev.size, ev.buffer);
|
||||
}
|
||||
|
||||
if (ev.size > scratch_size)
|
||||
scratch_size = ev.size;
|
||||
else
|
||||
ev.size = scratch_size;
|
||||
}
|
||||
|
||||
_model->end_write(false); /* FIXME: delete stuck notes iff percussion? */
|
||||
|
||||
free(ev.buffer);
|
||||
|
||||
_model_loaded = true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user