Simplify slightly odd update_length() signature.
[ardour.git] / libs / ardour / crossfade.cc
index a988585b906e24c3d66bc46b1fe620ed3ade8895..c687c60cd1a4341ae40c0c8436538da79e53eaab 100644 (file)
 
 */
 
-
-#include "pbd/stacktrace.h"
-
 #include "ardour/debug.h"
 #include "ardour/types.h"
 #include "ardour/crossfade.h"
-#include "ardour/crossfade_compare.h"
 #include "ardour/audioregion.h"
 #include "ardour/playlist.h"
 #include "ardour/utils.h"
@@ -89,14 +85,15 @@ Crossfade::operator== (const Crossfade& other)
 
 Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<AudioRegion> out,
                      framecnt_t length,
-                     framepos_t position,
                      AnchorPoint ap)
-       : AudioRegion (in->session(), position, length, in->name() + string ("<>") + out->name())
+       : AudioRegion (in->session(), 0, length, in->name() + string ("<>") + out->name())
        , CROSSFADE_DEFAULT_PROPERTIES
        , _fade_in (Evoral::Parameter(FadeInAutomation)) // linear (gain coefficient) => -inf..+6dB
        , _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB
 
 {
+       register_properties ();
+
        _in = in;
        _out = out;
        _anchor_point = ap;
@@ -112,6 +109,8 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioR
        , _fade_in (Evoral::Parameter(FadeInAutomation)) // linear (gain coefficient) => -inf..+6dB
        , _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB
 {
+       register_properties ();
+       
        _in_update = false;
        _fixed = false;
        _follow_overlap = false;
@@ -132,6 +131,8 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode const & node)
        , _fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB
 
 {
+       register_properties ();
+       
        boost::shared_ptr<Region> r;
        XMLProperty const * prop;
        LocaleGuard lg (X_("POSIX"));
@@ -153,7 +154,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode const & node)
                */
                r = RegionFactory::region_by_id (id);
        }
-       
+
        if (!r) {
                error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2 nor in region map"), id, playlist.name())
                      << endmsg;
@@ -176,7 +177,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode const & node)
        if (!r) {
                r = RegionFactory::region_by_id (id2);
        }
-       
+
        if (!r) {
                error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2 nor in region map"), id2, playlist.name())
                      << endmsg;
@@ -202,11 +203,14 @@ Crossfade::Crossfade (boost::shared_ptr<Crossfade> orig, boost::shared_ptr<Audio
        , _fade_in (orig->_fade_in)
        , _fade_out (orig->_fade_out)
 {
+       register_properties ();
+       
        _active           = orig->_active;
        _in_update        = orig->_in_update;
        _anchor_point     = orig->_anchor_point;
        _follow_overlap   = orig->_follow_overlap;
        _fixed            = orig->_fixed;
+       _position         = orig->_position;
 
        _in = newin;
        _out = newout;
@@ -229,6 +233,13 @@ Crossfade::~Crossfade ()
 {
 }
 
+void
+Crossfade::register_properties ()
+{
+       add_property (_active);
+       add_property (_follow_overlap);
+}
+
 void
 Crossfade::initialize ()
 {
@@ -240,7 +251,7 @@ Crossfade::initialize ()
         for (SourceList::iterator i = _sources.begin(); i != _sources.end(); ++i) {
                 (*i)->inc_use_count ();
         }
-        
+
        _master_sources = _in->master_sources();
        _master_sources.insert(_master_sources.end(), _out->master_sources().begin(), _out->master_sources().end());
 
@@ -318,8 +329,8 @@ Crossfade::read_raw_internal (Sample* buf, framecnt_t start, framecnt_t cnt, int
        Sample* mixdown = new Sample[cnt];
        float* gain = new float[cnt];
        framecnt_t ret;
-       
-       ret = read_at (buf, mixdown, gain, start, cnt, channel, cnt);
+
+       ret = read_at (buf, mixdown, gain, start, cnt, channel);
 
        delete [] mixdown;
        delete [] gain;
@@ -329,8 +340,7 @@ Crossfade::read_raw_internal (Sample* buf, framecnt_t start, framecnt_t cnt, int
 
 framecnt_t
 Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
-                   float *gain_buffer, framepos_t start, framecnt_t cnt, uint32_t chan_n,
-                   framecnt_t read_frames, framecnt_t skip_frames) const
+                   float *gain_buffer, framepos_t start, framecnt_t cnt, uint32_t chan_n) const
 {
        frameoffset_t offset;
        framecnt_t to_write;
@@ -372,8 +382,8 @@ Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
                memset (crossfade_buffer_in, 0, sizeof (Sample) * to_write);
        }
 
-       _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
-       _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
+       _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n);
+       _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n);
 
        float* fiv = new float[to_write];
        float* fov = new float[to_write];
@@ -443,6 +453,13 @@ Crossfade::refresh ()
                return false;
        }
 
+        /* regions must cannot be identically sized and placed */
+
+        if (_in->position() == _out->position() && _in->length() == _out->length()) {
+               Invalidated (shared_from_this());
+                return false;
+        }
+
        /* layer ordering cannot change */
 
        int32_t new_layer_relation = (int32_t) (_in->layer() - _out->layer());
@@ -584,8 +601,8 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
                        } else {
                                _position = top->last_frame() - short_xfade_length;
                        }
-
-                       _length = min (short_xfade_length, top->length());
+                       
+                       set_xfade_length (min (short_xfade_length, top->length()));
                        _follow_overlap = false;
                        _anchor_point = EndOfIn;
                        _active = true;
@@ -619,7 +636,7 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
                        _in = top;
                        _out = bottom;
                        _position = top->first_frame();
-                       _length = min (short_xfade_length, top->length());
+                       set_xfade_length (min (short_xfade_length, top->length()));
                        _follow_overlap = false;
                        _anchor_point = StartOfIn;
                        _active = true;
@@ -668,11 +685,11 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
 
                        if (model == FullCrossfade) {
                                _position = bottom->first_frame(); // "{"
-                               _length = _out->first_frame() + _out->length() - _in->first_frame();
+                               set_xfade_length (_out->first_frame() + _out->length() - _in->first_frame());
                                /* leave active alone */
                                _follow_overlap = true;
                        } else {
-                               _length = min (short_xfade_length, top->length());
+                               set_xfade_length (min (short_xfade_length, top->length()));
                                _position = top->last_frame() - _length;  // "]" - length
                                _active = true;
                                _follow_overlap = false;
@@ -692,11 +709,11 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
                        _anchor_point = StartOfIn;
 
                        if (model == FullCrossfade) {
-                               _length = _out->first_frame() + _out->length() - _in->first_frame();
+                               set_xfade_length (_out->first_frame() + _out->length() - _in->first_frame());
                                /* leave active alone */
                                _follow_overlap = true;
                        } else {
-                               _length = min (short_xfade_length, top->length());
+                               set_xfade_length (min (short_xfade_length, top->length()));
                                _active = true;
                                _follow_overlap = false;
 
@@ -776,9 +793,7 @@ Crossfade::set_state (const XMLNode& node, int /*version*/)
        PropertyChange what_changed;
        framepos_t val;
 
-       if ((prop = node.property (X_("id")))) {
-               _id = prop->value();
-       }
+       set_id (node);
 
        if ((prop = node.property ("position")) != 0) {
                sscanf (prop->value().c_str(), "%" PRId64, &val);
@@ -973,7 +988,7 @@ Crossfade::set_xfade_length (framecnt_t len)
        _length = len;
 
        PropertyChanged (PropertyChange (Properties::length));
-       
+
        return len;
 }