initial version of playback priority design. No GUI control over options yet

Conflicts:
	gtk2_ardour/editor_selection.cc
	libs/ardour/ardour/rc_configuration_vars.h
	libs/ardour/ardour/types.h
	libs/ardour/enums.cc
This commit is contained in:
Paul Davis 2015-01-16 12:17:09 -05:00
parent b4fe7e9026
commit fbfa4283b9
9 changed files with 200 additions and 42 deletions

View file

@ -669,7 +669,7 @@ ARDOUR_UI::install_actions ()
ActionManager::register_action (common_actions, X_("OpenMediaFolder"), _("OpenMediaFolder"), mem_fun(*this, &ARDOUR_UI::open_media_folder));
act = ActionManager::register_action (common_actions, X_("Save"), _("Save"), sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::save_state), string(""), false));
act = ActionManager::register_action (common_actions, X_("Save"), _("Save"), sigc::hide_return (sigc::bind (sigc::mem_fun(*this, &ARDOUR_UI::save_state), string(""), false)));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::write_sensitive_actions.push_back (act);

View file

@ -1149,6 +1149,16 @@ Editor::time_selection_changed ()
} else {
ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, true);
}
/* propagate into backend */
if (_session) {
if (selection->time.length() != 0) {
_session->set_range_selection (selection->time.start(), selection->time.end_frame());
} else {
_session->clear_range_selection ();
}
}
}
/** Set all region actions to have a given sensitivity */
@ -1457,6 +1467,17 @@ Editor::region_selection_changed ()
if (_session && !_session->transport_rolling() && !selection->regions.empty()) {
maybe_locate_with_edit_preroll (selection->regions.start());
}
/* propagate into backend */
if (_session) {
if (!selection->regions.empty()) {
_session->set_object_selection (selection->regions.start(), selection->regions.end_frame());
} else {
_session->clear_object_selection ();
}
}
}
void

View file

