push2: another bunch of Live-chasing functionality for trigger control
This commit is contained in:
parent
406080f1b8
commit
b98ec59ed8
|
@ -87,6 +87,7 @@ CueLayout::CueLayout (Push2& p, Session & s, std::string const & name)
|
|||
, track_base (0)
|
||||
, scene_base (0)
|
||||
, _knob_function (KnobGain)
|
||||
, _long_stop (0)
|
||||
{
|
||||
Pango::FontDescription fd ("Sans 10");
|
||||
|
||||
|
@ -261,7 +262,7 @@ CueLayout::show_knob_function ()
|
|||
void
|
||||
CueLayout::button_lower (uint32_t n)
|
||||
{
|
||||
if (_p2.stop_down()) {
|
||||
if (_p2.stop_down() || _long_stop) {
|
||||
std::cerr << "stop trigger in " << n + track_base << std::endl;
|
||||
_p2.unbang (n + track_base);
|
||||
} else {
|
||||
|
@ -351,40 +352,17 @@ CueLayout::viewport_changed ()
|
|||
{
|
||||
_route_connections.drop_connections ();
|
||||
|
||||
for (int n = 0; n < 64; ++n) {
|
||||
_trig_connections[n].disconnect ();
|
||||
}
|
||||
|
||||
for (int n = 0; n < 8; ++n) {
|
||||
|
||||
_route[n] = _session.get_remote_nth_route (track_base+n);
|
||||
|
||||
boost::shared_ptr<Route> r = _route[n];
|
||||
|
||||
boost::shared_ptr<Push2::Button> lower_button;
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
lower_button = _p2.button_by_id (Push2::Lower1);
|
||||
break;
|
||||
case 1:
|
||||
lower_button = _p2.button_by_id (Push2::Lower2);
|
||||
break;
|
||||
case 2:
|
||||
lower_button = _p2.button_by_id (Push2::Lower3);
|
||||
break;
|
||||
case 3:
|
||||
lower_button = _p2.button_by_id (Push2::Lower4);
|
||||
break;
|
||||
case 4:
|
||||
lower_button = _p2.button_by_id (Push2::Lower5);
|
||||
break;
|
||||
case 5:
|
||||
lower_button = _p2.button_by_id (Push2::Lower6);
|
||||
break;
|
||||
case 6:
|
||||
lower_button = _p2.button_by_id (Push2::Lower7);
|
||||
break;
|
||||
case 7:
|
||||
lower_button = _p2.button_by_id (Push2::Lower8);
|
||||
break;
|
||||
}
|
||||
boost::shared_ptr<Push2::Button> lower_button = _p2.lower_button_by_column (n);
|
||||
|
||||
if (r) {
|
||||
_route[n]->DropReferences.connect (_route_connections, invalidator (*this), boost::bind (&CueLayout::viewport_changed, this), &_p2);
|
||||
|
@ -447,6 +425,9 @@ CueLayout::viewport_changed ()
|
|||
if (tp && tp->region()) {
|
||||
/* trigger in slot */
|
||||
pad->set_color (color);
|
||||
|
||||
tp->PropertyChanged.connect (_trig_connections[n * 8 + y], invalidator (*this), boost::bind (&CueLayout::trigger_property_change, this, _1, n, y), &_p2);
|
||||
|
||||
} else {
|
||||
/* no trigger */
|
||||
pad->set_color (Push2::LED::Black);
|
||||
|
@ -514,12 +495,95 @@ CueLayout::button_stop_press ()
|
|||
_p2.get_session().stop_all_triggers (false); /* quantized global stop */
|
||||
}
|
||||
}
|
||||
void
|
||||
CueLayout::button_stop_release ()
|
||||
{
|
||||
std::cerr << "BS release, ls = " << _long_stop << std::endl;
|
||||
if (_long_stop) {
|
||||
_long_stop = 0;
|
||||
show_running_boxen (false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CueLayout::pad_press (int x, int y)
|
||||
CueLayout::button_stop_long_press ()
|
||||
{
|
||||
_long_stop++;
|
||||
|
||||
if (_long_stop == 1) {
|
||||
show_running_boxen (true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CueLayout::show_running_boxen (bool yn)
|
||||
{
|
||||
Push2::ButtonID lower_buttons[] = {
|
||||
Push2::Lower1, Push2::Lower2, Push2::Lower3, Push2::Lower4,
|
||||
Push2::Lower5, Push2::Lower6, Push2::Lower7, Push2::Lower8
|
||||
};
|
||||
|
||||
for (int n = 0; n < 8; ++n) {
|
||||
boost::shared_ptr<Push2::Button> lower_button = _p2.button_by_id (lower_buttons[n]);
|
||||
|
||||
if (!_route[n]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boost::shared_ptr<TriggerBox> tb = _route[n]->triggerbox();
|
||||
assert (tb);
|
||||
|
||||
if (yn) {
|
||||
|
||||
if (!tb->currently_playing()) {
|
||||
/* nothing playing, do not turn the blink on */
|
||||
continue;
|
||||
}
|
||||
|
||||
HSV hsv (_route[n]->presentation_info().color());
|
||||
hsv = hsv.shade (2.0);
|
||||
lower_button->set_color (_p2.get_color_index (hsv.color()));
|
||||
lower_button->set_state (Push2::LED::Blinking4th);
|
||||
|
||||
} else {
|
||||
std::cerr << "no blink " << n << std::endl;
|
||||
lower_button->set_color (_p2.get_color_index (_route[n]->presentation_info().color()));
|
||||
lower_button->set_state (Push2::LED::NoTransition);
|
||||
}
|
||||
|
||||
_p2.write (lower_button->state_msg());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CueLayout::pad_press (int y, int x) /* fix coordinate order one day */
|
||||
{
|
||||
std::cerr << "bang on " << x + track_base << ", " << y + scene_base << std::endl;
|
||||
_p2.bang (y + scene_base, x + track_base);
|
||||
|
||||
if (!_route[x]) {
|
||||
std::cerr << "no route\n";
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<TriggerBox> tb = _route[x]->triggerbox();
|
||||
|
||||
if (!tb) {
|
||||
std::cerr << "no TB\n";
|
||||
/* unpossible! */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tb->trigger (y + scene_base)->region()) {
|
||||
std::cerr << "empty slot, unbang TB\n";
|
||||
_p2.unbang (x + track_base);
|
||||
return;
|
||||
}
|
||||
|
||||
std::cerr << "bang TB\n";
|
||||
_p2.bang (x + track_base, y + scene_base);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -587,8 +651,109 @@ CueLayout::route_property_change (PropertyChange const& what_changed, uint32_t w
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
CueLayout::trigger_property_change (PropertyChange const& what_changed, uint32_t col, uint32_t row)
|
||||
{
|
||||
assert (_route[col]);
|
||||
|
||||
if (what_changed.contains (Properties::running)) {
|
||||
boost::shared_ptr<TriggerBox> tb = _route[col]->triggerbox ();
|
||||
assert (tb);
|
||||
|
||||
TriggerPtr trig = tb->trigger (row);
|
||||
assert (trig);
|
||||
|
||||
boost::shared_ptr<Push2::Pad> pad = _p2.pad_by_xy (col, row);
|
||||
assert (pad);
|
||||
|
||||
set_pad_color_from_trigger_state (col, pad, trig);
|
||||
_p2.write (pad->state_msg());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CueLayout::triggerbox_property_change (PropertyChange const& what_changed, uint32_t which)
|
||||
CueLayout::triggerbox_property_change (PropertyChange const& what_changed, uint32_t col)
|
||||
{
|
||||
std::cerr << "TB prop change "; what_changed.dump (std::cerr); std::cerr << std::endl;
|
||||
|
||||
assert (_route[col]);
|
||||
|
||||
if (what_changed.contains (Properties::currently_playing) || what_changed.contains (Properties::queued)) {
|
||||
|
||||
boost::shared_ptr<TriggerBox> tb = _route[col]->triggerbox ();
|
||||
assert (tb);
|
||||
|
||||
|
||||
/* make sure the blink state of all 8 pads for this
|
||||
* route/triggerbox are correct
|
||||
*/
|
||||
|
||||
for (uint32_t y = 0; y < 8; ++y) {
|
||||
boost::shared_ptr<Push2::Pad> pad = _p2.pad_by_xy (col, y);
|
||||
assert (pad);
|
||||
|
||||
TriggerPtr trig = tb->trigger (y);
|
||||
assert (trig);
|
||||
|
||||
set_pad_color_from_trigger_state (col, pad, trig);
|
||||
|
||||
_p2.write (pad->state_msg());
|
||||
}
|
||||
|
||||
|
||||
if (!what_changed.contains (Properties::queued)) {
|
||||
|
||||
/* currently_playing changed, if nothing is playing be
|
||||
* sure to disable blink on lower button
|
||||
*/
|
||||
|
||||
std::cerr << "running change on " << col << std::endl;
|
||||
|
||||
if (!tb->currently_playing()) {
|
||||
boost::shared_ptr<Push2::Button> lower_button = _p2.lower_button_by_column (col);
|
||||
lower_button->set_color (_p2.get_color_index (_route[col]->presentation_info().color()));
|
||||
lower_button->set_state (Push2::LED::NoTransition);
|
||||
_p2.write (lower_button->state_msg());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CueLayout::set_pad_color_from_trigger_state (int col, boost::shared_ptr<Push2::Pad> pad, TriggerPtr trig)
|
||||
{
|
||||
if (trig->region()) {
|
||||
|
||||
if (trig->active()) {
|
||||
|
||||
/* running or waiting to stop */
|
||||
|
||||
HSV hsv (_route[col]->presentation_info().color());
|
||||
hsv = hsv.shade (2.0);
|
||||
pad->set_color (_p2.get_color_index (hsv.color ()));
|
||||
pad->set_state (Push2::LED::Pulsing4th);
|
||||
|
||||
} else if (trig == trig->box().peek_next_trigger()) {
|
||||
|
||||
/* waiting to start */
|
||||
|
||||
HSV hsv (_route[col]->presentation_info().color());
|
||||
hsv = hsv.shade (2.0);
|
||||
pad->set_color (_p2.get_color_index (hsv.color ()));
|
||||
pad->set_state (Push2::LED::Pulsing16th);
|
||||
|
||||
} else {
|
||||
|
||||
/* not running */
|
||||
|
||||
pad->set_color (_p2.get_color_index (_route[col]->presentation_info().color()));
|
||||
pad->set_state (Push2::LED::NoTransition);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* empty slot */
|
||||
pad->set_color (Push2::LED::Black);
|
||||
pad->set_state (Push2::LED::NoTransition);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "layout.h"
|
||||
#include "push2.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class Route;
|
||||
|
@ -72,6 +73,8 @@ class CueLayout : public Push2Layout
|
|||
void button_page_left();
|
||||
void button_page_right();
|
||||
void button_stop_press ();
|
||||
void button_stop_release ();
|
||||
void button_stop_long_press ();
|
||||
|
||||
void strip_vpot (int, int);
|
||||
void strip_vpot_touch (int, bool);
|
||||
|
@ -91,14 +94,17 @@ class CueLayout : public Push2Layout
|
|||
uint32_t track_base;
|
||||
uint32_t scene_base;
|
||||
KnobFunction _knob_function;
|
||||
int _long_stop;
|
||||
|
||||
PBD::ScopedConnectionList _route_connections;
|
||||
PBD::ScopedConnectionList _route_connections;
|
||||
boost::shared_ptr<ARDOUR::Route> _route[8];
|
||||
PBD::ScopedConnectionList _session_connections;
|
||||
PBD::ScopedConnectionList _session_connections;
|
||||
PBD::ScopedConnection _trig_connections[64];
|
||||
|
||||
void routes_added ();
|
||||
void route_property_change (PBD::PropertyChange const& what_changed, uint32_t which);
|
||||
void triggerbox_property_change (PBD::PropertyChange const& what_changed, uint32_t which);
|
||||
void trigger_property_change (PBD::PropertyChange const& what_changed, uint32_t col, uint32_t row);
|
||||
|
||||
ArdourCanvas::Arc* _progress[8];
|
||||
boost::shared_ptr<ARDOUR::AutomationControl> _controllables[8];
|
||||
|
@ -108,6 +114,8 @@ class CueLayout : public Push2Layout
|
|||
void show_state ();
|
||||
void update_clip_progress (int);
|
||||
void show_knob_function ();
|
||||
void set_pad_color_from_trigger_state (int col, boost::shared_ptr<Push2::Pad>, boost::shared_ptr<ARDOUR::Trigger>);
|
||||
void show_running_boxen (bool);
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
|
|
@ -1912,3 +1912,39 @@ Push2::pad_by_xy (int x, int y)
|
|||
}
|
||||
return _xy_pad_map[index];
|
||||
}
|
||||
|
||||
boost::shared_ptr<Push2::Button>
|
||||
Push2::lower_button_by_column (uint32_t col)
|
||||
{
|
||||
assert (col < 8);
|
||||
|
||||
switch (col) {
|
||||
case 0:
|
||||
return button_by_id (Push2::Lower1);
|
||||
break;
|
||||
case 1:
|
||||
return button_by_id (Push2::Lower2);
|
||||
break;
|
||||
case 2:
|
||||
return button_by_id (Push2::Lower3);
|
||||
break;
|
||||
case 3:
|
||||
return button_by_id (Push2::Lower4);
|
||||
break;
|
||||
case 4:
|
||||
return button_by_id (Push2::Lower5);
|
||||
break;
|
||||
case 5:
|
||||
return button_by_id (Push2::Lower6);
|
||||
break;
|
||||
case 6:
|
||||
return button_by_id (Push2::Lower7);
|
||||
break;
|
||||
case 7:
|
||||
return button_by_id (Push2::Lower8);
|
||||
break;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
return boost::shared_ptr<Push2::Button>();
|
||||
}
|
||||
|
||||
|
|
|
@ -457,6 +457,7 @@ class Push2 : public ARDOUR::ControlProtocol
|
|||
PadMap const & nn_pad_map() const { return _nn_pad_map; }
|
||||
|
||||
boost::shared_ptr<Pad> pad_by_xy (int x, int y);
|
||||
boost::shared_ptr<Button> lower_button_by_column (uint32_t col);
|
||||
|
||||
CONTROL_PROTOCOL_THREADS_NEED_TEMPO_MAP_DECL();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user