2 Copyright (C) 2015 Paul Davis
3 Copyright (C) 2016 W.P. van Paassen
5 Thanks to Rolf Meyerhoff for reverse engineering the CC121 protocol.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "ardour/async_midi_port.h"
24 #include "ardour/monitor_processor.h"
25 #include "ardour/monitor_control.h"
26 #include "ardour/pannable.h"
27 #include "ardour/plugin_insert.h"
28 #include "ardour/rc_configuration.h"
29 #include "ardour/record_enable_control.h"
30 #include "ardour/session.h"
31 #include "ardour/track.h"
32 #include "ardour/types.h"
36 using namespace ARDOUR;
37 using namespace ArdourSurface;
40 /* this value is chosen to given smooth motion from 0..1.0 in about 270 degrees
41 * of encoder rotation.
43 static const double encoder_divider = 24.0;
46 CC121::input_monitor ()
48 if (_current_stripable) {
49 MonitorChoice choice = _current_stripable->monitoring_control()->monitoring_choice ();
52 _current_stripable->monitoring_control()->set_value (MonitorInput, PBD::Controllable::NoGroup);
53 get_button(InputMonitor).set_led_state (_output_port, true);
56 _current_stripable->monitoring_control()->set_value (MonitorDisk, PBD::Controllable::NoGroup);
57 get_button(InputMonitor).set_led_state (_output_port, false);
60 _current_stripable->monitoring_control()->set_value (MonitorCue, PBD::Controllable::NoGroup);
61 get_button(InputMonitor).set_led_state (_output_port, false);
64 _current_stripable->monitoring_control()->set_value (MonitorInput, PBD::Controllable::NoGroup);
65 get_button(InputMonitor).set_led_state (_output_port, true);
76 access_action ("Editor/select-prev-route");
79 //if ( (button_state & ShiftDown) == ShiftDown )
86 access_action ("Editor/select-next-route");
89 //if ( (button_state & ShiftDown) == ShiftDown )
96 if (_current_stripable) {
97 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
99 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Play );
107 if (_current_stripable) {
108 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
110 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Write );
118 if (_current_stripable) {
119 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
121 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Touch );
129 if (_current_stripable) {
130 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
132 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Off );
143 ControlProtocol::Undo (); /* EMIT SIGNAL */
149 ControlProtocol::Redo (); /* EMIT SIGNAL */
155 if (_jogmode == scroll) {
161 get_button (Jog).set_led_state (_output_port, _jogmode == scroll);
167 if (!_current_stripable) {
171 if (_current_stripable == session->monitor_out()) {
172 boost::shared_ptr<MonitorProcessor> mp = _current_stripable->monitor_control();
173 mp->set_cut_all (!mp->cut_all());
177 _current_stripable->mute_control()->set_value (!_current_stripable->mute_control()->muted(), PBD::Controllable::UseGroup);
183 if (!_current_stripable) {
186 _current_stripable->solo_control()->set_value (!_current_stripable->solo_control()->soloed(), PBD::Controllable::UseGroup);
192 if (!_current_stripable) {
196 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_current_stripable);
202 t->rec_enable_control()->set_value (!t->rec_enable_control()->get_value(), Controllable::UseGroup);
208 boost::shared_ptr<Stripable> r = session->master_out();
210 if (_current_stripable == r) {
211 r = pre_master_stripable.lock();
212 set_current_stripable (r);
213 get_button(Output).set_led_state (_output_port, false);
214 blinkers.remove (Output);
216 if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
217 pre_master_stripable = boost::weak_ptr<Stripable> (_current_stripable);
219 set_current_stripable (r);
220 get_button(Output).set_led_state (_output_port, true);
221 blinkers.remove (Output);
227 CC121::use_monitor ()
229 boost::shared_ptr<Stripable> r = session->monitor_out();
232 if (_current_stripable == r) {
233 r = pre_monitor_stripable.lock();
234 set_current_stripable (r);
235 get_button(Output).set_led_state (_output_port, false);
236 blinkers.remove (Output);
238 if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
239 pre_monitor_stripable = boost::weak_ptr<Stripable> (_current_stripable);
241 set_current_stripable (r);
242 get_button(Output).set_led_state (_output_port, true);
243 blinkers.push_back (Output);
249 CC121::set_controllable (boost::shared_ptr<AutomationControl> ac, float delta)
251 if (!ac || delta == 0) {
254 ac->start_touch (ac->session().transport_sample());
255 double v = ac->internal_to_interface (ac->get_value());
256 v = std::max (0.0, std::min (1.0, v + delta));
257 ac->set_value (ac->interface_to_internal(v), PBD::Controllable::NoGroup);
264 access_action ("Transport/TogglePunch");