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 && _current_stripable->monitoring_control()) {
49 MonitorChoice choice = _current_stripable->monitoring_control()->monitoring_choice ();
52 _current_stripable->monitoring_control()->set_value (MonitorInput, PBD::Controllable::NoGroup);
55 _current_stripable->monitoring_control()->set_value (MonitorDisk, PBD::Controllable::NoGroup);
58 _current_stripable->monitoring_control()->set_value (MonitorCue, PBD::Controllable::NoGroup);
61 _current_stripable->monitoring_control()->set_value (MonitorAuto, PBD::Controllable::NoGroup);
72 access_action ("Editor/select-prev-route");
75 //if ( (button_state & ShiftDown) == ShiftDown )
82 access_action ("Editor/select-next-route");
85 //if ( (button_state & ShiftDown) == ShiftDown )
92 if (_current_stripable) {
93 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
95 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Play );
103 if (_current_stripable) {
104 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
106 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Write );
114 if (_current_stripable) {
115 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
117 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Touch );
125 if (_current_stripable) {
126 boost::shared_ptr<AutomationControl> gain = _current_stripable->gain_control ();
128 gain->set_automation_state( (ARDOUR::AutoState) ARDOUR::Off );
139 ControlProtocol::Undo (); /* EMIT SIGNAL */
145 ControlProtocol::Redo (); /* EMIT SIGNAL */
151 if (_jogmode == scroll) {
157 get_button (Jog).set_led_state (_output_port, _jogmode == scroll);
163 if (!_current_stripable) {
167 if (_current_stripable == session->monitor_out()) {
168 boost::shared_ptr<MonitorProcessor> mp = _current_stripable->monitor_control();
169 mp->set_cut_all (!mp->cut_all());
173 _current_stripable->mute_control()->set_value (!_current_stripable->mute_control()->muted(), PBD::Controllable::UseGroup);
179 if (!_current_stripable) {
182 _current_stripable->solo_control()->set_value (!_current_stripable->solo_control()->soloed(), PBD::Controllable::UseGroup);
188 if (!_current_stripable) {
192 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_current_stripable);
198 t->rec_enable_control()->set_value (!t->rec_enable_control()->get_value(), Controllable::UseGroup);
204 boost::shared_ptr<Stripable> r = session->master_out();
206 if (_current_stripable == r) {
207 r = pre_master_stripable.lock();
208 set_current_stripable (r);
209 get_button(Output).set_led_state (_output_port, false);
210 blinkers.remove (Output);
212 if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
213 pre_master_stripable = boost::weak_ptr<Stripable> (_current_stripable);
215 set_current_stripable (r);
216 get_button(Output).set_led_state (_output_port, true);
217 blinkers.remove (Output);
223 CC121::use_monitor ()
225 boost::shared_ptr<Stripable> r = session->monitor_out();
228 if (_current_stripable == r) {
229 r = pre_monitor_stripable.lock();
230 set_current_stripable (r);
231 get_button(Output).set_led_state (_output_port, false);
232 blinkers.remove (Output);
234 if (_current_stripable != session->master_out() && _current_stripable != session->monitor_out()) {
235 pre_monitor_stripable = boost::weak_ptr<Stripable> (_current_stripable);
237 set_current_stripable (r);
238 get_button(Output).set_led_state (_output_port, true);
239 blinkers.push_back (Output);
245 CC121::set_controllable (boost::shared_ptr<AutomationControl> ac, float delta)
247 if (!ac || delta == 0) {
250 ac->start_touch (ac->session().transport_sample());
251 double v = ac->internal_to_interface (ac->get_value());
252 v = std::max (0.0, std::min (1.0, v + delta));
253 ac->set_value (ac->interface_to_internal(v), PBD::Controllable::NoGroup);
260 access_action ("Transport/TogglePunch");