mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 16:24:57 +01:00
Fix event allocation issues with MidiModel iteration.
git-svn-id: svn://localhost/ardour2/branches/3.0@3342 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
bded96269f
commit
a25be81b5d
2 changed files with 19 additions and 26 deletions
|
|
@ -255,8 +255,6 @@ MidiModel::const_iterator& MidiModel::const_iterator::operator=(const const_iter
|
||||||
if (_locked && _model != other._model)
|
if (_locked && _model != other._model)
|
||||||
_model->read_unlock();
|
_model->read_unlock();
|
||||||
|
|
||||||
assert( ! other._event.owns_buffer());
|
|
||||||
|
|
||||||
_model = other._model;
|
_model = other._model;
|
||||||
_event = other._event;
|
_event = other._event;
|
||||||
_active_notes = other._active_notes;
|
_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();
|
size_t index = other._control_iter - other._control_iters.begin();
|
||||||
_control_iter = _control_iters.begin() + index;
|
_control_iter = _control_iters.begin() + index;
|
||||||
|
|
||||||
assert( !_event.owns_buffer() );
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,6 +325,9 @@ size_t MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes,
|
||||||
return read_events;
|
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,
|
bool MidiModel::control_to_midi_event(MIDI::Event& ev,
|
||||||
const MidiControlIterator& iter) const
|
const MidiControlIterator& iter) const
|
||||||
{
|
{
|
||||||
|
|
@ -336,66 +335,54 @@ bool MidiModel::control_to_midi_event(MIDI::Event& ev,
|
||||||
|
|
||||||
switch (iter.automation_list->parameter().type()) {
|
switch (iter.automation_list->parameter().type()) {
|
||||||
case MidiCCAutomation:
|
case MidiCCAutomation:
|
||||||
if (ev.size() < 3) {
|
|
||||||
ev.set_buffer((Byte*)malloc(3), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(iter.automation_list);
|
assert(iter.automation_list);
|
||||||
assert(iter.automation_list->parameter().channel() < 16);
|
assert(iter.automation_list->parameter().channel() < 16);
|
||||||
assert(iter.automation_list->parameter().id() <= INT8_MAX);
|
assert(iter.automation_list->parameter().id() <= INT8_MAX);
|
||||||
assert(iter.y <= INT8_MAX);
|
assert(iter.y <= INT8_MAX);
|
||||||
|
|
||||||
|
ev.realloc(3);
|
||||||
ev.buffer()[0] = MIDI_CMD_CONTROL + iter.automation_list->parameter().channel();
|
ev.buffer()[0] = MIDI_CMD_CONTROL + iter.automation_list->parameter().channel();
|
||||||
ev.buffer()[1] = (Byte)iter.automation_list->parameter().id();
|
ev.buffer()[1] = (Byte)iter.automation_list->parameter().id();
|
||||||
ev.buffer()[2] = (Byte)iter.y;
|
ev.buffer()[2] = (Byte)iter.y;
|
||||||
ev.time() = iter.x;
|
ev.time() = iter.x;
|
||||||
ev.size() = 3;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MidiPgmChangeAutomation:
|
case MidiPgmChangeAutomation:
|
||||||
if (ev.size() < 2) {
|
|
||||||
ev.set_buffer((Byte*)malloc(2), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(iter.automation_list);
|
assert(iter.automation_list);
|
||||||
assert(iter.automation_list->parameter().channel() < 16);
|
assert(iter.automation_list->parameter().channel() < 16);
|
||||||
assert(iter.automation_list->parameter().id() == 0);
|
assert(iter.automation_list->parameter().id() == 0);
|
||||||
assert(iter.y <= INT8_MAX);
|
assert(iter.y <= INT8_MAX);
|
||||||
|
|
||||||
|
ev.realloc(2);
|
||||||
ev.buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.automation_list->parameter().channel();
|
ev.buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.automation_list->parameter().channel();
|
||||||
ev.buffer()[1] = (Byte)iter.y;
|
ev.buffer()[1] = (Byte)iter.y;
|
||||||
ev.time() = iter.x;
|
ev.time() = iter.x;
|
||||||
ev.size() = 2;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MidiPitchBenderAutomation:
|
case MidiPitchBenderAutomation:
|
||||||
if (ev.size() < 3) {
|
|
||||||
ev.set_buffer((Byte*)malloc(3), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(iter.automation_list);
|
assert(iter.automation_list);
|
||||||
assert(iter.automation_list->parameter().channel() < 16);
|
assert(iter.automation_list->parameter().channel() < 16);
|
||||||
assert(iter.automation_list->parameter().id() == 0);
|
assert(iter.automation_list->parameter().id() == 0);
|
||||||
assert(iter.y < (1<<14));
|
assert(iter.y < (1<<14));
|
||||||
|
|
||||||
|
ev.realloc(3);
|
||||||
ev.buffer()[0] = MIDI_CMD_BENDER + iter.automation_list->parameter().channel();
|
ev.buffer()[0] = MIDI_CMD_BENDER + iter.automation_list->parameter().channel();
|
||||||
ev.buffer()[1] = ((Byte)iter.y) & 0x7F; // LSB
|
ev.buffer()[1] = ((Byte)iter.y) & 0x7F; // LSB
|
||||||
ev.buffer()[2] = (((Byte)iter.y) >> 7) & 0x7F; // MSB
|
ev.buffer()[2] = (((Byte)iter.y) >> 7) & 0x7F; // MSB
|
||||||
ev.time() = iter.x;
|
ev.time() = iter.x;
|
||||||
ev.size() = 3;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MidiChannelAftertouchAutomation:
|
case MidiChannelAftertouchAutomation:
|
||||||
if (ev.size() < 2) {
|
|
||||||
ev.set_buffer((Byte*)malloc(2), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(iter.automation_list);
|
assert(iter.automation_list);
|
||||||
assert(iter.automation_list->parameter().channel() < 16);
|
assert(iter.automation_list->parameter().channel() < 16);
|
||||||
assert(iter.automation_list->parameter().id() == 0);
|
assert(iter.automation_list->parameter().id() == 0);
|
||||||
assert(iter.y <= INT8_MAX);
|
assert(iter.y <= INT8_MAX);
|
||||||
|
|
||||||
|
ev.realloc(2);
|
||||||
ev.buffer()[0]
|
ev.buffer()[0]
|
||||||
= MIDI_CMD_CHANNEL_PRESSURE + iter.automation_list->parameter().channel();
|
= MIDI_CMD_CHANNEL_PRESSURE + iter.automation_list->parameter().channel();
|
||||||
ev.buffer()[1] = (Byte)iter.y;
|
ev.buffer()[1] = (Byte)iter.y;
|
||||||
ev.time() = iter.x;
|
ev.time() = iter.x;
|
||||||
ev.size() = 2;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,14 @@ struct Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void realloc(size_t size) {
|
inline void realloc(size_t size) {
|
||||||
assert(_owns_buffer);
|
if (_owns_buffer) {
|
||||||
_buffer = (uint8_t*) ::realloc(_buffer, size);
|
_buffer = (uint8_t*) ::realloc(_buffer, size);
|
||||||
|
} else {
|
||||||
|
_buffer = (uint8_t*) ::malloc(size);
|
||||||
|
_owns_buffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue