Clear up confusion with overloads of _frozen and frozen()
[ardour.git] / libs / ardour / audioregion.cc
index fd98c602bb57069ad1004c50b5aabce5075b3a3e..5ea7b5cbef8483f68079803ea9d684d435a9c24f 100644 (file)
@@ -103,7 +103,7 @@ AudioRegion::register_properties ()
        , _fade_in_active (Properties::fade_in_active, true) \
        , _fade_out_active (Properties::fade_out_active, true) \
        , _scale_amplitude (Properties::scale_amplitude, 1.0)
-       
+
 #define AUDIOREGION_COPY_STATE(other) \
        _envelope_active (Properties::envelope_active, other->_envelope_active) \
        , _default_fade_in (Properties::default_fade_in, other->_default_fade_in) \
@@ -259,7 +259,7 @@ AudioRegion::post_set (const PropertyChange& /*ignored*/)
        if (_left_of_split) {
                if (_fade_in->back()->when >= _length) {
                        set_default_fade_in ();
-               } 
+               }
                set_default_fade_out ();
                _left_of_split = false;
        }
@@ -267,7 +267,7 @@ AudioRegion::post_set (const PropertyChange& /*ignored*/)
        if (_right_of_split) {
                if (_fade_out->back()->when >= _length) {
                        set_default_fade_out ();
-               } 
+               }
 
                set_default_fade_in ();
                _right_of_split = false;
@@ -346,17 +346,16 @@ framecnt_t
 AudioRegion::read (Sample* buf, framepos_t timeline_position, framecnt_t cnt, int channel) const
 {
        /* raw read, no fades, no gain, nada */
-       return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0));
+       return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, ReadOps (0));
 }
 
 framecnt_t
 AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
-                     framepos_t file_position, framecnt_t cnt, uint32_t chan_n,
-                     framecnt_t read_frames, framecnt_t skip_frames) const
+                     framepos_t file_position, framecnt_t cnt, uint32_t chan_n) const
 {
        /* regular diskstream/butler read complete with fades etc */
        return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
-                       file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
+                       file_position, cnt, chan_n, ReadOps (~0));
 }
 
 framecnt_t
@@ -365,20 +364,23 @@ AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_bu
 {
        /* do not read gain/scaling/fades and do not count this disk i/o in statistics */
 
+       assert (cnt >= 0);
+
        return _read_at (_master_sources, _master_sources.front()->length(_master_sources.front()->timeline_position()),
-                        buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0, ReadOps (0));
+                        buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, ReadOps (0));
 }
 
+/** @param position Position within the session */
 framecnt_t
-AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
+AudioRegion::_read_at (const SourceList& srcs, framecnt_t limit,
                       Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
-                      framepos_t position, 
+                      framepos_t position,
                       framecnt_t cnt,
                       uint32_t chan_n,
-                      framecnt_t /*read_frames*/,
-                      framecnt_t /*skip_frames*/,
                       ReadOps rops) const
 {
+       assert (cnt >= 0);
+       
        frameoffset_t internal_offset;
        frameoffset_t buf_offset;
        framecnt_t to_read;
@@ -397,6 +399,19 @@ AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
        if (position < _position) {
                internal_offset = 0;
                buf_offset = _position - position;
+               /* if this fails then the requested section is entirely
+                  before the position of this region. An error in xfade
+                  construction that was fixed in oct 2011 (rev 10259)
+                  led to this being the case. We don't want to crash
+                  when this error is encountered, so just settle
+                  on displaying an error.
+               */
+               if (cnt < buf_offset) {
+                       error << "trying to read region " << name() << " @ " << position << " which is outside region bounds " 
+                             << _position << " .. " << last_frame() << " (len = " << length() << ')'
+                             << endmsg;
+                       return 0; // read nothing
+               }
                cnt -= buf_offset;
        } else {
                internal_offset = position - _position;
@@ -418,21 +433,13 @@ AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
                mixdown_buffer += buf_offset;
        }
 
-       if (rops & ReadOpsCount) {
-               _read_data_count = 0;
-       }
-
        if (chan_n < n_channels()) {
 
-               boost::shared_ptr<AudioSource> src = audio_source(chan_n);
+               boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[chan_n]);
                if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
                        return 0; /* "read nothing" */
                }
 
