2 Copyright (C) 2006,2007 John Anderson
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #ifndef ardour_mackie_control_protocol_h
20 #define ardour_mackie_control_protocol_h
27 #include <boost/smart_ptr.hpp>
29 #include <glibmm/thread.h>
31 #include "pbd/abstract_ui.h"
33 #include "midi++/types.h"
35 #include "ardour/types.h"
36 #include "control_protocol/control_protocol.h"
39 #include "midi_byte_array.h"
41 #include "mackie_jog_wheel.h"
56 This handles the plugin duties, and the midi encoding and decoding,
57 and the signal callbacks, mostly from ARDOUR::Route.
59 The model of the control surface is handled by classes in controls.h
61 What happens is that each strip on the control surface has
62 a corresponding route in ControlProtocol::route_table. When
63 an incoming midi message is signaled, the correct route
64 is looked up, and the relevant changes made to it.
66 For each route currently in route_table, there's a RouteSignal object
67 which encapsulates the signals that indicate that there are changes
68 to be sent to the surface. The signals are handled by this class.
70 Calls to signal handlers pass a Route object which is used to look
71 up the relevant Strip in Surface. Then the state is retrieved from
72 the Route and encoded as the correct midi message.
75 struct MackieControlUIRequest : public BaseUI::BaseRequestObject {
77 MackieControlUIRequest () {}
78 ~MackieControlUIRequest () {}
81 class MackieControlProtocol
82 : public ARDOUR::ControlProtocol
83 , public AbstractUI<MackieControlUIRequest>
86 static const int MODIFIER_OPTION;
87 static const int MODIFIER_CONTROL;
88 static const int MODIFIER_SHIFT;
89 static const int MODIFIER_CMDALT;
91 MackieControlProtocol(ARDOUR::Session &);
92 virtual ~MackieControlProtocol();
94 static MackieControlProtocol* instance() { return _instance; }
96 int set_active (bool yn);
98 XMLNode& get_state ();
99 int set_state (const XMLNode&, int version);
103 typedef std::list<boost::shared_ptr<Mackie::Surface> > Surfaces;
106 std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
108 uint32_t n_strips () const;
110 bool has_editor () const { return true; }
111 void* get_gui () const;
112 void tear_down_gui ();
114 void select_track (boost::shared_ptr<ARDOUR::Route> r);
116 void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);
118 void notify_route_added (ARDOUR::RouteList &);
119 void notify_remote_id_changed();
121 /// rebuild the current bank. Called on route added/removed and
122 /// remote id changed.
123 void refresh_current_bank();
125 // button-related signals
126 void notify_record_state_changed();
127 void notify_transport_state_changed();
128 void notify_loop_state_changed();
129 // mainly to pick up punch-in and punch-out
130 void notify_parameter_changed(std::string const &);
131 void notify_solo_active_changed(bool);
133 /// Turn timecode on and beats off, or vice versa, depending
134 /// on state of _timecode_type
135 void update_timecode_beats_led();
137 /// this is called to generate the midi to send in response to a button press.
138 void update_led(Mackie::Surface&, Mackie::Button & button, Mackie::LedState);
140 void update_global_button(const std::string & name, Mackie::LedState);
141 void update_global_led(const std::string & name, Mackie::LedState);
143 /* implemented button handlers */
144 Mackie::LedState frm_left_press(Mackie::Button &);
145 Mackie::LedState frm_left_release(Mackie::Button &);
146 Mackie::LedState frm_right_press(Mackie::Button &);
147 Mackie::LedState frm_right_release(Mackie::Button &);
148 Mackie::LedState stop_press(Mackie::Button &);
149 Mackie::LedState stop_release(Mackie::Button &);
150 Mackie::LedState play_press(Mackie::Button &);
151 Mackie::LedState play_release(Mackie::Button &);
152 Mackie::LedState record_press(Mackie::Button &);
153 Mackie::LedState record_release(Mackie::Button &);
154 Mackie::LedState loop_press(Mackie::Button &);
155 Mackie::LedState loop_release(Mackie::Button &);
156 Mackie::LedState punch_in_press(Mackie::Button &);
157 Mackie::LedState punch_in_release(Mackie::Button &);
158 Mackie::LedState punch_out_press(Mackie::Button &);
159 Mackie::LedState punch_out_release(Mackie::Button &);
160 Mackie::LedState home_press(Mackie::Button &);
161 Mackie::LedState home_release(Mackie::Button &);
162 Mackie::LedState end_press(Mackie::Button &);
163 Mackie::LedState end_release(Mackie::Button &);
164 Mackie::LedState rewind_press(Mackie::Button & button);
165 Mackie::LedState rewind_release(Mackie::Button & button);
166 Mackie::LedState ffwd_press(Mackie::Button & button);
167 Mackie::LedState ffwd_release(Mackie::Button & button);
168 Mackie::LedState cursor_up_press (Mackie::Button &);
169 Mackie::LedState cursor_up_release (Mackie::Button &);
170 Mackie::LedState cursor_down_press (Mackie::Button &);
171 Mackie::LedState cursor_down_release (Mackie::Button &);
172 Mackie::LedState cursor_left_press (Mackie::Button &);
173 Mackie::LedState cursor_left_release (Mackie::Button &);
174 Mackie::LedState cursor_right_press (Mackie::Button &);
175 Mackie::LedState cursor_right_release (Mackie::Button &);
176 Mackie::LedState left_press(Mackie::Button &);
177 Mackie::LedState left_release(Mackie::Button &);
178 Mackie::LedState right_press(Mackie::Button &);
179 Mackie::LedState right_release(Mackie::Button &);
180 Mackie::LedState channel_left_press(Mackie::Button &);
181 Mackie::LedState channel_left_release(Mackie::Button &);
182 Mackie::LedState channel_right_press(Mackie::Button &);
183 Mackie::LedState channel_right_release(Mackie::Button &);
184 Mackie::LedState clicking_press(Mackie::Button &);
185 Mackie::LedState clicking_release(Mackie::Button &);
186 Mackie::LedState global_solo_press(Mackie::Button &);
187 Mackie::LedState global_solo_release(Mackie::Button &);
188 Mackie::LedState marker_press(Mackie::Button &);
189 Mackie::LedState marker_release(Mackie::Button &);
190 Mackie::LedState drop_press(Mackie::Button &);
191 Mackie::LedState drop_release(Mackie::Button &);
192 Mackie::LedState save_press(Mackie::Button &);
193 Mackie::LedState save_release(Mackie::Button &);
194 Mackie::LedState timecode_beats_press(Mackie::Button &);
195 Mackie::LedState timecode_beats_release(Mackie::Button &);
196 Mackie::LedState zoom_press(Mackie::Button &);
197 Mackie::LedState zoom_release(Mackie::Button &);
198 Mackie::LedState scrub_press(Mackie::Button &);
199 Mackie::LedState scrub_release(Mackie::Button &);
200 Mackie::LedState undo_press (Mackie::Button &);
201 Mackie::LedState undo_release (Mackie::Button &);
202 Mackie::LedState redo_press (Mackie::Button &);
203 Mackie::LedState redo_release (Mackie::Button &);
204 Mackie::LedState shift_press (Mackie::Button &);
205 Mackie::LedState shift_release (Mackie::Button &);
206 Mackie::LedState option_press (Mackie::Button &);
207 Mackie::LedState option_release (Mackie::Button &);
208 Mackie::LedState control_press (Mackie::Button &);
209 Mackie::LedState control_release (Mackie::Button &);
210 Mackie::LedState cmd_alt_press (Mackie::Button &);
211 Mackie::LedState cmd_alt_release (Mackie::Button &);
213 Mackie::LedState io_press (Mackie::Button &);
214 Mackie::LedState io_release (Mackie::Button &);
215 Mackie::LedState sends_press (Mackie::Button &);
216 Mackie::LedState sends_release (Mackie::Button &);
217 Mackie::LedState pan_press (Mackie::Button &);
218 Mackie::LedState pan_release (Mackie::Button &);
219 Mackie::LedState plugin_press (Mackie::Button &);
220 Mackie::LedState plugin_release (Mackie::Button &);
221 Mackie::LedState eq_press (Mackie::Button &);
222 Mackie::LedState eq_release (Mackie::Button &);
223 Mackie::LedState dyn_press (Mackie::Button &);
224 Mackie::LedState dyn_release (Mackie::Button &);
225 Mackie::LedState flip_press (Mackie::Button &);
226 Mackie::LedState flip_release (Mackie::Button &);
227 Mackie::LedState edit_press (Mackie::Button &);
228 Mackie::LedState edit_release (Mackie::Button &);
229 Mackie::LedState name_value_press (Mackie::Button &);
230 Mackie::LedState name_value_release (Mackie::Button &);
231 Mackie::LedState F1_press (Mackie::Button &);
232 Mackie::LedState F1_release (Mackie::Button &);
233 Mackie::LedState F2_press (Mackie::Button &);
234 Mackie::LedState F2_release (Mackie::Button &);
235 Mackie::LedState F3_press (Mackie::Button &);
236 Mackie::LedState F3_release (Mackie::Button &);
237 Mackie::LedState F4_press (Mackie::Button &);
238 Mackie::LedState F4_release (Mackie::Button &);
239 Mackie::LedState F5_press (Mackie::Button &);
240 Mackie::LedState F5_release (Mackie::Button &);
241 Mackie::LedState F6_press (Mackie::Button &);
242 Mackie::LedState F6_release (Mackie::Button &);
243 Mackie::LedState F7_press (Mackie::Button &);
244 Mackie::LedState F7_release (Mackie::Button &);
245 Mackie::LedState F8_press (Mackie::Button &);
246 Mackie::LedState F8_release (Mackie::Button &);
247 Mackie::LedState F9_press (Mackie::Button &);
248 Mackie::LedState F9_release (Mackie::Button &);
249 Mackie::LedState F10_press (Mackie::Button &);
250 Mackie::LedState F10_release (Mackie::Button &);
251 Mackie::LedState F11_press (Mackie::Button &);
252 Mackie::LedState F11_release (Mackie::Button &);
253 Mackie::LedState F12_press (Mackie::Button &);
254 Mackie::LedState F12_release (Mackie::Button &);
255 Mackie::LedState F13_press (Mackie::Button &);
256 Mackie::LedState F13_release (Mackie::Button &);
257 Mackie::LedState F14_press (Mackie::Button &);
258 Mackie::LedState F14_release (Mackie::Button &);
259 Mackie::LedState F15_press (Mackie::Button &);
260 Mackie::LedState F15_release (Mackie::Button &);
261 Mackie::LedState F16_press (Mackie::Button &);
262 Mackie::LedState F16_release (Mackie::Button &);
263 Mackie::LedState on_press (Mackie::Button &);
264 Mackie::LedState on_release (Mackie::Button &);
265 Mackie::LedState rec_ready_press (Mackie::Button &);
266 Mackie::LedState rec_ready_release (Mackie::Button &);
267 Mackie::LedState snapshot_press (Mackie::Button &);
268 Mackie::LedState snapshot_release (Mackie::Button &);
269 Mackie::LedState touch_press (Mackie::Button &);
270 Mackie::LedState touch_release (Mackie::Button &);
271 Mackie::LedState enter_press (Mackie::Button &);
272 Mackie::LedState enter_release (Mackie::Button &);
273 Mackie::LedState cancel_press (Mackie::Button &);
274 Mackie::LedState cancel_release (Mackie::Button &);
275 Mackie::LedState mixer_press (Mackie::Button &);
276 Mackie::LedState mixer_release (Mackie::Button &);
277 Mackie::LedState user_a_press (Mackie::Button &);
278 Mackie::LedState user_a_release (Mackie::Button &);
279 Mackie::LedState user_b_press (Mackie::Button &);
280 Mackie::LedState user_b_release (Mackie::Button &);
281 Mackie::LedState fader_touch_press (Mackie::Button &);
282 Mackie::LedState fader_touch_release (Mackie::Button &);
284 ARDOUR::Session & get_session() { return *session; }
286 void add_in_use_timeout (Mackie::Surface& surface, Mackie::Control& in_use_control, Mackie::Control* touch_control);
288 int modifier_state();
291 // shut down the surface
294 // This sets up the notifications and sets the
295 // controls to the correct values
296 void update_surfaces();
298 // connects global (not strip) signals from the Session to here
299 // so the surface can be notified of changes from the other UIs.
300 void connect_session_signals();
302 // set all controls to their zero position
306 Fetch the set of routes to be considered for control by the
307 surface. Excluding master, hidden and control routes, and inactive routes
309 typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
310 Sorted get_sorted_routes();
313 void switch_banks (uint32_t first_remote_id, bool force = false);
317 // also called from poll_automation to update timecode display
318 void update_timecode_display();
320 std::string format_bbt_timecode (ARDOUR::framepos_t now_frame);
321 std::string format_timecode_timecode (ARDOUR::framepos_t now_frame);
323 void do_request (MackieControlUIRequest*);
330 static MackieControlProtocol* _instance;
332 void create_surfaces ();
333 void port_connected_or_disconnected (std::string, std::string, bool);
334 bool control_in_use_timeout (Mackie::Surface*, Mackie::Control *, Mackie::Control *);
337 sigc::connection periodic_connection;
339 /// The initial remote_id of the currently switched in bank.
340 uint32_t _current_initial_bank;
342 /// protects the port list
343 Glib::Mutex update_mutex;
345 PBD::ScopedConnectionList audio_engine_connections;
346 PBD::ScopedConnectionList session_connections;
347 PBD::ScopedConnectionList port_connections;
348 PBD::ScopedConnectionList route_connections;
350 bool _transport_previously_rolling;
352 // timer for two quick marker left presses
353 Mackie::Timer _frm_left_last;
355 // last written timecode string
356 std::string _timecode_last;
358 // Which timecode are we displaying? BBT or Timecode
359 ARDOUR::AnyTime::Type _timecode_type;
361 // Bundle to represent our input ports
362 boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
363 // Bundle to represent our output ports
364 boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
372 int _current_selected_track;
375 typedef std::list<GSource*> PortSources;
376 PortSources port_sources;
378 bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
381 struct ButtonHandlers {
382 Mackie::LedState (MackieControlProtocol::*press) (Mackie::Button&);
383 Mackie::LedState (MackieControlProtocol::*release) (Mackie::Button&);
385 ButtonHandlers (Mackie::LedState (MackieControlProtocol::*p) (Mackie::Button&),
386 Mackie::LedState (MackieControlProtocol::*r) (Mackie::Button&))
391 typedef std::map<int,ButtonHandlers> ButtonMap;
392 ButtonMap button_map;
394 void build_button_map ();
399 #endif // ardour_mackie_control_protocol_h