diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-04-04 03:26:08 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-04-04 03:26:08 +0000 |
commit | f7c82c69113419a8db083f0095044af5ad4c872c (patch) | |
tree | 158067acc6c957b2f973802c089878812134b2b0 | |
parent | af5815e79bcd2a17edbdf5d45f1c7df02af546d8 (diff) |
a) start at creating ControlProtocol objects
b) basic support for Frontier Design Tranzport
c) probably broke some aspect of existing generic MIDI feedback
git-svn-id: svn://localhost/trunk/ardour2@441 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | SConstruct | 2 | ||||
-rw-r--r-- | ardour.rc.in | 1 | ||||
-rw-r--r-- | gtk2_ardour/SConscript | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 8 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/audio_time_axis.cc | 16 | ||||
-rw-r--r-- | gtk2_ardour/audio_time_axis.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 50 | ||||
-rw-r--r-- | libs/ardour/SConscript | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration_vars.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/control_protocol.h | 45 | ||||
-rw-r--r-- | libs/ardour/ardour/generic_midi_control_protocol.h | 31 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 36 | ||||
-rw-r--r-- | libs/ardour/ardour/tranzport_control_protocol.h | 142 | ||||
-rw-r--r-- | libs/ardour/generic_midi_control_protocol.cc | 54 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 6 | ||||
-rw-r--r-- | libs/ardour/session.cc | 18 | ||||
-rw-r--r-- | libs/ardour/session_control.cc | 30 | ||||
-rw-r--r-- | libs/ardour/session_feedback.cc | 86 | ||||
-rw-r--r-- | libs/ardour/session_midi.cc | 68 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 6 | ||||
-rw-r--r-- | libs/ardour/tranzport_control_protocol.cc | 718 |
22 files changed, 1181 insertions, 149 deletions
diff --git a/SConstruct b/SConstruct index aab1b830b5..0806ac4d26 100644 --- a/SConstruct +++ b/SConstruct @@ -389,6 +389,8 @@ libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomeca libraries['glade2'] = LibraryInfo() libraries['glade2'].ParseConfig ('pkg-config --cflags --libs libglade-2.0') +libraries['usb'] = LibraryInfo (LIBS='usb') + #libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas') libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour') diff --git a/ardour.rc.in b/ardour.rc.in index 55948d4f74..96e0fe0a5b 100644 --- a/ardour.rc.in +++ b/ardour.rc.in @@ -26,6 +26,7 @@ <Option name="auditioner-right-out" value="%JACK_INPUT%2"/> <Option name="quieten-at-speed" value="1.000000"/> <Option name="use-vst" value="yes"/> + <Option name="use-tranzport" value="yes"/> </Config> <extra> <Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/> diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 38cac52b40..0ca9def5fe 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -24,6 +24,7 @@ gtkardour.Append(POTFILE=domain + '.pot') gtkardour.Merge ([ libraries['ardour'], + libraries['usb'], libraries['gtkmm2ext'], # libraries['flowcanvas'], libraries['midi++2'], diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 2b7b87f93b..79c81992dc 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1261,14 +1261,6 @@ ARDOUR_UI::map_transport_state () } void -ARDOUR_UI::send_all_midi_feedback () -{ - if (session) { - session->send_all_midi_feedback(); - } -} - -void ARDOUR_UI::allow_local_only () { diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 9c1ae4c45f..e658aa23e9 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -286,8 +286,6 @@ ARDOUR_UI::install_actions () act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Time\nmaster"), mem_fun(*this, &ARDOUR_UI::toggle_time_master)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (common_actions, X_("SendAllMidiFeedback"), _("Send All Midi Feedback"), mem_fun(*this, &ARDOUR_UI::send_all_midi_feedback)); - ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (common_actions, X_("ToggleRecordEnableTrack1"), _("Toggle Record Enable Track1"), bind (mem_fun(*this, &ARDOUR_UI::toggle_record_enable), 0U)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (common_actions, X_("ToggleRecordEnableTrack2"), _("Toggle Record Enable Track2"), bind (mem_fun(*this, &ARDOUR_UI::toggle_record_enable), 1U)); diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index b4a5413d04..6bb6fc45ce 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -141,6 +141,15 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt _route.panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans)); + solo_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + mute_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + playlist_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + automation_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + size_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + visual_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + hide_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); + solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false); solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false); mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false); @@ -1960,3 +1969,10 @@ AudioTimeAxisView::color_handler (ColorID id, uint32_t val) break; } } + +bool +AudioTimeAxisView::select_me (GdkEventButton* ev) +{ + editor.get_selection().add (this); + return false; +} diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h index 0e2eab66c9..d1fbde3e9c 100644 --- a/gtk2_ardour/audio_time_axis.h +++ b/gtk2_ardour/audio_time_axis.h @@ -315,6 +315,7 @@ class AudioTimeAxisView : public RouteUI, public TimeAxisView void map_frozen (); void color_handler (ColorID, uint32_t); + bool select_me (GdkEventButton*); }; #endif /* __ardour_trackview_h__ */ diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index f78ecbbcbe..03ea5ac456 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -1394,10 +1394,6 @@ Editor::set_selection_from_loop() void Editor::set_selection_from_range (Location& loc) { - if (clicked_trackview == 0) { - return; - } - begin_reversible_command (_("set selection from range")); selection->set (0, loc.start(), loc.end()); commit_reversible_command (); @@ -1408,13 +1404,8 @@ Editor::set_selection_from_range (Location& loc) void Editor::select_all_selectables_using_time_selection () { - list<Selectable *> touched; - if (clicked_trackview == 0) { - return; - } - if (selection->time.empty()) { return; } @@ -1432,10 +1423,10 @@ Editor::select_all_selectables_using_time_selection () } (*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched); } + begin_reversible_command (_("select all from range")); selection->set (touched); commit_reversible_command (); - } @@ -1491,18 +1482,19 @@ Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after) list<Selectable *> touched; if (after) { - begin_reversible_command (_("select all after cursor")); - start = cursor->current_frame ; - end = session->current_end_frame(); + begin_reversible_command (_("select all after cursor")); + start = cursor->current_frame ; + end = session->current_end_frame(); } else { - if (cursor->current_frame > 0) { - begin_reversible_command (_("select all before cursor")); - start = 0; - end = cursor->current_frame - 1; - } else { - return; - } + if (cursor->current_frame > 0) { + begin_reversible_command (_("select all before cursor")); + start = 0; + end = cursor->current_frame - 1; + } else { + return; + } } + for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { if ((*iter)->hidden()) { continue; @@ -1520,19 +1512,21 @@ Editor::select_all_selectables_between_cursors (Cursor *cursor, Cursor *other_cu jack_nframes_t end; list<Selectable *> touched; bool other_cursor_is_first = cursor->current_frame > other_cursor->current_frame; + if (cursor->current_frame == other_cursor->current_frame) { - return; + return; } - begin_reversible_command (_("select all between cursors")); - if ( other_cursor_is_first) { - start = other_cursor->current_frame; - end = cursor->current_frame - 1; + begin_reversible_command (_("select all between cursors")); + if (other_cursor_is_first) { + start = other_cursor->current_frame; + end = cursor->current_frame - 1; + } else { - start = cursor->current_frame; - end = other_cursor->current_frame - 1; + start = cursor->current_frame; + end = other_cursor->current_frame - 1; } - + for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { if ((*iter)->hidden()) { continue; diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index dd9de55929..8bf62b9c01 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -31,6 +31,7 @@ automation.cc automation_event.cc configuration.cc connection.cc +control_protocol.cc crossfade.cc curve.cc cycle_timer.cc @@ -41,6 +42,7 @@ externalsource.cc filesource.cc gain.cc gdither.cc +generic_midi_control_protocol.cc globals.cc import.cc insert.cc @@ -67,6 +69,7 @@ send.cc session.cc session_butler.cc session_click.cc +session_control.cc session_events.cc session_export.cc session_feedback.cc @@ -82,6 +85,7 @@ source.cc state_manager.cc stateful.cc tempo.cc +tranzport_control_protocol.cc utils.cc version.cc mix.cc @@ -178,7 +182,7 @@ ardour.Merge ([ libraries['sigc2'], libraries['pbd3'], libraries['soundtouch'], - libraries['midi++2'] + libraries['midi++2'], ]) diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 7d3a9db8b8..d54264c1c0 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -33,11 +33,12 @@ CONFIG_VARIABLE(bool, timecode_source_is_synced, "timecode-source-is-synced", tr CONFIG_VARIABLE(bool, latched_record_enable, "latched-record-enable", false) CONFIG_VARIABLE(bool, use_vst, "use-vst", true) CONFIG_VARIABLE(bool, quieten_at_speed, "quieten-at-speed", true) -CONFIG_VARIABLE(uint32_t, midi_feedback_interval_ms, "midi-feedback-interval-ms", 100) +CONFIG_VARIABLE(uint32_t, feedback_interval_ms, "feedback-interval-ms", 100) CONFIG_VARIABLE(uint32_t, disk_choice_space_threshold, "disk-choice-space-threshold", 57600000) CONFIG_VARIABLE(uint32_t, destructive_xfade_msecs, "destructive-xfade-msecs", 2) CONFIG_VARIABLE(SampleFormat, native_file_data_format, "native-file-data-format", ARDOUR::FormatFloat) CONFIG_VARIABLE(HeaderFormat, native_file_header_format, "native-file-header-format", ARDOUR::WAVE) +CONFIG_VARIABLE(bool, use_tranzport, "use-tranzport", false) /* these variables have custom set() methods */ diff --git a/libs/ardour/ardour/control_protocol.h b/libs/ardour/ardour/control_protocol.h new file mode 100644 index 0000000000..c0869fad9a --- /dev/null +++ b/libs/ardour/ardour/control_protocol.h @@ -0,0 +1,45 @@ +#ifndef ardour_control_protocols_h +#define ardour_control_protocols_h + +#include <string> +#include <list> +#include <sigc++/sigc++.h> + +namespace ARDOUR { + +class Route; +class Session; + +class ControlProtocol : sigc::trackable { + public: + ControlProtocol (Session&, std::string name); + virtual ~ControlProtocol(); + + virtual int init () { return 0; } + virtual bool active() const = 0; + + enum SendWhat { + SendRoute, + SendGlobal + }; + + std::string name() const { return _name; } + + void set_send (SendWhat); + + bool send() const { return _send != 0; } + bool send_route_feedback () const { return _send & SendRoute; } + bool send_global_feedback () const { return _send & SendGlobal; } + + virtual void send_route_feedback (std::list<Route*>&) {} + virtual void send_global_feedback () {} + + protected: + ARDOUR::Session& session; + SendWhat _send; + std::string _name; +}; + +} + +#endif // ardour_control_protocols_h diff --git a/libs/ardour/ardour/generic_midi_control_protocol.h b/libs/ardour/ardour/generic_midi_control_protocol.h new file mode 100644 index 0000000000..75b514f016 --- /dev/null +++ b/libs/ardour/ardour/generic_midi_control_protocol.h @@ -0,0 +1,31 @@ +#ifndef ardour_generic_midi_control_protocol_h +#define ardour_generic_midi_control_protocol_h + +#include <ardour/control_protocol.h> + +namespace MIDI { + class Port; +} + +namespace ARDOUR { + +class GenericMidiControlProtocol : public ControlProtocol { + public: + GenericMidiControlProtocol (Session&); + virtual ~GenericMidiControlProtocol(); + + bool active() const; + + void set_port (MIDI::Port*); + MIDI::Port* port () const { return _port; } + + void send_route_feedback (std::list<Route*>&); + + private: + void route_feedback (ARDOUR::Route&, bool); + MIDI::Port* _port; +}; + +} + +#endif // ardour_generic_midi_control_protocol_h diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 1e25c5f38b..1f6f464d24 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -22,12 +22,7 @@ #define __ardour_session_h__ #include <string> -#if __GNUC__ >= 3 -#include <ext/slist> -using __gnu_cxx::slist; -#else -#include <slist.h> -#endif +#include <list> #include <map> #include <vector> #include <set> @@ -84,6 +79,8 @@ class AudioRegion; class Region; class Playlist; class VSTPlugin; +class ControlProtocol; +class GenericMidiControlProtocol; struct AudioExportSpecification; struct RouteGroup; @@ -283,7 +280,7 @@ class Session : public sigc::trackable, public Stateful void foreach_diskstream (void (DiskStream::*func)(void)); template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&)); - typedef slist<Route *> RouteList; + typedef list<Route *> RouteList; RouteList get_routes() const { RWLockMonitor rlock (route_lock, false, __LINE__, __FILE__); @@ -303,6 +300,7 @@ class Session : public sigc::trackable, public Stateful template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg); Route *route_by_name (string); + Route *route_by_remote_id (uint32_t id); bool route_name_unique (string) const; @@ -407,7 +405,9 @@ class Session : public sigc::trackable, public Stateful CrossfadingModel, SeamlessLoop, MidiFeedback, - MidiControl + MidiControl, + TranzportControl, + Feedback }; sigc::signal<void,ControlType> ControlChanged; @@ -428,6 +428,7 @@ class Session : public sigc::trackable, public Stateful void set_do_not_record_plugins (bool yn); void set_crossfades_active (bool yn); void set_seamless_loop (bool yn); + void set_feedback (bool yn); bool get_auto_play () const { return auto_play; } bool get_auto_input () const { return auto_input; } @@ -444,6 +445,8 @@ class Session : public sigc::trackable, public Stateful bool get_midi_control () const; bool get_do_not_record_plugins () const { return do_not_record_plugins; } bool get_crossfades_active () const { return crossfades_active; } + bool get_feedback() const; + bool get_tranzport_control() const; bool get_input_auto_connect () const; AutoConnectOption get_output_auto_connect () const { return output_auto_connect; } @@ -815,7 +818,6 @@ class Session : public sigc::trackable, public Stateful bool get_trace_midi_output(MIDI::Port *port = 0); void send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes); - void send_all_midi_feedback (); void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size); @@ -1133,9 +1135,9 @@ class Session : public sigc::trackable, public Stateful bool send_mtc; bool send_mmc; bool mmc_control; - bool midi_feedback; bool midi_control; - + bool midi_feedback; + RingBuffer<Event*> pending_events; void hookup_io (); @@ -1598,9 +1600,9 @@ class Session : public sigc::trackable, public Stateful /* INSERT AND SEND MANAGEMENT */ - slist<PortInsert *> _port_inserts; - slist<PluginInsert *> _plugin_inserts; - slist<Send *> _sends; + list<PortInsert *> _port_inserts; + list<PluginInsert *> _plugin_inserts; + list<Send *> _sends; uint32_t send_cnt; uint32_t insert_cnt; @@ -1768,6 +1770,12 @@ class Session : public sigc::trackable, public Stateful LayerModel layer_model; CrossfadeModel xfade_model; + + /* control protocols */ + + vector<ControlProtocol*> control_protocols; + GenericMidiControlProtocol* generic_midi_control_protocol; + void initialize_control (); }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/tranzport_control_protocol.h b/libs/ardour/ardour/tranzport_control_protocol.h new file mode 100644 index 0000000000..448d803c36 --- /dev/null +++ b/libs/ardour/ardour/tranzport_control_protocol.h @@ -0,0 +1,142 @@ +#ifndef ardour_tranzport_control_protocol_h +#define ardour_tranzport_control_protocol_h + +#include <pthread.h> +#include <usb.h> +#include <ardour/control_protocol.h> +#include <ardour/types.h> + +namespace ARDOUR { + +class TranzportControlProtocol : public ControlProtocol { + public: + TranzportControlProtocol (Session&); + virtual ~TranzportControlProtocol(); + + int init (); + bool active() const; + + void send_route_feedback (std::list<Route*>&); + void send_global_feedback (); + + 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; + + enum LightID { + LightRecord = 0, + LightTrackrec, + LightTrackmute, + LightTracksolo, + LightAnysolo, + LightLoop, + LightPunch + }; + + enum ButtonID { + ButtonBattery = 0x00004000, + ButtonBacklight = 0x00008000, + ButtonTrackLeft = 0x04000000, + ButtonTrackRight = 0x40000000, + ButtonTrackRec = 0x00040000, + ButtonTrackMute = 0x00400000, + ButtonTrackSolo = 0x00000400, + ButtonUndo = 0x80000000, + ButtonIn = 0x02000000, + ButtonOut = 0x20000000, + ButtonPunch = 0x00800000, + ButtonLoop = 0x00080000, + ButtonPrev = 0x00020000, + ButtonAdd = 0x00200000, + ButtonNext = 0x00000200, + ButtonRewind = 0x01000000, + ButtonFastForward = 0x10000000, + ButtonStop = 0x00010000, + ButtonPlay = 0x00100000, + ButtonRecord = 0x00000100, + ButtonShift = 0x08000000 + }; + + pthread_t thread; + uint32_t buttonmask; + uint32_t timeout; + uint8_t _datawheel; + uint8_t _device_status; + usb_dev_handle* udev; + Route* current_route; + uint32_t current_track_id; + + bool last_negative; + uint32_t last_hrs; + uint32_t last_mins; + uint32_t last_secs; + uint32_t last_frames; + jack_nframes_t last_where; + + int open (); + int read (); + int write (uint8_t* cmd); + int close (); + + int open_core (struct usb_device*); + + void lcd_clear (); + int lcd_write (uint8_t cell, const char *text); + + int light_on (LightID); + int light_off (LightID); + + void show_current_track (); + + static void* _thread_work (void* arg); + void* thread_work (); + + void button_event_battery_press (bool shifted); + void button_event_battery_release (bool shifted); + void button_event_backlight_press (bool shifted); + void button_event_backlight_release (bool shifted); + void button_event_trackleft_press (bool shifted); + void button_event_trackleft_release (bool shifted); + void button_event_trackright_press (bool shifted); + void button_event_trackright_release (bool shifted); + void button_event_trackrec_press (bool shifted); + void button_event_trackrec_release (bool shifted); + void button_event_trackmute_press (bool shifted); + void button_event_trackmute_release (bool shifted); + void button_event_tracksolo_press (bool shifted); + void button_event_tracksolo_release (bool shifted); + void button_event_undo_press (bool shifted); + void button_event_undo_release (bool shifted); + void button_event_in_press (bool shifted); + void button_event_in_release (bool shifted); + void button_event_out_press (bool shifted); + void button_event_out_release (bool shifted); + void button_event_punch_press (bool shifted); + void button_event_punch_release (bool shifted); + void button_event_loop_press (bool shifted); + void button_event_loop_release (bool shifted); + void button_event_prev_press (bool shifted); + void button_event_prev_release (bool shifted); + void button_event_add_press (bool shifted); + void button_event_add_release (bool shifted); + void button_event_next_press (bool shifted); + void button_event_next_release (bool shifted); + void button_event_rewind_press (bool shifted); + void button_event_rewind_release (bool shifted); + void button_event_fastforward_press (bool shifted); + void button_event_fastforward_release (bool shifted); + void button_event_stop_press (bool shifted); + void button_event_stop_release (bool shifted); + void button_event_play_press (bool shifted); + void button_event_play_release (bool shifted); + void button_event_record_press (bool shifted); + void button_event_record_release (bool shifted); +}; + +} // namespace + +#endif // ardour_tranzport_control_protocol_h diff --git a/libs/ardour/generic_midi_control_protocol.cc b/libs/ardour/generic_midi_control_protocol.cc new file mode 100644 index 0000000000..f9b9750982 --- /dev/null +++ b/libs/ardour/generic_midi_control_protocol.cc @@ -0,0 +1,54 @@ +#include <ardour/generic_midi_control_protocol.h> +#include <ardour/route.h> +#include <ardour/session.h> + +using namespace ARDOUR; + +#include "i18n.h" + +GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s) + : ControlProtocol (s, _("GenericMIDI")) +{ + _port = 0; +} + +GenericMidiControlProtocol::~GenericMidiControlProtocol () +{ +} + +void +GenericMidiControlProtocol::set_port (MIDI::Port* p) +{ + _port = p; +} + +void +GenericMidiControlProtocol::send_route_feedback (list<Route*>& routes) +{ + if (_port != 0) { + + const int32_t bufsize = 16 * 1024; + int32_t bsize = bufsize; + MIDI::byte* buf = new MIDI::byte[bufsize]; + MIDI::byte* end = buf; + + for (list<Route*>::iterator r = routes.begin(); r != routes.end(); ++r) { + end = (*r)->write_midi_feedback (end, bsize); + } + + if (end == buf) { + delete [] buf; + return; + } + + session.deliver_midi (_port, buf, (int32_t) (end - buf)); + //cerr << "MIDI feedback: wrote " << (int32_t) (end - buf) << " to midi port\n"; + } +} + +bool +GenericMidiControlProtocol::active() const +{ + return _port && send(); +} + diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 5cfe83e944..7210fcf9f5 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -336,7 +336,7 @@ find_file (string name, string dir, string subdir = "") string path; char* envvar = getenv("ARDOUR_PATH"); - /* stop A: any directory in ARDOUR_PATH */ + /* 1st attempt: any directory in ARDOUR_PATH */ if (envvar != 0) { @@ -354,7 +354,7 @@ find_file (string name, string dir, string subdir = "") } } - /* stop B: ~/.ardour/ */ + /* 2nd attempt: ~/.ardour/ */ path = get_user_ardour_path(); @@ -367,7 +367,7 @@ find_file (string name, string dir, string subdir = "") return path; } - /* C: dir/... */ + /* 3rd attempt: dir/... */ path = dir; path += "/ardour2/"; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 5e9a196c9a..22686c6cbe 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -767,7 +767,7 @@ Session::when_engine_running () insert_cnt = 0; - for (slist<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) { + for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) { uint32_t id; if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) { @@ -779,7 +779,7 @@ Session::when_engine_running () send_cnt = 0; - for (slist<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) { + for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) { uint32_t id; if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) { @@ -2211,6 +2211,20 @@ Session::route_by_name (string name) return 0; } +Route * +Session::route_by_remote_id (uint32_t id) +{ + RWLockMonitor lm (route_lock, false, __LINE__, __FILE__); + + for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + if ((*i)->remote_control_id() == id) { + return* i; + } + } + + return 0; +} + void Session::find_current_end () { diff --git a/libs/ardour/session_control.cc b/libs/ardour/session_control.cc new file mode 100644 index 0000000000..8e0a3e99a1 --- /dev/null +++ b/libs/ardour/session_control.cc @@ -0,0 +1,30 @@ + +#include <ardour/session.h> +#include <ardour/control_protocol.h> +#include <ardour/generic_midi_control_protocol.h> +#include <ardour/tranzport_control_protocol.h> + +using namespace ARDOUR; + +void +Session::initialize_control () +{ + GenericMidiControlProtocol* midi_protocol = new GenericMidiControlProtocol (*this); + + if (midi_protocol->init() == 0) { + control_protocols.push_back (midi_protocol); + } + + if (Config->get_use_tranzport()) { + cerr << "Creating new tranzport control" << endl; + + TranzportControlProtocol* tranzport_protocol = new TranzportControlProtocol (*this); + + cerr << "Initializing new tranzport control" << endl; + + if (tranzport_protocol->init() == 0) { + control_protocols.push_back (tranzport_protocol); + } + } +} + diff --git a/libs/ardour/session_feedback.cc b/libs/ardour/session_feedback.cc index 840cb6a97d..09e9021461 100644 --- a/libs/ardour/session_feedback.cc +++ b/libs/ardour/session_feedback.cc @@ -37,6 +37,7 @@ #include <ardour/session.h> #include <ardour/audio_track.h> #include <ardour/diskstream.h> +#include <ardour/control_protocol.h> #include "i18n.h" @@ -65,11 +66,6 @@ Session::init_feedback () } active_feedback = 0; - midi_feedback = false; - - /* add possible feedback functions here */ - - feedback_functions.push_back (mem_fun (*this, &Session::feedback_generic_midi_function)); if (pthread_create_and_store ("feedback", &feedback_thread, 0, _feedback_thread_work, this)) { error << _("Session: could not create feedback thread") << endmsg; @@ -99,6 +95,28 @@ Session::stop_feedback () } void +Session::set_feedback (bool yn) +{ + set_dirty(); + + if (yn) { + /* make sure the feedback thread is alive */ + start_feedback (); + } else { + /* maybe put the feedback thread to sleep */ + stop_feedback (); + } + + ControlChanged (Feedback); /* EMIT SIGNAL */ +} + +bool +Session::get_feedback() const +{ + return active_feedback > 0; +} + +void Session::terminate_feedback () { void* status; @@ -123,8 +141,7 @@ Session::feedback_thread_work () pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); if (active_feedback) { - /* XXX use Config->feedback_interval_usecs()*/; - timeout = max (5, (int) Config->get_midi_feedback_interval_ms()); + timeout = max (5, (int) Config->get_feedback_interval_ms()); } else { timeout = -1; } @@ -162,7 +179,7 @@ Session::feedback_thread_work () switch ((FeedbackRequest::Type) req) { case FeedbackRequest::Start: - timeout = max (5, (int) Config->get_midi_feedback_interval_ms()); + timeout = max (5, (int) Config->get_feedback_interval_ms()); active_feedback++; break; @@ -197,50 +214,29 @@ Session::feedback_thread_work () continue; } - for (list<FeedbackFunctionPtr>::iterator i = feedback_functions.begin(); i != feedback_functions.end(); ) { - - list<FeedbackFunctionPtr>::iterator tmp; - - tmp = i; - ++tmp; - - if ((*i) ()) { - feedback_functions.erase (i); + bool send = false; + + for (vector<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) { + if ((*i)->send()) { + send = true; + break; } - - i = tmp; } - } - - return 0; -} + + if (send) { -int -Session::feedback_generic_midi_function () -{ - const int32_t bufsize = 16 * 1024; - int32_t bsize = bufsize; - MIDI::byte* buf = new MIDI::byte[bufsize]; - MIDI::byte* end = buf; + RouteList routes = get_routes(); /* copies the routes */ - { - RWLockMonitor lm (route_lock, false, __LINE__, __FILE__); - - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - end = (*i)->write_midi_feedback (end, bsize); + for (vector<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) { + if ((*i)->send_route_feedback ()) { + (*i)->send_route_feedback (routes); + } + (*i)->send_global_feedback (); + } } } - - if (end == buf) { - delete [] buf; - return 0; - } - deliver_midi (_midi_port, buf, (int32_t) (end - buf)); - - //cerr << "MIDI feedback: wrote " << (int32_t) (end - buf) << " to midi port\n"; - - return 0; } + diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 1ac7d9e300..af08d3cc3e 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -40,6 +40,7 @@ #include <ardour/diskstream.h> #include <ardour/slave.h> #include <ardour/cycles.h> +#include <ardour/generic_midi_control_protocol.h> #include "i18n.h" @@ -166,6 +167,24 @@ Session::set_send_mmc (bool yn) ControlChanged (SendMMC); /* EMIT SIGNAL */ } +void +Session::set_midi_feedback (bool yn) +{ + if (generic_midi_control_protocol) { + if (yn) { + generic_midi_control_protocol->set_send (ControlProtocol::SendRoute); + } else { + generic_midi_control_protocol->set_send (ControlProtocol::SendWhat (0)); + } + } +} + +bool +Session::get_midi_feedback () const +{ + return generic_midi_control_protocol && generic_midi_control_protocol->active(); +} + bool Session::get_send_mtc () const { @@ -308,6 +327,10 @@ Session::set_midi_port (string port_tag) } _midi_port = port; + + if (generic_midi_control_protocol) { + generic_midi_control_protocol->set_port (port); + } Config->set_midi_port_name (port_tag); @@ -449,42 +472,6 @@ Session::get_trace_midi_output(MIDI::Port *port) } - -void -Session::set_midi_feedback (bool yn) -{ - if (_midi_port == 0) { - return; - } - - midi_feedback = yn; - set_dirty(); - - if (yn) { - /* make sure the feedback thread is alive */ - start_feedback (); - } else { - /* maybe put the feedback thread to sleep */ - stop_feedback (); - } - - ControlChanged (MidiFeedback); /* EMIT SIGNAL */ - - send_all_midi_feedback (); -} - -void -Session::send_all_midi_feedback () -{ - if (midi_feedback) { - // send out current state of all routes - RWLockMonitor lm (route_lock, false, __LINE__, __FILE__); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - (*i)->send_all_midi_feedback (); - } - } -} - void Session::setup_midi_control () { @@ -1483,14 +1470,7 @@ Session::get_mmc_control () const { return mmc_control; } -bool -Session::get_midi_feedback () const -{ - /* since this a "write" function we have to check the port as well - as the control toggle. - */ - return _midi_port && midi_feedback; -} + bool Session::get_midi_control () const { diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 5301019fa0..5decba1d09 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -165,6 +165,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) butler_mixdown_buffer = 0; butler_gain_buffer = 0; auditioner = 0; + generic_midi_control_protocol = 0; mmc_control = false; midi_feedback = false; midi_control = true; @@ -301,6 +302,8 @@ Session::second_stage_init (bool new_session) return -1; } + initialize_control(); + if (init_feedback ()) { return -1; } @@ -344,7 +347,8 @@ Session::second_stage_init (bool new_session) _engine.transport_locate (0); deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0); deliver_mmc (MIDI::MachineControl::cmdLocate, 0); - send_all_midi_feedback(); + + // XXX need to poke the feedback thread to send full state if (new_session) { _end_location_is_free = true; diff --git a/libs/ardour/tranzport_control_protocol.cc b/libs/ardour/tranzport_control_protocol.cc new file mode 100644 index 0000000000..9640ea4a75 --- /dev/null +++ b/libs/ardour/tranzport_control_protocol.cc @@ -0,0 +1,718 @@ +#include <iostream> + +#include <pbd/pthread_utils.h> + +#include <ardour/tranzport_control_protocol.h> +#include <ardour/route.h> +#include <ardour/session.h> + +using namespace ARDOUR; +using namespace std; + +#include "i18n.h" + +TranzportControlProtocol::TranzportControlProtocol (Session& s) + : ControlProtocol (s, _("Tranzport")) +{ + timeout = 60000; + buttonmask = 0; + _datawheel = 0; + _device_status = STATUS_OFFLINE; + udev = 0; + current_route = 0; + current_track_id = 0; + last_where = max_frames; +} + +TranzportControlProtocol::~TranzportControlProtocol () +{ + if (udev) { + pthread_cancel_one (thread); + close (); + } +} + +int +TranzportControlProtocol::init () +{ + if (open ()) { + return -1; + } + + pthread_create_and_store (X_("Tranzport"), &thread, 0, _thread_work, this); + + return 0; +} + +bool +TranzportControlProtocol::active() const +{ + return true; +} + +void +TranzportControlProtocol::send_route_feedback (list<Route*>& routes) +{ +} + +void +TranzportControlProtocol::send_global_feedback () +{ + jack_nframes_t where = session.transport_frame(); + + if (where != last_where) { + + char clock_label[16]; + SMPTE_Time smpte; + char* ptr = clock_label; + + session.smpte_time (where, smpte); + memset (clock_label, ' ', sizeof (clock_label)); + + if (smpte.negative) { + sprintf (ptr, "-%02ld:", smpte.hours); + } else { + sprintf (ptr, " %02ld:", smpte.hours); + } + ptr += 4; + + sprintf (ptr, "%02ld:", smpte.minutes); + ptr += 3; + + sprintf (ptr, "%02ld:", smpte.seconds); + ptr += 3; + + sprintf (ptr, "%02ld", smpte.frames); + ptr += 2; + + lcd_write (7, &clock_label[0]); + lcd_write (8, &clock_label[4]); + lcd_write (9, &clock_label[8]); + + last_where = where; + } +} + +void* +TranzportControlProtocol::_thread_work (void* arg) +{ + return static_cast<TranzportControlProtocol*>(arg)->thread_work (); +} + +void* +TranzportControlProtocol::thread_work () +{ + cerr << "tranzport thread here, sending message to LCD\n"; + + while (true) { + if (read()) { + return 0; + } + switch (_device_status) { + case STATUS_OFFLINE: + cerr << "offline\n"; + break; + case STATUS_ONLINE: + cerr << "online\n"; + break; + default: + cerr << "unknown status\n"; + break; + } + + if (_device_status == STATUS_ONLINE) { + break; + } + } + + lcd_write (0, " "); + lcd_write (1, "WELC"); + lcd_write (2, "OME "); + lcd_write (3, "TO "); + lcd_write (4, " "); + lcd_write (5, " "); + lcd_write (6, " "); + lcd_write (7, "ARDO"); + lcd_write (8, "UR "); + lcd_write (9, " "); + + while (true) { + if (read ()) { + cerr << "Tranzport command received\n"; + break; + } + } + + return 0; +} + +int +TranzportControlProtocol::open () +{ + struct usb_bus *bus; + struct usb_device *dev; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + cerr << "checking busses\n"; + + for (bus = usb_busses; bus; bus = bus->next) { + + cerr << "checking devices\n"; + + for(dev = bus->devices; dev; dev = dev->next) { + cerr << "Checking " << dev->descriptor.idVendor << '/' << dev->descriptor.idProduct << endl; + if (dev->descriptor.idVendor != VENDORID) + continue; + if (dev->descriptor.idProduct != PRODUCTID) + continue; + cerr << "Open this one" << endl; + return open_core (dev); + } + } + + error << _("Tranzport: no device detected") << endmsg; + return -1; +} + +int +TranzportControlProtocol::open_core (struct usb_device* dev) +{ + if (!(udev = usb_open (dev))) { + error << _("Tranzport: cannot open USB transport") << endmsg; + return -1; + } + + if (usb_claim_interface (udev, 0) < 0) { + error << _("Tranzport: cannot claim USB interface") << endmsg; + usb_close (udev); + udev = 0; + return -1; + } + + return 0; +} + +int +TranzportControlProtocol::close () +{ + int ret = 0; + + if (udev == 0) { + return 0; + } + + if (usb_release_interface (udev, 0) < 0) { + error << _("Tranzport: cannot release interface") << endmsg; + ret = -1; + } + + if (usb_close (udev)) { + error << _("Tranzport: cannot close device") << endmsg; + ret = 0; + } + + return ret; +} + +int +TranzportControlProtocol::write (uint8_t* cmd) +{ + int val; + val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout); + if (val < 0) + return val; + if (val != 8) + return -1; + return 0; + +} + +void +TranzportControlProtocol::lcd_clear () +{ + lcd_write (0, " "); + lcd_write (1, " "); + lcd_write (2, " "); + lcd_write (3, " "); + lcd_write (4, " "); + lcd_write (5, " "); + lcd_write (6, " "); + lcd_write (7, " "); + lcd_write (8, " "); + lcd_write (9, " "); +} + +int +TranzportControlProtocol::lcd_write (uint8_t cell, const char* text) +{ + uint8_t cmd[8]; + + if (cell > 9) { + return -1; + } + + cmd[0] = 0x00; + cmd[1] = 0x01; + cmd[2] = cell; + cmd[3] = text[0]; + cmd[4] = text[1]; + cmd[5] = text[2]; + cmd[6] = text[3]; + cmd[7] = 0x00; + + return write (cmd); +} + +int +TranzportControlProtocol::light_on (LightID light) +{ + uint8_t cmd[8]; + + cmd[0] = 0x00; + cmd[1] = 0x00; + cmd[2] = light; + cmd[3] = 0x01; + cmd[4] = 0x00; + cmd[5] = 0x00; + cmd[6] = 0x00; + cmd[7] = 0x00; + + return write (cmd); +} + +int +TranzportControlProtocol::light_off (LightID light) +{ + uint8_t cmd[8]; + + cmd[0] = 0x00; + cmd[1] = 0x00; + cmd[2] = light; + cmd[3] = 0x00; + cmd[4] = 0x00; + cmd[5] = 0x00; + cmd[6] = 0x00; + cmd[7] = 0x00; + + return write (cmd); +} + +int +TranzportControlProtocol::read () +{ + uint8_t buf[8]; + int val; + + memset(buf, 0, 8); + val = usb_interrupt_read(udev, READ_ENDPOINT, (char*) buf, 8, timeout); + if (val < 0) { + cerr << "Tranzport read error, val = " << val << endl; + return val; + } + if (val != 8) { + cerr << "Tranzport short read, val = " << val << endl; + return -1; + } + + /*printf("read: %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);*/ + + uint32_t this_button_mask; + uint32_t button_changes; + + _device_status = buf[1]; + this_button_mask = 0; + this_button_mask |= buf[2] << 24; + this_button_mask |= buf[3] << 16; + this_button_mask |= buf[4] << 8; + this_button_mask |= buf[5]; + _datawheel = buf[6]; + + button_changes = (this_button_mask ^ buttonmask); + buttonmask = this_button_mask; + + if (button_changes & ButtonBattery) { + if (buttonmask & ButtonBattery) { + button_event_battery_press (buttonmask&ButtonShift); + } else { + button_event_battery_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonBacklight) { + if (buttonmask & ButtonBacklight) { + button_event_backlight_press (buttonmask&ButtonShift); + } else { + button_event_backlight_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonTrackLeft) { + if (buttonmask & ButtonTrackLeft) { + button_event_trackleft_press (buttonmask&ButtonShift); + } else { + button_event_trackleft_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonTrackRight) { + if (buttonmask & ButtonTrackRight) { + button_event_trackright_press (buttonmask&ButtonShift); + } else { + button_event_trackright_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonTrackRec) { + if (buttonmask & ButtonTrackRec) { + button_event_trackrec_press (buttonmask&ButtonShift); + } else { + button_event_trackrec_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonTrackMute) { + if (buttonmask & ButtonTrackMute) { + button_event_trackmute_press (buttonmask&ButtonShift); + } else { + button_event_trackmute_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonTrackSolo) { + if (buttonmask & ButtonTrackSolo) { + button_event_tracksolo_press (buttonmask&ButtonShift); + } else { + button_event_tracksolo_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonUndo) { + if (buttonmask & ButtonUndo) { + button_event_undo_press (buttonmask&ButtonShift); + } else { + button_event_undo_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonIn) { + if (buttonmask & ButtonIn) { + button_event_in_press (buttonmask&ButtonShift); + } else { + button_event_in_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonOut) { + if (buttonmask & ButtonOut) { + button_event_out_press (buttonmask&ButtonShift); + } else { + button_event_out_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonPunch) { + if (buttonmask & ButtonPunch) { + button_event_punch_press (buttonmask&ButtonShift); + } else { + button_event_punch_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonLoop) { + if (buttonmask & ButtonLoop) { + button_event_loop_press (buttonmask&ButtonShift); + } else { + button_event_loop_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonPrev) { + if (buttonmask & ButtonPrev) { + button_event_prev_press (buttonmask&ButtonShift); + } else { + button_event_prev_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonAdd) { + if (buttonmask & ButtonAdd) { + button_event_add_press (buttonmask&ButtonShift); + } else { + button_event_add_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonNext) { + if (buttonmask & ButtonNext) { + button_event_next_press (buttonmask&ButtonShift); + } else { + button_event_next_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonRewind) { + if (buttonmask & ButtonRewind) { + button_event_rewind_press (buttonmask&ButtonShift); + } else { + button_event_rewind_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonFastForward) { + if (buttonmask & ButtonFastForward) { + button_event_fastforward_press (buttonmask&ButtonShift); + } else { + button_event_fastforward_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonStop) { + if (buttonmask & ButtonStop) { + button_event_stop_press (buttonmask&ButtonShift); + } else { + button_event_stop_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonPlay) { + if (buttonmask & ButtonPlay) { + button_event_play_press (buttonmask&ButtonShift); + } else { + button_event_play_release (buttonmask&ButtonShift); + } + } + if (button_changes & ButtonRecord) { + if (buttonmask & ButtonRecord) { + button_event_record_press (buttonmask&ButtonShift); + } else { + button_event_record_release (buttonmask&ButtonShift); + } + } + + return 0; +} + +void +TranzportControlProtocol::show_current_track () +{ + current_route = session.route_by_remote_id (current_track_id); + + if (current_route == 0) { + char buf[5]; + lcd_clear (); + lcd_write (0, "NO T"); + lcd_write (1, "RACK"); + lcd_write (2, " ID "); + snprintf (buf, sizeof (buf), "%4d", current_track_id); + lcd_write (3, buf); + return; + } + + string name = current_route->name(); + + lcd_write (0, name.substr (0, 4).c_str()); + lcd_write (1, name.substr (4, 4).c_str()); +} + +void +TranzportControlProtocol::button_event_battery_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_battery_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_backlight_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_backlight_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_trackleft_press (bool shifted) +{ + if (current_track_id == 0) { + current_track_id = session.nroutes() - 1; + } else { + current_track_id--; + } + + show_current_track (); +} + +void +TranzportControlProtocol::button_event_trackleft_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_trackright_press (bool shifted) +{ + if (current_track_id == session.nroutes()) { + current_track_id = 0; + } else { + current_track_id++; + } + + show_current_track (); +} + +void +TranzportControlProtocol::button_event_trackright_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_trackrec_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_trackrec_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_trackmute_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_trackmute_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_tracksolo_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_tracksolo_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_undo_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_undo_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_in_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_in_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_out_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_out_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_punch_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_punch_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_loop_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_loop_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_prev_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_prev_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_add_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_add_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_next_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_next_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_rewind_press (bool shifted) +{ + session.request_transport_speed (-2.0f); +} + +void +TranzportControlProtocol::button_event_rewind_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_fastforward_press (bool shifted) +{ + session.request_transport_speed (2.0f); +} + +void +TranzportControlProtocol::button_event_fastforward_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_stop_press (bool shifted) +{ + session.request_transport_speed (0.0); +} + +void +TranzportControlProtocol::button_event_stop_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_play_press (bool shifted) +{ + session.request_transport_speed (1.0); +} + +void +TranzportControlProtocol::button_event_play_release (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_record_press (bool shifted) +{ +} + +void +TranzportControlProtocol::button_event_record_release (bool shifted) +{ +} |