-               if (rops & ReadOpsCount) {
-                       _read_data_count += src->read_data_count();
-               }
-
        } else {
 
                /* track is N-channel, this region has less channels; silence the ones
@@ -442,16 +449,14 @@ AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
                if (Config->get_replicate_missing_region_channels()) {
                        /* track is N-channel, this region has less channels, so use a relevant channel
                         */
-                       
+
                        uint32_t channel = n_channels() % chan_n;
-                       boost::shared_ptr<AudioSource> src = audio_source (channel);
+                       boost::shared_ptr<AudioSource> src = boost::dynamic_pointer_cast<AudioSource> (srcs[channel]);
 
                        if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
                                return 0; /* "read nothing" */
                        }
 
-                       /* adjust read data count appropriately since this was a duplicate read */
-                       src->dec_read_data_count (to_read);
                } else {
                        memset (mixdown_buffer, 0, sizeof (Sample) * cnt);
                }
@@ -580,10 +585,10 @@ AudioRegion::state ()
        child = node.add_child ("Envelope");
 
        bool default_env = false;
-       
+
        // If there are only two points, the points are in the start of the region and the end of the region
        // so, if they are both at 1.0f, that means the default region.
-       
+
        if (_envelope->size() == 2 &&
            _envelope->front()->value == 1.0f &&
            _envelope->back()->value==1.0f) {
@@ -591,7 +596,7 @@ AudioRegion::state ()
                        default_env = true;
                }
        }
-       
+
        if (default_env) {
                child->add_property ("default", "yes");
        } else {
@@ -623,7 +628,7 @@ AudioRegion::_set_state (const XMLNode& node, int version, PropertyChange& what_
        const XMLNodeList& nlist = node.children();
        const XMLProperty *prop;
        LocaleGuard lg (X_("POSIX"));
-       boost::shared_ptr<Playlist> the_playlist (_playlist.lock());    
+       boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
 
        suspend_property_changes ();
 
@@ -752,7 +757,7 @@ AudioRegion::set_fade_in (boost::shared_ptr<AutomationList> f)
        _fade_in->freeze ();
        *_fade_in = *f;
        _fade_in->thaw ();
-       
+
        send_change (PropertyChange (Properties::fade_in));
 }
 
@@ -985,7 +990,7 @@ AudioRegion::recompute_at_end ()
        _envelope->truncate_end (_length);
        _envelope->set_max_xval (_length);
        _envelope->thaw ();
-       
+
        suspend_property_changes();
 
        if (_left_of_split) {
@@ -1000,7 +1005,7 @@ AudioRegion::recompute_at_end ()
                _fade_in->extend_to (_length);
                send_change (PropertyChange (Properties::fade_in));
        }
-       
+
        resume_property_changes();
 }
 
@@ -1010,7 +1015,7 @@ AudioRegion::recompute_at_start ()
        /* as above, but the shift was from the front */
 
        _envelope->truncate_start (_length);
-       
+
        suspend_property_changes();
 
        if (_right_of_split) {
@@ -1025,7 +1030,7 @@ AudioRegion::recompute_at_start ()
                _fade_out->extend_to (_length);
                send_change (PropertyChange (Properties::fade_out));
        }
-       
+
        resume_property_changes();
 }
 
@@ -1062,7 +1067,7 @@ AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr
                 */
 
                PropertyList plist;
-               
+
                plist.add (Properties::start, _start.val());
                plist.add (Properties::length, _length.val());
                plist.add (Properties::name, new_name);
