Fix event allocation issues with MidiModel iteration.
authorDavid Robillard <d@drobilla.net>
Tue, 13 May 2008 00:15:26 +0000 (00:15 +0000)
committerDavid Robillard <d@drobilla.net>
Tue, 13 May 2008 00:15:26 +0000 (00:15 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@3342 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/midi_model.cc
libs/midi++2/midi++/event.h

index 10e89918053f04a58a6c4e0a3e79c0fbc370a73b..0ca84741dc6e2419f66a079ad111aad7bb24f3b3 100644 (file)
@@ -255,8 +255,6 @@ MidiModel::const_iterator& MidiModel::const_iterator::operator=(const const_iter
        if (_locked && _model != other._model)
                _model->read_unlock();
 
-       assert( ! other._event.owns_buffer());
-
        _model = other._model;
        _event = other._event;
        _active_notes = other._active_notes;
@@ -267,8 +265,6 @@ MidiModel::const_iterator& MidiModel::const_iterator::operator=(const const_iter
        size_t index = other._control_iter - other._control_iters.begin();
        _control_iter = _control_iters.begin() + index;
 
-       assert( !_event.owns_buffer() );
-
        return *this;
 }
 
@@ -329,6 +325,9 @@ size_t MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes,
        return read_events;
 }
 
+/** Write the controller event pointed to by \a iter to \a ev.
+ * Ev will have a newly allocated buffer containing the event.
+ */
 bool MidiModel::control_to_midi_event(MIDI::Event& ev,
                const MidiControlIterator& iter) const
 {
@@ -336,66 +335,54 @@ bool MidiModel::control_to_midi_event(MIDI::Event& ev,
        
        switch (iter.automation_list->parameter().type()) {
        case MidiCCAutomation:
-               if (ev.size() < 3) {
-                       ev.set_buffer((Byte*)malloc(3), true);
-               }
-
                assert(iter.automation_list);
                assert(iter.automation_list->parameter().channel() < 16);
                assert(iter.automation_list->parameter().id() <= INT8_MAX);
                assert(iter.y <= INT8_MAX);
+               
+               ev.realloc(3);
                ev.buffer()[0] = MIDI_CMD_CONTROL + iter.automation_list->parameter().channel();
                ev.buffer()[1] = (Byte)iter.automation_list->parameter().id();
                ev.buffer()[2] = (Byte)iter.y;
                ev.time() = iter.x;
-               ev.size() = 3;
                return true;
 
        case MidiPgmChangeAutomation:
-               if (ev.size() < 2) {
-                       ev.set_buffer((Byte*)malloc(2), true);
-               }
-
                assert(iter.automation_list);
                assert(iter.automation_list->parameter().channel() < 16);
                assert(iter.automation_list->parameter().id() == 0);
                assert(iter.y <= INT8_MAX);
+               
+               ev.realloc(2);
                ev.buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.automation_list->parameter().channel();
                ev.buffer()[1] = (Byte)iter.y;
                ev.time() = iter.x;
-               ev.size() = 2;
                return true;
 
        case MidiPitchBenderAutomation:
-               if (ev.size() < 3) {
-                       ev.set_buffer((Byte*)malloc(3), true);
-               }
-
                assert(iter.automation_list);
                assert(iter.automation_list->parameter().channel() < 16);
                assert(iter.automation_list->parameter().id() == 0);
                assert(iter.y < (1<<14));
+               
+               ev.realloc(3);
                ev.buffer()[0] = MIDI_CMD_BENDER + iter.automation_list->parameter().channel();
                ev.buffer()[1] = ((Byte)iter.y) & 0x7F; // LSB
                ev.buffer()[2] = (((Byte)iter.y) >> 7) & 0x7F; // MSB
                ev.time() = iter.x;
-               ev.size() = 3;
                return true;
 
        case MidiChannelAftertouchAutomation:
-               if (ev.size() < 2) {
-                       ev.set_buffer((Byte*)malloc(2), true);
-               }
-
                assert(iter.automation_list);
                assert(iter.automation_list->parameter().channel() < 16);
                assert(iter.automation_list->parameter().id() == 0);
                assert(iter.y <= INT8_MAX);
+
+               ev.realloc(2);
                ev.buffer()[0]
                                = MIDI_CMD_CHANNEL_PRESSURE + iter.automation_list->parameter().channel();
                ev.buffer()[1] = (Byte)iter.y;
                ev.time() = iter.x;
-               ev.size() = 2;
                return true;
 
        default:
index 4a0210095f57af9cc8f4e5f4d1e021974c46483c..fed5c5dd4466c656b2bd17c30d13aab0c111a7bb 100644 (file)
@@ -155,8 +155,14 @@ struct Event {
        }
 
        inline void realloc(size_t size) {
-               assert(_owns_buffer);
-               _buffer = (uint8_t*) ::realloc(_buffer, size);
+               if (_owns_buffer) {
+                       _buffer = (uint8_t*) ::realloc(_buffer, size);
+               } else {
+                       _buffer = (uint8_t*) ::malloc(size);
+                       _owns_buffer = true;
+               }
+
+               _size = size;
        }
 
 #else