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/threads.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 int last_read_error; 157 158 uint32_t buttonmask; 159 uint32_t timeout; 160 uint32_t inflight; 161 uint32_t current_track_id; 162 int last_write_error; 163 uint8_t _datawheel; 164 uint8_t _device_status; 165 WheelMode wheel_mode; 166 WheelShiftMode wheel_shift_mode; 167 DisplayMode display_mode; 168 BlingMode bling_mode; 169 WheelIncrement wheel_increment; 170 171 ARDOUR::gain_t gain_fraction; 172 173 Glib::Threads::Mutex update_lock; 174 175 std::bitset<ROWS*COLUMNS> screen_invalid; 176 char screen_current[ROWS][COLUMNS]; 177 char screen_pending[ROWS][COLUMNS]; 178 char screen_flash[ROWS][COLUMNS]; 179 180 std::bitset<LIGHTS> lights_invalid; 181 std::bitset<LIGHTS> lights_current; 182 std::bitset<LIGHTS> lights_pending; 183 std::bitset<LIGHTS> lights_flash; 184 185 int32_t last_notify; 186 char last_notify_msg[COLUMNS+1]; 187 uint32_t last_bars; 188 uint32_t last_beats; 189 uint32_t last_ticks; 190 191 bool last_negative; 192 uint32_t last_hrs; 193 uint32_t last_mins; 194 uint32_t last_secs; 195 uint32_t last_samples; 196 samplepos_t last_where; 197 ARDOUR::gain_t last_track_gain; 198 uint32_t last_meter_fill; 199 struct timeval last_wheel_motion; 200 int last_wheel_dir; 201 202 Glib::Mutex io_lock; 203 204 int open (); 205 int read (uint8_t *buf,uint32_t timeout_override = 0); 206 int write (uint8_t* cmd, uint32_t timeout_override = 0); 207 int write_noretry (uint8_t* cmd, uint32_t timeout_override = 0); 208 int close (); 209 int save_config(char *name = "default"); 210 int load_config(char *name = "default"); 211 int save(char *name); 212 int load(char *name); 213 void print (int row, int col, const char* text); 214 void print_noretry (int row, int col, const char* text); 215 void notify(const char *msg); 216 217 #if HAVE_TRANZPORT_KERNEL_DRIVER 218 int rtpriority_set(int priority = 3); // we don't need serious rt privs anymore 219 #else 220 int rtpriority_set(int priority = 52); 221 #endif 222 int rtpriority_unset(int priority = 0); 223 224 // I hate changing the api to do either but until I have clean io class what can you do? 225 #if !HAVE_TRANZPORT_KERNEL_DRIVER 226 int open_core (struct usb_device*); 227 #endif 228 static void* _monitor_work (void* arg); 229 void* monitor_work (); 230 231 int process (uint8_t *); 232 int update_state(); 233 void invalidate(); 234 int flush(); 235 // bool isuptodate(); // think on this. It seems futile to update more than 30/sec 236 237 // A screen is a cache of what should be on the lcd 238 239 void screen_init(); 240 void screen_validate(); 241 void screen_invalidate(); 242 int screen_flush(); 243 void screen_clear(); 244 // bool screen_isuptodate(); // think on this - 245 int screen_show_bling(); 246 247 // Commands to write to the lcd 248 249 int lcd_init(); 250 bool lcd_damage(); 251 bool lcd_isdamaged(); 252 253 bool lcd_damage(int row, int col = 0, int length = COLUMNS); 254 bool lcd_isdamaged(int row, int col = 0, int length = COLUMNS); 255 256 int lcd_flush(); 257 int lcd_write(uint8_t* cmd, uint32_t timeout_override = 0); // pedantic alias for write 258 void lcd_fill (uint8_t fill_char); 259 void lcd_clear (); 260 void lcd_print (int row, int col, const char* text); 261 void lcd_print_noretry (int row, int col, const char* text); 262 263 // Commands to write to the lights 264 // FIXME - on some devices lights can have intensity and colors 265 266 void lights_init(); 267 void lights_validate(); 268 void lights_invalidate(); 269 void light_validate(LightID light); 270 void light_invalidate(LightID light); 271 int lights_flush(); 272 int lights_write(uint8_t* cmd,uint32_t timeout_override = 0); // pedantic alias to write 273 274 // a cache of what should be lit 275 276 void lights_off (); 277 void lights_on (); 278 int light_set(LightID, bool offon = true); 279 int light_on (LightID); 280 int light_off (LightID); 281 282 // some modes for the lights, should probably be renamed 283 284 int lights_show_normal(); 285 int lights_show_recording(); 286 int lights_show_tempo(); 287 int lights_show_bling(); 288 289 void enter_big_meter_mode (); 290 void enter_normal_display_mode (); 291 void enter_config_mode(); 292 void enter_recording_mode(); 293 void enter_bling_mode(); 294 295 void next_marker (); // basicui doesn't give me enough info 296 void prev_marker (); 297 298 void next_display_mode (); 299 void normal_update (); 300 301 void show_current_track (); 302 void show_track_gain (); 303 void show_transport_time (); 304 void show_bbt (samplepos_t where); 305 void show_timecode (samplepos_t where); 306 void show_wheel_mode (); 307 void show_gain (); 308 void show_pan (); 309 void show_meter (); 310 void show_mini_meter (); 311 void show_bling(); 312 void show_notify(); 313 314 void datawheel (); 315 void scrub (); 316 void scroll (); 317 void shuttle (); 318 void config (); 319 320 void next_wheel_mode (); 321 void next_wheel_shift_mode (); 322 323 void set_current_track (ARDOUR::Route*); 324 void next_track (); 325 void prev_track (); 326 void step_gain_up (); 327 void step_gain_down (); 328 void step_pan_right (); 329 void step_pan_left (); 330 331 332 void button_event_battery_press (bool shifted); 333 void button_event_battery_release (bool shifted); 334 void button_event_backlight_press (bool shifted); 335 void button_event_backlight_release (bool shifted); 336 void button_event_trackleft_press (bool shifted); 337 void button_event_trackleft_release (bool shifted); 338 void button_event_trackright_press (bool shifted); 339 void button_event_trackright_release (bool shifted); 340 void button_event_trackrec_press (bool shifted); 341 void button_event_trackrec_release (bool shifted); 342 void button_event_trackmute_press (bool shifted); 343 void button_event_trackmute_release (bool shifted); 344 void button_event_tracksolo_press (bool shifted); 345 void button_event_tracksolo_release (bool shifted); 346 void button_event_undo_press (bool shifted); 347 void button_event_undo_release (bool shifted); 348 void button_event_in_press (bool shifted); 349 void button_event_in_release (bool shifted); 350 void button_event_out_press (bool shifted); 351 void button_event_out_release (bool shifted); 352 void button_event_punch_press (bool shifted); 353 void button_event_punch_release (bool shifted); 354 void button_event_loop_press (bool shifted); 355 void button_event_loop_release (bool shifted); 356 void button_event_prev_press (bool shifted); 357 void button_event_prev_release (bool shifted); 358 void button_event_add_press (bool shifted); 359 void button_event_add_release (bool shifted); 360 void button_event_next_press (bool shifted); 361 void button_event_next_release (bool shifted); 362 void button_event_rewind_press (bool shifted); 363 void button_event_rewind_release (bool shifted); 364 void button_event_fastforward_press (bool shifted); 365 void button_event_fastforward_release (bool shifted); 366 void button_event_stop_press (bool shifted); 367 void button_event_stop_release (bool shifted); 368 void button_event_play_press (bool shifted); 369 void button_event_play_release (bool shifted); 370 void button_event_record_press (bool shifted); 371 void button_event_record_release (bool shifted); 372 void button_event_footswitch_press(bool shifted); 373 void button_event_footswitch_release (bool shifted); 374 375 // new api - still thinking about it 376 void button_event_mute (bool pressed, bool shifted); 377 }; 378 379 380 #endif // ardour_tranzport_control_protocol_h 381