@@ -1080,73 +1085,7 @@ AudioRegion::separate_by_channel (Session& /*session*/, vector<boost::shared_ptr
 framecnt_t
 AudioRegion::read_raw_internal (Sample* buf, framepos_t pos, framecnt_t cnt, int channel) const
 {
-       return audio_source()->read (buf, pos, cnt, channel);
-}
-
-int
-AudioRegion::exportme (Session& /*session*/, ARDOUR::ExportSpecification& /*spec*/)
-{
-       // TODO EXPORT
-//     const framecnt_t blocksize = 4096;
-//     framecnt_t to_read;
-//     int status = -1;
-//
-//     spec.channels = _sources.size();
-//
-//     if (spec.prepare (blocksize, session.frame_rate())) {
-//             goto out;
-//     }
-//
-//     spec.pos = 0;
-//     spec.total_frames = _length;
-//
-//     while (spec.pos < _length && !spec.stop) {
-//
-//
-//             /* step 1: interleave */
-//
-//             to_read = min (_length - spec.pos, blocksize);
-//
-//             if (spec.channels == 1) {
-//
-//                     if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
-//                             goto out;
-//                     }
-//
-//             } else {
-//
-//                     Sample buf[blocksize];
-//
-//                     for (uint32_t chan = 0; chan < spec.channels; ++chan) {
-//
-//                             if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
-//                                     goto out;
-//                             }
-//
-//                             for (framecnt_t x = 0; x < to_read; ++x) {
-//                                     spec.dataF[chan+(x*spec.channels)] = buf[x];
-//                             }
-//                     }
-//             }
-//
-//             if (spec.process (to_read)) {
-//                     goto out;
-//             }
-//
-//             spec.pos += to_read;
-//             spec.progress = (double) spec.pos /_length;
-//
-//     }
-//
-//     status = 0;
-//
-//  out:
-//     spec.running = false;
-//     spec.status = status;
-//     spec.clear();
-//
-//     return status;
-       return 0;
+       return audio_source(channel)->read (buf, pos, cnt);
 }
 
 void
@@ -1179,7 +1118,7 @@ AudioRegion::maximum_amplitude (Progress* p) const
 
        framecnt_t const blocksize = 64 * 1024;
        Sample buf[blocksize];
-       
+
        while (fpos < fend) {
 
                uint32_t n;
@@ -1190,7 +1129,7 @@ AudioRegion::maximum_amplitude (Progress* p) const
 
                        /* read it in */
 
-                       if (read_raw_internal (buf, fpos, to_read, 0) != to_read) {
+                       if (read_raw_internal (buf, fpos, to_read, n) != to_read) {
                                return 0;
                        }
 
@@ -1320,7 +1259,7 @@ AudioRegion::source_offset_changed ()
 
        if (afs && afs->destructive()) {
                // set_start (source()->natural_position(), this);
-               set_position (source()->natural_position(), this);
+               set_position (source()->natural_position());
        }
 }
 
@@ -1331,17 +1270,17 @@ AudioRegion::audio_source (uint32_t n) const
        return boost::dynamic_pointer_cast<AudioSource>(source(n));
 }
 
-int 
+int
 AudioRegion::adjust_transients (frameoffset_t delta)
 {
        for (AnalysisFeatureList::iterator x = _transients.begin(); x != _transients.end(); ++x) {
                (*x) = (*x) + delta;
        }
-       
+
        send_change (PropertyChange (Properties::valid_transients));
-       
-       return 0;  
-} 
+
+       return 0;
+}
 
 int
 AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
@@ -1350,11 +1289,11 @@ AudioRegion::update_transient (framepos_t old_position, framepos_t new_position)
                if ((*x) == old_position) {
                        (*x) = new_position;
                        send_change (PropertyChange (Properties::valid_transients));
-                       
+
                        break;
                }
        }
-       
+
        return 0;
 }
 
@@ -1363,7 +1302,7 @@ AudioRegion::add_transient (framepos_t where)
 {
        _transients.push_back(where);
        _valid_transients = true;
-       
+
        send_change (PropertyChange (Properties::valid_transients));
 }
 
@@ -1372,7 +1311,7 @@ AudioRegion::remove_transient (framepos_t where)
 {
        _transients.remove(where);
        _valid_transients = true;
-       
+
        send_change (PropertyChange (Properties::valid_transients));
 }
 
@@ -1382,9 +1321,9 @@ AudioRegion::set_transients (AnalysisFeatureList& results)
        _transients.clear();
        _transients = results;
        _valid_transients = true;
-       
+
        send_change (PropertyChange (Properties::valid_transients));
-       
+
        return 0;
 }