929cca3e2b827c70d0607862837b73a6e5ecf6c9
[ardour.git] / libs / surfaces / tranzport / tranzport_control_protocol.h
1 /*
2   Copyright (C) 2006 Paul Davis 
3   Copyright (C) 2007 Mike Taht
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
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.
14
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21
22 #ifndef ardour_tranzport_control_protocol_h
23 #define ardour_tranzport_control_protocol_h
24
25 #include "tranzport_base.h"
26
27 #include <vector>
28 #include <bitset>
29 #include <sys/time.h>
30 #include <pthread.h>
31
32 #if !HAVE_TRANZPORT_KERNEL_DRIVER
33 #include <usb.h>
34 #endif
35
36 #include <glibmm/thread.h>
37 #include <ardour/types.h>
38
39 #include <control_protocol/control_protocol.h>
40
41 class TranzportControlProtocol : public ARDOUR::ControlProtocol
42 {
43 public:
44         TranzportControlProtocol (ARDOUR::Session&);
45         virtual ~TranzportControlProtocol();
46
47         int set_active (bool yn);
48
49         static bool probe ();
50
51         XMLNode& get_state ();
52         int set_state (const XMLNode&);
53
54 private:
55         static const int VENDORID = 0x165b;
56         static const int PRODUCTID = 0x8101;
57         static const int READ_ENDPOINT  = 0x81;
58         static const int WRITE_ENDPOINT = 0x02;
59         const static int STATUS_OFFLINE  = 0xff;
60         const static int STATUS_ONLINE = 0x01;
61         const static int STATUS_OK = 0x00;
62   
63         const static int LIGHTS = 7;
64         const static int ROWS = 2;
65         const static int COLUMNS = 20;
66         const static uint8_t WheelDirectionThreshold = 0x7f;
67
68         enum LightID {
69                 LightRecord = 0,
70                 LightTrackrec,
71                 LightTrackmute,
72                 LightTracksolo,
73                 LightAnysolo,
74                 LightLoop,
75                 LightPunch
76         };
77
78         enum ButtonID {
79                 ButtonBattery = 0x00004000,
80                 ButtonBacklight = 0x00008000,
81                 ButtonTrackLeft = 0x04000000,
82                 ButtonTrackRight = 0x40000000,
83                 ButtonTrackRec = 0x00040000,
84                 ButtonTrackMute = 0x00400000,
85                 ButtonTrackSolo = 0x00000400,
86                 ButtonUndo = 0x80000000,
87                 ButtonIn = 0x02000000,
88                 ButtonOut = 0x20000000,
89                 ButtonPunch = 0x00800000,
90                 ButtonLoop = 0x00080000,
91                 ButtonPrev = 0x00020000,
92                 ButtonAdd = 0x00200000,
93                 ButtonNext = 0x00000200,
94                 ButtonRewind = 0x01000000,
95                 ButtonFastForward = 0x10000000,
96                 ButtonStop = 0x00010000,
97                 ButtonPlay = 0x00100000,
98                 ButtonRecord = 0x00000100,
99                 ButtonShift = 0x08000000,
100                 ButtonFootswitch = 0x00001000 
101         };
102
103         enum WheelShiftMode {
104                 WheelShiftGain,
105                 WheelShiftPan,
106                 WheelShiftMaster,
107                 WheelShiftMarker
108         };
109                 
110         enum WheelMode {
111                 WheelTimeline,
112                 WheelScrub,
113                 WheelShuttle
114         };
115
116         // FIXME - look at gtk2_ardour for snap settings
117
118         enum WheelIncrement {
119                 WheelIncrSlave,
120                 WheelIncrScreen,
121                 WheelIncrSample,
122                 WheelIncrBeat,
123                 WheelIncrBar,
124                 WheelIncrSecond,
125                 WheelIncrMinute
126         };
127           
128         enum DisplayMode {
129                 DisplayNormal,
130                 DisplayRecording,
131                 DisplayRecordingMeter,
132                 DisplayBigMeter,
133                 DisplayConfig,
134                 DisplayBling,
135                 DisplayBlingMeter
136         };
137
138         enum BlingMode {
139                 BlingOff,
140                 BlingKit,
141                 BlingRotating,
142                 BlingPairs,
143                 BlingRows,
144                 BlingFlashAll,
145                 BlingEnter,
146                 BlingExit
147         };
148         
149         pthread_t       thread;
150 #if HAVE_TRANZPORT_KERNEL_DRIVER
151         int udev;
152 #else
153         usb_dev_handle* udev;
154 #endif
155
156 #if TRANZPORT_THREADS
157         pthread_t       thread_read;
158 #endif
159         int             last_read_error;
160
161         uint32_t        buttonmask;
162         uint32_t        timeout;
163         uint32_t        inflight;
164         uint32_t        current_track_id;
165 #if TRANZPORT_THREADS
166         pthread_t       thread_write;
167 #endif
168         int             last_write_error;
169         uint8_t        _datawheel;
170         uint8_t        _device_status;
171         WheelMode       wheel_mode;
172         WheelShiftMode  wheel_shift_mode;
173         DisplayMode     display_mode;
174         BlingMode       bling_mode;
175         WheelIncrement  wheel_increment;
176
177         ARDOUR::gain_t  gain_fraction;
178
179         Glib::Mutex update_lock;
180
181         std::bitset<ROWS*COLUMNS> screen_invalid;
182         char screen_current[ROWS][COLUMNS];
183         char screen_pending[ROWS][COLUMNS];
184         char screen_flash[ROWS][COLUMNS];
185
186         std::bitset<LIGHTS> lights_invalid;
187         std::bitset<LIGHTS> lights_current;
188         std::bitset<LIGHTS> lights_pending;
189         std::bitset<LIGHTS> lights_flash;
190
191         int32_t       last_notify;
192         char           last_notify_msg[COLUMNS+1]; 
193         uint32_t       last_bars;
194         uint32_t       last_beats;
195         uint32_t       last_ticks;
196
197         bool           last_negative;
198         uint32_t       last_hrs;
199         uint32_t       last_mins;
200         uint32_t       last_secs;
201         uint32_t       last_frames;
202         nframes_t      last_where;
203         ARDOUR::gain_t last_track_gain;
204         uint32_t       last_meter_fill;
205         struct timeval last_wheel_motion;
206         int            last_wheel_dir;
207
208         Glib::Mutex io_lock;
209
210         int open ();
211         int read (uint8_t *buf,uint32_t timeout_override = 0);
212         int write (uint8_t* cmd, uint32_t timeout_override = 0);
213         int write_noretry (uint8_t* cmd, uint32_t timeout_override = 0);
214         int close ();
215         int save_config(char *name = "default");
216         int load_config(char *name = "default");
217         int save(char *name);
218         int load(char *name);
219         void print (int row, int col, const char* text);
220         void print_noretry (int row, int col, const char* text);
221         void notify(const char *msg);
222
223 #if HAVE_TRANZPORT_KERNEL_DRIVER
224         int rtpriority_set(int priority = 3); // we don't need serious rt privs anymore
225 #else
226         int rtpriority_set(int priority = 52);
227 #endif
228         int rtpriority_unset(int priority = 0);
229
230         // I hate changing the api to do either but until I have clean io class what can you do?
231 #if !HAVE_TRANZPORT_KERNEL_DRIVER
232         int open_core (struct usb_device*);
233 #endif
234         static void* _monitor_work (void* arg);
235         void* monitor_work ();
236
237         int process (uint8_t *);
238         int update_state();
239         void invalidate();
240         int flush();
241         // bool isuptodate(); // think on this. It seems futile to update more than 30/sec
242
243         // A screen is a cache of what should be on the lcd
244
245         void screen_init();
246         void screen_validate();
247         void screen_invalidate();
248         int  screen_flush();
249         void screen_clear();
250         // bool screen_isuptodate(); // think on this - 
251         int  screen_show_bling();
252
253         // Commands to write to the lcd 
254
255         int  lcd_init();
256         bool lcd_damage();
257         bool lcd_isdamaged();
258
259         bool lcd_damage(int row, int col = 0, int length = COLUMNS);
260         bool lcd_isdamaged(int row, int col = 0, int length = COLUMNS);
261
262         int  lcd_flush();
263         int  lcd_write(uint8_t* cmd, uint32_t timeout_override = 0); // pedantic alias for write
264         void lcd_fill (uint8_t fill_char);
265         void lcd_clear ();
266         void lcd_print (int row, int col, const char* text);
267         void lcd_print_noretry (int row, int col, const char* text);
268
269         // Commands to write to the lights
270         // FIXME - on some devices lights can have intensity and colors
271
272         void lights_init();
273         void lights_validate();
274         void lights_invalidate();
275         void light_validate(LightID light);
276         void light_invalidate(LightID light);
277         int  lights_flush();
278         int  lights_write(uint8_t* cmd,uint32_t timeout_override = 0); // pedantic alias to write
279
280         // a cache of what should be lit
281
282         void lights_off ();
283         void lights_on ();
284         int  light_set(LightID, bool offon = true);
285         int  light_on (LightID);
286         int  light_off (LightID);
287
288         // some modes for the lights, should probably be renamed
289
290         int  lights_show_normal();
291         int  lights_show_recording();
292         int  lights_show_tempo();
293         int  lights_show_bling();
294
295         void enter_big_meter_mode ();
296         void enter_normal_display_mode ();
297         void enter_config_mode();
298         void enter_recording_mode();
299         void enter_bling_mode();
300
301         void next_marker (); // basicui doesn't give me enough info
302         void prev_marker (); 
303
304         void next_display_mode ();
305         void normal_update ();
306
307         void show_current_track ();
308         void show_track_gain ();
309         void show_transport_time ();
310         void show_bbt (nframes_t where);        
311         void show_smpte (nframes_t where);
312         void show_wheel_mode ();
313         void show_gain ();
314         void show_pan ();
315         void show_meter ();
316         void show_mini_meter ();
317         void show_bling();
318         void show_notify();
319
320         void datawheel ();
321         void scrub ();
322         void scroll ();
323         void shuttle ();
324         void config ();
325
326         void next_wheel_mode ();
327         void next_wheel_shift_mode ();
328
329         void set_current_track (ARDOUR::Route*);
330         void next_track ();
331         void prev_track ();
332         void step_gain_up ();
333         void step_gain_down ();
334         void step_pan_right ();
335         void step_pan_left ();
336
337
338         void button_event_battery_press (bool shifted);
339         void button_event_battery_release (bool shifted);
340         void button_event_backlight_press (bool shifted);
341         void button_event_backlight_release (bool shifted);
342         void button_event_trackleft_press (bool shifted);
343         void button_event_trackleft_release (bool shifted);
344         void button_event_trackright_press (bool shifted);
345         void button_event_trackright_release (bool shifted);
346         void button_event_trackrec_press (bool shifted);
347         void button_event_trackrec_release (bool shifted);
348         void button_event_trackmute_press (bool shifted);
349         void button_event_trackmute_release (bool shifted);
350         void button_event_tracksolo_press (bool shifted);
351         void button_event_tracksolo_release (bool shifted);
352         void button_event_undo_press (bool shifted);
353         void button_event_undo_release (bool shifted);
354         void button_event_in_press (bool shifted);
355         void button_event_in_release (bool shifted);
356         void button_event_out_press (bool shifted);
357         void button_event_out_release (bool shifted);
358         void button_event_punch_press (bool shifted);
359         void button_event_punch_release (bool shifted);
360         void button_event_loop_press (bool shifted);
361         void button_event_loop_release (bool shifted);
362         void button_event_prev_press (bool shifted);
363         void button_event_prev_release (bool shifted);
364         void button_event_add_press (bool shifted);
365         void button_event_add_release (bool shifted);
366         void button_event_next_press (bool shifted);
367         void button_event_next_release (bool shifted);
368         void button_event_rewind_press (bool shifted);
369         void button_event_rewind_release (bool shifted);
370         void button_event_fastforward_press (bool shifted);
371         void button_event_fastforward_release (bool shifted);
372         void button_event_stop_press (bool shifted);
373         void button_event_stop_release (bool shifted);
374         void button_event_play_press (bool shifted);
375         void button_event_play_release (bool shifted);
376         void button_event_record_press (bool shifted);
377         void button_event_record_release (bool shifted);
378         void button_event_footswitch_press(bool shifted);
379         void button_event_footswitch_release (bool shifted);
380
381         // new api - still thinking about it
382         void button_event_mute (bool pressed, bool shifted);
383 };
384
385
386 #endif // ardour_tranzport_control_protocol_h