mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-18 03:15:52 +01:00
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:
parent
b4fe7e9026
commit
fbfa4283b9
9 changed files with 200 additions and 42 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue