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);
Evoral::Parameter param = ac->parameter();
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (ac->list ());
- assert (al);
- al->automation_state_changed.connect_same_thread (
- _list_connections, boost::bind (&Automatable::automation_list_automation_state_changed, this, ac->parameter(), _1)
- );
+ if (al) {
+ al->automation_state_changed.connect_same_thread (
+ _list_connections,
+ boost::bind (&Automatable::automation_list_automation_state_changed,
+ this, ac->parameter(), _1));
+ }
ControlSet::add_control (ac);
_can_automate_list.insert (param);
- automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up
+ if (al) {
+ automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up
+ }
}
string
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;
}
void
AutomationControl::set_automation_state (AutoState as)
{
- if (as != alist()->automation_state()) {
+ if (_list && as != alist()->automation_state()) {
alist()->set_automation_state (as);
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)
{
ac->ListMarkedDirty.connect_same_thread (_control_connections, boost::bind (&ControlSet::control_list_marked_dirty, this));
- ac->list()->InterpolationChanged.connect_same_thread (
- _list_connections, boost::bind (&ControlSet::control_list_interpolation_changed, this, ac->parameter(), _1)
- );
+ if (ac->list()) {
+ ac->list()->InterpolationChanged.connect_same_thread (
+ _list_connections,
+ boost::bind (&ControlSet::control_list_interpolation_changed,
+ this, ac->parameter(), _1));
+ }
}
void
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) {
_control_connections.drop_connections ();
_list_connections.drop_connections ();
- for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li)
- li->second->list()->clear();
+ for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) {
+ if (li->second->list()) {
+ li->second->list()->clear();
+ }
+ }
}
} // namespace Evoral