Add configure option to raise a FP exception when a denormal
[ardour.git] / libs / ardour / region.cc
index 17698d88a75f22fd1f223a581816ceea7933f973..adc6334334215798e2ccbd0edc43ca3503ac84bd 100644 (file)
@@ -32,6 +32,7 @@
 #include "ardour/file_source.h"
 #include "ardour/filter.h"
 #include "ardour/playlist.h"
+#include "ardour/playlist_source.h"
 #include "ardour/profile.h"
 #include "ardour/region.h"
 #include "ardour/region_factory.h"
@@ -159,24 +160,24 @@ Region::register_properties ()
 }
 
 #define REGION_DEFAULT_STATE(s,l) \
-       _muted (Properties::muted, false)            \
-       , _opaque (Properties::opaque, true) \
-       , _locked (Properties::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) \
+       _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) \
+       , _muted (Properties::muted, false) \
+       , _opaque (Properties::opaque, true) \
+       , _locked (Properties::locked, false) \
+       , _automatic (Properties::automatic, false) \
+       , _whole_file (Properties::whole_file, false) \
+       , _import (Properties::import, false) \
+       , _external (Properties::external, false) \
+       , _hidden (Properties::hidden, false) \
+       , _position_locked (Properties::position_locked, false) \
        , _ancestral_start (Properties::ancestral_start, (s)) \
        , _ancestral_length (Properties::ancestral_length, (l)) \
        , _stretch (Properties::stretch, 1.0) \
@@ -184,24 +185,24 @@ Region::register_properties ()
        , _position_lock_style (Properties::position_lock_style, _type == DataType::AUDIO ? AudioTime : MusicTime)
 
 #define REGION_COPY_STATE(other) \
-         _muted (Properties::muted, other->_muted)                     \
-       , _opaque (Properties::opaque, other->_opaque)          \
-       , _locked (Properties::locked, other->_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) \
+         _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)             \
+        , _muted (Properties::muted, other->_muted)            \
+       , _opaque (Properties::opaque, other->_opaque)          \
+       , _locked (Properties::locked, other->_locked)          \
+       , _automatic (Properties::automatic, other->_automatic) \
+       , _whole_file (Properties::whole_file, other->_whole_file) \
+       , _import (Properties::import, other->_import)          \
+       , _external (Properties::external, other->_external)    \
+       , _hidden (Properties::hidden, other->_hidden)          \
+       , _position_locked (Properties::position_locked, other->_position_locked) \
        , _ancestral_start (Properties::ancestral_start, other->_ancestral_start) \
        , _ancestral_length (Properties::ancestral_length, other->_ancestral_length) \
        , _stretch (Properties::stretch, other->_stretch)       \
