2 * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
3 * Copyright (C) 2015 Paul Davis
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.
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.
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.
20 #ifndef ardour_surface_faderport8_h
21 #define ardour_surface_faderport8_h
23 // allow to undo "mute clear", "solo clear"
24 // eventually this should use some libardour mixer history/undo
25 #define FP8_MUTESOLO_UNDO
29 #include <glibmm/threads.h>
31 #define ABSTRACT_UI_EXPORTS
32 #include "pbd/abstract_ui.h"
33 #include "pbd/properties.h"
34 #include "pbd/controllable.h"
36 #include "ardour/types.h"
37 #include "ardour/async_midi_port.h"
38 #include "ardour/midi_port.h"
40 #include "control_protocol/control_protocol.h"
43 #include "fp8_controls.h"
56 namespace ArdourSurface { namespace FP_NAMESPACE {
58 struct FaderPort8Request : public BaseUI::BaseRequestObject
61 FaderPort8Request () {}
62 ~FaderPort8Request () {}
65 class FaderPort8 : public FP8Base, public ARDOUR::ControlProtocol, public AbstractUI<FaderPort8Request>
68 FaderPort8 (ARDOUR::Session&);
69 virtual ~FaderPort8();
71 int set_active (bool yn);
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.
76 static bool probe() { return true; }
77 static void* request_factory (uint32_t);
79 XMLNode& get_state ();
80 int set_state (const XMLNode&, int version);
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;
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; }
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; }
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; }
103 void do_request (FaderPort8Request*);
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 ();
110 size_t tx_midi (std::vector<uint8_t> const&) const;
115 void start_midi_handling ();
116 void stop_midi_handling ();
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;
125 bool midi_input_handler (Glib::IOCondition ioc, boost::weak_ptr<ARDOUR::AsyncMIDIPort> port);
127 bool connection_handler (std::string name1, std::string name2);
128 void engine_reset ();
130 enum ConnectionState {
131 InputConnected = 0x1,
132 OutputConnected = 0x2
136 void disconnected ();
137 int _connection_state;
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;
149 /* ***************************************************************************
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);
159 void assign_strips ();
160 void bank (bool down, bool page);
161 void move_selected_into_view ();
162 void select_prev_next (bool next);
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);
173 void toggle_preset_param_mode ();
174 void bank_param (bool down, bool page);
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 ; }
179 int _channel_off[FP8Types::MixModeMax + 1];
183 /* plugin + send mode stripable
185 * This is used when parameters of one strip are assigned to
186 * individual FP8Strip controls (Edit Send, Edit Plugins).
188 * When there's one stripable per FP8Strip, FP8Strip itself keeps
189 * track of the object lifetime and these are NULL.
191 PBD::ScopedConnectionList processor_connections;
193 PBD::ScopedConnectionList assigned_stripable_connections;
194 typedef std::map<boost::shared_ptr<ARDOUR::Stripable>, uint8_t> StripAssignmentMap;
195 StripAssignmentMap _assigned_strips;
197 void drop_ctrl_connections ();
199 void select_strip (boost::weak_ptr<ARDOUR::Stripable>);
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 ();
205 PBD::ScopedConnection selection_connection;
206 PBD::ScopedConnectionList automation_state_connections;
207 PBD::ScopedConnectionList modechange_connections;
208 /* **************************************************************************/
209 struct ProcessorCtrl {
210 ProcessorCtrl (std::string const &n, boost::shared_ptr<ARDOUR::AutomationControl> c)
215 boost::shared_ptr<ARDOUR::AutomationControl> ac;
217 std::list <ProcessorCtrl> _proc_params;
218 boost::weak_ptr<ARDOUR::PluginInsert> _plugin_insert;
220 int _showing_well_known;
221 /* **************************************************************************/
223 /* periodic updates, parameter poll */
224 sigc::connection _periodic_connection;
226 std::string _timecode;
227 std::string _musical_time;
228 std::string const& timecode () const { return _timecode; }
229 std::string const& musical_time () const { return _musical_time; }
233 bool show_meters () const { return _scribble_mode & 1; }
234 bool show_panner () const { return _scribble_mode & 2; }
236 /* sync button blink -- the FP's blink mode does not work */
237 sigc::connection _blink_connection;
242 sigc::connection _shift_connection;
245 bool shift_timeout () { _shift_lock = true; return false; }
246 bool shift_mod () const { return _shift_lock || (_shift_pressed > 0); }
252 /* setup callbacks & actions */
253 void connect_session_signals ();
254 void setup_actions ();
255 void send_session_state ();
258 PBD::ScopedConnectionList session_connections;
259 void notify_parameter_changed (std::string);
260 void notify_record_state_changed ();
261 void notify_transport_state_changed ();
262 void notify_loop_state_changed ();
263 void notify_snap_change ();
264 void notify_session_dirty_changed ();
265 void notify_history_changed ();
266 void notify_solo_changed ();
267 void notify_mute_changed ();
268 void notify_automation_mode_changed ();
269 void notify_plugin_active_changed ();
272 PBD::ScopedConnectionList button_connections;
275 void button_record ();
277 void button_metronom ();
278 void button_bypass ();
282 void button_varispeed (bool);
283 #ifdef FP8_MUTESOLO_UNDO
284 void button_solo_clear ();
286 void button_mute_clear ();
287 void button_arm (bool);
288 void button_arm_all ();
289 void button_automation (ARDOUR::AutoState);
290 void button_prev_next (bool);
291 void button_action (const std::string& group, const std::string& item);
293 void button_encoder ();
294 void button_parameter ();
295 void encoder_navigate (bool, int);
296 void encoder_parameter (bool, int);
298 /* mute undo history */
299 #ifdef FP8_MUTESOLO_UNDO
300 std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _mute_state;
301 std::vector <boost::weak_ptr<ARDOUR::AutomationControl> > _solo_state;
304 /* Encoder handlers */
305 void handle_encoder_pan (int steps);
306 void handle_encoder_link (int steps);
312 void unlock_link (bool drop = false);
313 void nofity_focus_control (boost::weak_ptr<PBD::Controllable>);
314 PBD::ScopedConnection link_connection;
315 PBD::ScopedConnection link_locked_connection;
316 boost::weak_ptr<PBD::Controllable> _link_control;
318 bool _link_locked; // can only be true if _link_enabled
321 uint32_t _clock_mode;
322 uint32_t _scribble_mode;
326 /* user bound actions */
327 void button_user (bool, FP8Controls::ButtonId);
332 // InternalFunction, // unused
336 UserAction () : _type (Unset) {}
339 std::string _action_name;
340 //boost::function<void()> function; // unused
345 _action_name.clear();
348 void assign_action (std::string const& action_name)
350 if (action_name.empty ()) {
352 _action_name.clear();
355 _action_name = action_name;
361 return _type == Unset;
364 void call (FaderPort8& _base) const
368 _base.access_action (_action_name);
376 struct ButtonAction {
378 UserAction on_release;
380 UserAction& action (bool press)
382 return press ? on_press : on_release;
385 UserAction const& action (bool press) const
387 return press ? on_press : on_release;
390 void call (FaderPort8& _base, bool press) const
392 action (press).call (_base);
396 return on_press.empty () && on_release.empty();
400 typedef std::map<FP8Controls::ButtonId, ButtonAction> UserActionMap;
401 UserActionMap _user_action_map;
406 #endif /* ardour_surface_faderport8_h */