X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fautomatable.cc;h=067e64a870f5b4c1e974125416084639c9845b4b;hb=23c6936f433bfd07437b157eda4f36210819f2cf;hp=8c061ad296ac8b3997d2316f4be200a272821210;hpb=bbf41757133a29df0d37905f2fdce091878d2ffd;p=ardour.git diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 8c061ad296..067e64a870 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include "i18n.h" @@ -33,6 +34,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +nframes_t Automatable::_automation_interval = 0; Automatable::Automatable(Session& _session, const string& name) : SessionObject(_session, name) @@ -62,7 +64,7 @@ Automatable::old_set_automation_state (const XMLNode& node) if (sstr.fail()) { break; } - mark_automation_visible (ParamID(PluginAutomation, what), true); + mark_automation_visible (Parameter(PluginAutomation, what), true); } } @@ -90,7 +92,7 @@ Automatable::load_automation (const string& path) } Glib::Mutex::Lock lm (_automation_lock); - set tosave; + set tosave; _controls.clear (); _last_automation_snapshot = 0; @@ -105,9 +107,9 @@ Automatable::load_automation (const string& path) in >> value; if (!in) goto bad; /* FIXME: this is legacy and only used for plugin inserts? I think? */ - boost::shared_ptr c = control (ParamID(PluginAutomation, port), true); + boost::shared_ptr c = control (Parameter(PluginAutomation, port), true); c->list()->add (when, value); - tosave.insert (ParamID(PluginAutomation, port)); + tosave.insert (Parameter(PluginAutomation, port)); } return 0; @@ -121,12 +123,10 @@ Automatable::load_automation (const string& path) void Automatable::add_control(boost::shared_ptr ac) { - ParamID param = ac->list()->param_id(); + Parameter param = ac->parameter(); _controls[param] = ac; - cerr << _name << ": added parameter " << param.to_string() << endl; - _can_automate_list.insert(param); // Sync everything (derived classes) up to initial values @@ -134,7 +134,7 @@ Automatable::add_control(boost::shared_ptr ac) } void -Automatable::what_has_automation (set& s) const +Automatable::what_has_automation (set& s) const { Glib::Mutex::Lock lm (_automation_lock); Controls::const_iterator li; @@ -146,10 +146,10 @@ Automatable::what_has_automation (set& s) const } void -Automatable::what_has_visible_automation (set& s) const +Automatable::what_has_visible_automation (set& s) const { Glib::Mutex::Lock lm (_automation_lock); - set::const_iterator li; + set::const_iterator li; for (li = _visible_controls.begin(); li != _visible_controls.end(); ++li) { s.insert (*li); @@ -159,7 +159,7 @@ Automatable::what_has_visible_automation (set& s) const /** Returns NULL if we don't have an AutomationList for \a parameter. */ boost::shared_ptr -Automatable::control (ParamID parameter, bool create_if_missing) +Automatable::control (Parameter parameter, bool create_if_missing) { Controls::iterator i = _controls.find(parameter); @@ -167,10 +167,9 @@ Automatable::control (ParamID parameter, bool create_if_missing) return i->second; } else if (create_if_missing) { - assert(parameter.type() != GainAutomation); boost::shared_ptr al (new AutomationList ( parameter, FLT_MIN, FLT_MAX, default_parameter_value (parameter))); - boost::shared_ptr ac (new AutomationControl(_session, al)); + boost::shared_ptr ac(control_factory(al)); add_control(ac); return ac; @@ -181,7 +180,7 @@ Automatable::control (ParamID parameter, bool create_if_missing) } boost::shared_ptr -Automatable::control (ParamID parameter) const +Automatable::control (Parameter parameter) const { Controls::const_iterator i = _controls.find(parameter); @@ -195,33 +194,224 @@ Automatable::control (ParamID parameter) const string -Automatable::describe_parameter (ParamID param) +Automatable::describe_parameter (Parameter param) { /* derived classes like PluginInsert should override this */ - if (param == ParamID(GainAutomation)) + if (param == Parameter(GainAutomation)) { return _("Fader"); - else if (param == ParamID(PanAutomation)) - return _("Pan"); - else if (param.type() == MidiCCAutomation) - return string_compose("CC %1", param.id()); - else + } else if (param.type() == PanAutomation) { + return (string_compose(_("Pan %1"), param.id())); + } else if (param.type() == MidiCCAutomation) { + string name = get_name_for_cc_number(param.id()); + if(name.length() != 0) { + return string_compose("%1 [%2]", name, int(param.channel()) + 1); + } else { + return string_compose("CC %1 [%2]", param.id(), int(param.channel()) + 1); + } + } else if (param.type() == MidiPgmChangeAutomation) { + return string_compose("Program [%1]", int(param.channel()) + 1); + } else if (param.type() == MidiPitchBenderAutomation) { + return string_compose("Bender [%1]", int(param.channel()) + 1); + } else if (param.type() == MidiChannelAftertouchAutomation) { + return string_compose("Aftertouch [%1]", int(param.channel()) + 1); + } else { return param.to_string(); + } +} + +string +Automatable::get_name_for_cc_number (uint32_t cc_number) +{ + string name; + + switch (cc_number) { + case 0: + name = "Upper Bank"; + break; + + case 32: + name = "Lower Bank"; + break; + + case 1: + name = "Modulation MSB"; + break; + + case 2: + name = "Breath Controller"; + break; + + case 4: + name = "Foot Controller"; + break; + + case 5: + name = "Portamento Time"; + break; + + case 6: + name = "RPN Controller"; + break; + + case 7: + name = "Main Volume"; + break; + + case 8: + name = "Balance"; + break; + + case 10: + name = "Panorama"; + break; + + case 11: + name = "Expression"; + break; + + case 12: + name = "Effect 1"; + break; + + case 13: + name = "Effect 2"; + break; + + case 16: + case 17: + case 18: + case 19: + name = string_compose("General Purpose %1", cc_number - 15); + break; + + case 64: + name = "Sustain Pedal"; + break; + + case 65: + name = "Portamento"; + break; + + case 66: + name = "Sostenuto"; + break; + + case 67: + name = "Soft Pedal"; + break; + + case 68: + name = "Legato Footswitch"; + break; + + case 69: + name = "Hold 2"; + break; + + case 70: + case 71: + case 72: + case 73: + case 74: + name = string_compose("Sound Controller %1", cc_number - 69); + break; + + case 80: + case 81: + case 82: + case 83: + name = string_compose("General Purpose %1", cc_number - 75); + break; + + case 84: + name = "Portamento Control"; + break; + + case 91: + case 92: + case 93: + case 94: + case 95: + name = string_compose("Effects %1 Depth", cc_number - 90); + break; + + case 96: + name = "Data Increment RPN/NRPN"; + break; + + case 97: + name = "Data Decrement RPN/NRPN"; + break; + + case 98: + name = "NRPN LSB"; + break; + + case 99: + name = "NRPN MSB"; + break; + + case 100: + name = "RPN LSB"; + break; + + case 101: + name = "RPN MSB"; + break; + + case 120: + name = "all sounds off"; + break; + + case 121: + name = "Controller Reset"; + break; + + case 122: + name = "Local Control on/off"; + break; + + case 123: + name = "all notes off"; + break; + + case 124: + name = "omni off"; + break; + + case 125: + name = "omni on"; + break; + + case 126: + name = "mono on / poly off"; + break; + + case 127: + name = "poly on / mono off"; + break; + + default: + break; + } + + return name; } void -Automatable::can_automate (ParamID what) +Automatable::can_automate (Parameter what) { _can_automate_list.insert (what); } void -Automatable::mark_automation_visible (ParamID what, bool yn) +Automatable::mark_automation_visible (Parameter what, bool yn) { if (yn) { _visible_controls.insert (what); } else { - set::iterator i; + set::iterator i; if ((i = _visible_controls.find (what)) != _visible_controls.end()) { _visible_controls.erase (i); @@ -233,7 +423,6 @@ bool Automatable::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_event) const { Controls::const_iterator li; - AutomationList::TimeComparator cmp; next_event.when = max_frames; @@ -243,7 +432,8 @@ Automatable::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_e boost::shared_ptr alist (li->second->list()); ControlEvent cp (now, 0.0f); - for (i = lower_bound (alist->const_begin(), alist->const_end(), &cp, cmp); i != alist->const_end() && (*i)->when < end; ++i) { + for (i = lower_bound (alist->const_begin(), alist->const_end(), &cp, AutomationList::time_comparator); + i != alist->const_end() && (*i)->when < end; ++i) { if ((*i)->when > now) { break; } @@ -265,7 +455,7 @@ Automatable::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_e * pass that type and it will be used for the untyped AutomationList found. */ int -Automatable::set_automation_state (const XMLNode& node, ParamID legacy_param) +Automatable::set_automation_state (const XMLNode& node, Parameter legacy_param) { Glib::Mutex::Lock lm (_automation_lock); @@ -287,21 +477,21 @@ Automatable::set_automation_state (const XMLNode& node, ParamID legacy_param) const XMLProperty* id_prop = (*niter)->property("automation-id"); - ParamID param = (id_prop ? ParamID(id_prop->value()) : legacy_param); + Parameter param = (id_prop ? Parameter(id_prop->value()) : legacy_param); boost::shared_ptr al (new AutomationList(**niter, param)); if (!id_prop) { warning << "AutomationList node without automation-id property, " << "using default: " << legacy_param.to_string() << endmsg; - al->set_param_id(legacy_param); + al->set_parameter(legacy_param); } boost::shared_ptr existing = control(param); if (existing) existing->set_list(al); else - add_control(boost::shared_ptr(new AutomationControl(_session, al))); + add_control(control_factory(al)); } else { error << "Expected AutomationList node, got '" << (*niter)->name() << endmsg; @@ -340,7 +530,7 @@ Automatable::clear_automation () } void -Automatable::set_parameter_automation_state (ParamID param, AutoState s) +Automatable::set_parameter_automation_state (Parameter param, AutoState s) { Glib::Mutex::Lock lm (_automation_lock); @@ -353,7 +543,7 @@ Automatable::set_parameter_automation_state (ParamID param, AutoState s) } AutoState -Automatable::get_parameter_automation_state (ParamID param, bool lock) +Automatable::get_parameter_automation_state (Parameter param, bool lock) { AutoState result = Off; @@ -372,7 +562,7 @@ Automatable::get_parameter_automation_state (ParamID param, bool lock) } void -Automatable::set_parameter_automation_style (ParamID param, AutoStyle s) +Automatable::set_parameter_automation_style (Parameter param, AutoStyle s) { Glib::Mutex::Lock lm (_automation_lock); @@ -385,7 +575,7 @@ Automatable::set_parameter_automation_style (ParamID param, AutoStyle s) } AutoStyle -Automatable::get_parameter_automation_style (ParamID param) +Automatable::get_parameter_automation_style (Parameter param) { Glib::Mutex::Lock lm (_automation_lock); @@ -401,11 +591,11 @@ Automatable::get_parameter_automation_style (ParamID param) void Automatable::protect_automation () { - set automated_params; + set automated_params; what_has_automation (automated_params); - for (set::iterator i = automated_params.begin(); i != automated_params.end(); ++i) { + for (set::iterator i = automated_params.begin(); i != automated_params.end(); ++i) { boost::shared_ptr c = control(*i); @@ -423,9 +613,9 @@ Automatable::protect_automation () } void -Automatable::automation_snapshot (nframes_t now) +Automatable::automation_snapshot (nframes_t now, bool force) { - if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _session.automation_interval()) { + if (force || _last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) { for (Controls::iterator i = _controls.begin(); i != _controls.end(); ++i) { if (i->second->list()->automation_write()) { @@ -452,3 +642,19 @@ Automatable::transport_stopped (nframes_t now) } } +/* FIXME: this probably doesn't belong here */ +boost::shared_ptr +Automatable::control_factory(boost::shared_ptr list) +{ + if ( + list->parameter().type() == MidiCCAutomation || + list->parameter().type() == MidiPgmChangeAutomation || + list->parameter().type() == MidiChannelAftertouchAutomation + ) { + // FIXME: this will die horribly if this is not a MidiTrack + return boost::shared_ptr(new MidiTrack::MidiControl((MidiTrack*)this, list)); + } else { + return boost::shared_ptr(new AutomationControl(_session, list)); + } +} +