13
0

US2400: Mark controls dirty and send them from the periodic update thread.

This commit is contained in:
Ben Loftis 2017-10-19 11:53:08 -05:00
parent ee09ae1c6b
commit 2a310e5f79
12 changed files with 74 additions and 55 deletions

View File

@ -104,6 +104,8 @@ public:
Surface& surface() const { return _surface; }
void mark_dirty() { _led.mark_dirty(); }
void pressed ();
void released ();

View File

@ -71,6 +71,8 @@ public:
virtual void set_control (boost::shared_ptr<ARDOUR::AutomationControl>);
virtual void reset_control () { normal_ac.reset(); }
virtual void mark_dirty() = 0;
float get_value ();
void set_value (float val, PBD::Controllable::GroupControlDisposition gcd = PBD::Controllable::UseGroup);

View File

@ -26,6 +26,8 @@ class Fader : public Control
static Control* factory (Surface&, int id, const char*, Group&);
void mark_dirty() { last_update_position = llast_update_position = -1; }
private:
float position;
int last_update_position;

View File

@ -52,12 +52,9 @@ Led::set_state (LedState new_state)
llast_state = last_state;
last_state = new_state;
state = new_state;
MIDI::byte msg = 0;
switch (state.state()) {
switch (new_state.state()) {
case LedState::on:
msg = 0x7f;
break;

View File

@ -41,12 +41,13 @@ public:
Led (int id, std::string name, Group & group)
: Control (id, name, group)
, state (off)
, last_state (off)
, llast_state (on)
, last_state (none)
, llast_state (none)
{
}
void mark_dirty() { last_state = llast_state = none; }
Led & led() { return *this; }
MidiByteArray set_state (LedState);
@ -55,7 +56,6 @@ public:
static Control* factory (Surface&, int id, const char*, Group&);
private:
LedState state;
LedState last_state;
LedState llast_state;
};

View File

@ -46,6 +46,8 @@ public:
void send_update (Surface&, float dB);
bool enabled () const { return _enabled; }
void mark_dirty() {}
MidiByteArray zero();
static Control* factory (Surface&, int id, const char*, Group&);

View File

@ -51,6 +51,8 @@ public:
static Control* factory (Surface&, int id, const char*, Group&);
void mark_dirty() { last_update_position = llast_update_position = -1; }
int last_update_position;
int llast_update_position;

View File

@ -171,18 +171,9 @@ Strip::set_stripable (boost::shared_ptr<Stripable> r, bool /*with_messages*/)
_fader->set_control (boost::shared_ptr<AutomationControl>());
_vpot->set_control (boost::shared_ptr<AutomationControl>());
_surface->write (_solo->set_state(on));
_surface->write (_solo->set_state(off));
_surface->write (_mute->set_state(on));
_surface->write (_mute->set_state(off));
_surface->write (_select->set_state(on));
_surface->write (_select->set_state(off));
_stripable = r;
reset_saved_values ();
mark_dirty ();
if (!r) {
DEBUG_TRACE (DEBUG::US2400, string_compose ("Surface %1 Strip %2 mapped to null route\n", _surface->number(), _index));
@ -263,7 +254,7 @@ Strip::reset_stripable ()
_stripable.reset();
reset_saved_values ();
mark_dirty ();
notify_all ();
}
@ -300,6 +291,7 @@ Strip::notify_solo_changed ()
// _surface->write (_solo->set_state (_stripable->solo_control()->soloed() ? on : off));
// }
_solo->mark_dirty ();
_trickle_counter = 0;
}
@ -316,6 +308,7 @@ Strip::notify_mute_changed ()
// _surface->write (_mute->zero());
// }
_mute->mark_dirty ();
_trickle_counter = 0;
}
@ -334,6 +327,7 @@ Strip::notify_stripable_deleted ()
void
Strip::notify_gain_changed (bool force_update)
{
_fader->mark_dirty();
_trickle_counter = 0;
}
@ -350,6 +344,7 @@ Strip::notify_property_changed (const PropertyChange& what_changed)
void
Strip::update_selection_state ()
{
_select->mark_dirty ();
_trickle_counter = 0;
// if(_stripable) {
@ -365,12 +360,14 @@ Strip::show_stripable_name ()
void
Strip::notify_vpot_change ()
{
_vpot->mark_dirty();
_trickle_counter = 0;
}
void
Strip::notify_panner_azi_changed (bool force_update)
{
_vpot->mark_dirty();
_trickle_counter = 0;
}
@ -402,6 +399,8 @@ Strip::select_event (Button&, ButtonState bs)
DEBUG_TRACE (DEBUG::US2400, "remove select button on release\n");
_surface->mcp().remove_down_select_button (_surface->number(), _index);
}
_trickle_counter = 0;
}
void
@ -602,7 +601,7 @@ Strip::periodic (ARDOUR::microseconds_t now)
update_meter ();
if ( _trickle_counter %5 == 0 ) {
if ( _trickle_counter %24 == 0 ) {
if ( _fader->control() ) {
_surface->write (_fader->set_position (_fader->control()->internal_to_interface (_fader->control()->get_value ())));
@ -627,7 +626,13 @@ Strip::periodic (ARDOUR::microseconds_t now)
}
}
//after a hard write, queue us for trickling data later
if (_trickle_counter == 0)
_trickle_counter = global_index()+1;
_trickle_counter++;
}
void
@ -932,7 +937,7 @@ Strip::set_vpot_parameter (AutomationType p)
DEBUG_TRACE (DEBUG::US2400, string_compose ("switch to vpot mode %1\n", p));
reset_saved_values ();
mark_dirty ();
switch (p) {
case PanAzimuthAutomation:
@ -967,8 +972,13 @@ Strip::is_midi_track () const
}
void
Strip::reset_saved_values ()
Strip::mark_dirty ()
{
_fader->mark_dirty();
_vpot->mark_dirty();
_solo->mark_dirty();
_mute->mark_dirty();
_trickle_counter=0;
}
void

