X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fregion.cc;h=813fb93584b7cbcf69b3a2b20a1736c6df097978;hb=239da0efb58849e545ec44aeb839d41b8e4792cf;hp=d337cf6625e84cbc677cd62b2121070d1de9b1d3;hpb=a107b95307658af9f881e453362c1388ffac2463;p=ardour.git diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index d337cf6625..813fb93584 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -23,13 +23,10 @@ #include #include -#include +#include #include "pbd/xml++.h" -#include "pbd/stacktrace.h" -#include "pbd/enumwriter.h" #include "ardour/debug.h" -#include "ardour/file_source.h" #include "ardour/filter.h" #include "ardour/playlist.h" #include "ardour/playlist_source.h" @@ -38,9 +35,7 @@ #include "ardour/region_factory.h" #include "ardour/session.h" #include "ardour/source.h" -#include "ardour/source_factory.h" #include "ardour/tempo.h" -#include "ardour/utils.h" #include "i18n.h" @@ -49,10 +44,12 @@ using namespace ARDOUR; using namespace PBD; namespace ARDOUR { + class Progress; namespace Properties { PBD::PropertyDescriptor muted; PBD::PropertyDescriptor opaque; PBD::PropertyDescriptor locked; + PBD::PropertyDescriptor video_locked; PBD::PropertyDescriptor automatic; PBD::PropertyDescriptor whole_file; PBD::PropertyDescriptor import; @@ -73,6 +70,7 @@ namespace ARDOUR { PBD::PropertyDescriptor stretch; PBD::PropertyDescriptor shift; PBD::PropertyDescriptor position_lock_style; + PBD::PropertyDescriptor layering_index; } } @@ -87,6 +85,8 @@ Region::make_property_quarks () DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for opaque = %1\n", Properties::opaque.property_id)); Properties::locked.property_id = g_quark_from_static_string (X_("locked")); DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for locked = %1\n", Properties::locked.property_id)); + Properties::video_locked.property_id = g_quark_from_static_string (X_("video-locked")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for video-locked = %1\n", Properties::video_locked.property_id)); Properties::automatic.property_id = g_quark_from_static_string (X_("automatic")); DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for automatic = %1\n", Properties::automatic.property_id)); Properties::whole_file.property_id = g_quark_from_static_string (X_("whole-file")); @@ -127,6 +127,8 @@ Region::make_property_quarks () DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for shift = %1\n", Properties::shift.property_id)); Properties::position_lock_style.property_id = g_quark_from_static_string (X_("positional-lock-style")); DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for position_lock_style = %1\n", Properties::position_lock_style.property_id)); + Properties::layering_index.property_id = g_quark_from_static_string (X_("layering-index")); + DEBUG_TRACE (DEBUG::Properties, string_compose ("quark for layering_index = %1\n", Properties::layering_index.property_id)); } void @@ -137,6 +139,7 @@ Region::register_properties () add_property (_muted); add_property (_opaque); add_property (_locked); + add_property (_video_locked); add_property (_automatic); add_property (_whole_file); add_property (_import); @@ -151,63 +154,65 @@ Region::register_properties () add_property (_length); add_property (_position); add_property (_sync_position); - add_property (_layer); add_property (_ancestral_start); add_property (_ancestral_length); add_property (_stretch); add_property (_shift); add_property (_position_lock_style); + add_property (_layering_index); } #define REGION_DEFAULT_STATE(s,l) \ - _muted (Properties::muted, false) \ + _sync_marked (Properties::sync_marked, false) \ + , _left_of_split (Properties::left_of_split, false) \ + , _right_of_split (Properties::right_of_split, false) \ + , _valid_transients (Properties::valid_transients, false) \ + , _start (Properties::start, (s)) \ + , _length (Properties::length, (l)) \ + , _position (Properties::position, 0) \ + , _sync_position (Properties::sync_position, (s)) \ + , _muted (Properties::muted, false) \ , _opaque (Properties::opaque, true) \ , _locked (Properties::locked, false) \ + , _video_locked (Properties::video_locked, false) \ , _automatic (Properties::automatic, false) \ , _whole_file (Properties::whole_file, false) \ , _import (Properties::import, false) \ , _external (Properties::external, false) \ - , _sync_marked (Properties::sync_marked, false) \ - , _left_of_split (Properties::left_of_split, false) \ - , _right_of_split (Properties::right_of_split, false) \ , _hidden (Properties::hidden, false) \ , _position_locked (Properties::position_locked, false) \ - , _valid_transients (Properties::valid_transients, false) \ - , _start (Properties::start, (s)) \ - , _length (Properties::length, (l)) \ - , _position (Properties::position, 0) \ - , _sync_position (Properties::sync_position, (s)) \ - , _layer (Properties::layer, 0) \ , _ancestral_start (Properties::ancestral_start, (s)) \ , _ancestral_length (Properties::ancestral_length, (l)) \ , _stretch (Properties::stretch, 1.0) \ , _shift (Properties::shift, 1.0) \ - , _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime) + , _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime) \ + , _layering_index (Properties::layering_index, 0) #define REGION_COPY_STATE(other) \ - _muted (Properties::muted, other->_muted) \ + _sync_marked (Properties::sync_marked, other->_sync_marked) \ + , _left_of_split (Properties::left_of_split, other->_left_of_split) \ + , _right_of_split (Properties::right_of_split, other->_right_of_split) \ + , _valid_transients (Properties::valid_transients, other->_valid_transients) \ + , _start(Properties::start, other->_start) \ + , _length(Properties::length, other->_length) \ + , _position(Properties::position, other->_position) \ + , _sync_position(Properties::sync_position, other->_sync_position) \ + , _muted (Properties::muted, other->_muted) \ , _opaque (Properties::opaque, other->_opaque) \ , _locked (Properties::locked, other->_locked) \ + , _video_locked (Properties::video_locked, other->_video_locked) \ , _automatic (Properties::automatic, other->_automatic) \ , _whole_file (Properties::whole_file, other->_whole_file) \ , _import (Properties::import, other->_import) \ , _external (Properties::external, other->_external) \ - , _sync_marked (Properties::sync_marked, other->_sync_marked) \ - , _left_of_split (Properties::left_of_split, other->_left_of_split) \ - , _right_of_split (Properties::right_of_split, other->_right_of_split) \ , _hidden (Properties::hidden, other->_hidden) \ , _position_locked (Properties::position_locked, other->_position_locked) \ - , _valid_transients (Properties::valid_transients, other->_valid_transients) \ - , _start(Properties::start, other->_start) \ - , _length(Properties::length, other->_length) \ - , _position(Properties::position, other->_position) \ - , _sync_position(Properties::sync_position, other->_sync_position) \ - , _layer (Properties::layer, other->_layer) \ , _ancestral_start (Properties::ancestral_start, other->_ancestral_start) \ , _ancestral_length (Properties::ancestral_length, other->_ancestral_length) \ , _stretch (Properties::stretch, other->_stretch) \ , _shift (Properties::shift, other->_shift) \ - , _position_lock_style (Properties::position_lock_style, other->_position_lock_style) + , _position_lock_style (Properties::position_lock_style, other->_position_lock_style) \ + , _layering_index (Properties::layering_index, other->_layering_index) /* derived-from-derived constructor (no sources in constructor) */ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& name, DataType type) @@ -217,8 +222,7 @@ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& n , _last_length (length) , _last_position (0) , _first_edit (EditChangesNothing) - , _last_layer_op(0) - , _pending_explicit_relayer (false) + , _layer (0) { register_properties (); @@ -233,8 +237,7 @@ Region::Region (const SourceList& srcs) , _last_length (0) , _last_position (0) , _first_edit (EditChangesNothing) - , _last_layer_op (0) - , _pending_explicit_relayer (false) + , _layer (0) { register_properties (); @@ -254,9 +257,7 @@ Region::Region (boost::shared_ptr other) , _last_length (other->_last_length) , _last_position(other->_last_position) \ , _first_edit (EditChangesNothing) - , _last_layer_op (0) - , _pending_explicit_relayer (false) - + , _layer (other->_layer) { register_properties (); @@ -326,9 +327,7 @@ Region::Region (boost::shared_ptr other, frameoffset_t offset) , _last_length (other->_last_length) , _last_position(other->_last_position) \ , _first_edit (EditChangesNothing) - , _last_layer_op (0) - , _pending_explicit_relayer (false) - + , _layer (other->_layer) { register_properties (); @@ -383,8 +382,7 @@ Region::Region (boost::shared_ptr other, const SourceList& srcs) , _last_length (other->_last_length) , _last_position (other->_last_position) , _first_edit (EditChangesID) - , _last_layer_op (other->_last_layer_op) - , _pending_explicit_relayer (false) + , _layer (other->_layer) { register_properties (); @@ -551,7 +549,7 @@ Region::set_position_lock_style (PositionLockStyle ps) _position_lock_style = ps; if (_position_lock_style == MusicTime) { - _session.tempo_map().bbt_time (_position, _bbt_time); + _session.bbt_time (_position, _bbt_time); } send_change (Properties::position_lock_style); @@ -596,8 +594,13 @@ Region::set_position (framepos_t pos) void Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute) { + /* We emit a change of Properties::position even if the position hasn't changed + (see Region::set_position), so we must always set this up so that + e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position. + */ + _last_position = _position; + if (_position != pos) { - _last_position = _position; _position = pos; /* check that the new _position wouldn't make the current @@ -619,41 +622,18 @@ Region::set_position_internal (framepos_t pos, bool allow_bbt_recompute) } } -void -Region::set_position_on_top (framepos_t pos) -{ - if (locked()) { - return; - } - - if (_position != pos) { - set_position_internal (pos, true); - } - - boost::shared_ptr pl (playlist()); - - if (pl) { - pl->raise_region_to_top (shared_from_this ()); - } - - /* do this even if the position is the same. this helps out - a GUI that has moved its representation already. - */ - send_change (Properties::position); -} - void Region::recompute_position_from_lock_style () { if (_position_lock_style == MusicTime) { - _session.tempo_map().bbt_time (_position, _bbt_time); + _session.bbt_time (_position, _bbt_time); } } void Region::nudge_position (frameoffset_t n) { - if (locked()) { + if (locked() || video_locked()) { return; } @@ -694,7 +674,7 @@ Region::set_ancestral_data (framepos_t s, framecnt_t l, float st, float sh) void Region::set_start (framepos_t pos) { - if (locked() || position_locked()) { + if (locked() || position_locked() || video_locked()) { return; } /* This just sets the start, nothing else. It effectively shifts @@ -708,7 +688,7 @@ Region::set_start (framepos_t pos) return; } - _start = pos; + set_start_internal (pos); _whole_file = false; first_edit (); invalidate_transients (); @@ -718,32 +698,32 @@ Region::set_start (framepos_t pos) } void -Region::trim_start (framepos_t new_position) +Region::move_start (frameoffset_t distance) { - if (locked() || position_locked()) { + if (locked() || position_locked() || video_locked()) { return; } + framepos_t new_start; - frameoffset_t const start_shift = new_position - _position; - if (start_shift > 0) { + if (distance > 0) { - if (_start > max_framepos - start_shift) { - new_start = max_framepos; + if (_start > max_framepos - distance) { + new_start = max_framepos; // makes no sense } else { - new_start = _start + start_shift; + new_start = _start + distance; } if (!verify_start (new_start)) { return; } - } else if (start_shift < 0) { + } else if (distance < 0) { - if (_start < -start_shift) { + if (_start < -distance) { new_start = 0; } else { - new_start = _start + start_shift; + new_start = _start + distance; } } else { @@ -754,7 +734,8 @@ Region::trim_start (framepos_t new_position) return; } - _start = new_start; + set_start_internal (new_start); + _whole_file = false; first_edit (); @@ -910,7 +891,7 @@ Region::trim_to_internal (framepos_t position, framecnt_t length) PropertyChange what_changed; if (_start != new_start) { - _start = new_start; + set_start_internal (new_start); what_changed.add (Properties::start); } @@ -1004,6 +985,15 @@ Region::set_locked (bool yn) } } +void +Region::set_video_locked (bool yn) +{ + if (video_locked() != yn) { + _video_locked = yn; + send_change (Properties::video_locked); + } +} + void Region::set_position_locked (bool yn) { @@ -1139,11 +1129,7 @@ Region::lower_to_bottom () void Region::set_layer (layer_t l) { - if (_layer != l) { - _layer = l; - - send_change (Properties::layer); - } + _layer = l; } XMLNode& @@ -1152,10 +1138,21 @@ Region::state () XMLNode *node = new XMLNode ("Region"); char buf[64]; char buf2[64]; - LocaleGuard lg (X_("POSIX")); + LocaleGuard lg (X_("C")); const char* fe = NULL; - add_properties (*node); + /* custom version of 'add_properties (*node);' + * skip values that have have dedicated save functions + * in AudioRegion::state() + */ + for (OwnedPropertyList::iterator i = _properties->begin(); i != _properties->end(); ++i) { + if (!strcmp(i->second->property_name(), (const char*)"Envelope")) continue; + if (!strcmp(i->second->property_name(), (const char*)"FadeIn")) continue; + if (!strcmp(i->second->property_name(), (const char*)"FadeOut")) continue; + if (!strcmp(i->second->property_name(), (const char*)"InverseFadeIn")) continue; + if (!strcmp(i->second->property_name(), (const char*)"InverseFadeOut")) continue; + i->second->get_value (*node); + } id().print (buf, sizeof (buf)); node->add_property ("id", buf); @@ -1319,7 +1316,7 @@ Region::send_change (const PropertyChange& what_changed) Stateful::send_change (what_changed); - if (!Stateful::frozen()) { + if (!Stateful::property_changes_suspended()) { /* Try and send a shared_pointer unless this is part of the constructor. If so, do nothing. @@ -1334,16 +1331,10 @@ Region::send_change (const PropertyChange& what_changed) } } -void -Region::set_last_layer_op (uint64_t when) -{ - _last_layer_op = when; -} - bool Region::overlap_equivalent (boost::shared_ptr other) const { - return coverage (other->first_frame(), other->last_frame()) != OverlapNone; + return coverage (other->first_frame(), other->last_frame()) != Evoral::OverlapNone; } bool @@ -1442,6 +1433,25 @@ Region::source_equivalent (boost::shared_ptr other) const return true; } +bool +Region::any_source_equivalent (boost::shared_ptr other) const +{ + if (!other) { + return false; + } + + SourceList::const_iterator i; + SourceList::const_iterator io; + + for (i = _sources.begin(), io = other->_sources.begin(); i != _sources.end() && io != other->_sources.end(); ++i, ++io) { + if ((*i)->id() == (*io)->id()) { + return true; + } + } + + return false; +} + std::string Region::source_string () const { @@ -1480,20 +1490,20 @@ Region::uses_source (boost::shared_ptr source) const } } - return false; -} + for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { + if (*i == source) { + return true; + } -bool -Region::uses_source_path (const std::string& path) const -{ - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - boost::shared_ptr fs = boost::dynamic_pointer_cast (*i); - if (fs) { - if (fs->path() == path) { - return true; - } - } + boost::shared_ptr ps = boost::dynamic_pointer_cast (*i); + + if (ps) { + if (ps->playlist()->uses_source (source)) { + return true; + } + } } + return false; } @@ -1505,7 +1515,7 @@ Region::source_length(uint32_t n) const } bool -Region::verify_length (framecnt_t len) +Region::verify_length (framecnt_t& len) { if (source() && (source()->destructive() || source()->length_mutable())) { return true; @@ -1693,3 +1703,39 @@ Region::post_set (const PropertyChange& pc) recompute_position_from_lock_style (); } } + +void +Region::set_start_internal (framecnt_t s) +{ + _start = s; +} + +framepos_t +Region::earliest_possible_position () const +{ + if (_start > _position) { + return 0; + } else { + return _position - _start; + } +} + +framecnt_t +Region::latest_possible_frame () const +{ + framecnt_t minlen = max_framecnt; + + for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { + /* non-audio regions have a length that may vary based on their + * position, so we have to pass it in the call. + */ + minlen = min (minlen, (*i)->length (_position)); + } + + /* the latest possible last frame is determined by the current + * position, plus the shortest source extent past _start. + */ + + return _position + (minlen - _start) - 1; +} +