OSC: implement controls and feedback for a banked trigger grid controller

(first iteration ... API may change)
This commit is contained in:
Ben Loftis 2022-11-01 13:52:23 -05:00
parent bdf9cedb0e
commit c6dade9484
5 changed files with 97 additions and 9 deletions

View File

@ -117,6 +117,7 @@ OSC::OSC (Session& s, uint32_t port)
, default_send_size (0)
, default_plugin_size (0)
, tick (true)
, global_init (true)
, bank_dirty (false)
, observer_busy (true)
, scrub_speed (0)
@ -466,6 +467,9 @@ OSC::register_callbacks()
REGISTER_CALLBACK (serv, X_("/trigger_bang"), "ii", trigger_bang); //Route num (position on the Cue page), Trigger index
REGISTER_CALLBACK (serv, X_("/trigger_unbang"), "ii", trigger_unbang); //Route num (position on the Cue page), Trigger index
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_("/save_state"), "", save_state);
REGISTER_CALLBACK (serv, X_("/save_state"), "f", save_state);
REGISTER_CALLBACK (serv, X_("/prev_marker"), "", prev_marker);
@ -1176,6 +1180,8 @@ OSC::get_surfaces ()
PBD::info << string_compose (" Expanded flag %1 Track: %2 Jogmode: %3\n", sur->expand_enable, sur->expand, sur->jogmode);
PBD::info << string_compose (" Personal monitor flag %1, Aux master: %2, Number of sends: %3\n", sur->cue, sur->aux, sur->sends.size());
PBD::info << string_compose (" Linkset: %1 Device Id: %2\n", sur->linkset, sur->linkid);
PBD::info << string_compose (" Global Observer: %1\n", sur->global_obs != NULL ? "yes" : "NO");
}
PBD::info << string_compose ("\nList of LinkSets (%1):\n", link_sets.size());
std::map<uint32_t, LinkSet>::iterator it;
@ -1305,6 +1311,22 @@ OSC::osc_toggle_roll (bool ret2strt)
return 0;
}
int
OSC::osc_tbank_step_routes (int step, lo_message msg)
{
tbank_step_routes(step);
trigger_bank_state(get_address(msg));
return 0;
}
int
OSC::osc_tbank_step_rows (int step, lo_message msg)
{
tbank_step_rows(step);
trigger_bank_state(get_address(msg));
return 0;
}
lo_address
OSC::get_address (lo_message msg)
{
@ -1927,6 +1949,7 @@ OSC::set_surface_feedback (uint32_t fb, lo_message msg)
strip_feedback (s, true);
global_feedback (s);
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), get_address (msg));
return 0;
}
@ -2085,12 +2108,10 @@ OSC::global_feedback (OSCSurface* sur)
delete o;
sur->global_obs = 0;
}
if (sur->feedback[4] || sur->feedback[3] || sur->feedback[5] || sur->feedback[6]) {
if (sur->feedback[4] || sur->feedback[3] || sur->feedback[5] || sur->feedback[6] || sur->feedback[15]) {
// create a new Global Observer for this surface
OSCGlobalObserver* o = new OSCGlobalObserver (*this, *session, sur);
sur->global_obs = o;
o->jog_mode (sur->jogmode);
sur->global_obs = new OSCGlobalObserver (*this, *session, sur);
sur->global_obs->jog_mode (sur->jogmode);
}
}
@ -3104,6 +3125,39 @@ OSC::jog_mode (float mode, lo_message msg)
return 0;
}
int
OSC::trigger_bank_state (lo_address addr)
{
if (!session) return -1;
lo_message bank_msg = lo_message_new ();
lo_message_add_int32 (bank_msg, session->num_triggerboxes()); //total avail routes (with triggers)
lo_message_add_int32 (bank_msg, _tbank_start_route); //route start offs
lo_message_add_int32 (bank_msg, TriggerBox::default_triggers_per_box); //total avail triggers
lo_message_add_int32 (bank_msg, _tbank_start_row); //trigger start offs
lo_send_message (addr, X_("/trigger_grid/bank"), bank_msg);
lo_message_free (bank_msg);
return 0;
}
int
OSC::trigger_grid_state (lo_address addr, bool zero_it)
{
if (!session) return -1;
for (int rt = 0; rt < 8; rt++) { //TODO: route bank size
lo_message trig_msg = lo_message_new ();
lo_message_add_float (trig_msg, zero_it ? -1 : trigger_progress_at(rt)); //progress
for (int row = 0; row < 8; row++) { //ToDo: trigger bank size
lo_message_add_int32 (trig_msg, zero_it ? -1 : trigger_display_at(rt, row).state); // -1 = empty; 0 stopped; 1 playing
}
lo_send_message (addr, string_compose(X_("/trigger_grid/%1/state"), rt).c_str(), trig_msg);
lo_message_free (trig_msg);
}
return 0;
}
// two structs to help with going to markers
struct LocationMarker {
LocationMarker (const std::string& l, samplepos_t w)
@ -5962,9 +6016,8 @@ OSC::periodic (void)
if ((co = dynamic_cast<OSCCueObserver*>(sur->cue_obs)) != 0) {
co->tick ();
}
OSCGlobalObserver* go;
if ((go = dynamic_cast<OSCGlobalObserver*>(sur->global_obs)) != 0) {
go->tick ();
if (sur->global_obs) {
sur->global_obs->tick ();
}
for (uint32_t i = 0; i < sur->observers.size(); i++) {
OSCRouteObserver* ro;
@ -5972,7 +6025,6 @@ OSC::periodic (void)
ro->tick ();
}
}
}
for (FakeTouchMap::iterator x = _touch_timeout.begin(); x != _touch_timeout.end();) {
_touch_timeout[(*x).first] = (*x).second - 1;

View File

@ -189,6 +189,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
* [12] - Send Playhead position like primary/secondary GUI clocks
* [13] - Send well known feedback (for /select/command
* [14] - use OSC 1.0 only (#reply -> /reply)
* [15] - report 8x8 trigger grid status
*
* Strip_type bits:
* [0] - Audio Tracks
@ -264,6 +265,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
CONTROL_PROTOCOL_THREADS_NEED_TEMPO_MAP_DECL();
int trigger_bank_state (lo_address addr);
int trigger_grid_state (lo_address addr, bool zero_it = false);
protected:
void thread_init ();
void do_request (OSCUIRequest*);
@ -521,6 +525,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
return 0; \
}
PATH_CALLBACK1_MSG(osc_tbank_step_routes,i);
PATH_CALLBACK1_MSG(osc_tbank_step_rows,i);
PATH_CALLBACK1_MSG(scrub,f);
PATH_CALLBACK1_MSG(jog,f);
PATH_CALLBACK1_MSG(jog_mode,f);
@ -632,6 +639,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
PATH_CALLBACK1_MSG(route_plugin_list,i);
PATH_CALLBACK2_MSG(route_plugin_descriptor,i,i);
PATH_CALLBACK2_MSG(route_plugin_reset,i,i);
PATH_CALLBACK2(tbank_set_size,i,i);
PATH_CALLBACK2_MSG(trigger_bang,i,i);
PATH_CALLBACK2_MSG(trigger_unbang,i,i);
PATH_CALLBACK2_MSG(trigger_stop,i,i); /* second arg is 'stop now' */
@ -740,6 +750,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
void notify_routes_added (ARDOUR::RouteList &);
void notify_vca_added (ARDOUR::VCAList &);
int osc_tbank_step_routes (int step, lo_message msg);
int osc_tbank_step_rows (int step, lo_message msg);
int cancel_all_solos ();
int osc_toggle_roll (bool ret2strt);
bool periodic (void);

View File

@ -173,6 +173,9 @@ OSCGlobalObserver::clear_observer ()
if (feedback[11]) { // minutes/seconds enabled
_osc.text_message (X_("/position/time"), " ", addr);
}
if (feedback[15]) { // trigger grid status
_osc.trigger_grid_state(addr, true); //zero it out
}
if (feedback[10]) { // samples
_osc.text_message (X_("/position/samples"), " ", addr);
}
@ -226,6 +229,14 @@ OSCGlobalObserver::tick ()
return;
}
samplepos_t now_sample = session->transport_sample();
if (feedback[15]) { // trigger grid status
if (_heartbeat == 0) {
_osc.trigger_grid_state(addr);
_osc.trigger_bank_state(addr);
} else if (now_sample != _last_sample) {
_osc.trigger_grid_state(addr);
}
}
if (now_sample != _last_sample) {
if (feedback[6]) { // timecode enabled
Timecode::Time timecode;

View File

@ -395,6 +395,12 @@ OSC_GUI::OSC_GUI (OSC& p)
fbtable->attach (use_osc10, 1, 2, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0);
++fn;
label = manage (new Gtk::Label(_("Report 8x8 Trigger Grid status:")));
label->set_alignment(1, .5);
fbtable->attach (*label, 0, 1, fn, fn+1, AttachOptions(FILL|EXPAND), AttachOptions(0));
fbtable->attach (trigger_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
@ -426,6 +432,7 @@ OSC_GUI::OSC_GUI (OSC& p)
hp_gui.signal_clicked().connect (sigc::mem_fun (*this, &OSC_GUI::set_bitsets));
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));
preset_busy = false;
}
@ -680,6 +687,7 @@ OSC_GUI::reshow_values ()
//hp_gui.set_active (false); // we don't have this yet (Mixbus wants)
select_fb.set_active(def_feedback & 8192);
use_osc10.set_active(def_feedback & 16384);
trigger_status.set_active(def_feedback & 32768);
calculate_strip_types ();
calculate_feedback ();
@ -734,6 +742,9 @@ OSC_GUI::calculate_feedback ()
if (use_osc10.get_active()) {
fbvalue += 16384;
}
if (trigger_status.get_active()) {
fbvalue += 32768;
}
current_feedback.set_text(string_compose("%1", fbvalue));
}

View File

@ -113,6 +113,7 @@ private:
Gtk::CheckButton hp_gui;
Gtk::CheckButton select_fb;
Gtk::CheckButton use_osc10;
Gtk::CheckButton trigger_status;
int fbvalue;
void set_bitsets ();