3007df8f5a5d60a37dce0a4cee3a8f5426829b34
[ardour.git] / libs / surfaces / mackie / mackie_control_protocol.h
1 /*
2     Copyright (C) 2006,2007 John Anderson
3     
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.
8     
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.
13     
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.
17 */
18
19 #ifndef ardour_mackie_control_protocol_h
20 #define ardour_mackie_control_protocol_h
21
22 #include <vector>
23
24 #include <sys/time.h>
25 #include <pthread.h>
26
27 #include <glibmm/thread.h>
28
29 #include "ardour/types.h"
30 #include "ardour/midi_ui.h"
31 #include "midi++/types.h"
32
33 #include "control_protocol/control_protocol.h"
34 #include "midi_byte_array.h"
35 #include "controls.h"
36 #include "dummy_port.h"
37 #include "route_signal.h"
38 #include "mackie_button_handler.h"
39 #include "mackie_port.h"
40 #include "mackie_jog_wheel.h"
41 #include "timer.h"
42
43 namespace MIDI {
44         class Port;
45 }
46
47 namespace Mackie {
48         class Surface;
49 }
50
51 /**
52         This handles the plugin duties, and the midi encoding and decoding,
53         and the signal callbacks, mostly from ARDOUR::Route.
54
55         The model of the control surface is handled by classes in controls.h
56
57         What happens is that each strip on the control surface has
58         a corresponding route in ControlProtocol::route_table. When
59         an incoming midi message is signaled, the correct route
60         is looked up, and the relevant changes made to it.
61
62         For each route currently in route_table, there's a RouteSignal object
63         which encapsulates the signals that indicate that there are changes
64         to be sent to the surface. The signals are handled by this class.
65
66         Calls to signal handlers pass a Route object which is used to look
67         up the relevant Strip in Surface. Then the state is retrieved from
68         the Route and encoded as the correct midi message.
69 */
70
71 class MackieControlProtocol 
72         : public ARDOUR::ControlProtocol
73         , public Mackie::MackieButtonHandler
74 {
75   public:
76         MackieControlProtocol(ARDOUR::Session &);
77         virtual ~MackieControlProtocol();
78
79         int set_active (bool yn);
80
81         XMLNode& get_state ();
82         int set_state (const XMLNode&, int version);
83   
84         static bool probe();
85         
86         Mackie::Surface & surface();
87
88         std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
89
90         // control events
91         void handle_control_event(Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state);
92
93         // strip/route related stuff
94   public:       
95         /// Signal handler for Route::solo
96         void notify_solo_changed(Mackie::RouteSignal *);
97         /// Signal handler for Route::mute
98         void notify_mute_changed(Mackie::RouteSignal *);
99         /// Signal handler for Route::record_enable_changed
100         void notify_record_enable_changed(Mackie::RouteSignal *);
101         /// Signal handler for Route::gain_changed (from IO)
102         void notify_gain_changed(Mackie::RouteSignal *, bool force_update = true);
103         /// Signal handler for Route::name_change
104         void notify_property_changed(const PBD::PropertyChange&, Mackie::RouteSignal *);
105         /// Signal handler from Panner::Change
106         void notify_panner_changed(Mackie::RouteSignal *, bool force_update = true);
107         /// Signal handler for new routes added
108         void notify_route_added(ARDOUR::RouteList &);
109         /// Signal handler for Route::active_changed
110         void notify_active_changed(Mackie::RouteSignal *);
111  
112         void notify_remote_id_changed();
113
114         /// rebuild the current bank. Called on route added/removed and
115         /// remote id changed.
116         void refresh_current_bank();
117
118         // global buttons (ie button not part of strips)
119
120   public:
121         // button-related signals
122         void notify_record_state_changed();
123         void notify_transport_state_changed();
124         // mainly to pick up punch-in and punch-out
125         void notify_parameter_changed(std::string const &);
126         void notify_solo_active_changed(bool);
127
128         /// Turn timecode on and beats off, or vice versa, depending
129         /// on state of _timecode_type
130         void update_timecode_beats_led();
131   
132         /// this is called to generate the midi to send in response to a button press.
133         void update_led(Mackie::Button & button, Mackie::LedState);
134   
135         void update_global_button(const std::string & name, Mackie::LedState);
136         void update_global_led(const std::string & name, Mackie::LedState);
137   
138         // transport button handler methods from MackieButtonHandler
139         virtual Mackie::LedState frm_left_press(Mackie::Button &);
140         virtual Mackie::LedState frm_left_release(Mackie::Button &);
141
142         virtual Mackie::LedState frm_right_press(Mackie::Button &);
143         virtual Mackie::LedState frm_right_release(Mackie::Button &);
144
145         virtual Mackie::LedState stop_press(Mackie::Button &);
146         virtual Mackie::LedState stop_release(Mackie::Button &);
147
148         virtual Mackie::LedState play_press(Mackie::Button &);
149         virtual Mackie::LedState play_release(Mackie::Button &);
150
151         virtual Mackie::LedState record_press(Mackie::Button &);
152         virtual Mackie::LedState record_release(Mackie::Button &);
153
154         virtual Mackie::LedState loop_press(Mackie::Button &);
155         virtual Mackie::LedState loop_release(Mackie::Button &);
156
157         virtual Mackie::LedState punch_in_press(Mackie::Button &);
158         virtual Mackie::LedState punch_in_release(Mackie::Button &);
159
160         virtual Mackie::LedState punch_out_press(Mackie::Button &);
161         virtual Mackie::LedState punch_out_release(Mackie::Button &);
162
163         virtual Mackie::LedState home_press(Mackie::Button &);
164         virtual Mackie::LedState home_release(Mackie::Button &);
165
166         virtual Mackie::LedState end_press(Mackie::Button &);
167         virtual Mackie::LedState end_release(Mackie::Button &);
168         
169         virtual Mackie::LedState rewind_press(Mackie::Button & button);
170         virtual Mackie::LedState rewind_release(Mackie::Button & button);
171
172         virtual Mackie::LedState ffwd_press(Mackie::Button & button);
173         virtual Mackie::LedState ffwd_release(Mackie::Button & button);
174
175         // bank switching button handler methods from MackieButtonHandler
176         virtual Mackie::LedState left_press(Mackie::Button &);
177         virtual Mackie::LedState left_release(Mackie::Button &);
178
179         virtual Mackie::LedState right_press(Mackie::Button &);
180         virtual Mackie::LedState right_release(Mackie::Button &);
181
182         virtual Mackie::LedState channel_left_press(Mackie::Button &);
183         virtual Mackie::LedState channel_left_release(Mackie::Button &);
184
185         virtual Mackie::LedState channel_right_press(Mackie::Button &);
186         virtual Mackie::LedState channel_right_release(Mackie::Button &);
187         
188         virtual Mackie::LedState clicking_press(Mackie::Button &);
189         virtual Mackie::LedState clicking_release(Mackie::Button &);
190         
191         virtual Mackie::LedState global_solo_press(Mackie::Button &);
192         virtual Mackie::LedState global_solo_release(Mackie::Button &);
193         
194         // function buttons
195         virtual Mackie::LedState marker_press(Mackie::Button &);
196         virtual Mackie::LedState marker_release(Mackie::Button &);
197
198         virtual Mackie::LedState drop_press(Mackie::Button &);
199         virtual Mackie::LedState drop_release(Mackie::Button &);
200
201         virtual Mackie::LedState save_press(Mackie::Button &);
202         virtual Mackie::LedState save_release(Mackie::Button &);
203
204         virtual Mackie::LedState timecode_beats_press(Mackie::Button &);
205         virtual Mackie::LedState timecode_beats_release(Mackie::Button &);
206
207         // jog wheel states
208         virtual Mackie::LedState zoom_press(Mackie::Button &);
209         virtual Mackie::LedState zoom_release(Mackie::Button &);
210
211         virtual Mackie::LedState scrub_press(Mackie::Button &);
212         virtual Mackie::LedState scrub_release(Mackie::Button &);
213         
214         /// This is the main MCU port, ie not an extender port
215         /// Only for use by JogWheel
216         const Mackie::SurfacePort & mcu_port() const;
217         Mackie::SurfacePort & mcu_port();
218         ARDOUR::Session & get_session() { return *session; }
219  
220   protected:
221         // create instances of MackiePort, depending on what's found in ardour.rc
222         void create_ports();
223   
224         // shut down the surface
225         void close();
226   
227         // create the Surface object, with the correct number
228         // of strips for the currently connected ports and 
229         // hook up the control event notification
230         void initialize_surface();
231   
232         // This sets up the notifications and sets the
233         // controls to the correct values
234         void update_surface();
235         
236         // connects global (not strip) signals from the Session to here
237         // so the surface can be notified of changes from the other UIs.
238         void connect_session_signals();
239         
240         // set all controls to their zero position
241         void zero_all();
242         
243         /**
244            Fetch the set of routes to be considered for control by the
245            surface. Excluding master, hidden and control routes, and inactive routes
246         */
247         typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
248         Sorted get_sorted_routes();
249   
250         // bank switching
251         void switch_banks(int initial);
252         void prev_track();
253         void next_track();
254   
255         // delete all RouteSignal objects connecting Routes to Strips
256         void clear_route_signals();
257         
258         typedef std::vector<Mackie::RouteSignal*> RouteSignals;
259         RouteSignals route_signals;
260         
261         // return which of the ports a particular route_table
262         // index belongs to
263         Mackie::MackiePort & port_for_id(uint32_t index);
264
265         /**
266            Handle a button press for the control and return whether
267            the corresponding light should be on or off.
268         */
269         bool handle_strip_button(Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route>);
270
271         void add_port (MIDI::Port &, MIDI::Port &, int number);
272
273         /**
274            Read session data and send to surface. Includes
275            automation from the currently active routes and
276            timecode displays.
277         */
278         void poll_session_data();
279         
280         // called from poll_automation to figure out which automations need to be sent
281         void update_automation(Mackie::RouteSignal &);
282         
283         // also called from poll_automation to update timecode display
284         void update_timecode_display();
285
286         std::string format_bbt_timecode (ARDOUR::nframes_t now_frame);
287         std::string format_timecode_timecode (ARDOUR::nframes_t now_frame);
288         
289         /**
290            notification that the port is about to start it's init sequence.
291            We must make sure that before this exits, the port is being polled
292            for new data.
293         */
294         void handle_port_init(Mackie::SurfacePort *);
295
296         /// notification from a MackiePort that it's now active
297         void handle_port_active(Mackie::SurfacePort *);
298         
299         /// notification from a MackiePort that it's now inactive
300         void handle_port_inactive(Mackie::SurfacePort *);
301         
302         boost::shared_ptr<ARDOUR::Route> master_route();
303         Mackie::Strip & master_strip();
304
305   private:
306         boost::shared_ptr<Mackie::RouteSignal> master_route_signal;
307         
308         static const char * default_port_name;
309         
310         /// The Midi port(s) connected to the units
311         typedef std::vector<Mackie::MackiePort*> MackiePorts;
312         MackiePorts _ports;
313   
314         /// Sometimes the real port goes away, and we want to contain the breakage
315         Mackie::DummyPort _dummy_port;
316   
317         /// The initial remote_id of the currently switched in bank.
318         uint32_t _current_initial_bank;
319         
320         /// protects the port list
321         Glib::Mutex update_mutex;
322   
323         PBD::ScopedConnectionList session_connections;
324         PBD::ScopedConnectionList port_connections;
325         PBD::ScopedConnectionList route_connections;
326         
327         /// The representation of the physical controls on the surface.
328         Mackie::Surface * _surface;
329         
330         bool _transport_previously_rolling;
331         
332         // timer for two quick marker left presses
333         Mackie::Timer _frm_left_last;
334         
335         Mackie::JogWheel _jog_wheel;
336         
337         // last written timecode string
338         std::string _timecode_last;
339         
340         // Which timecode are we displaying? BBT or Timecode
341         ARDOUR::AnyTime::Type _timecode_type;
342
343         // Bundle to represent our input ports
344         boost::shared_ptr<ARDOUR::Bundle> _input_bundle;
345         // Bundle to represent our output ports
346         boost::shared_ptr<ARDOUR::Bundle> _output_bundle;
347 };
348
349 #endif // ardour_mackie_control_protocol_h