+void
+OSCSelectObserver::set_send_page (uint32_t page)
+{
+ if (send_page != page) {
+ send_page = page;
+ renew_sends ();
+ }
+}
+
+void
+OSCSelectObserver::set_send_size (uint32_t size)
+{
+ send_page_size = size;
+ renew_sends ();
+}
+
+void
+OSCSelectObserver::renew_sends () {
+ send_connections.drop_connections ();
+ send_timeout.clear();
+ send_init();
+}
+
+void
+OSCSelectObserver::send_init()
+{
+ send_size = nsends;
+ if (send_page_size) {
+ send_size = send_page_size;
+ }
+ if (!send_size) {
+ return;
+ }
+ uint32_t page_start = ((send_page - 1) * send_size);
+ uint32_t last_send = send_page * send_size;
+ uint32_t c = 1;
+ send_timeout.push_back (2);
+ _last_send.clear();
+ _last_send.push_back (0.0);
+
+ for (uint32_t s = page_start; s < last_send; ++s, ++c) {
+
+ bool send_valid = false;
+ if (_strip->send_level_controllable (s)) {
+ _strip->send_level_controllable(s)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_gain, this, c, _strip->send_level_controllable(s)), OSC::instance());
+ send_timeout.push_back (2);
+ _last_send.push_back (20.0);
+ send_gain (c, _strip->send_level_controllable(s));
+ send_valid = true;
+ } else {
+ send_gain (c, _strip->send_level_controllable(s));
+ _osc.float_message_with_id (X_("/select/send_enable"), c, 0, in_line, addr);
+ _osc.text_message_with_id (X_("/select/send_name"), c, " ", in_line, addr);
+ }
+
+ if (_strip->send_enable_controllable (s)) {
+ _strip->send_enable_controllable(s)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::enable_message_with_id, this, X_("/select/send_enable"), c, _strip->send_enable_controllable(s)), OSC::instance());
+ enable_message_with_id (X_("/select/send_enable"), c, _strip->send_enable_controllable(s));
+ } else if (send_valid) {
+ boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (_strip);
+ if (!r) {
+ // should never get here
+ _osc.float_message_with_id (X_("/select/send_enable"), c, 0, in_line, addr);
+ }
+ boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(s));
+ if (snd) {
+ boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (snd);
+ proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_enable, this, X_("/select/send_enable"), c, proc), OSC::instance());
+ _osc.float_message_with_id (X_("/select/send_enable"), c, proc->enabled(), in_line, addr);
+ }
+ }
+ if ((gainmode != 1) && send_valid) {
+ _osc.text_message_with_id (X_("/select/send_name"), c, _strip->send_name(s), in_line, addr);
+ }
+ }
+}
+
+void
+OSCSelectObserver::send_end ()
+{
+ send_connections.drop_connections ();
+ for (uint32_t i = 1; i <= send_size; i++) {
+ if (gainmode) {
+ _osc.float_message_with_id (X_("/select/send_fader"), i, 0, in_line, addr);
+ } else {
+ _osc.float_message_with_id (X_("/select/send_gain"), i, -193, in_line, addr);
+ }
+ // next enable
+ _osc.float_message_with_id (X_("/select/send_enable"), i, 0, in_line, addr);
+ // next name
+ _osc.text_message_with_id (X_("/select/send_name"), i, " ", in_line, addr);
+ }
+ // need to delete or clear send_timeout
+ send_size = 0;
+ send_timeout.clear();
+}
+
+void
+OSCSelectObserver::set_plugin_id (int id, uint32_t page)
+{
+ plug_id = id;
+ plug_page = page;
+ renew_plugin ();
+}
+
+void
+OSCSelectObserver::set_plugin_page (uint32_t page)
+{
+ plug_page = page;
+ renew_plugin ();
+}
+
+void
+OSCSelectObserver::set_plugin_size (uint32_t size)
+{
+ plug_page_size = size;
+ renew_plugin ();
+}
+
+void
+OSCSelectObserver::renew_plugin () {
+ plugin_connections.drop_connections ();
+ plugin_init();
+}
+
+void
+OSCSelectObserver::plugin_init()
+{
+ if (plug_id < 0) {
+ plugin_end ();
+ return;
+ }
+ boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(_strip);
+ if (!r) {
+ plugin_end ();
+ return;
+ }
+
+ // we have a plugin number now get the processor
+ boost::shared_ptr<Processor> proc = r->nth_plugin (plug_id);
+ boost::shared_ptr<PluginInsert> pi;
+ if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
+ plugin_end ();
+ return;
+ }
+ boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
+ // we have a plugin we can ask if it is activated
+ proc->ActiveChanged.connect (plugin_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::plug_enable, this, X_("/select/plugin/activate"), proc), OSC::instance());
+ _osc.float_message (X_("/select/plugin/activate"), proc->enabled(), addr);
+
+ bool ok = false;
+ // put only input controls into a vector
+ plug_params.clear ();
+ uint32_t nplug_params = pip->parameter_count();
+ for ( uint32_t ppi = 0; ppi < nplug_params; ++ppi) {
+ uint32_t controlid = pip->nth_parameter(ppi, ok);
+ if (!ok) {
+ continue;
+ }
+ if (pip->parameter_is_input(controlid)) {
+ plug_params.push_back (ppi);
+ }
+ }
+ nplug_params = plug_params.size ();
+
+ // default of 0 page size means show all
+ plug_size = nplug_params;
+ if (plug_page_size) {
+ plug_size = plug_page_size;
+ }
+ _osc.text_message (X_("/select/plugin/name"), pip->name(), addr);
+ uint32_t page_start = plug_page - 1;
+ uint32_t page_end = page_start + plug_size;
+
+ int pid = 1;
+ for ( uint32_t ppi = page_start; ppi < page_end; ++ppi, ++pid) {
+ if (ppi >= nplug_params) {
+ _osc.text_message_with_id (X_("/select/plugin/parameter/name"), pid, " ", in_line, addr);
+ _osc.float_message_with_id (X_("/select/plugin/parameter"), pid, 0, in_line, addr);
+ continue;
+ }
+
+ uint32_t controlid = pip->nth_parameter(plug_params[ppi], ok);
+ if (!ok) {
+ continue;
+ }
+ ParameterDescriptor pd;
+ pip->get_parameter_descriptor(controlid, pd);
+ _osc.text_message_with_id (X_("/select/plugin/parameter/name"), pid, pd.label, in_line, addr);
+ if ( pip->parameter_is_input(controlid)) {
+ boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
+ if (c) {
+ bool swtch = false;
+ if (pd.integer_step && pd.upper == 1) {
+ swtch = true;
+ }
+ c->Changed.connect (plugin_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::plugin_parameter_changed, this, pid, swtch, c), OSC::instance());
+ plugin_parameter_changed (pid, swtch, c);
+ }
+ }
+ }
+}
+
+void
+OSCSelectObserver::plugin_parameter_changed (int pid, bool swtch, boost::shared_ptr<PBD::Controllable> controllable)
+{
+ if (swtch) {
+ enable_message_with_id (X_("/select/plugin/parameter"), pid, controllable);
+ } else {
+ change_message_with_id (X_("/select/plugin/parameter"), pid, controllable);
+ }
+}
+
+void
+OSCSelectObserver::plugin_end ()
+{
+ plugin_connections.drop_connections ();
+ _osc.float_message (X_("/select/plugin/activate"), 0, addr);
+ _osc.text_message (X_("/select/plugin/name"), " ", addr);
+ for (uint32_t i = 1; i <= plug_size; i++) {
+ _osc.float_message_with_id (X_("/select/plugin/parameter"), i, 0, in_line, addr);
+ // next name
+ _osc.text_message_with_id (X_("/select/plugin/parameter/name"), i, " ", in_line, addr);
+ }
+ plug_size = 0;
+ nplug_params = 0;