From 7038e586d04b3cc8a62c489a2e6fd79eb99f0c68 Mon Sep 17 00:00:00 2001 From: Ben Loftis Date: Mon, 7 Nov 2022 10:28:13 -0600 Subject: [PATCH] OSC: add support for Mixer Scenes: save, recall, and state feedback --- libs/surfaces/osc/osc.cc | 25 +++++++++++++++++++++++- libs/surfaces/osc/osc.h | 6 ++++++ libs/surfaces/osc/osc_global_observer.cc | 17 ++++++++++++++++ libs/surfaces/osc/osc_global_observer.h | 2 +- libs/surfaces/osc/osc_gui.cc | 11 +++++++++++ libs/surfaces/osc/osc_gui.h | 1 + 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index fc6a593ba7..84f57df02b 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -50,6 +50,7 @@ #include "ardour/route_group.h" #include "ardour/audio_track.h" #include "ardour/midi_track.h" +#include "ardour/mixer_scene.h" #include "ardour/vca.h" #include "ardour/monitor_control.h" #include "ardour/dB.h" @@ -470,6 +471,9 @@ OSC::register_callbacks() REGISTER_CALLBACK (serv, X_("/tbank_step_route"), "i", osc_tbank_step_routes); REGISTER_CALLBACK (serv, X_("/tbank_step_row"), "i", osc_tbank_step_rows); + REGISTER_CALLBACK (serv, X_("/store_mixer_scene"), "i", store_mixer_scene); + REGISTER_CALLBACK (serv, X_("/recall_mixer_scene"), "i", apply_mixer_scene); + REGISTER_CALLBACK (serv, X_("/save_state"), "", save_state); REGISTER_CALLBACK (serv, X_("/save_state"), "f", save_state); REGISTER_CALLBACK (serv, X_("/prev_marker"), "", prev_marker); @@ -2108,7 +2112,7 @@ OSC::global_feedback (OSCSurface* sur) delete o; sur->global_obs = 0; } - if (sur->feedback[4] || sur->feedback[3] || sur->feedback[5] || sur->feedback[6] || sur->feedback[15]) { + if (sur->feedback[4] || sur->feedback[3] || sur->feedback[5] || sur->feedback[6] || sur->feedback[15] || sur->feedback[16]) { // create a new Global Observer for this surface sur->global_obs = new OSCGlobalObserver (*this, *session, sur); sur->global_obs->jog_mode (sur->jogmode); @@ -3158,6 +3162,25 @@ OSC::trigger_grid_state (lo_address addr, bool zero_it) return 0; } +int +OSC::mixer_scene_state (lo_address addr, bool zero_it) +{ + if (!session) return -1; + + for (int scn = 0; scn < 8; scn++) { //TODO: mixer scene size + lo_message scene_msg = lo_message_new (); + if (!zero_it && session->nth_mixer_scene_valid(scn)) { + boost::shared_ptr scene = session->nth_mixer_scene(scn); + lo_message_add_string (scene_msg, scene->name().c_str()); + } else { + lo_message_add_string (scene_msg, ""); + } + lo_send_message (addr, string_compose(X_("/mixer_scene/%1/name"), scn).c_str(), scene_msg); + lo_message_free (scene_msg); + } + return 0; +} + // two structs to help with going to markers struct LocationMarker { LocationMarker (const std::string& l, samplepos_t w) diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h index 1daf734cf3..38776d5fdb 100644 --- a/libs/surfaces/osc/osc.h +++ b/libs/surfaces/osc/osc.h @@ -190,6 +190,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI * [13] - Send well known feedback (for /select/command * [14] - use OSC 1.0 only (#reply -> /reply) * [15] - report 8x8 trigger grid status + * [16] - report mixer scene status * * Strip_type bits: * [0] - Audio Tracks @@ -268,6 +269,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int trigger_bank_state (lo_address addr); int trigger_grid_state (lo_address addr, bool zero_it = false); + int mixer_scene_state (lo_address addr, bool zero_it = false); + protected: void thread_init (); void do_request (OSCUIRequest*); @@ -493,6 +496,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI PATH_CALLBACK1(trigger_cue_row,i,); PATH_CALLBACK1(trigger_stop_all,i,); //0 = "stop at end of bar" 1 = "stop now" + PATH_CALLBACK1(store_mixer_scene,i,); + PATH_CALLBACK1(apply_mixer_scene,i,); + PATH_CALLBACK1(set_transport_speed,f,); PATH_CALLBACK1(add_marker_name,s,&); PATH_CALLBACK1(access_action,s,&); diff --git a/libs/surfaces/osc/osc_global_observer.cc b/libs/surfaces/osc/osc_global_observer.cc index 7654d33c59..ef9d6ff324 100644 --- a/libs/surfaces/osc/osc_global_observer.cc +++ b/libs/surfaces/osc/osc_global_observer.cc @@ -25,6 +25,7 @@ #include "ardour/session.h" #include "ardour/dB.h" #include "ardour/meter.h" +#include "ardour/mixer_scene.h" #include "ardour/monitor_processor.h" #include "temporal/tempo.h" @@ -58,6 +59,13 @@ OSCGlobalObserver::OSCGlobalObserver (OSC& o, Session& s, ArdourSurface::OSC::OS uint32_t jogmode = sur->jogmode; _last_sample = -1; mark_text = ""; + + if (feedback[16]) { + //Mixer Scenes + MixerScene::Change.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::update_mixer_scene_state, this), OSC::instance()); + update_mixer_scene_state(); + } + if (feedback[4]) { // connect to all the things we want to send feed back from @@ -176,6 +184,9 @@ OSCGlobalObserver::clear_observer () if (feedback[15]) { // trigger grid status _osc.trigger_grid_state(addr, true); //zero it out } + if (feedback[16]) { // mixer scene status + _osc.mixer_scene_state(addr, true); //zero it out + } if (feedback[10]) { // samples _osc.text_message (X_("/position/samples"), " ", addr); } @@ -222,6 +233,12 @@ OSCGlobalObserver::clear_observer () } +void +OSCGlobalObserver::update_mixer_scene_state () +{ + _osc.mixer_scene_state(addr); +} + void OSCGlobalObserver::tick () { diff --git a/libs/surfaces/osc/osc_global_observer.h b/libs/surfaces/osc/osc_global_observer.h index 4238d1cca0..19d35f08ae 100644 --- a/libs/surfaces/osc/osc_global_observer.h +++ b/libs/surfaces/osc/osc_global_observer.h @@ -87,7 +87,7 @@ class OSCGlobalObserver } }; - + void update_mixer_scene_state(); void send_change_message (std::string path, boost::shared_ptr controllable); void send_gain_message (std::string path, boost::shared_ptr controllable); void send_trim_message (std::string path, boost::shared_ptr controllable); diff --git a/libs/surfaces/osc/osc_gui.cc b/libs/surfaces/osc/osc_gui.cc index 74b1122343..a5e184d299 100644 --- a/libs/surfaces/osc/osc_gui.cc +++ b/libs/surfaces/osc/osc_gui.cc @@ -401,6 +401,12 @@ OSC_GUI::OSC_GUI (OSC& p) fbtable->attach (trigger_status, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); ++fn; + label = manage (new Gtk::Label(_("Report Mixer Scene status:"))); + label->set_alignment(1, .5); + fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); + fbtable->attach (scene_status, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); + ++fn; + fbtable->show_all (); append_page (*fbtable, _("Default Feedback")); // set strips and feedback from loaded default values @@ -433,6 +439,7 @@ OSC_GUI::OSC_GUI (OSC& p) select_fb.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); use_osc10.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); trigger_status.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); + scene_status.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets)); preset_busy = false; } @@ -688,6 +695,7 @@ OSC_GUI::reshow_values () select_fb.set_active(def_feedback & 8192); use_osc10.set_active(def_feedback & 16384); trigger_status.set_active(def_feedback & 32768); + scene_status.set_active(def_feedback & 65536); calculate_strip_types (); calculate_feedback (); @@ -745,6 +753,9 @@ OSC_GUI::calculate_feedback () if (trigger_status.get_active()) { fbvalue += 32768; } + if (scene_status.get_active()) { + fbvalue += 65536; + } current_feedback.set_text(string_compose("%1", fbvalue)); } diff --git a/libs/surfaces/osc/osc_gui.h b/libs/surfaces/osc/osc_gui.h index 60dfdcc3ce..a78935953b 100644 --- a/libs/surfaces/osc/osc_gui.h +++ b/libs/surfaces/osc/osc_gui.h @@ -114,6 +114,7 @@ private: Gtk::CheckButton select_fb; Gtk::CheckButton use_osc10; Gtk::CheckButton trigger_status; + Gtk::CheckButton scene_status; int fbvalue; void set_bitsets ();