From 389d2cab368c96726e06067c12e0733570e4889a Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 30 Jun 2017 19:55:03 +0200 Subject: FP8: Scribble-strip display preferences --- libs/surfaces/faderport8/faderport8.cc | 31 +++++++-- libs/surfaces/faderport8/faderport8.h | 18 +++++ libs/surfaces/faderport8/fp8_base.h | 5 ++ libs/surfaces/faderport8/fp8_strip.cc | 124 +++++++++++++++++++++++++-------- libs/surfaces/faderport8/fp8_strip.h | 7 +- libs/surfaces/faderport8/gui.cc | 120 +++++++++++++++++++++++++++++++ libs/surfaces/faderport8/gui.h | 12 ++++ 7 files changed, 279 insertions(+), 38 deletions(-) (limited to 'libs/surfaces/faderport8') diff --git a/libs/surfaces/faderport8/faderport8.cc b/libs/surfaces/faderport8/faderport8.cc index 42c6c99b36..923f635324 100644 --- a/libs/surfaces/faderport8/faderport8.cc +++ b/libs/surfaces/faderport8/faderport8.cc @@ -44,6 +44,7 @@ #include "ardour/route.h" #include "ardour/session.h" #include "ardour/session_configuration.h" +#include "ardour/tempo.h" #include "ardour/vca.h" #include "faderport8.h" @@ -99,6 +100,9 @@ FaderPort8::FaderPort8 (Session& s) , _shift_lock (false) , _shift_pressed (0) , gui (0) + , _clock_mode (1) + , _scribble_mode (2) + , _two_line_text (false) { boost::shared_ptr inp; boost::shared_ptr outp; @@ -217,15 +221,24 @@ FaderPort8::thread_init () bool FaderPort8::periodic () { - /* prepare TC display -- handled by stripable Periodic () */ - if (_ctrls.display_timecode ()) { - // TODO allow BBT, HHMMSS - // used in FP8Strip::periodic_update_timecode + /* prepare TC display -- handled by stripable Periodic () + * in FP8Strip::periodic_update_timecode + */ + if (_ctrls.display_timecode () && clock_mode ()) { Timecode::Time TC; session->timecode_time (TC); _timecode = Timecode::timecode_format_time(TC); + + char buf[16]; + Timecode::BBT_Time BBT = session->tempo_map ().bbt_at_frame (session->transport_frame ()); + snprintf (buf, sizeof (buf), + " %02" PRIu32 "|%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32, + BBT.bars % 100, BBT.beats %100, + (BBT.ticks/ 100) %100, BBT.ticks %100); + _musical_time = std::string (buf); } else { _timecode.clear (); + _musical_time.clear (); } /* update stripables */ @@ -688,6 +701,9 @@ FaderPort8::get_state () child->add_child_nocopy (boost::shared_ptr(_output_port)->get_state()); node.add_child_nocopy (*child); + node.set_property (X_("clock-mode"), _clock_mode); + node.set_property (X_("scribble-mode"), _scribble_mode); + for (UserActionMap::const_iterator i = _user_action_map.begin (); i != _user_action_map.end (); ++i) { if (i->second.empty()) { continue; @@ -738,6 +754,9 @@ FaderPort8::set_state (const XMLNode& node, int version) } } + node.get_property (X_("clock-mode"), _clock_mode); + node.get_property (X_("scribble-mode"), _scribble_mode); + _user_action_map.clear (); // TODO: When re-loading state w/o surface re-init becomes possible, // unset lights and reset colors of user buttons. @@ -903,7 +922,7 @@ FaderPort8::filter_stripables (StripableList& strips) const strips.sort (Stripable::Sorter()); } -/* Track/Pan mode: assign stripable to strips */ +/* Track/Pan mode: assign stripable to strips, Send-mode: selection */ void FaderPort8::assign_stripables (bool select_only) { @@ -936,6 +955,7 @@ FaderPort8::assign_stripables (bool select_only) boost::bind (&FaderPort8::notify_stripable_property_changed, this, boost::weak_ptr (*s), _1), this); if (select_only) { + /* used in send mode */ _ctrls.strip(id).set_text_line (3, (*s)->name (), true); _ctrls.strip(id).select_button ().set_color ((*s)->presentation_info ().color()); /* update selection lights */ @@ -954,6 +974,7 @@ FaderPort8::assign_stripables (bool select_only) } for (; id < 8; ++id) { _ctrls.strip(id).unset_controllables (select_only ? (FP8Strip::CTRL_SELECT | FP8Strip::CTRL_TEXT3) : FP8Strip::CTRL_ALL); + _ctrls.strip(id).set_periodic_display_mode (FP8Strip::Stripables); } } diff --git a/libs/surfaces/faderport8/faderport8.h b/libs/surfaces/faderport8/faderport8.h index 20ed84e0f5..70dcfb8790 100644 --- a/libs/surfaces/faderport8/faderport8.h +++ b/libs/surfaces/faderport8/faderport8.h @@ -88,6 +88,14 @@ public: std::string get_button_action (FP8Controls::ButtonId, bool); FP8Controls const& control () const { return _ctrls; } + void set_clock_mode (uint32_t m) { _clock_mode = m; } + void set_scribble_mode (uint32_t m) { _scribble_mode = m; } + void set_two_line_text (bool yn) { _two_line_text = yn; } + + uint32_t clock_mode () const { return _clock_mode; } + uint32_t scribble_mode () const { return _scribble_mode; } + bool twolinetext () const { return _two_line_text; } + int stop (); void do_request (FaderPort8Request*); void thread_init (); @@ -210,7 +218,12 @@ private: sigc::connection _periodic_connection; bool periodic (); std::string _timecode; + std::string _musical_time; std::string const& timecode () const { return _timecode; } + std::string const& musical_time () const { return _musical_time; } + + bool show_meters () const { return _scribble_mode & 1; } + bool show_panner () const { return _scribble_mode & 2; } /* sync button blink -- the FP's blink mode does not work */ sigc::connection _blink_connection; @@ -277,6 +290,11 @@ private: std::vector > _solo_state; #endif + /* user prefs */ + uint32_t _clock_mode; + uint32_t _scribble_mode; + bool _two_line_text; + /* user bound actions */ void button_user (bool, FP8Controls::ButtonId); diff --git a/libs/surfaces/faderport8/fp8_base.h b/libs/surfaces/faderport8/fp8_base.h index 56f2b0c4f0..efd634f71c 100644 --- a/libs/surfaces/faderport8/fp8_base.h +++ b/libs/surfaces/faderport8/fp8_base.h @@ -48,7 +48,12 @@ public: virtual size_t tx_midi (std::vector const&) const = 0; virtual std::string const& timecode () const = 0; + virtual std::string const& musical_time () const = 0; virtual bool shift_mod () const = 0; + virtual bool show_meters () const = 0; + virtual bool show_panner () const = 0; + virtual bool twolinetext () const = 0; + virtual uint32_t clock_mode () const = 0; size_t tx_midi2 (uint8_t sb, uint8_t d1) const { diff --git a/libs/surfaces/faderport8/fp8_strip.cc b/libs/surfaces/faderport8/fp8_strip.cc index 54180d32b8..3a5b97a1e2 100644 --- a/libs/surfaces/faderport8/fp8_strip.cc +++ b/libs/surfaces/faderport8/fp8_strip.cc @@ -178,6 +178,7 @@ FP8Strip::unset_controllables (int which) { _peak_meter = boost::shared_ptr(); _redux_ctrl = boost::shared_ptr(); + _stripable_name.clear (); if (which & CTRL_FADER) { set_fader_controllable (boost::shared_ptr()); @@ -201,25 +202,44 @@ FP8Strip::unset_controllables (int which) select_button ().set_blinking (false); } if (which & CTRL_TEXT0) { - set_text_line (0x00, ""); + set_text_line (0, ""); } if (which & CTRL_TEXT1) { - set_text_line (0x01, ""); + set_text_line (1, ""); } if (which & CTRL_TEXT2) { - set_text_line (0x02, ""); + set_text_line (2, ""); } if (which & CTRL_TEXT3) { - set_text_line (0x03, ""); + set_text_line (3, ""); } set_bar_mode (4); // Off } +void +FP8Strip::set_strip_name () +{ + size_t lb = _base.show_meters () ? 6 : 9; + set_text_line (0, _stripable_name.substr (0, lb)); + set_text_line (1, _stripable_name.length() > lb ? _stripable_name.substr (lb) : ""); +} + void FP8Strip::set_stripable (boost::shared_ptr s, bool panmode) { assert (s); + if (_base.show_meters () && _base.show_panner ()) { + set_strip_mode (5, true); + } else if (_base.show_meters ()) { + set_strip_mode (4, true); + } else { + set_strip_mode (0, true); + } + if (!_base.show_panner ()) { + set_bar_mode (4, true); // Off + } + if (panmode) { set_fader_controllable (s->pan_azimuth_control ()); } else { @@ -251,11 +271,16 @@ FP8Strip::set_stripable (boost::shared_ptr s, bool panmode) select_button ().set_color (s->presentation_info ().color()); //select_button ().set_blinking (false); - set_strip_mode (0x05); - set_text_line (0x00, s->name ()); - set_text_line (0x01, _pan_ctrl ? _pan_ctrl->get_user_string () : ""); - set_text_line (0x02, ""); - set_text_line (0x03, ""); + _stripable_name = s->name (); + + if (_base.twolinetext ()) { + set_text_line (0, s->name ()); + set_text_line (1, _pan_ctrl ? _pan_ctrl->get_user_string () : ""); + } else { + set_strip_name (); + } + set_text_line (2, ""); + set_text_line (3, ""); } /* ***************************************************************************** @@ -467,10 +492,11 @@ FP8Strip::set_periodic_display_mode (DisplayMode m) { void FP8Strip::periodic_update_meter () { + bool show_meters = _base.show_meters (); bool have_meter = false; bool have_panner = false; - if (_peak_meter) { + if (_peak_meter && show_meters) { have_meter = true; float dB = _peak_meter->meter_level (0, MeterMCP); // TODO: deflect meter @@ -480,7 +506,7 @@ FP8Strip::periodic_update_meter () _last_meter = val; } - } else { + } else if (show_meters) { if (0 != _last_meter) { _base.tx_midi2 (0xd0 + _id, 0); _last_meter = 0; @@ -488,7 +514,7 @@ FP8Strip::periodic_update_meter () } // show redux only if there's a meter, too (strip display mode 5) - if (_peak_meter && _redux_ctrl) { + if (_peak_meter && _redux_ctrl && show_meters) { float rx = (1.f - _redux_ctrl->get_parameter ()) * 127.f; // TODO: deflect redux int val = std::min (127.f, std::max (0.f, rx)); @@ -496,7 +522,7 @@ FP8Strip::periodic_update_meter () _base.tx_midi2 (0xd8 + _id, val & 0x7f); _last_redux = val; } - } else { + } else if (show_meters) { if (0 != _last_redux) { _base.tx_midi2 (0xd8 + _id, 0); _last_redux = 0; @@ -515,28 +541,37 @@ FP8Strip::periodic_update_meter () } } else { set_bar_mode (4); // Off - set_text_line (0x02, ""); + set_text_line (2, ""); } } else if (_displaymode == SendDisplay) { set_bar_mode (4); // Off if (_fader_ctrl) { - set_text_line (0x01, value_as_string(_fader_ctrl->desc(), _fader_ctrl->get_value())); + set_text_line (1, value_as_string(_fader_ctrl->desc(), _fader_ctrl->get_value())); } else { - set_text_line (0x01, ""); + set_text_line (1, ""); } } else if (_pan_ctrl) { - have_panner = true; + have_panner = _base.show_panner (); float panpos = _pan_ctrl->internal_to_interface (_pan_ctrl->get_value()); int val = std::min (127.f, std::max (0.f, panpos * 128.f)); - set_bar_mode (1); // Bipolar - if (val != _last_barpos) { + set_bar_mode (have_panner ? 1 : 4); // Bipolar or Off + if (val != _last_barpos && have_panner) { _base.tx_midi3 (0xb0, 0x30 + _id, val & 0x7f); _last_barpos = val; } - set_text_line (0x01, _pan_ctrl->get_user_string ()); + if (_base.twolinetext ()) { + set_text_line (1, _pan_ctrl->get_user_string ()); + } else { + set_strip_name (); + } } else { set_bar_mode (4); // Off + if (_base.twolinetext ()) { + set_text_line (1, ""); + } else { + set_strip_name (); + } } if (_displaymode == SendDisplay || _displaymode == PluginParam) { @@ -549,9 +584,9 @@ FP8Strip::periodic_update_meter () set_strip_mode (4); // big meters + 3 lines of text (3rd line is large) } else if (have_panner) { - set_strip_mode (0); // 3 lines of text (3rd line is large) + value-bar + set_strip_mode (0); // 3 lines of text (3rd line is large + long) + value-bar } else { - set_strip_mode (0); // 3 lines of text (3rd line is large) + value-bar + set_strip_mode (0); // 3 lines of text (3rd line is large + long) + value-bar } } @@ -561,16 +596,32 @@ FP8Strip::set_strip_mode (uint8_t strip_mode, bool clear) if (strip_mode == _strip_mode && !clear) { return; } + _strip_mode = strip_mode; _base.tx_sysex (3, 0x13, _id, (_strip_mode & 0x07) | (clear ? 0x10 : 0)); + + if (clear) { + /* work-around, when swiching modes, the FP8 may not + * properly redraw long lines. Only update lines 0, 1 + * (line 2 is timecode, line 3 may be inverted) + */ + _base.tx_text (_id, 0, 0x00, _last_line[0]); + _base.tx_text (_id, 1, 0x00, _last_line[1]); + } } void -FP8Strip::set_bar_mode (uint8_t bar_mode) +FP8Strip::set_bar_mode (uint8_t bar_mode, bool force) { - if (bar_mode == _bar_mode) { + if (bar_mode == _bar_mode && !force) { return; } + + if (bar_mode == 4) { + _base.tx_midi3 (0xb0, 0x30 + _id, 0); + _last_barpos = 0xff; + } + _bar_mode = bar_mode; _base.tx_midi3 (0xb0, 0x38 + _id, bar_mode); } @@ -587,16 +638,29 @@ FP8Strip::set_text_line (uint8_t line, std::string const& txt, bool inv) } void -FP8Strip::periodic_update_timecode () +FP8Strip::periodic_update_timecode (uint32_t m) { - if (_id >= 2 && _id < 6) { - std::string const& tc = _base.timecode(); - //" HH:MM:SS:FF" + if (m == 0) { + return; + } + if (m == 3) { + bool mc = _id >= 4; + std::string const& tc = mc ? _base.musical_time () : _base.timecode(); + std::string t; + if (tc.size () == 12) { + t = tc.substr (1 + (_id - (mc ? 4 : 0)) * 3, 2); + } + set_text_line (2, t); + } else if (_id >= 2 && _id < 6) { + std::string const& tc = (m == 2) ? _base.musical_time () : _base.timecode(); + //" HH:MM:SS:FF" or " BR|BT|TI|CK" std::string t; if (tc.size () == 12) { t = tc.substr (1 + (_id - 2) * 3, 2); } - set_text_line (0x02, t); + set_text_line (2, t); + } else { + set_text_line (2, ""); } } @@ -606,6 +670,6 @@ FP8Strip::periodic () periodic_update_fader (); periodic_update_meter (); if (_displaymode != PluginSelect && _displaymode != PluginParam) { - periodic_update_timecode (); + periodic_update_timecode (_base.clock_mode ()); } } diff --git a/libs/surfaces/faderport8/fp8_strip.h b/libs/surfaces/faderport8/fp8_strip.h index f22ff190fa..200dae86cb 100644 --- a/libs/surfaces/faderport8/fp8_strip.h +++ b/libs/surfaces/faderport8/fp8_strip.h @@ -107,7 +107,7 @@ private: PBD::ScopedConnection _base_connection; // periodic PBD::ScopedConnectionList _button_connections; - boost::shared_ptr _stripable; + std::string _stripable_name; boost::shared_ptr _fader_ctrl; boost::shared_ptr _mute_ctrl; @@ -148,9 +148,10 @@ private: void set_recarm (); /* periodic poll, update view */ + void set_strip_name (); void periodic_update_fader (); void periodic_update_meter (); - void periodic_update_timecode (); + void periodic_update_timecode (uint32_t); void periodic (); /* cache */ @@ -161,7 +162,7 @@ private: /* display */ void set_strip_mode (uint8_t, bool clear = false); - void set_bar_mode (uint8_t); + void set_bar_mode (uint8_t, bool force = false); uint8_t _strip_mode; uint8_t _bar_mode; diff --git a/libs/surfaces/faderport8/gui.cc b/libs/surfaces/faderport8/gui.cc index 3bd9a9464e..19edafde92 100644 --- a/libs/surfaces/faderport8/gui.cc +++ b/libs/surfaces/faderport8/gui.cc @@ -82,6 +82,7 @@ FP8GUI::FP8GUI (FaderPort8& p) : fp (p) , table (2, 3) , ignore_active_change (false) + , two_line_text (_("Two Line Trackname")) { set_border_width (12); @@ -106,9 +107,16 @@ FP8GUI::FP8GUI (FaderPort8& p) input_combo.pack_start (midi_port_columns.short_name); output_combo.pack_start (midi_port_columns.short_name); + build_prefs_combos (); + update_prefs_combos (); + input_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FP8GUI::active_port_changed), &input_combo, true)); output_combo.signal_changed().connect (sigc::bind (sigc::mem_fun (*this, &FP8GUI::active_port_changed), &output_combo, false)); + clock_combo.signal_changed().connect (sigc::mem_fun (*this, &FP8GUI::clock_mode_changed)); + scribble_combo.signal_changed().connect (sigc::mem_fun (*this, &FP8GUI::scribble_mode_changed)); + two_line_text.signal_toggled().connect(sigc::mem_fun (*this, &FP8GUI::twolinetext_toggled)); + l = manage (new Gtk::Label); l->set_markup (string_compose ("%1", _("Incoming MIDI on:"))); l->set_alignment (1.0, 0.5); @@ -161,6 +169,28 @@ FP8GUI::FP8GUI (FaderPort8& p) table.attach (*vsep, 3 * c + 2, 3 * c + 3, row, row + 4, AttachOptions(0), AttachOptions(FILL), 6, 0); } + row += 4; + + hsep = manage(new Gtk::HSeparator); + table.attach (*hsep, 0, 8, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 6); + row++; + + l = manage (new Gtk::Label); + l->set_markup (string_compose ("%1", _("Clock:"))); + l->set_alignment (1.0, 0.5); + table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); + table.attach (clock_combo, 1, 5, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); + + table.attach (two_line_text, 5, 8, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); + row++; + + l = manage (new Gtk::Label); + l->set_markup (string_compose ("%1", _("Display:"))); + l->set_alignment (1.0, 0.5); + table.attach (*l, 0, 1, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0)); + table.attach (scribble_combo, 1, 5, row, row+1, AttachOptions(FILL|EXPAND), AttachOptions(0), 0, 0); + row++; + /* update the port connection combos */ update_port_combos (); @@ -443,3 +473,93 @@ FP8GUI::action_changed (Gtk::ComboBox* cb, FP8Controls::ButtonId id) string action_path = (*row)[action_columns.path]; fp.set_button_action (id, false, action_path); } + + +void +FP8GUI::build_prefs_combos () +{ + vector clock_strings; + vector scribble_strings; + + //clock_strings.push_back (_("Off")); + clock_strings.push_back (_("Timecode")); + clock_strings.push_back (_("BBT")); + clock_strings.push_back (_("Timecode + BBT")); + + scribble_strings.push_back (_("Off")); + scribble_strings.push_back (_("Meter")); + scribble_strings.push_back (_("Pan")); + scribble_strings.push_back (_("Meter + Pan")); + + set_popdown_strings (clock_combo, clock_strings); + set_popdown_strings (scribble_combo, scribble_strings); +} + +void +FP8GUI::update_prefs_combos () +{ + switch (fp.clock_mode()) { + default: + clock_combo.set_active_text (_("Off")); + break; + case 1: + clock_combo.set_active_text (_("Timecode")); + break; + case 2: + clock_combo.set_active_text (_("BBT")); + break; + case 3: + clock_combo.set_active_text (_("Timecode + BBT")); + break; + } + + switch (fp.scribble_mode()) { + default: + scribble_combo.set_active_text (_("Off")); + break; + case 1: + scribble_combo.set_active_text (_("Meter")); + break; + case 2: + scribble_combo.set_active_text (_("Pan")); + break; + case 3: + scribble_combo.set_active_text (_("Meter + Pan")); + break; + } + two_line_text.set_active (fp.twolinetext ()); +} + +void +FP8GUI::clock_mode_changed () +{ + string str = clock_combo.get_active_text(); + if (str == _("BBT")) { + fp.set_clock_mode (2); + } else if (str == _("Timecode + BBT")) { + fp.set_clock_mode (3); + } else { + fp.set_clock_mode (1); + } +} + +void +FP8GUI::scribble_mode_changed () +{ + string str = scribble_combo.get_active_text(); + if (str == _("Off")) { + fp.set_scribble_mode (0); + } else if (str == _("Meter")) { + fp.set_scribble_mode (1); + } else if (str == _("Pan")) { + fp.set_scribble_mode (2); + } else { + fp.set_scribble_mode (3); + } +} + +void +FP8GUI::twolinetext_toggled () +{ + fp.set_two_line_text (two_line_text.get_active ()); +} diff --git a/libs/surfaces/faderport8/gui.h b/libs/surfaces/faderport8/gui.h index c7bc91080f..2ee51645f2 100644 --- a/libs/surfaces/faderport8/gui.h +++ b/libs/surfaces/faderport8/gui.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -73,6 +74,17 @@ private: Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input); void active_port_changed (Gtk::ComboBox*,bool for_input); + /* misc Prefs */ + Gtk::ComboBoxText clock_combo; + Gtk::ComboBoxText scribble_combo; + Gtk::CheckButton two_line_text; + + void build_prefs_combos (); + void update_prefs_combos (); + void clock_mode_changed (); + void scribble_mode_changed (); + void twolinetext_toggled (); + /* user actions */ void build_available_action_menu (); void build_action_combo (Gtk::ComboBox& cb, FP8Controls::ButtonId id); -- cgit v1.2.3