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
25 #include <glibmm/threads.h>
27 #define ABSTRACT_UI_EXPORTS
28 #include "pbd/abstract_ui.h"
29 #include "pbd/properties.h"
31 #include "ardour/types.h"
32 #include "ardour/async_midi_port.h"
33 #include "ardour/midi_port.h"
35 #include "control_protocol/control_protocol.h"
38 #include "fp8_controls.h"
50 namespace ArdourSurface {
52 struct FaderPort8Request : public BaseUI::BaseRequestObject
55 FaderPort8Request () {}
56 ~FaderPort8Request () {}
59 class FaderPort8 : public FP8Base, public ARDOUR::ControlProtocol, public AbstractUI<FaderPort8Request>
62 FaderPort8 (ARDOUR::Session&);
63 virtual ~FaderPort8();
65 int set_active (bool yn);
67 /* we probe for a device when our ports are connected. Before that,
68 * there's no way to know if the device exists or not.
70 static bool probe() { return true; }
71 static void* request_factory (uint32_t);
73 XMLNode& get_state ();
74 int set_state (const XMLNode&, int version);
76 /* configuration GUI */
77 bool has_editor () const { return true; }
78 void* get_gui () const;
79 void tear_down_gui ();
80 PBD::Signal0<void> ConnectionChange;
82 void set_button_action (FP8Controls::ButtonId, bool, std::string const&);
83 std::string get_button_action (FP8Controls::ButtonId, bool);
84 FP8Controls const& control () const { return _ctrls; }
87 void do_request (FaderPort8Request*);
90 boost::shared_ptr<ARDOUR::Port> input_port() const { return _input_port; }
91 boost::shared_ptr<ARDOUR::Port> output_port() const { return _output_port; }
92 std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
94 size_t tx_midi (std::vector<uint8_t> const&) const;
99 void start_midi_handling ();
100 void stop_midi_handling ();
103 PBD::ScopedConnection port_connection;
104 boost::shared_ptr<ARDOUR::AsyncMIDIPort> _input_port;
105 boost::shared_ptr<ARDOUR::AsyncMIDIPort> _output_port;
106 boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
107 boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
109 bool midi_input_handler (Glib::IOCondition ioc, boost::weak_ptr<ARDOUR::AsyncMIDIPort> port);
111 bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
113 enum ConnectionState {
114 InputConnected = 0x1,
115 OutputConnected = 0x2
119 void disconnected ();
120 int _connection_state;
123 /* MIDI input message handling */
124 void sysex_handler (MIDI::Parser &p, MIDI::byte *, size_t);
125 void polypressure_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
126 void pitchbend_handler (MIDI::Parser &, uint8_t chan, MIDI::pitchbend_t pb);
127 void controller_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
128 void note_on_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
129 void note_off_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb);
130 PBD::ScopedConnectionList midi_connections;
132 /* ***************************************************************************
136 void notify_stripable_added_or_removed ();
137 void notify_fader_mode_changed ();
138 void filter_stripables (ARDOUR::StripableList& strips) const;
139 void assign_stripables (bool select_only = false);
140 void set_periodic_display_mode (FP8Strip::DisplayMode);
142 void assign_strips (bool reset_bank);
143 void bank (bool down, bool page);
144 void move_selected_into_view ();
145 void select_prev_next (bool next);
147 void assign_sends ();
148 void spill_plugins ();
149 void assign_processor_ctrls ();
150 void build_well_known_processor_ctrls (boost::shared_ptr<ARDOUR::Stripable>, bool);
151 void select_plugin (int num);
153 void bank_param (bool down, bool page);
159 /* plugin + send mode stripable
161 * This is used when parameters of one strip are assigned to
162 * individual FP8Strip controls (Edit Send, Edit Plugins).
164 * When there's one stripable per FP8Strip, FP8Strip itself keeps
165 * track of the object lifetime and these are NULL.
167 PBD::ScopedConnectionList processor_connections;
169 PBD::ScopedConnectionList assigned_stripable_connections;
170 typedef std::map<boost::shared_ptr<ARDOUR::Stripable>, uint8_t> StripAssignmentMap;
171 StripAssignmentMap _assigned_strips;
173 void drop_ctrl_connections ();
175 void select_strip (boost::weak_ptr<ARDOUR::Stripable>);
176 void notify_pi_property_changed (const PBD::PropertyChange&);
177 void notify_stripable_property_changed (boost::weak_ptr<ARDOUR::Stripable>, const PBD::PropertyChange&);
178 void gui_track_selection_changed ();
180 PBD::ScopedConnection selection_connection;
181 PBD::ScopedConnectionList automation_state_connections;
182 PBD::ScopedConnectionList modechange_connections;
183 /* **************************************************************************/
184 struct ProcessorCtrl {
185 ProcessorCtrl (std::string const &n, boost::shared_ptr<ARDOUR::AutomationControl> c)
190 boost::shared_ptr<ARDOUR::AutomationControl> ac;
192 std::list <ProcessorCtrl> _proc_params;
193 int _showing_well_known;
194 /* **************************************************************************/
196 /* periodic updates, parameter poll */
197 sigc::connection _periodic_connection;
199 std::string _timecode;
200 std::string const& timecode () const { return _timecode; }
202 /* sync button blink -- the FP's blink mode does not work */
203 sigc::connection _blink_connection;
208 sigc::connection _shift_connection;
211 bool shift_timeout () { _shift_lock = true; return false; }
212 bool shift_mod () const { return _shift_lock || (_shift_pressed > 0); }
218 /* setup callbacks & actions */
219 void connect_session_signals ();
220 void setup_actions ();
221 void send_session_state ();
224 PBD::ScopedConnectionList session_connections;
225 void notify_parameter_changed (std::string);
226 void notify_record_state_changed ();
227 void notify_transport_state_changed ();
228 void notify_loop_state_changed ();
229 void notify_snap_change ();
230 void notify_session_dirty_changed ();
231 void notify_history_changed ();
232 void notify_solo_changed ();
233 void notify_mute_changed ();
234 void notify_automation_mode_changed ();
237 PBD::ScopedConnectionList button_connections;
240 void button_record ();
242 void button_metronom ();
243 void button_varispeed (bool);
244 void button_mute_clear ();
245 void button_arm (bool);
246 void button_arm_all ();
247 void button_automation (ARDOUR::AutoState);
248 void button_prev_next (bool);
249 void button_action (const std::string& group, const std::string& item);
251 void button_encoder ();
252 void button_parameter ();
253 void encoder_navigate (bool, int);
254 void encoder_parameter (bool, int);
256 /* user bound actions */
257 void button_user (bool, FP8Controls::ButtonId);
262 // InternalFunction, // unused
266 UserAction () : _type (Unset) {}
269 std::string _action_name;
270 //boost::function<void()> function; // unused
275 _action_name.clear();
278 void assign_action (std::string const& action_name)
280 if (action_name.empty ()) {
282 _action_name.clear();
285 _action_name = action_name;
291 return _type == Unset;
294 void call (FaderPort8& _base) const
298 _base.access_action (_action_name);
306 struct ButtonAction {
308 UserAction on_release;
310 UserAction& action (bool press)
312 return press ? on_press : on_release;
315 UserAction const& action (bool press) const
317 return press ? on_press : on_release;
320 void call (FaderPort8& _base, bool press) const
322 action (press).call (_base);
326 return on_press.empty () && on_release.empty();
330 typedef std::map<FP8Controls::ButtonId, ButtonAction> UserActionMap;
331 UserActionMap _user_action_map;
336 #endif /* ardour_surface_faderport8_h */