@@ -216,7 +217,6 @@ Region::Region (Session& s, framepos_t start, framecnt_t length, const string& n
        , _last_length (length)
        , _last_position (0)
        , _first_edit (EditChangesNothing)
-       , _read_data_count(0)
        , _last_layer_op(0)
        , _pending_explicit_relayer (false)
 {
@@ -233,7 +233,6 @@ Region::Region (const SourceList& srcs)
        , _last_length (0)
        , _last_position (0)
        , _first_edit (EditChangesNothing)
-       , _read_data_count(0)
        , _last_layer_op (0)
        , _pending_explicit_relayer (false)
 {
@@ -255,7 +254,6 @@ Region::Region (boost::shared_ptr<const Region> other)
        , _last_length (other->_last_length)
        , _last_position(other->_last_position) \
        , _first_edit (EditChangesNothing)
-       , _read_data_count(0)
        , _last_layer_op (0)
        , _pending_explicit_relayer (false)
 
@@ -328,7 +326,6 @@ Region::Region (boost::shared_ptr<const Region> other, frameoffset_t offset)
        , _last_length (other->_last_length)
        , _last_position(other->_last_position) \
        , _first_edit (EditChangesNothing)
-       , _read_data_count(0)
        , _last_layer_op (0)
        , _pending_explicit_relayer (false)
 
@@ -386,7 +383,6 @@ Region::Region (boost::shared_ptr<const Region> other, const SourceList& srcs)
        , _last_length (other->_last_length)
        , _last_position (other->_last_position)
        , _first_edit (EditChangesID)
-       , _read_data_count (0)
        , _last_layer_op (other->_last_layer_op)
        , _pending_explicit_relayer (false)
 {
@@ -552,10 +548,6 @@ Region::set_position_lock_style (PositionLockStyle ps)
 
                boost::shared_ptr<Playlist> pl (playlist());
 
-               if (!pl) {
-                       return;
-               }
-
                _position_lock_style = ps;
 
                if (_position_lock_style == MusicTime) {
@@ -563,12 +555,11 @@ Region::set_position_lock_style (PositionLockStyle ps)
                }
 
                send_change (Properties::position_lock_style);
-
        }
 }
 
 void
-Region::update_position_after_tempo_map_change ()
+Region::update_after_tempo_map_change ()
 {
        boost::shared_ptr<Playlist> pl (playlist());
 
@@ -605,8 +596,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
@@ -628,29 +624,6 @@ 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<Playlist> 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 ()
 {
@@ -846,7 +819,7 @@ Region::modify_end (framepos_t new_endpoint, bool reset_fade)
        }
 
        if (new_endpoint > _position) {
-               trim_to_internal (_position, new_endpoint - _position +1);
+               trim_to_internal (_position, new_endpoint - _position);
                if (reset_fade) {
                        _left_of_split = true;
                }
@@ -1166,7 +1139,7 @@ Region::state ()
 
        add_properties (*node);
 
-       _id.print (buf, sizeof (buf));
+       id().print (buf, sizeof (buf));
        node->add_property ("id", buf);
        node->add_property ("type", _type.to_string());
 
@@ -1207,7 +1180,11 @@ Region::state ()
                node->add_property (buf2, buf);
        }
 
-       if (max_source_level() > 0) {
+       /* Only store nested sources for the whole-file region that acts
+          as the parent/root of all regions using it.
+       */
+
+       if (_whole_file && max_source_level() > 0) {
 
                XMLNode* nested_node = new XMLNode (X_("NestedSource"));
 
@@ -1249,23 +1226,12 @@ int
 Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_changed, bool send)
 {
        const XMLProperty* prop;
-       const XMLNodeList& nlist = node.children();
 
-       for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
-
-               XMLNode *child = (*niter);
-
-               if (child->name () == "Extra") {
-                       delete _extra_xml;
-                       _extra_xml = new XMLNode (*child);
-               }
-       }
+       Stateful::save_extra_xml (node);
 
        what_changed = set_values (node);
 
-       if ((prop = node.property (X_("id")))) {
-               _id = prop->value();
-       }
+       set_id (node);
 
        if (_position_lock_style == MusicTime) {
                if ((prop = node.property ("bbt-position")) == 0) {
@@ -1335,7 +1301,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.
@@ -1486,21 +1452,16 @@ Region::uses_source (boost::shared_ptr<const Source> source) const
                if (*i == source) {
                        return true;
                }
-       }
-       return false;
-}
 
-bool
-Region::uses_source_path (const std::string& path) const
-{
-       for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
-                boost::shared_ptr<const FileSource> fs = boost::dynamic_pointer_cast<const FileSource> (*i);
-                if (fs) {
-                        if (fs->path() == path) {
-                                return true;
-                        }
-                }
+               boost::shared_ptr<PlaylistSource> ps = boost::dynamic_pointer_cast<PlaylistSource> (*i);
+
+               if (ps) {
+                       if (ps->playlist()->uses_source (source)) {
+                               return true;
+                       }
+               }
        }
+
        return false;
 }
 
@@ -1692,3 +1653,11 @@ Region::is_compound () const
 {
        return max_source_level() > 0;
 }
+
+void
+Region::post_set (const PropertyChange& pc)
+{
+       if (pc.contains (Properties::position)) {
+               recompute_position_from_lock_style ();
+       }
+}