View File

@ -85,7 +85,8 @@ public:
void update_selection_state ();
int global_index() { return _surface->mcp().global_index (*this); }
void set_global_index( int g ) { _global_index = g; }
int global_index() { return _global_index; }
private:
enum VPotDisplayMode {
@ -101,6 +102,7 @@ private:
Fader* _fader;
Meter* _meter;
int _index;
int _global_index;
Surface* _surface;
bool _controls_locked;
bool _transport_is_rolling;
@ -139,7 +141,7 @@ private:
void set_vpot_parameter (ARDOUR::AutomationType);
void show_stripable_name ();
void reset_saved_values ();
void mark_dirty ();
bool is_midi_track () const;

View File

@ -352,6 +352,8 @@ Surface::init_strips (uint32_t n)
Strip* strip = new Strip (*this, name, i, strip_buttons);
strip->set_global_index( _number*n + i );
groups[name] = strip;
strips.push_back (strip);
}
@ -801,8 +803,7 @@ Surface::turn_it_on ()
_active = true;
if ( _stype == st_mcu ) //do this once, when we hear from the master. this sets up current bank, etc
_mcp.device_ready ();
_mcp.device_ready (); //this gets redundantly called with each new surface connection; but this is desirable to get the banks set up correctly
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
(*s)->notify_all ();
@ -896,9 +897,11 @@ Surface::zero_controls ()
void
Surface::periodic (uint64_t now_usecs)
{
master_gain_changed();
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
(*s)->periodic (now_usecs);
if (_active) {
master_gain_changed();
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
(*s)->periodic (now_usecs);
}
}
}

View File

@ -155,7 +155,7 @@ int
SurfacePort::write (const MidiByteArray & mba)
{
if (mba.empty()) {
DEBUG_TRACE (DEBUG::US2400, string_compose ("port %1 asked to write an empty MBA\n", output_port().name()));
// DEBUG_TRACE (DEBUG::US2400, string_compose ("port %1 asked to write an empty MBA\n", output_port().name()));
return 0;
}
@ -170,6 +170,7 @@ SurfacePort::write (const MidiByteArray & mba)
*/
int count = output_port().write (&mba[0], mba.size(), 0);
g_usleep (1000);
if (count != (int) mba.size()) {

View File

@ -412,7 +412,7 @@ US2400Protocol::set_active (bool yn)
/* set up periodic task for timecode display and metering and automation
*/
Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (100); // milliseconds
Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (10); // milliseconds
periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &US2400Protocol::periodic));
periodic_timeout->attach (main_loop()->get_context());
@ -540,26 +540,12 @@ void
US2400Protocol::device_ready ()
{
DEBUG_TRACE (DEBUG::US2400, string_compose ("device ready init (active=%1)\n", active()));
//this gets called every time a new surface appears; we have to do this to reset the banking etc
//particularly when the user is setting it up the first time; we can't guarantee the order that they will be connected
update_surfaces ();
update_global_button (Button::Send, on);
update_global_button (Button::Send, off);
update_global_button (Button::Scrub, on);
update_global_button (Button::Scrub, off);
update_global_button (Button::ClearSolo, on);
update_global_button (Button::ClearSolo, off);
update_global_button (Button::Pan, off);
update_global_button (Button::Pan, on);
update_global_button (Button::Flip, on);
update_global_button (Button::Flip, off);
update_global_button (Button::MstrSelect, on);
update_global_button (Button::MstrSelect, off);
set_subview_mode (US2400Protocol::None, first_selected_stripable());
}
@ -595,7 +581,22 @@ US2400Protocol::initialize()
}
// update global buttons and displays
update_global_button (Button::Send, on);
update_global_button (Button::Send, off);
update_global_button (Button::Scrub, on);
update_global_button (Button::Scrub, off);
notify_solo_active_changed(false);
update_global_button (Button::Pan, off);
update_global_button (Button::Pan, on);
update_global_button (Button::Flip, on);
update_global_button (Button::Flip, off);
update_global_button (Button::MstrSelect, on);
update_global_button (Button::MstrSelect, off);
notify_transport_state_changed();
@ -1853,15 +1854,11 @@ US2400Protocol::stripable_selection_changed ()
(*si)->update_strip_selection ();
}
printf("stripable_selection_changed\n");
//first check for the dedicated Master strip
boost::shared_ptr<Stripable> s = ControlProtocol::first_selected_stripable();
if (s && s->is_master()) {
printf("stripable_selection_changed found master as selected_stripable\n");
update_global_button(Button::MstrSelect, on); //NOTE: surface does not respond to this
} else {
if (s) printf("stripable_selection_changed not master: %s\n", s->name().c_str());
update_global_button(Button::MstrSelect, off);
//not the master; now check for other strips ( this will only allow a selection if the strip is mapped on our surface )
@ -1879,7 +1876,6 @@ if (s) printf("stripable_selection_changed not master: %s\n", s->name().c_str(
*/
if (set_subview_mode (TrackView, s)) {
printf("set_subview_mode failed for master... (?)\n");
set_subview_mode (None, boost::shared_ptr<Stripable>());
}