OSC: Changed gainVCA to gainfader as VCA is already used.
[ardour.git] / libs / surfaces / tranzport / tranzport_control_protocol.h
index 44045f683484df88a3bb867a9445a59b6d99e808..32d88aaf5e9a431b75f424ea38bf92f24367f6ca 100644 (file)
@@ -1,21 +1,46 @@
+/*
+  Copyright (C) 2006 Paul Davis
+  Copyright (C) 2007 Mike Taht
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+
 #ifndef ardour_tranzport_control_protocol_h
 #define ardour_tranzport_control_protocol_h
 
-#include <vector>
+#include "tranzport_base.h"
 
+#include <vector>
+#include <bitset>
 #include <sys/time.h>
 #include <pthread.h>
-#include <usb.h>
 
-#include <glibmm/thread.h>
+#if !HAVE_TRANZPORT_KERNEL_DRIVER
+#include <usb.h>
+#endif
 
-#include <ardour/types.h>
+#include <glibmm/threads.h>
+#include "ardour/types.h"
 
-#include "control_protocol.h"
+#include "control_protocol/control_protocol.h"
 
 class TranzportControlProtocol : public ARDOUR::ControlProtocol
 {
-  public:
+public:
        TranzportControlProtocol (ARDOUR::Session&);
        virtual ~TranzportControlProtocol();
 
@@ -23,14 +48,22 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
 
        static bool probe ();
 
-  private:
+       XMLNode& get_state ();
+       int set_state (const XMLNode&);
+
+private:
        static const int VENDORID = 0x165b;
        static const int PRODUCTID = 0x8101;
        static const int READ_ENDPOINT  = 0x81;
        static const int WRITE_ENDPOINT = 0x02;
        const static int STATUS_OFFLINE  = 0xff;
        const static int STATUS_ONLINE = 0x01;
-       const static uint8_t WheelDirectionThreshold = 0x3f;
+       const static int STATUS_OK = 0x00;
+
+        const static int LIGHTS = 7;
+        const static int ROWS = 2;
+        const static int COLUMNS = 20;
+       const static uint8_t WheelDirectionThreshold = 0x7f;
 
        enum LightID {
                LightRecord = 0,
@@ -63,51 +96,104 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
                ButtonStop = 0x00010000,
                ButtonPlay = 0x00100000,
                ButtonRecord = 0x00000100,
-               ButtonShift = 0x08000000
+               ButtonShift = 0x08000000,
+               ButtonFootswitch = 0x00001000
        };
 
        enum WheelShiftMode {
                WheelShiftGain,
                WheelShiftPan,
-               WheelShiftMaster
+               WheelShiftMaster,
+               WheelShiftMarker
        };
-               
+
        enum WheelMode {
                WheelTimeline,
                WheelScrub,
                WheelShuttle
        };
 
+       // FIXME - look at gtk2_ardour for snap settings
+
+       enum WheelIncrement {
+               WheelIncrSlave,
+               WheelIncrScreen,
+               WheelIncrSample,
+               WheelIncrBeat,
+               WheelIncrBar,
+               WheelIncrSecond,
+               WheelIncrMinute
+       };
+
        enum DisplayMode {
                DisplayNormal,
-               DisplayBigMeter
+               DisplayRecording,
+               DisplayRecordingMeter,
+               DisplayBigMeter,
+               DisplayConfig,
+               DisplayBling,
+               DisplayBlingMeter
+       };
+
+       enum BlingMode {
+               BlingOff,
+               BlingKit,
+               BlingRotating,
+               BlingPairs,
+               BlingRows,
+               BlingFlashAll,
+               BlingEnter,
+               BlingExit
        };
-       
+
        pthread_t       thread;
+#if HAVE_TRANZPORT_KERNEL_DRIVER
+       int udev;
+#else
+       usb_dev_handle* udev;
+#endif
+
+       int             last_read_error;
+
        uint32_t        buttonmask;
        uint32_t        timeout;
+       uint32_t        inflight;
+       uint32_t        current_track_id;
+       int             last_write_error;
        uint8_t        _datawheel;
        uint8_t        _device_status;
-       usb_dev_handle* udev;
-
-       uint32_t        current_track_id;
        WheelMode       wheel_mode;
        WheelShiftMode  wheel_shift_mode;
        DisplayMode     display_mode;
+       BlingMode       bling_mode;
+       WheelIncrement  wheel_increment;
+
        ARDOUR::gain_t  gain_fraction;
 
-       Glib::Mutex update_lock;
-       char current_screen[2][20];
-       char pending_screen[2][20];
-       bool lights[7];
-       bool pending_lights[7];
+        Glib::Threads::Mutex update_lock;
+
+        std::bitset<ROWS*COLUMNS> screen_invalid;
+       char screen_current[ROWS][COLUMNS];
+       char screen_pending[ROWS][COLUMNS];
+       char screen_flash[ROWS][COLUMNS];
+
+        std::bitset<LIGHTS> lights_invalid;
+        std::bitset<LIGHTS> lights_current;
+        std::bitset<LIGHTS> lights_pending;
+        std::bitset<LIGHTS> lights_flash;
+
+       int32_t       last_notify;
+       char           last_notify_msg[COLUMNS+1];
+       uint32_t       last_bars;
+       uint32_t       last_beats;
+       uint32_t       last_ticks;
 
        bool           last_negative;
        uint32_t       last_hrs;
        uint32_t       last_mins;
        uint32_t       last_secs;
        uint32_t       last_frames;
-       jack_nframes_t last_where;
+       framepos_t     last_where;
        ARDOUR::gain_t last_track_gain;
        uint32_t       last_meter_fill;
        struct timeval last_wheel_motion;
@@ -116,37 +202,120 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        Glib::Mutex io_lock;
 
        int open ();
-       int read (uint32_t timeout_override = 0);
+       int read (uint8_t *buf,uint32_t timeout_override = 0);
        int write (uint8_t* cmd, uint32_t timeout_override = 0);
+       int write_noretry (uint8_t* cmd, uint32_t timeout_override = 0);
        int close ();
-
+       int save_config(char *name = "default");
+       int load_config(char *name = "default");
+       int save(char *name);
+       int load(char *name);
+        void print (int row, int col, const char* text);
+       void print_noretry (int row, int col, const char* text);
+       void notify(const char *msg);
+
+#if HAVE_TRANZPORT_KERNEL_DRIVER
+       int rtpriority_set(int priority = 3); // we don't need serious rt privs anymore
+#else
+       int rtpriority_set(int priority = 52);
+#endif
+       int rtpriority_unset(int priority = 0);
+
+       // I hate changing the api to do either but until I have clean io class what can you do?
+#if !HAVE_TRANZPORT_KERNEL_DRIVER
        int open_core (struct usb_device*);
+#endif
+       static void* _monitor_work (void* arg);
+       void* monitor_work ();
+
+       int process (uint8_t *);
+       int update_state();
+       void invalidate();
+       int flush();
+       // bool isuptodate(); // think on this. It seems futile to update more than 30/sec
+
+       // A screen is a cache of what should be on the lcd
+
+       void screen_init();
+       void screen_validate();
+       void screen_invalidate();
+       int  screen_flush();
+       void screen_clear();
+       // bool screen_isuptodate(); // think on this -
+       int  screen_show_bling();
+
+       // Commands to write to the lcd
 
+       int  lcd_init();
+        bool lcd_damage();
+       bool lcd_isdamaged();
+
+        bool lcd_damage(int row, int col = 0, int length = COLUMNS);
+       bool lcd_isdamaged(int row, int col = 0, int length = COLUMNS);
+
+       int  lcd_flush();
+       int  lcd_write(uint8_t* cmd, uint32_t timeout_override = 0); // pedantic alias for write
+       void lcd_fill (uint8_t fill_char);
        void lcd_clear ();
-       void print (int row, int col, const char* text);
+       void lcd_print (int row, int col, const char* text);
+       void lcd_print_noretry (int row, int col, const char* text);
+
+       // Commands to write to the lights
+       // FIXME - on some devices lights can have intensity and colors
+
+       void lights_init();
+       void lights_validate();
+       void lights_invalidate();
+       void light_validate(LightID light);
+       void light_invalidate(LightID light);
+       int  lights_flush();
+       int  lights_write(uint8_t* cmd,uint32_t timeout_override = 0); // pedantic alias to write
+
+       // a cache of what should be lit
+
+       void lights_off ();
+       void lights_on ();
+       int  light_set(LightID, bool offon = true);
        int  light_on (LightID);
        int  light_off (LightID);
-       void lights_off ();
+
+       // some modes for the lights, should probably be renamed
+
+       int  lights_show_normal();
+       int  lights_show_recording();
+       int  lights_show_tempo();
+       int  lights_show_bling();
 
        void enter_big_meter_mode ();
        void enter_normal_display_mode ();
+       void enter_config_mode();
+       void enter_recording_mode();
+       void enter_bling_mode();
 
-       void next_display_mode ();
+       void next_marker (); // basicui doesn't give me enough info
+       void prev_marker ();
 
+       void next_display_mode ();
        void normal_update ();
 
        void show_current_track ();
        void show_track_gain ();
        void show_transport_time ();
+       void show_bbt (framepos_t where);
+       void show_timecode (framepos_t where);
        void show_wheel_mode ();
        void show_gain ();
        void show_pan ();
        void show_meter ();
+       void show_mini_meter ();
+       void show_bling();
+       void show_notify();
 
        void datawheel ();
        void scrub ();
        void scroll ();
        void shuttle ();
+       void config ();
 
        void next_wheel_mode ();
        void next_wheel_shift_mode ();
@@ -159,8 +328,6 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        void step_pan_right ();
        void step_pan_left ();
 
-       static void* _monitor_work (void* arg);
-       void* monitor_work ();
 
        void button_event_battery_press (bool shifted);
        void button_event_battery_release (bool shifted);
@@ -202,9 +369,11 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
        void button_event_play_release (bool shifted);
        void button_event_record_press (bool shifted);
        void button_event_record_release (bool shifted);
+       void button_event_footswitch_press(bool shifted);
+       void button_event_footswitch_release (bool shifted);
 
-       int process (uint8_t *);
-       int update_state();
+       // new api - still thinking about it
+       void button_event_mute (bool pressed, bool shifted);
 };