@ -159,6 +159,7 @@ CONFIG_VARIABLE (bool, locate_while_waiting_for_sync, "locate-while-waiting-for-
CONFIG_VARIABLE (bool, disable_disarm_during_roll, "disable-disarm-during-roll", false)
CONFIG_VARIABLE (bool, follow_edits, "follow-edits", false)
CONFIG_VARIABLE (bool, super_rapid_clock_update, "super-rapid-clock-update", false)
CONFIG_VARIABLE (AutoReturnTarget, auto_return_target_list, "auto-return-target-list", AutoReturnTarget(LastLocate|RangeSelectionStart|Loop|RegionSelectionStart))
/* metering */

View file

@ -819,6 +819,14 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void maybe_update_session_range (framepos_t, framepos_t);
/* temporary hacks to allow selection to be pushed from GUI into backend.
Whenever we move the selection object into libardour, these will go away.
*/
void set_range_selection (framepos_t start, framepos_t end);
void set_object_selection (framepos_t start, framepos_t end);
void clear_range_selection ();
void clear_object_selection ();
/* buffers for gain and pan */
gain_t* gain_automation_buffer () const;
@ -1391,13 +1399,15 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void post_transport ();
void engine_halted ();
void xrun_recovery ();
bool select_playhead_priority_target (framepos_t&);
void follow_playhead_priority ();
/* These are synchronous and so can only be called from within the process
* cycle
*/
/* These are synchronous and so can only be called from within the process
* cycle
*/
int send_full_time_code (framepos_t, pframes_t nframes);
void send_song_position_pointer (framepos_t);
int send_full_time_code (framepos_t, pframes_t nframes);
void send_song_position_pointer (framepos_t);
TempoMap *_tempo_map;
void tempo_map_changed (const PBD::PropertyChange&);
@ -1613,6 +1623,12 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void set_play_range (std::list<AudioRange>&, bool leave_rolling);
void unset_play_range ();
/* temporary hacks to allow selection to be pushed from GUI into backend
Whenever we move the selection object into libardour, these will go away.
*/
Evoral::Range<framepos_t> _range_selection;
Evoral::Range<framepos_t> _object_selection;
/* main outs */
uint32_t main_outs;

View file

@ -598,6 +598,13 @@ namespace ARDOUR {
uint32_t max; //< samples
};
enum AutoReturnTarget {
LastLocate = 0x1,
RangeSelectionStart = 0x2,
Loop = 0x4,
RegionSelectionStart = 0x8,
};
} // namespace ARDOUR
@ -627,6 +634,8 @@ std::istream& operator>>(std::istream& o, ARDOUR::WaveformScale& sf);
std::istream& operator>>(std::istream& o, ARDOUR::WaveformShape& sf);
std::istream& operator>>(std::istream& o, ARDOUR::PositionLockStyle& sf);
std::istream& operator>>(std::istream& o, ARDOUR::FadeShape& sf);
std::istream& operator>>(std::istream& o, ARDOUR::RegionSelectionAfterSplit& sf);
std::istream& operator>>(std::istream& o, ARDOUR::AutoReturnTarget& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::SampleFormat& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf);
@ -650,6 +659,22 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformScale& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformShape& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::PositionLockStyle& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::FadeShape& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::RegionSelectionAfterSplit& sf);
std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoReturnTarget& sf);
/* because these operators work on types which can be used when making
a UI_CONFIG_VARIABLE (in gtk2_ardour) we need them to be exported.
*/
LIBARDOUR_API std::istream& operator>>(std::istream& o, ARDOUR::WaveformScale& sf);
LIBARDOUR_API std::istream& operator>>(std::istream& o, ARDOUR::WaveformShape& sf);
LIBARDOUR_API std::istream& operator>>(std::istream& o, ARDOUR::VUMeterStandard& sf);
LIBARDOUR_API std::istream& operator>>(std::istream& o, ARDOUR::MeterLineUp& sf);
LIBARDOUR_API std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformScale& sf);
LIBARDOUR_API std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformShape& sf);
LIBARDOUR_API std::ostream& operator<<(std::ostream& o, const ARDOUR::VUMeterStandard& sf);
LIBARDOUR_API std::ostream& operator<<(std::ostream& o, const ARDOUR::MeterLineUp& sf);
static inline ARDOUR::framepos_t
session_frame_to_track_frame (ARDOUR::framepos_t session_frame, double speed)

View file

@ -127,7 +127,8 @@ setup_enum_writer ()
Session::SlaveState _Session_SlaveState;
MTC_Status _MIDI_MTC_Status;
Evoral::OverlapType _OverlapType;
AutoReturnTarget _AutoReturnTarget;
#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e)
@ -634,6 +635,13 @@ setup_enum_writer ()
REGISTER_ENUM (Evoral::OverlapEnd);
REGISTER_ENUM (Evoral::OverlapExternal);
REGISTER(_OverlapType);
REGISTER_ENUM (LastLocate);
REGISTER_ENUM (RangeSelectionStart);
REGISTER_ENUM (Loop);
REGISTER_ENUM (RegionSelectionStart);
REGISTER_BITS (_AutoReturnTarget);
}
} /* namespace ARDOUR */
@ -951,3 +959,31 @@ std::ostream& operator<<(std::ostream& o, const FadeShape& var)
std::string s = enum_2_string (var);
return o << s;
}
std::istream& operator>>(std::istream& o, RegionSelectionAfterSplit& var)
{
std::string s;
o >> s;
var = (RegionSelectionAfterSplit) string_2_enum (s, var);
return o;
}
std::ostream& operator<<(std::ostream& o, const RegionSelectionAfterSplit& var)
{
std::string s = enum_2_string (var);
return o << s;
}
std::istream& operator>>(std::istream& o, AutoReturnTarget& var)
{
std::string s;
o >> s;
var = (AutoReturnTarget) string_2_enum (s, var);
return o;
}
std::ostream& operator<<(std::ostream& o, const AutoReturnTarget& var)
{
std::string s = enum_2_string (var);
return o << s;
}

View file

