mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
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
This commit is contained in:
parent
af5815e79b
commit
f7c82c6911
22 changed files with 1183 additions and 151 deletions
|
|
@ -389,6 +389,8 @@ libraries['libgnomecanvas2'].ParseConfig ('pkg-config --cflags --libs libgnomeca
|
||||||
libraries['glade2'] = LibraryInfo()
|
libraries['glade2'] = LibraryInfo()
|
||||||
libraries['glade2'].ParseConfig ('pkg-config --cflags --libs libglade-2.0')
|
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['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
|
||||||
|
|
||||||
libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
|
libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
<Option name="auditioner-right-out" value="%JACK_INPUT%2"/>
|
<Option name="auditioner-right-out" value="%JACK_INPUT%2"/>
|
||||||
<Option name="quieten-at-speed" value="1.000000"/>
|
<Option name="quieten-at-speed" value="1.000000"/>
|
||||||
<Option name="use-vst" value="yes"/>
|
<Option name="use-vst" value="yes"/>
|
||||||
|
<Option name="use-tranzport" value="yes"/>
|
||||||
</Config>
|
</Config>
|
||||||
<extra>
|
<extra>
|
||||||
<Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>
|
<Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ gtkardour.Append(POTFILE=domain + '.pot')
|
||||||
|
|
||||||
gtkardour.Merge ([
|
gtkardour.Merge ([
|
||||||
libraries['ardour'],
|
libraries['ardour'],
|
||||||
|
libraries['usb'],
|
||||||
libraries['gtkmm2ext'],
|
libraries['gtkmm2ext'],
|
||||||
# libraries['flowcanvas'],
|
# libraries['flowcanvas'],
|
||||||
libraries['midi++2'],
|
libraries['midi++2'],
|
||||||
|
|
|
||||||
|
|
@ -1260,14 +1260,6 @@ ARDOUR_UI::map_transport_state ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ARDOUR_UI::send_all_midi_feedback ()
|
|
||||||
{
|
|
||||||
if (session) {
|
|
||||||
session->send_all_midi_feedback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ARDOUR_UI::allow_local_only ()
|
ARDOUR_UI::allow_local_only ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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));
|
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);
|
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));
|
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);
|
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));
|
act = ActionManager::register_action (common_actions, X_("ToggleRecordEnableTrack2"), _("Toggle Record Enable Track2"), bind (mem_fun(*this, &ARDOUR_UI::toggle_record_enable), 1U));
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,15 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt
|
||||||
|
|
||||||
_route.panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans));
|
_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_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false);
|
||||||
solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), 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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AudioTimeAxisView::select_me (GdkEventButton* ev)
|
||||||
|
{
|
||||||
|
editor.get_selection().add (this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,7 @@ class AudioTimeAxisView : public RouteUI, public TimeAxisView
|
||||||
void map_frozen ();
|
void map_frozen ();
|
||||||
|
|
||||||
void color_handler (ColorID, uint32_t);
|
void color_handler (ColorID, uint32_t);
|
||||||
|
bool select_me (GdkEventButton*);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ardour_trackview_h__ */
|
#endif /* __ardour_trackview_h__ */
|
||||||
|
|
|
||||||
|
|
@ -1394,10 +1394,6 @@ Editor::set_selection_from_loop()
|
||||||
void
|
void
|
||||||
Editor::set_selection_from_range (Location& loc)
|
Editor::set_selection_from_range (Location& loc)
|
||||||
{
|
{
|
||||||
if (clicked_trackview == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
begin_reversible_command (_("set selection from range"));
|
begin_reversible_command (_("set selection from range"));
|
||||||
selection->set (0, loc.start(), loc.end());
|
selection->set (0, loc.start(), loc.end());
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
|
|
@ -1408,13 +1404,8 @@ Editor::set_selection_from_range (Location& loc)
|
||||||
void
|
void
|
||||||
Editor::select_all_selectables_using_time_selection ()
|
Editor::select_all_selectables_using_time_selection ()
|
||||||
{
|
{
|
||||||
|
|
||||||
list<Selectable *> touched;
|
list<Selectable *> touched;
|
||||||
|
|
||||||
if (clicked_trackview == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selection->time.empty()) {
|
if (selection->time.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1432,10 +1423,10 @@ Editor::select_all_selectables_using_time_selection ()
|
||||||
}
|
}
|
||||||
(*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched);
|
(*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched);
|
||||||
}
|
}
|
||||||
|
|
||||||
begin_reversible_command (_("select all from range"));
|
begin_reversible_command (_("select all from range"));
|
||||||
selection->set (touched);
|
selection->set (touched);
|
||||||
commit_reversible_command ();
|
commit_reversible_command ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1491,18 +1482,19 @@ Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
|
||||||
list<Selectable *> touched;
|
list<Selectable *> touched;
|
||||||
|
|
||||||
if (after) {
|
if (after) {
|
||||||
begin_reversible_command (_("select all after cursor"));
|
begin_reversible_command (_("select all after cursor"));
|
||||||
start = cursor->current_frame ;
|
start = cursor->current_frame ;
|
||||||
end = session->current_end_frame();
|
end = session->current_end_frame();
|
||||||
} else {
|
} else {
|
||||||
if (cursor->current_frame > 0) {
|
if (cursor->current_frame > 0) {
|
||||||
begin_reversible_command (_("select all before cursor"));
|
begin_reversible_command (_("select all before cursor"));
|
||||||
start = 0;
|
start = 0;
|
||||||
end = cursor->current_frame - 1;
|
end = cursor->current_frame - 1;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
|
for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
|
||||||
if ((*iter)->hidden()) {
|
if ((*iter)->hidden()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1520,17 +1512,19 @@ Editor::select_all_selectables_between_cursors (Cursor *cursor, Cursor *other_cu
|
||||||
jack_nframes_t end;
|
jack_nframes_t end;
|
||||||
list<Selectable *> touched;
|
list<Selectable *> touched;
|
||||||
bool other_cursor_is_first = cursor->current_frame > other_cursor->current_frame;
|
bool other_cursor_is_first = cursor->current_frame > other_cursor->current_frame;
|
||||||
|
|
||||||
if (cursor->current_frame == other_cursor->current_frame) {
|
if (cursor->current_frame == other_cursor->current_frame) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
begin_reversible_command (_("select all between cursors"));
|
begin_reversible_command (_("select all between cursors"));
|
||||||
if ( other_cursor_is_first) {
|
if (other_cursor_is_first) {
|
||||||
start = other_cursor->current_frame;
|
start = other_cursor->current_frame;
|
||||||
end = cursor->current_frame - 1;
|
end = cursor->current_frame - 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
start = cursor->current_frame;
|
start = cursor->current_frame;
|
||||||
end = other_cursor->current_frame - 1;
|
end = other_cursor->current_frame - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
|
for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ automation.cc
|
||||||
automation_event.cc
|
automation_event.cc
|
||||||
configuration.cc
|
configuration.cc
|
||||||
connection.cc
|
connection.cc
|
||||||
|
control_protocol.cc
|
||||||
crossfade.cc
|
crossfade.cc
|
||||||
curve.cc
|
curve.cc
|
||||||
cycle_timer.cc
|
cycle_timer.cc
|
||||||
|
|
@ -41,6 +42,7 @@ externalsource.cc
|
||||||
filesource.cc
|
filesource.cc
|
||||||
gain.cc
|
gain.cc
|
||||||
gdither.cc
|
gdither.cc
|
||||||
|
generic_midi_control_protocol.cc
|
||||||
globals.cc
|
globals.cc
|
||||||
import.cc
|
import.cc
|
||||||
insert.cc
|
insert.cc
|
||||||
|
|
@ -67,6 +69,7 @@ send.cc
|
||||||
session.cc
|
session.cc
|
||||||
session_butler.cc
|
session_butler.cc
|
||||||
session_click.cc
|
session_click.cc
|
||||||
|
session_control.cc
|
||||||
session_events.cc
|
session_events.cc
|
||||||
session_export.cc
|
session_export.cc
|
||||||
session_feedback.cc
|
session_feedback.cc
|
||||||
|
|
@ -82,6 +85,7 @@ source.cc
|
||||||
state_manager.cc
|
state_manager.cc
|
||||||
stateful.cc
|
stateful.cc
|
||||||
tempo.cc
|
tempo.cc
|
||||||
|
tranzport_control_protocol.cc
|
||||||
utils.cc
|
utils.cc
|
||||||
version.cc
|
version.cc
|
||||||
mix.cc
|
mix.cc
|
||||||
|
|
@ -178,7 +182,7 @@ ardour.Merge ([
|
||||||
libraries['sigc2'],
|
libraries['sigc2'],
|
||||||
libraries['pbd3'],
|
libraries['pbd3'],
|
||||||
libraries['soundtouch'],
|
libraries['soundtouch'],
|
||||||
libraries['midi++2']
|
libraries['midi++2'],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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, latched_record_enable, "latched-record-enable", false)
|
||||||
CONFIG_VARIABLE(bool, use_vst, "use-vst", true)
|
CONFIG_VARIABLE(bool, use_vst, "use-vst", true)
|
||||||
CONFIG_VARIABLE(bool, quieten_at_speed, "quieten-at-speed", 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, disk_choice_space_threshold, "disk-choice-space-threshold", 57600000)
|
||||||
CONFIG_VARIABLE(uint32_t, destructive_xfade_msecs, "destructive-xfade-msecs", 2)
|
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(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(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 */
|
/* these variables have custom set() methods */
|
||||||
|
|
||||||
|
|
|
||||||
45
libs/ardour/ardour/control_protocol.h
Normal file
45
libs/ardour/ardour/control_protocol.h
Normal file
|
|
@ -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
|
||||||
31
libs/ardour/ardour/generic_midi_control_protocol.h
Normal file
31
libs/ardour/ardour/generic_midi_control_protocol.h
Normal file
|
|
@ -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
|
||||||
|
|
@ -22,12 +22,7 @@
|
||||||
#define __ardour_session_h__
|
#define __ardour_session_h__
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#if __GNUC__ >= 3
|
#include <list>
|
||||||
#include <ext/slist>
|
|
||||||
using __gnu_cxx::slist;
|
|
||||||
#else
|
|
||||||
#include <slist.h>
|
|
||||||
#endif
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
@ -84,6 +79,8 @@ class AudioRegion;
|
||||||
class Region;
|
class Region;
|
||||||
class Playlist;
|
class Playlist;
|
||||||
class VSTPlugin;
|
class VSTPlugin;
|
||||||
|
class ControlProtocol;
|
||||||
|
class GenericMidiControlProtocol;
|
||||||
|
|
||||||
struct AudioExportSpecification;
|
struct AudioExportSpecification;
|
||||||
struct RouteGroup;
|
struct RouteGroup;
|
||||||
|
|
@ -283,7 +280,7 @@ class Session : public sigc::trackable, public Stateful
|
||||||
void foreach_diskstream (void (DiskStream::*func)(void));
|
void foreach_diskstream (void (DiskStream::*func)(void));
|
||||||
template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&));
|
template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&));
|
||||||
|
|
||||||
typedef slist<Route *> RouteList;
|
typedef list<Route *> RouteList;
|
||||||
|
|
||||||
RouteList get_routes() const {
|
RouteList get_routes() const {
|
||||||
RWLockMonitor rlock (route_lock, false, __LINE__, __FILE__);
|
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);
|
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_name (string);
|
||||||
|
Route *route_by_remote_id (uint32_t id);
|
||||||
|
|
||||||
bool route_name_unique (string) const;
|
bool route_name_unique (string) const;
|
||||||
|
|
||||||
|
|
@ -407,7 +405,9 @@ class Session : public sigc::trackable, public Stateful
|
||||||
CrossfadingModel,
|
CrossfadingModel,
|
||||||
SeamlessLoop,
|
SeamlessLoop,
|
||||||
MidiFeedback,
|
MidiFeedback,
|
||||||
MidiControl
|
MidiControl,
|
||||||
|
TranzportControl,
|
||||||
|
Feedback
|
||||||
};
|
};
|
||||||
|
|
||||||
sigc::signal<void,ControlType> ControlChanged;
|
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_do_not_record_plugins (bool yn);
|
||||||
void set_crossfades_active (bool yn);
|
void set_crossfades_active (bool yn);
|
||||||
void set_seamless_loop (bool yn);
|
void set_seamless_loop (bool yn);
|
||||||
|
void set_feedback (bool yn);
|
||||||
|
|
||||||
bool get_auto_play () const { return auto_play; }
|
bool get_auto_play () const { return auto_play; }
|
||||||
bool get_auto_input () const { return auto_input; }
|
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_midi_control () const;
|
||||||
bool get_do_not_record_plugins () const { return do_not_record_plugins; }
|
bool get_do_not_record_plugins () const { return do_not_record_plugins; }
|
||||||
bool get_crossfades_active () const { return crossfades_active; }
|
bool get_crossfades_active () const { return crossfades_active; }
|
||||||
|
bool get_feedback() const;
|
||||||
|
bool get_tranzport_control() const;
|
||||||
|
|
||||||
bool get_input_auto_connect () const;
|
bool get_input_auto_connect () const;
|
||||||
AutoConnectOption get_output_auto_connect () const { return output_auto_connect; }
|
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);
|
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_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);
|
void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size);
|
||||||
|
|
||||||
|
|
@ -1133,8 +1135,8 @@ class Session : public sigc::trackable, public Stateful
|
||||||
bool send_mtc;
|
bool send_mtc;
|
||||||
bool send_mmc;
|
bool send_mmc;
|
||||||
bool mmc_control;
|
bool mmc_control;
|
||||||
bool midi_feedback;
|
|
||||||
bool midi_control;
|
bool midi_control;
|
||||||
|
bool midi_feedback;
|
||||||
|
|
||||||
RingBuffer<Event*> pending_events;
|
RingBuffer<Event*> pending_events;
|
||||||
|
|
||||||
|
|
@ -1598,9 +1600,9 @@ class Session : public sigc::trackable, public Stateful
|
||||||
|
|
||||||
/* INSERT AND SEND MANAGEMENT */
|
/* INSERT AND SEND MANAGEMENT */
|
||||||
|
|
||||||
slist<PortInsert *> _port_inserts;
|
list<PortInsert *> _port_inserts;
|
||||||
slist<PluginInsert *> _plugin_inserts;
|
list<PluginInsert *> _plugin_inserts;
|
||||||
slist<Send *> _sends;
|
list<Send *> _sends;
|
||||||
uint32_t send_cnt;
|
uint32_t send_cnt;
|
||||||
uint32_t insert_cnt;
|
uint32_t insert_cnt;
|
||||||
|
|
||||||
|
|
@ -1768,6 +1770,12 @@ class Session : public sigc::trackable, public Stateful
|
||||||
|
|
||||||
LayerModel layer_model;
|
LayerModel layer_model;
|
||||||
CrossfadeModel xfade_model;
|
CrossfadeModel xfade_model;
|
||||||
|
|
||||||
|
/* control protocols */
|
||||||
|
|
||||||
|
vector<ControlProtocol*> control_protocols;
|
||||||
|
GenericMidiControlProtocol* generic_midi_control_protocol;
|
||||||
|
void initialize_control ();
|
||||||
};
|
};
|
||||||
|
|
||||||
}; /* namespace ARDOUR */
|
}; /* namespace ARDOUR */
|
||||||
|
|
|
||||||
142
libs/ardour/ardour/tranzport_control_protocol.h
Normal file
142
libs/ardour/ardour/tranzport_control_protocol.h
Normal file
|
|
@ -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
|
||||||
54
libs/ardour/generic_midi_control_protocol.cc
Normal file
54
libs/ardour/generic_midi_control_protocol.cc
Normal file
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -336,7 +336,7 @@ find_file (string name, string dir, string subdir = "")
|
||||||
string path;
|
string path;
|
||||||
char* envvar = getenv("ARDOUR_PATH");
|
char* envvar = getenv("ARDOUR_PATH");
|
||||||
|
|
||||||
/* stop A: any directory in ARDOUR_PATH */
|
/* 1st attempt: any directory in ARDOUR_PATH */
|
||||||
|
|
||||||
if (envvar != 0) {
|
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();
|
path = get_user_ardour_path();
|
||||||
|
|
||||||
|
|
@ -367,7 +367,7 @@ find_file (string name, string dir, string subdir = "")
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C: dir/... */
|
/* 3rd attempt: dir/... */
|
||||||
|
|
||||||
path = dir;
|
path = dir;
|
||||||
path += "/ardour2/";
|
path += "/ardour2/";
|
||||||
|
|
|
||||||
|
|
@ -767,7 +767,7 @@ Session::when_engine_running ()
|
||||||
|
|
||||||
insert_cnt = 0;
|
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;
|
uint32_t id;
|
||||||
|
|
||||||
if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
|
if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
|
||||||
|
|
@ -779,7 +779,7 @@ Session::when_engine_running ()
|
||||||
|
|
||||||
send_cnt = 0;
|
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;
|
uint32_t id;
|
||||||
|
|
||||||
if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
|
if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
|
||||||
|
|
@ -2211,6 +2211,20 @@ Session::route_by_name (string name)
|
||||||
return 0;
|
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
|
void
|
||||||
Session::find_current_end ()
|
Session::find_current_end ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
30
libs/ardour/session_control.cc
Normal file
30
libs/ardour/session_control.cc
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include <ardour/session.h>
|
#include <ardour/session.h>
|
||||||
#include <ardour/audio_track.h>
|
#include <ardour/audio_track.h>
|
||||||
#include <ardour/diskstream.h>
|
#include <ardour/diskstream.h>
|
||||||
|
#include <ardour/control_protocol.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -65,11 +66,6 @@ Session::init_feedback ()
|
||||||
}
|
}
|
||||||
|
|
||||||
active_feedback = 0;
|
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)) {
|
if (pthread_create_and_store ("feedback", &feedback_thread, 0, _feedback_thread_work, this)) {
|
||||||
error << _("Session: could not create feedback thread") << endmsg;
|
error << _("Session: could not create feedback thread") << endmsg;
|
||||||
|
|
@ -98,6 +94,28 @@ Session::stop_feedback ()
|
||||||
return poke_feedback (FeedbackRequest::Stop);
|
return poke_feedback (FeedbackRequest::Stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
Session::terminate_feedback ()
|
Session::terminate_feedback ()
|
||||||
{
|
{
|
||||||
|
|
@ -123,8 +141,7 @@ Session::feedback_thread_work ()
|
||||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||||
|
|
||||||
if (active_feedback) {
|
if (active_feedback) {
|
||||||
/* XXX use Config->feedback_interval_usecs()*/;
|
timeout = max (5, (int) Config->get_feedback_interval_ms());
|
||||||
timeout = max (5, (int) Config->get_midi_feedback_interval_ms());
|
|
||||||
} else {
|
} else {
|
||||||
timeout = -1;
|
timeout = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +179,7 @@ Session::feedback_thread_work ()
|
||||||
switch ((FeedbackRequest::Type) req) {
|
switch ((FeedbackRequest::Type) req) {
|
||||||
|
|
||||||
case FeedbackRequest::Start:
|
case FeedbackRequest::Start:
|
||||||
timeout = max (5, (int) Config->get_midi_feedback_interval_ms());
|
timeout = max (5, (int) Config->get_feedback_interval_ms());
|
||||||
active_feedback++;
|
active_feedback++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -197,50 +214,29 @@ Session::feedback_thread_work ()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list<FeedbackFunctionPtr>::iterator i = feedback_functions.begin(); i != feedback_functions.end(); ) {
|
bool send = false;
|
||||||
|
|
||||||
list<FeedbackFunctionPtr>::iterator tmp;
|
for (vector<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) {
|
||||||
|
if ((*i)->send()) {
|
||||||
tmp = i;
|
send = true;
|
||||||
++tmp;
|
break;
|
||||||
|
|
||||||
if ((*i) ()) {
|
|
||||||
feedback_functions.erase (i);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i = tmp;
|
if (send) {
|
||||||
|
|
||||||
|
RouteList routes = get_routes(); /* copies the routes */
|
||||||
|
|
||||||
|
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 ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
{
|
|
||||||
RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
|
|
||||||
|
|
||||||
for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
|
|
||||||
end = (*i)->write_midi_feedback (end, bsize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include <ardour/diskstream.h>
|
#include <ardour/diskstream.h>
|
||||||
#include <ardour/slave.h>
|
#include <ardour/slave.h>
|
||||||
#include <ardour/cycles.h>
|
#include <ardour/cycles.h>
|
||||||
|
#include <ardour/generic_midi_control_protocol.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -166,6 +167,24 @@ Session::set_send_mmc (bool yn)
|
||||||
ControlChanged (SendMMC); /* EMIT SIGNAL */
|
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
|
bool
|
||||||
Session::get_send_mtc () const
|
Session::get_send_mtc () const
|
||||||
{
|
{
|
||||||
|
|
@ -309,6 +328,10 @@ Session::set_midi_port (string port_tag)
|
||||||
|
|
||||||
_midi_port = port;
|
_midi_port = port;
|
||||||
|
|
||||||
|
if (generic_midi_control_protocol) {
|
||||||
|
generic_midi_control_protocol->set_port (port);
|
||||||
|
}
|
||||||
|
|
||||||
Config->set_midi_port_name (port_tag);
|
Config->set_midi_port_name (port_tag);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
@ -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
|
void
|
||||||
Session::setup_midi_control ()
|
Session::setup_midi_control ()
|
||||||
{
|
{
|
||||||
|
|
@ -1483,14 +1470,7 @@ Session::get_mmc_control () const
|
||||||
{
|
{
|
||||||
return mmc_control;
|
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
|
bool
|
||||||
Session::get_midi_control () const
|
Session::get_midi_control () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||||
butler_mixdown_buffer = 0;
|
butler_mixdown_buffer = 0;
|
||||||
butler_gain_buffer = 0;
|
butler_gain_buffer = 0;
|
||||||
auditioner = 0;
|
auditioner = 0;
|
||||||
|
generic_midi_control_protocol = 0;
|
||||||
mmc_control = false;
|
mmc_control = false;
|
||||||
midi_feedback = false;
|
midi_feedback = false;
|
||||||
midi_control = true;
|
midi_control = true;
|
||||||
|
|
@ -301,6 +302,8 @@ Session::second_stage_init (bool new_session)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize_control();
|
||||||
|
|
||||||
if (init_feedback ()) {
|
if (init_feedback ()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +347,8 @@ Session::second_stage_init (bool new_session)
|
||||||
_engine.transport_locate (0);
|
_engine.transport_locate (0);
|
||||||
deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
|
deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
|
||||||
deliver_mmc (MIDI::MachineControl::cmdLocate, 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) {
|
if (new_session) {
|
||||||
_end_location_is_free = true;
|
_end_location_is_free = true;
|
||||||
|
|
|
||||||
718
libs/ardour/tranzport_control_protocol.cc
Normal file
718
libs/ardour/tranzport_control_protocol.cc
Normal file
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue