rework Stateful::set_state() patch to avoid default version argument
[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 #ifndef ardour_mackie_control_protocol_h
19 #define ardour_mackie_control_protocol_h
20
21 #include <vector>
22
23 #include <sys/time.h>
24 #include <pthread.h>
25
26 #include <glibmm/thread.h>
27
28 #include <ardour/types.h>
29 #include <ardour/session.h>
30 #include <midi++/types.h>
31
32 #include <control_protocol/control_protocol.h>
33 #include "midi_byte_array.h"
34 #include "controls.h"
35 #include "dummy_port.h"
36 #include "route_signal.h"
37 #include "mackie_button_handler.h"
38 #include "mackie_port.h"
39 #include "mackie_jog_wheel.h"
40 #include "timer.h"
41
42 namespace MIDI {
43         class Port;
44         class Parser;
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 class MackieControlProtocol
71 : public ARDOUR::ControlProtocol
72 , public Mackie::MackieButtonHandler
73 {
74   public:
75         MackieControlProtocol( ARDOUR::Session & );
76         virtual ~MackieControlProtocol();
77
78         int set_active (bool yn);
79
80         XMLNode& get_state ();
81         int set_state (const XMLNode&, int version);
82   
83         static bool probe();
84         
85         Mackie::Surface & surface();
86
87    // control events
88    void handle_control_event( Mackie::SurfacePort & port, Mackie::Control & control, const Mackie::ControlState & state );
89
90   // strip/route related stuff
91   public:       
92         /// Signal handler for Route::solo
93         void notify_solo_changed( Mackie::RouteSignal * );
94         /// Signal handler for Route::mute
95         void notify_mute_changed( Mackie::RouteSignal * );
96         /// Signal handler for Route::record_enable_changed
97         void notify_record_enable_changed( Mackie::RouteSignal * );
98         /// Signal handler for Route::gain_changed ( from IO )
99         void notify_gain_changed( Mackie::RouteSignal *, bool force_update = true );
100         /// Signal handler for Route::name_change
101         void notify_name_changed( Mackie::RouteSignal * );
102         /// Signal handler from Panner::Change
103         void notify_panner_changed( Mackie::RouteSignal *, bool force_update = true );
104         /// Signal handler for new routes added
105         void notify_route_added( ARDOUR::RouteList & );
106         /// Signal handler for Route::active_changed
107         void notify_active_changed( Mackie::RouteSignal * );
108  
109         void notify_remote_id_changed();
110
111         /// rebuild the current bank. Called on route added/removed and
112    /// remote id changed.
113         void refresh_current_bank();
114
115   // global buttons (ie button not part of strips)
116   public:
117    // button-related signals
118         void notify_record_state_changed();
119    void notify_transport_state_changed();
120    // mainly to pick up punch-in and punch-out
121         void notify_parameter_changed( std::string const & );
122    void notify_solo_active_changed( bool );
123
124         /// Turn smpte on and beats off, or vice versa, depending
125         /// on state of _timecode_type
126         void update_smpte_beats_led();
127   
128         /// this is called to generate the midi to send in response to a button press.
129         void update_led( Mackie::Button & button, Mackie::LedState );
130   
131         void update_global_button( const std::string & name, Mackie::LedState );
132         void update_global_led( const std::string & name, Mackie::LedState );
133   
134    // transport button handler methods from MackieButtonHandler
135         virtual Mackie::LedState frm_left_press( Mackie::Button & );
136         virtual Mackie::LedState frm_left_release( Mackie::Button & );
137
138         virtual Mackie::LedState frm_right_press( Mackie::Button & );
139         virtual Mackie::LedState frm_right_release( Mackie::Button & );
140
141         virtual Mackie::LedState stop_press( Mackie::Button & );
142         virtual Mackie::LedState stop_release( Mackie::Button & );
143
144         virtual Mackie::LedState play_press( Mackie::Button & );
145         virtual Mackie::LedState play_release( Mackie::Button & );
146
147         virtual Mackie::LedState record_press( Mackie::Button & );
148         virtual Mackie::LedState record_release( Mackie::Button & );
149
150         virtual Mackie::LedState loop_press( Mackie::Button & );
151         virtual Mackie::LedState loop_release( Mackie::Button & );
152
153         virtual Mackie::LedState punch_in_press( Mackie::Button & );
154         virtual Mackie::LedState punch_in_release( Mackie::Button & );
155
156         virtual Mackie::LedState punch_out_press( Mackie::Button & );
157         virtual Mackie::LedState punch_out_release( Mackie::Button & );
158
159         virtual Mackie::LedState home_press( Mackie::Button & );
160         virtual Mackie::LedState home_release( Mackie::Button & );
161
162         virtual Mackie::LedState end_press( Mackie::Button & );
163         virtual Mackie::LedState end_release( Mackie::Button & );
164         
165         virtual Mackie::LedState rewind_press( Mackie::Button & button );
166         virtual Mackie::LedState rewind_release( Mackie::Button & button );
167
168         virtual Mackie::LedState ffwd_press( Mackie::Button & button );
169         virtual Mackie::LedState ffwd_release( Mackie::Button & button );
170
171         // bank switching button handler methods from MackieButtonHandler
172         virtual Mackie::LedState left_press( Mackie::Button & );
173         virtual Mackie::LedState left_release( Mackie::Button & );
174
175         virtual Mackie::LedState right_press( Mackie::Button & );
176         virtual Mackie::LedState right_release( Mackie::Button & );
177
178         virtual Mackie::LedState channel_left_press( Mackie::Button & );
179         virtual Mackie::LedState channel_left_release( Mackie::Button & );
180
181         virtual Mackie::LedState channel_right_press( Mackie::Button & );
182         virtual Mackie::LedState channel_right_release( Mackie::Button & );
183         
184         virtual Mackie::LedState clicking_press( Mackie::Button & );
185         virtual Mackie::LedState clicking_release( Mackie::Button & );
186         
187         virtual Mackie::LedState global_solo_press( Mackie::Button & );
188         virtual Mackie::LedState global_solo_release( Mackie::Button & );
189         
190         // function buttons
191         virtual Mackie::LedState marker_press( Mackie::Button & );
192         virtual Mackie::LedState marker_release( Mackie::Button & );
193
194         virtual Mackie::LedState drop_press( Mackie::Button & );
195         virtual Mackie::LedState drop_release( Mackie::Button & );
196
197         virtual Mackie::LedState save_press( Mackie::Button & );
198         virtual Mackie::LedState save_release( Mackie::Button & );
199
200         virtual Mackie::LedState smpte_beats_press( Mackie::Button & );
201         virtual Mackie::LedState smpte_beats_release( Mackie::Button & );
202
203         // jog wheel states
204         virtual Mackie::LedState zoom_press( Mackie::Button & );
205         virtual Mackie::LedState zoom_release( Mackie::Button & );
206
207         virtual Mackie::LedState scrub_press( Mackie::Button & );
208         virtual Mackie::LedState scrub_release( Mackie::Button & );
209         
210    /// This is the main MCU port, ie not an extender port
211         /// Only for use by JogWheel
212         const Mackie::SurfacePort & mcu_port() const;
213         Mackie::SurfacePort & mcu_port();
214         ARDOUR::Session & get_session() { return *session; }
215  
216   protected:
217         // create instances of MackiePort, depending on what's found in ardour.rc
218         void create_ports();
219   
220         // shut down the surface
221         void close();
222   
223         // create the Surface object, with the correct number
224         // of strips for the currently connected ports and 
225         // hook up the control event notification
226         void initialize_surface();
227   
228         // This sets up the notifications and sets the
229    // controls to the correct values
230         void update_surface();
231   
232    // connects global (not strip) signals from the Session to here
233    // so the surface can be notified of changes from the other UIs.
234    void connect_session_signals();
235   
236    // set all controls to their zero position
237         void zero_all();
238         
239         /**
240                 Fetch the set of routes to be considered for control by the
241                 surface. Excluding master, hidden and control routes, and inactive routes
242         */
243         typedef std::vector<boost::shared_ptr<ARDOUR::Route> > Sorted;
244         Sorted get_sorted_routes();
245   
246    // bank switching
247    void switch_banks( int initial );
248    void prev_track();
249    void next_track();
250   
251    // delete all RouteSignal objects connecting Routes to Strips
252    void clear_route_signals();
253         
254         typedef std::vector<Mackie::RouteSignal*> RouteSignals;
255         RouteSignals route_signals;
256         
257    // return which of the ports a particular route_table
258    // index belongs to
259         Mackie::MackiePort & port_for_id( uint32_t index );
260
261         /**
262                 Handle a button press for the control and return whether
263                 the corresponding light should be on or off.
264         */
265         bool handle_strip_button( Mackie::Control &, Mackie::ButtonState, boost::shared_ptr<ARDOUR::Route> );
266
267         /// thread started. Calls monitor_work.
268         static void* _monitor_work (void* arg);
269         
270         /// Polling midi port(s) for incoming messages
271         void* monitor_work ();
272         
273         /// rebuild the set of ports for this surface
274         void update_ports();
275         
276         /// Returns true if there is pending data, false otherwise
277         bool poll_ports();
278         
279         /// Trigger the MIDI::Parser
280         void read_ports();
281
282         void add_port( MIDI::Port &, int number );
283
284         /**
285                 Read session data and send to surface. Includes
286                 automation from the currently active routes and
287                 timecode displays.
288         */
289         void poll_session_data();
290         
291         // called from poll_automation to figure out which automations need to be sent
292         void update_automation( Mackie::RouteSignal & );
293         
294         // also called from poll_automation to update timecode display
295         void update_timecode_display();
296
297         std::string format_bbt_timecode( nframes_t now_frame );
298         std::string format_smpte_timecode( nframes_t now_frame );
299         
300         /**
301                 notification that the port is about to start it's init sequence.
302                 We must make sure that before this exits, the port is being polled
303                 for new data.
304         */
305         void handle_port_init( Mackie::SurfacePort * );
306
307         /// notification from a MackiePort that it's now active
308         void handle_port_active( Mackie::SurfacePort * );
309         
310         /// notification from a MackiePort that it's now inactive
311         void handle_port_inactive( Mackie::SurfacePort * );
312         
313         boost::shared_ptr<ARDOUR::Route> master_route();
314         Mackie::Strip & master_strip();
315
316   private:
317         boost::shared_ptr<Mackie::RouteSignal> master_route_signal;
318   
319    static const char * default_port_name;
320   
321         /// The Midi port(s) connected to the units
322         typedef std::vector<Mackie::MackiePort*> MackiePorts;
323         MackiePorts _ports;
324   
325         /// Sometimes the real port goes away, and we want to contain the breakage
326         Mackie::DummyPort _dummy_port;
327   
328    // the thread that polls the ports for incoming midi data
329         pthread_t thread;
330   
331         /// The initial remote_id of the currently switched in bank.
332    uint32_t _current_initial_bank;
333         
334    /// protects the port list, and polling structures
335         Glib::Mutex update_mutex;
336   
337         /// Protects set_active, and allows waiting on the poll thread
338         Glib::Cond update_cond;
339
340         // because sigc::trackable doesn't seem to be working
341         std::vector<sigc::connection> _connections;
342         std::back_insert_iterator<std::vector<sigc::connection> > connections_back;
343
344    /// The representation of the physical controls on the surface.
345         Mackie::Surface * _surface;
346         
347         /// If a port is opened or closed, this will be
348         /// true until the port configuration is updated;
349         bool _ports_changed;
350
351         bool _polling;
352         struct pollfd * pfd;
353         int nfds;
354         
355         bool _transport_previously_rolling;
356         
357         // timer for two quick marker left presses
358         Mackie::Timer _frm_left_last;
359         
360         Mackie::JogWheel _jog_wheel;
361         
362         // Timer for controlling midi bandwidth used by automation polls
363         Mackie::Timer _automation_last;
364         
365         // last written timecode string
366         std::string _timecode_last;
367         
368         // Which timecode are we displaying? BBT or SMPTE
369         ARDOUR::AnyTime::Type _timecode_type;
370 };
371
372 #endif // ardour_mackie_control_protocol_h