@ -283,6 +283,8 @@ Session::Session (AudioEngine &eng,
, click_emphasis_length (0)
, _clicks_cleared (0)
, _play_range (false)
, _range_selection (-1,-1)
, _object_selection (-1,-1)
, main_outs (0)
, first_file_data_format_reset (true)
, first_file_header_format_reset (true)
@ -5977,3 +5979,32 @@ Session::reconnect_ltc_output ()
#endif
}
}
void
Session::set_range_selection (framepos_t start, framepos_t end)
{
cerr << "set range selection " << start << " .. " << end << endl;
_range_selection = Evoral::Range<framepos_t> (start, end);
follow_playhead_priority ();
}
void
Session::set_object_selection (framepos_t start, framepos_t end)
{
_object_selection = Evoral::Range<framepos_t> (start, end);
follow_playhead_priority ();
}
void
Session::clear_range_selection ()
{
_range_selection = Evoral::Range<framepos_t> (-1,-1);
follow_playhead_priority ();
}
void
Session::clear_object_selection ()
{
_object_selection = Evoral::Range<framepos_t> (-1,-1);
follow_playhead_priority ();
}

View file

@ -459,6 +459,61 @@ Session::non_realtime_locate ()
clear_clicks ();
}
bool
Session::select_playhead_priority_target (framepos_t& jump_to)
{
jump_to = -1;
AutoReturnTarget autoreturn = Config->get_auto_return_target_list ();
if (!autoreturn) {
return false;
}
/* Note that the order of checking each AutoReturnTarget flag defines
the priority each flag.
*/
if (autoreturn & LastLocate) {
jump_to = _last_roll_location;
}
if (jump_to < 0 && (autoreturn & RangeSelectionStart)) {
if (!_range_selection.empty()) {
jump_to = _range_selection.from;
}
}
if (jump_to < 0 && (autoreturn & Loop)) {
/* don't try to handle loop play when synced to JACK */
if (!synced_to_engine()) {
Location *location = _locations->auto_loop_location();
if (location) {
jump_to = location->start();
}
}
}
if (jump_to < 0 && (autoreturn & RegionSelectionStart)) {
if (!_object_selection.empty()) {
jump_to = _object_selection.from;
}
}
return jump_to >= 0;
}
void
Session::follow_playhead_priority ()
{
framepos_t target;
if (select_playhead_priority_target (target)) {
request_locate (target);
}
}
void
Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
@ -542,8 +597,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
update_latency_compensation ();
}
bool const auto_return_enabled =
(!config.get_external_sync() && (config.get_auto_return() || abort));
bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
if (auto_return_enabled ||
(ptw & PostTransportLocate) ||
@ -569,40 +623,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
do_locate = true;
} else {
if (config.get_auto_return()) {
framepos_t jump_to;
if (play_loop) {
if (select_playhead_priority_target (jump_to)) {
/* don't try to handle loop play when synced to JACK */
_transport_frame = jump_to;
do_locate = true;
if (!synced_to_engine()) {
Location *location = _locations->auto_loop_location();
if (location != 0) {
_transport_frame = location->start();
} else {
_transport_frame = _last_roll_location;
}
do_locate = true;
}
} else if (_play_range) {
/* return to start of range */
if (!current_audio_range.empty()) {
_transport_frame = current_audio_range.front().start;
do_locate = true;
}
} else {
/* regular auto-return */
_transport_frame = _last_roll_location;
do_locate = true;
}
} else if (abort) {
_transport_frame = _last_roll_location;
@ -1133,7 +1160,7 @@ Session::set_transport_speed (double speed, framepos_t destination_frame, bool a
}
_engine.transport_stop ();
} else {
bool const auto_return_enabled = (!config.get_external_sync() && (config.get_auto_return() || abort));
bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
if (!auto_return_enabled) {
_requested_return_frame = destination_frame;

View file

@ -41,6 +41,7 @@
<Option name="timecode-format" value="timecode_30"/>
<Option name="font-scale" value="81920"/>
<Option name="seamless-loop" value="1"/>
<Option name="auto-return-target-list" value="RangeSelectionStart,Loop,RegionSelectionStart"/>
</Config>
<extra>
<Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>