FP2: Fix banking in NavChannel mode.
[ardour.git] / libs / surfaces / faderport8 / faderport8.h
1 /*
2  * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
3  * Copyright (C) 2015 Paul Davis
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #ifndef ardour_surface_faderport8_h
21 #define ardour_surface_faderport8_h
22
23 // allow to undo "mute clear", "solo clear"
24 // eventually this should use some libardour mixer history/undo
25 #define FP8_MUTESOLO_UNDO
26
27 #include <list>
28 #include <map>
29 #include <glibmm/threads.h>
30
31 #define ABSTRACT_UI_EXPORTS
32 #include "pbd/abstract_ui.h"
33 #include "pbd/properties.h"
34 #include "pbd/controllable.h"
35
36 #include "ardour/types.h"
37 #include "ardour/async_midi_port.h"
38 #include "ardour/midi_port.h"
39
40 #include "control_protocol/control_protocol.h"
41
42 #include "fp8_base.h"
43 #include "fp8_controls.h"
44
45 namespace MIDI {
46         class Parser;
47 }
48
49 namespace ARDOUR {
50         class Bundle;
51         class Session;
52         class Processor;
53         class PluginInsert;
54 }
55
56 namespace ArdourSurface { namespace FP_NAMESPACE {
57
58 struct FaderPort8Request : public BaseUI::BaseRequestObject
59 {
60         public:
61                 FaderPort8Request () {}
62                 ~FaderPort8Request () {}
63 };
64
65 class FaderPort8 : public FP8Base, public ARDOUR::ControlProtocol, public AbstractUI<FaderPort8Request>
66 {
67 public:
68         FaderPort8 (ARDOUR::Session&);
69         virtual ~FaderPort8();
70
71         int set_active (bool yn);
72
73         /* we probe for a device when our ports are connected. Before that,
74          * there's no way to know if the device exists or not.
75          */
76         static bool  probe() { return true; }
77         static void* request_factory (uint32_t);
78
79         XMLNode& get_state ();
80         int set_state (const XMLNode&, int version);
81
82         /* configuration GUI */
83         bool  has_editor () const { return true; }
84         void* get_gui () const;
85         void  tear_down_gui ();
86         PBD::Signal0<void> ConnectionChange;
87
88         void set_button_action (FP8Controls::ButtonId, bool, std::string const&);
89         std::string get_button_action (FP8Controls::ButtonId, bool);
90         FP8Controls const& control () const { return  _ctrls; }
91
92         void set_clock_mode (uint32_t m) { _clock_mode = m; }
93         void set_scribble_mode (uint32_t m) { _scribble_mode = m; }
94         void set_two_line_text (bool yn) { _two_line_text = yn; }
95         void set_auto_pluginui (bool yn) { _auto_pluginui = yn; }
96
97         uint32_t clock_mode () const { return _clock_mode; }
98         uint32_t scribble_mode () const { return _scribble_mode; }
99         bool twolinetext () const { return _two_line_text; }
100         bool auto_pluginui () const { return _auto_pluginui; }
101
102         void stop ();
103         void do_request (FaderPort8Request*);
104         void thread_init ();
105
106         boost::shared_ptr<ARDOUR::Port> input_port() const { return _input_port; }
107         boost::shared_ptr<ARDOUR::Port> output_port() const { return _output_port; }
108         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
109
110         size_t tx_midi (std::vector<uint8_t> const&) const;
111
112 private:
113         void close ();
114
115         void start_midi_handling ();
116         void stop_midi_handling ();
117
118         /* I/O Ports */
119         PBD::ScopedConnectionList port_connections;
120         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
121         boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
122         boost::shared_ptr<ARDOUR::Bundle>        _input_bundle;
123         boost::shared_ptr<ARDOUR::Bundle>        _output_bundle;
124
125         bool midi_input_handler (Glib::IOCondition ioc, boost::weak_ptr<ARDOUR::AsyncMIDIPort> port);
126
127         bool connection_handler (std::string name1, std::string name2);
128         void engine_reset ();
129
130         enum ConnectionState {
131                 InputConnected = 0x1,
132                 OutputConnected = 0x2
133         };
134
135         void connected ();
136         void disconnected ();
137         int  _connection_state;
138         bool _device_active;
139
140         /* MIDI input message handling */
141         void sysex_handler (MIDI::Parser &p, MIDI::byte *, size_t);
142         void polypressure_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
143         void pitchbend_handler (MIDI::Parser &, uint8_t chan, MIDI::pitchbend_t pb);
144         void controller_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
145         void note_on_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
146         void note_off_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
147         PBD::ScopedConnectionList midi_connections;
148
149         /* ***************************************************************************
150          * Control Elements
151          */
152         FP8Controls _ctrls;
153         void notify_stripable_added_or_removed ();
154         void notify_fader_mode_changed ();
155         void filter_stripables (ARDOUR::StripableList& strips) const;
156         void assign_stripables (bool select_only = false);
157         void set_periodic_display_mode (FP8Strip::DisplayMode);
158
159         void assign_strips ();
160         void bank (bool down, bool page);
161         void move_selected_into_view ();
162         void select_prev_next (bool next);
163
164         void assign_sends ();
165         void spill_plugins ();
166         void assign_processor_ctrls ();
167         bool assign_plugin_presets (boost::shared_ptr<ARDOUR::PluginInsert>);
168         void build_well_known_processor_ctrls (boost::shared_ptr<ARDOUR::Stripable>, bool);
169         void preset_changed ();
170         void select_plugin (int num);
171         void select_plugin_preset (size_t num);
172
173         void toggle_preset_param_mode ();
174         void bank_param (bool down, bool page);
175         /* bank offsets */
176         int  get_channel_off (FP8Types::MixMode m) const { return _channel_off [m]; }
177         void set_channel_off (FP8Types::MixMode m, int off) {_channel_off [m] = off ; }
178
179         int _channel_off[FP8Types::MixModeMax + 1];
180         int _plugin_off;
181         int _parameter_off;
182
183         /* plugin + send mode stripable
184          *
185          * This is used when parameters of one strip are assigned to
186          * individual FP8Strip controls (Edit Send, Edit Plugins).
187          *
188          * When there's one stripable per FP8Strip, FP8Strip itself keeps
189          * track of the object lifetime and these are NULL.
190          */
191         PBD::ScopedConnectionList processor_connections;
192
193         PBD::ScopedConnectionList assigned_stripable_connections;
194         typedef std::map<boost::shared_ptr<ARDOUR::Stripable>, uint8_t> StripAssignmentMap;
195         StripAssignmentMap _assigned_strips;
196
197         void drop_ctrl_connections ();
198
199         void select_strip (boost::weak_ptr<ARDOUR::Stripable>);
200
201         void notify_pi_property_changed (const PBD::PropertyChange&);
202         void notify_stripable_property_changed (boost::weak_ptr<ARDOUR::Stripable>, const PBD::PropertyChange&);
203         void stripable_selection_changed ();
204         void subscribe_to_strip_signals ();
205
206         PBD::ScopedConnection selection_connection;
207         PBD::ScopedConnectionList route_state_connections;
208         PBD::ScopedConnectionList modechange_connections;
209         /* **************************************************************************/
210         struct ProcessorCtrl {
211                 ProcessorCtrl (std::string const &n, boost::shared_ptr<ARDOUR::AutomationControl> c)
212                  : name (n)
213                  , ac (c)
214                 {}
215                 std::string name;
216                 boost::shared_ptr<ARDOUR::AutomationControl> ac;
217         };
218         std::list <ProcessorCtrl> _proc_params;
219         boost::weak_ptr<ARDOUR::PluginInsert> _plugin_insert;
220         bool _show_presets;
221         int _showing_well_known;
222         /* **************************************************************************/
223
224         /* periodic updates, parameter poll */
225         sigc::connection _periodic_connection;
226         bool periodic ();
227         std::string _timecode;
228         std::string _musical_time;
229         std::string const& timecode () const { return _timecode; }
230         std::string const& musical_time () const { return _musical_time; }
231
232         int _timer_divider;
233
234         bool show_meters () const { return _scribble_mode & 1; }
235         bool show_panner () const { return _scribble_mode & 2; }
236
237         /* sync button blink -- the FP's blink mode does not work */
238         sigc::connection _blink_connection;
239         bool _blink_onoff;
240         bool blink_it ();
241
242         /* shift key */
243         sigc::connection _shift_connection;
244         bool _shift_lock;
245         int _shift_pressed;
246         bool shift_timeout () { _shift_lock = true; return false; }
247         bool shift_mod () const { return _shift_lock || (_shift_pressed > 0); }
248
249         /* GUI */
250         void build_gui ();
251         mutable void *gui;
252
253         /* setup callbacks & actions */
254         void connect_session_signals ();
255         void setup_actions ();
256         void send_session_state ();
257
258         /* callbacks */
259         PBD::ScopedConnectionList session_connections;
260         void notify_parameter_changed (std::string);
261         void notify_record_state_changed ();
262         void notify_transport_state_changed ();
263         void notify_loop_state_changed ();
264         void notify_snap_change ();
265         void notify_session_dirty_changed ();
266         void notify_history_changed ();
267         void notify_solo_changed ();
268         void notify_mute_changed ();
269         void notify_route_state_changed ();
270         void notify_plugin_active_changed ();
271
272         /* actions */
273         PBD::ScopedConnectionList button_connections;
274         void button_play ();
275         void button_stop ();
276         void button_record ();
277         void button_loop ();
278         void button_metronom ();
279         void button_bypass ();
280         void button_open ();
281         void button_link ();
282         void button_lock ();
283         void button_varispeed (bool);
284 #ifdef FP8_MUTESOLO_UNDO
285         void button_solo_clear ();
286 #endif
287         void button_mute_clear ();
288         void button_arm (bool);
289         void button_arm_all ();
290         void button_automation (ARDOUR::AutoState);
291         void button_prev_next (bool);
292         void button_action (const std::string& group, const std::string& item);
293
294         void button_chanlock (); /* FP2 only */
295         void button_flip (); /* FP2 only */
296
297         void button_encoder ();
298         void button_parameter ();
299         void encoder_navigate (bool, int);
300         void encoder_parameter (bool, int);
301
302         /* mute undo history */
303 #ifdef FP8_MUTESOLO_UNDO
304         std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _mute_state;
305         std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _solo_state;
306 #endif
307
308         /* Encoder handlers */
309         void handle_encoder_pan (int steps);
310         void handle_encoder_link (int steps);
311
312         /* Control Link */
313         void stop_link ();
314         void start_link ();
315         void lock_link ();
316         void unlock_link (bool drop = false);
317         void nofity_focus_control (boost::weak_ptr<PBD::Controllable>);
318         PBD::ScopedConnection link_connection;
319         PBD::ScopedConnection link_locked_connection;
320         boost::weak_ptr<PBD::Controllable> _link_control;
321         bool _link_enabled;
322         bool _link_locked; // can only be true if _link_enabled
323
324         bool _chan_locked; /* FP2 only */
325
326         /* user prefs */
327         uint32_t _clock_mode;
328         uint32_t _scribble_mode;
329         bool     _two_line_text;
330         bool     _auto_pluginui;
331
332         /* user bound actions */
333         void button_user (bool, FP8Controls::ButtonId);
334
335         enum ActionType {
336                 Unset,
337                 NamedAction,
338                 // InternalFunction, // unused
339         };
340
341         struct UserAction {
342                 UserAction () : _type (Unset) {}
343
344                 ActionType _type;
345                 std::string _action_name;
346                 //boost::function<void()> function; // unused
347
348                 void clear ()
349                 {
350                         _type = Unset;
351                         _action_name.clear();
352                 }
353
354                 void assign_action (std::string const& action_name)
355                 {
356                         if (action_name.empty ()) {
357                                 _type = Unset;
358                                 _action_name.clear();
359                         } else {
360                                 _type = NamedAction;
361                                 _action_name = action_name;
362                         }
363                 }
364
365                 bool empty () const
366                 {
367                         return _type == Unset;
368                 }
369
370                 void call (FaderPort8& _base) const
371                 {
372                         switch (_type) {
373                                 case NamedAction:
374                                         _base.access_action (_action_name);
375                                         break;
376                                 default:
377                                         break;
378                         }
379                 }
380         };
381
382         struct ButtonAction {
383                 UserAction on_press;
384                 UserAction on_release;
385
386                 UserAction& action (bool press)
387                 {
388                         return press ? on_press : on_release;
389                 }
390
391                 UserAction const& action (bool press) const
392                 {
393                         return press ? on_press : on_release;
394                 }
395
396                 void call (FaderPort8& _base, bool press) const
397                 {
398                         action (press).call (_base);
399                 }
400                 bool empty () const
401                 {
402                         return on_press.empty () && on_release.empty();
403                 }
404         };
405
406         typedef std::map<FP8Controls::ButtonId, ButtonAction> UserActionMap;
407         UserActionMap _user_action_map;
408 };
409
410 } } /* namespace */
411
412 #endif /* ardour_surface_faderport8_h */