Fix crash when changing automation mode for MIDI track control automation.
Also some work towards tolerating automation controls with no automation list, towards actually doing something for these cases, though not required just to fix this crash (MidiTrack::set_parameter_automation_state() avoids those paths).
This commit is contained in:
parent
b012f2cd18
commit
34c1465cf9
|
@ -93,6 +93,8 @@ public:
|
|||
MidiTrack* _route;
|
||||
};
|
||||
|
||||
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
|
||||
|
||||
NoteMode note_mode() const { return _note_mode; }
|
||||
void set_note_mode (NoteMode m);
|
||||
|
||||
|
|
|
@ -137,16 +137,20 @@ Automatable::add_control(boost::shared_ptr<Evoral::Control> ac)
|
|||
Evoral::Parameter param = ac->parameter();
|
||||
|
||||
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (ac->list ());
|
||||
assert (al);
|
||||
|
||||
if (al) {
|
||||
al->automation_state_changed.connect_same_thread (
|
||||
_list_connections, boost::bind (&Automatable::automation_list_automation_state_changed, this, ac->parameter(), _1)
|
||||
);
|
||||
_list_connections,
|
||||
boost::bind (&Automatable::automation_list_automation_state_changed,
|
||||
this, ac->parameter(), _1));
|
||||
}
|
||||
|
||||
ControlSet::add_control (ac);
|
||||
_can_automate_list.insert (param);
|
||||
|
||||
if (al) {
|
||||
automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
|
@ -394,6 +398,7 @@ Automatable::control_factory(const Evoral::Parameter& param)
|
|||
MidiTrack* mt = dynamic_cast<MidiTrack*>(this);
|
||||
if (mt) {
|
||||
control = new MidiTrack::MidiControl(mt, param);
|
||||
list.reset(); // No list, this is region "automation"
|
||||
} else {
|
||||
warning << "MidiCCAutomation for non-MidiTrack" << endl;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ AutomationControl::set_list (boost::shared_ptr<Evoral::ControlList> list)
|
|||
void
|
||||
AutomationControl::set_automation_state (AutoState as)
|
||||
{
|
||||
if (as != alist()->automation_state()) {
|
||||
if (_list && as != alist()->automation_state()) {
|
||||
|
||||
alist()->set_automation_state (as);
|
||||
|
||||
|
|
|
@ -622,6 +622,24 @@ MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
|
|||
return (_immediate_events.write(0, type, size, buf) == size);
|
||||
}
|
||||
|
||||
void
|
||||
MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
|
||||
{
|
||||
switch (param.type()) {
|
||||
case MidiCCAutomation:
|
||||
case MidiPgmChangeAutomation:
|
||||
case MidiPitchBenderAutomation:
|
||||
case MidiChannelPressureAutomation:
|
||||
case MidiSystemExclusiveAutomation:
|
||||
/* The track control for MIDI parameters is for immediate events to act
|
||||
as a control surface, write/touch for them is not currently
|
||||
supported. */
|
||||
return;
|
||||
default:
|
||||
Automatable::set_parameter_automation_state(param, state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTrack::MidiControl::set_value(double val)
|
||||
{
|
||||
|
|
|
@ -45,9 +45,12 @@ ControlSet::add_control(boost::shared_ptr<Control> ac)
|
|||
|
||||
ac->ListMarkedDirty.connect_same_thread (_control_connections, boost::bind (&ControlSet::control_list_marked_dirty, this));
|
||||
|
||||
if (ac->list()) {
|
||||
ac->list()->InterpolationChanged.connect_same_thread (
|
||||
_list_connections, boost::bind (&ControlSet::control_list_interpolation_changed, this, ac->parameter(), _1)
|
||||
);
|
||||
_list_connections,
|
||||
boost::bind (&ControlSet::control_list_interpolation_changed,
|
||||
this, ac->parameter(), _1));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -95,6 +98,9 @@ ControlSet::find_next_event (double now, double end, ControlEvent& next_event) c
|
|||
ControlList::const_iterator i;
|
||||
boost::shared_ptr<const ControlList> alist (li->second->list());
|
||||
ControlEvent cp (now, 0.0f);
|
||||
if (!alist) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = lower_bound (alist->begin(), alist->end(), &cp, ControlList::time_comparator);
|
||||
i != alist->end() && (*i)->when < end; ++i) {
|
||||
|
@ -121,8 +127,11 @@ ControlSet::clear_controls ()
|
|||
_control_connections.drop_connections ();
|
||||
_list_connections.drop_connections ();
|
||||
|
||||
for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li)
|
||||
for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) {
|
||||
if (li->second->list()) {
|
||||
li->second->list()->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Evoral
|
||||
|
|
Loading…
Reference in New Issue
Block a user