Make source length a dynamic thing.
authorDavid Robillard <d@drobilla.net>
Fri, 20 Feb 2009 00:30:42 +0000 (00:30 +0000)
committerDavid Robillard <d@drobilla.net>
Fri, 20 Feb 2009 00:30:42 +0000 (00:30 +0000)
Update MIDI region length (actually and visually) when position changes.

git-svn-id: svn://localhost/ardour2/branches/3.0@4644 d708f5d6-7413-0410-9779-e7cbd77b26cf

28 files changed:
gtk2_ardour/audio_streamview.cc
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_export_audio.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_streamview.cc
gtk2_ardour/sfdb_ui.cc
libs/ardour/analyser.cc
libs/ardour/ardour/audiosource.h
libs/ardour/ardour/crossfade.h
libs/ardour/ardour/midi_region.h
libs/ardour/ardour/midi_source.h
libs/ardour/ardour/region.h
libs/ardour/ardour/source.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_track.cc
libs/ardour/audioregion.cc
libs/ardour/audiosource.cc
libs/ardour/crossfade.cc
libs/ardour/file_source.cc
libs/ardour/midi_region.cc
libs/ardour/midi_source.cc
libs/ardour/region.cc
libs/ardour/region_factory.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/smf_source.cc
libs/ardour/source.cc

index d205e400d288d7c84800db66a5c92dc34af50038..f102674fb4ddc36ac7462f8ba1263d039716bcca 100644 (file)
@@ -699,7 +699,7 @@ AudioStreamView::update_rec_regions ()
 
                                if (nlen != region->length()) {
 
-                                       if (region->source(0)->length() >= region->start() + nlen) {
+                                       if (region->source_length(0) >= region->start() + nlen) {
 
                                                region->freeze ();
                                                region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
index ab5cea3f7b1908a21f7231e55bc55d6e7e3d36ce..730063655a39ed80988d1d4d6f9f1572c8506d14 100644 (file)
@@ -732,8 +732,8 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
 
                region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
                
-               regions.push_back (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
-                                                          Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
+               regions.push_back (RegionFactory::create (sources, 0, sources[0]->length(pos), region_name, 0,
+                               Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
                
        } else if (target_regions == -1 || target_regions > 1) {
 
@@ -750,8 +750,8 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
                        
                        region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n);
 
-                       regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
-                                                                  Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
+                       regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(pos), region_name, 0,
+                                       Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
 
                }
        }
index 7586a813cfeae8230f3fdcbe84d427a806244648..ea1876ca94b03534183ed0470af2a41cff99315b 100644 (file)
@@ -170,7 +170,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
        
        /* don't do duplicate of the entire source if that's what is going on here */
 
-       if (region->start() == 0 && region->length() == region->source()->length()) {
+       if (region->start() == 0 && region->length() == region->source_length(0)) {
                /* XXX should link(2) to create a new inode with "path" */
                return true;
        }
index 694d9033dcd00b62356cec94b240fe5962f4444e..b97c8acc9e7d4c7872e29a910e922598a5fff143 100644 (file)
@@ -989,7 +989,7 @@ Editor::region_list_sorter (TreeModel::iterator a, TreeModel::iterator b)
                break;
 
        case BySourceFileLength:
-               cmp = region1->source()->length() - region2->source()->length();
+               cmp = region1->source_length(0) - region2->source_length(0);
                break;
                
        case BySourceFileCreationDate:
index 3087d3436ee10cf950997fbb0a0f818501d2d884..aca13c8c4433a4bb2ef985f9a469d18650d72b42 100644 (file)
@@ -685,6 +685,7 @@ MidiRegionView::region_resized (Change what_changed)
        RegionView::region_resized(what_changed);
        
        if (what_changed & ARDOUR::PositionChanged) {
+               set_duration(_region->length(), 0);
                if (_enable_display) {
                        redisplay_model();
                }
index 4e1afffbfbf47bb734ec79369b56a496c7650cdb..ed364e715654482eb165345dd3c1335a905044dc 100644 (file)
@@ -594,7 +594,7 @@ MidiStreamView::update_rec_regions (boost::shared_ptr<MidiModel> data, nframes_t
 
                                if (nlen != region->length()) {
 
-                                       if (region->source(0)->length() >= region->position() + nlen) {
+                                       if (region->source_length(0) >= region->position() + nlen) {
 
                                                region->freeze ();
                                                region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
index bb95da5c0064e91be34ff0595ce247a9ebb894b8..0ee8935f1b3c89ba57195ad3d48fcb4e188f7fa4 100644 (file)
@@ -352,7 +352,9 @@ SoundFileBox::audition ()
        
        afs = boost::dynamic_pointer_cast<AudioFileSource> (srclist[0]);
        string rname = region_name_from_path (afs->path(), false);
-       r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0, srclist[0]->length(), rname, 0, Region::DefaultFlags, false));
+       r = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (srclist, 0,
+                               srclist[0]->length(srclist[0]->timeline_position()),
+                               rname, 0, Region::DefaultFlags, false));
 
        _session->audition_region(r);
 }
index 28eeeb190cf60afb4057c26d21f0b6be19806c54..6d2392eb20c8fa23c96d59d952a3112f41b47ef0 100644 (file)
@@ -95,7 +95,7 @@ Analyser::work ()
 
                boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
 
-               if (afs && afs->length()) {
+               if (afs && afs->length(afs->timeline_position())) {
                        analyse_audio_file_source (afs);
                }
        }
@@ -116,4 +116,3 @@ Analyser::analyse_audio_file_source (boost::shared_ptr<AudioFileSource> src)
 
 }
 
-               
index 08435bf3b1a422aee9552ca469dce9ba3615310b..4f2ad0eee131dd344e7d1dffade0335a8b8130a5 100644 (file)
@@ -54,6 +54,9 @@ class AudioSource : virtual public Source,
 
        nframes64_t readable_length() const { return _length; }
        uint32_t    n_channels()      const { return 1; }
+       
+       sframes_t length (sframes_t pos) const;
+       void      update_length (sframes_t pos, sframes_t cnt);
 
        virtual nframes_t available_peaks (double zoom) const;
 
@@ -108,6 +111,7 @@ class AudioSource : virtual public Source,
        static bool _build_missing_peakfiles;
        static bool _build_peakfiles;
 
+       sframes_t            _length;
        bool                 _peaks_built;
        mutable Glib::Mutex  _peaks_ready_lock;
        Glib::ustring         peakpath;
index 2b893478d46b7728740684f879802abdd635812e..4ad2ab551d4f93cc61187b6d05220e9429db09da 100644 (file)
@@ -129,7 +129,7 @@ class Crossfade : public ARDOUR::AudioRegion
        AutomationList& fade_in() { return _fade_in; } 
        AutomationList& fade_out() { return _fade_out; }
 
-       nframes_t set_length (nframes_t);
+       nframes_t set_xfade_length (nframes_t);
 
        bool is_dependent() const { return true; }
        bool depends_on (boost::shared_ptr<Region> other) const { 
index 0760fb7268603bca0590a436fe86ebba1d88a91e..9f4041060e69d94756a52bb0b971025722719343 100644 (file)
@@ -115,6 +115,8 @@ class MidiRegion : public Region
 
        void recompute_at_start ();
        void recompute_at_end ();
+       
+       void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
 
        void switch_source(boost::shared_ptr<Source> source);
 
index ec454803dcbb073e090d6e5ce004d99e096940b8..0c18b096bd9c474b54725e31ae92bc752d009cdf 100644 (file)
@@ -69,6 +69,9 @@ class MidiSource : virtual public Source
 
        virtual void append_event_unlocked_frames(const Evoral::Event<nframes_t>& ev,
                        sframes_t position) = 0;
+       
+       virtual sframes_t length (sframes_t pos) const;
+       virtual void      update_length (sframes_t pos, sframes_t cnt);
 
        virtual void mark_streaming_midi_write_started (NoteMode mode, sframes_t start_time);
        virtual void mark_streaming_write_started ();
@@ -118,15 +121,18 @@ class MidiSource : virtual public Source
                        sframes_t position,
                        nframes_t cnt) = 0;
        
-       std::string         _captured_for;
-       mutable uint32_t    _read_data_count;  ///< modified in read()
-       mutable uint32_t    _write_data_count; ///< modified in write()
+       std::string      _captured_for;
+       mutable uint32_t _read_data_count;  ///< modified in read()
+       mutable uint32_t _write_data_count; ///< modified in write()
        
        boost::shared_ptr<MidiModel> _model;
        bool                         _writing;
        
        mutable Evoral::Sequence<double>::const_iterator _model_iter;
-       mutable sframes_t                                _last_read_end;
+       
+       mutable double    _length_beats;
+       mutable sframes_t _last_read_end;
+       sframes_t         _last_write_end;
 
   private:
        bool file_changed (std::string path);
index a4ce35b61b933f3b1981cb5c1c9e664fd5ae12bf..2696c7da91a40b44a08cf8565fc3863dbe172b07 100644 (file)
@@ -120,6 +120,8 @@ class Region
        nframes_t length()    const { return _length; }
        layer_t   layer ()    const { return _layer; }
 
+       sframes_t source_length(uint32_t n) const;
+
        /* these two are valid ONLY during a StateChanged signal handler */
 
        nframes_t last_position() const { return _last_position; }
@@ -288,7 +290,7 @@ class Region
        void send_change (Change);
 
        void trim_to_internal (nframes_t position, nframes_t length, void *src);
-       void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
+       virtual void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
 
        bool copied() const { return _flags & Copied; }
        void maybe_uncopy ();
index 36d7e1fe96f0e466e85ee5d31c3d737c9cdc582a..7905debbcc16cc12eb0c4802edd9b418929f33fb 100644 (file)
@@ -61,7 +61,8 @@ class Source : public SessionObject, public boost::noncopyable
        time_t timestamp() const { return _timestamp; }
        void stamp (time_t when) { _timestamp = when; }
        
-       sframes_t length() const { return _length; }
+       virtual sframes_t length (sframes_t pos) const = 0;
+       virtual void      update_length (sframes_t pos, sframes_t cnt) = 0;
        
        virtual const Glib::ustring& path() const = 0;
 
@@ -104,10 +105,8 @@ class Source : public SessionObject, public boost::noncopyable
        std::string get_transients_path() const;
        int load_transients (const std::string&);
        
-       void update_length (sframes_t pos, sframes_t cnt);
-       
-       int64_t timeline_position() const { return _timeline_position; }
-       virtual void set_timeline_position (int64_t pos);
+       sframes_t    timeline_position() const { return _timeline_position; }
+       virtual void set_timeline_position (sframes_t pos);
        
        void set_allow_remove_if_empty (bool yn);
        
@@ -118,8 +117,7 @@ class Source : public SessionObject, public boost::noncopyable
        DataType            _type;
        Flag                _flags;
        time_t              _timestamp;
-       sframes_t           _length;
-       int64_t             _timeline_position;
+       sframes_t           _timeline_position;
        bool                _analysed;
        mutable Glib::Mutex _lock;
        mutable Glib::Mutex _analysis_lock;
index ed8027ec59204a342a7d32816de33d627f0fde88..e08118c0fc7654f0ed064a716f73027a7d93c868 100644 (file)
@@ -2373,9 +2373,9 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
        
        try {
                region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
-                               pending_sources, 0, first_fs->length(),
-                         region_name_from_path (first_fs->name(), true), 0,
-                         Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
+                               pending_sources, 0, first_fs->length(first_fs->timeline_position()),
+                               region_name_from_path (first_fs->name(), true), 0,
+                               Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
                region->special_set_position (0);
        }
 
@@ -2389,7 +2389,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
 
        try {
                region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (
-                               pending_sources, 0, first_fs->length(),
+                               pending_sources, 0, first_fs->length(first_fs->timeline_position()),
                                region_name_from_path (first_fs->name(), true)));
        }
 
index df648bc05568f6b59a6cb8c61d484f61672a85f2..2e1a26657796d4764570982f8d83f44557986fc3 100644 (file)
@@ -897,10 +897,11 @@ AudioTrack::freeze (InterThreadInfo& itt)
 
        /* create a new region from all filesources, keep it private */
 
-       boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(), 
-                                                                region_name, 0, 
-                                                                (Region::Flag) (Region::WholeFile|Region::DefaultFlags),
-                                                                false));
+       boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0,
+                       srcs[0]->length(srcs[0]->timeline_position()), 
+                       region_name, 0,
+                       (Region::Flag) (Region::WholeFile|Region::DefaultFlags),
+                       false));
 
        new_playlist->set_orig_diskstream_id (diskstream->id());
        new_playlist->add_region (region, _session.current_start_frame());
index aafa67e7d3da8b63e91482205ee7e2385faa4c11..3ea00deb59773d00e46e7e29e196a9260c7a6954 100644 (file)
@@ -348,14 +348,18 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
                nframes_t read_frames, nframes_t skip_frames) 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));
+       return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer,
+                       file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0));
 }
 
 nframes_t
 AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
                sframes_t position, nframes_t cnt, uint32_t chan_n) const
 {
-       return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 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);
 }
 
 nframes_t
index 15f35bf1f1cd76a8429161d7766940e2cd6e933f..24ca406b38337e62bb3689c86134c980ef2878ed 100644 (file)
@@ -57,6 +57,7 @@ bool AudioSource::_build_peakfiles = false;
 
 AudioSource::AudioSource (Session& s, ustring name)
        : Source (s, DataType::AUDIO, name)
+       , _length (0)
 {
        _peaks_built = false;
        _peak_byte_max = 0;
@@ -70,6 +71,7 @@ AudioSource::AudioSource (Session& s, ustring name)
 
 AudioSource::AudioSource (Session& s, const XMLNode& node) 
        : Source (s, node)
+       , _length (0)
 {
        
        _peaks_built = false;
@@ -125,6 +127,21 @@ AudioSource::set_state (const XMLNode& node)
        return 0;
 }
 
+sframes_t
+AudioSource::length (sframes_t pos) const
+{
+       return _length;
+}
+
+void
+AudioSource::update_length (sframes_t pos, sframes_t cnt)
+{
+       if (pos + cnt > _length) {
+               _length = pos + cnt;
+       }
+}
+
+
 /***********************************************************************
   PEAK FILE STUFF
  ***********************************************************************/
@@ -211,7 +228,7 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
                
                /* we found it in the peaks dir, so check it out */
                
-               if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) {
+               if (statbuf.st_size == 0 || ((nframes_t) statbuf.st_size < ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) {
                        // empty
                        _peaks_built = false;
                } else {
@@ -895,10 +912,8 @@ AudioSource::file_changed (ustring path)
 nframes_t
 AudioSource::available_peaks (double zoom_factor) const
 {
-       off_t end;
-
        if (zoom_factor < _FPP) {
-               return length(); // peak data will come from the audio file
+               return length(_timeline_position); // peak data will come from the audio file
        } 
        
        /* peak data comes from peakfile, but the filesize might not represent
@@ -907,7 +922,7 @@ AudioSource::available_peaks (double zoom_factor) const
           but _peak_byte_max only monotonically increases after initialization.
        */
 
-       end = _peak_byte_max;
+       off_t end = _peak_byte_max;
 
        return (end/sizeof(PeakData)) * _FPP;
 }
index 5d180ceccc9dcaa3861285f989fcae62c9a56939..9d10f1d1cccabc9fccc8477ce69a5026258acd79 100644 (file)
@@ -187,7 +187,7 @@ Crossfade::Crossfade (boost::shared_ptr<Crossfade> orig, boost::shared_ptr<Audio
        layer_relation = (int32_t) (_in->layer() - _out->layer());
 
        // Let's make sure the fade isn't too long
-       set_length(_length);
+       set_xfade_length(_length);
 }
 
 
@@ -869,16 +869,16 @@ Crossfade::set_follow_overlap (bool yn)
        _follow_overlap = yn;
 
        if (!yn) {
-               set_length (_short_xfade_length);
+               set_xfade_length (_short_xfade_length);
        } else {
-               set_length (_out->first_frame() + _out->length() - _in->first_frame());
+               set_xfade_length (_out->first_frame() + _out->length() - _in->first_frame());
        }
 
        StateChanged (FollowOverlapChanged);
 }
 
 nframes_t
-Crossfade::set_length (nframes_t len)
+Crossfade::set_xfade_length (nframes_t len)
 {
        nframes_t limit = 0;
 
index ed9c80338abeb30724e6cf0d90972a4dbe7b5cca..649fc6156b5bf641f33ae3a4e74120c2e58ae98f 100644 (file)
@@ -77,13 +77,12 @@ FileSource::removable () const
 {
        return (_flags & Removable)
                && (   (_flags & RemoveAtDestroy)
-                       || ((_flags & RemovableIfEmpty) && length() == 0));
+                       || ((_flags & RemovableIfEmpty) && length(timeline_position()) == 0));
 }
 
 int
 FileSource::init (const ustring& pathstr, bool must_exist)
 {
-       _length = 0;
        _timeline_position = 0;
 
        if (!find (_type, pathstr, must_exist, _file_is_new, _channel)) {
index 5eea77ebcacd985895ba9fe34b9172177ea40930..a30b837c5f73465e5d9f5bbf7f613d8406d84753 100644 (file)
@@ -116,6 +116,19 @@ MidiRegion::~MidiRegion ()
 {
 }
 
+void
+MidiRegion::set_position_internal (nframes_t pos, bool allow_bbt_recompute)
+{
+       BeatsFramesConverter old_converter(_session, _position - _start);
+       double length_beats = old_converter.from(_length);
+
+       Region::set_position_internal(pos, allow_bbt_recompute);
+       
+       BeatsFramesConverter new_converter(_session, pos - _start);
+
+       set_length(new_converter.to(length_beats), 0);
+}
+
 nframes_t
 MidiRegion::read_at (MidiRingBuffer<nframes_t>& out, sframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
 {
index bb5179d2bbb3ea3f53ed09702811a5505746ed81..7cb8cbb83e3798317c523a1c3749a771de7564af 100644 (file)
@@ -54,7 +54,9 @@ MidiSource::MidiSource (Session& s, string name, Source::Flag flags)
        , _read_data_count(0)
        , _write_data_count(0)
        , _writing (false)
+       , _length_beats(0.0)
        , _last_read_end(0)
+       , _last_write_end(0)
 {
 }
 
@@ -63,7 +65,9 @@ MidiSource::MidiSource (Session& s, const XMLNode& node)
        , _read_data_count(0)
        , _write_data_count(0)
        , _writing (false)
+       , _length_beats(0.0)
        , _last_read_end(0)
+       , _last_write_end(0)
 {
        _read_data_count = 0;
        _write_data_count = 0;
@@ -101,6 +105,19 @@ MidiSource::set_state (const XMLNode& node)
        return 0;
 }
 
+sframes_t
+MidiSource::length (sframes_t pos) const
+{
+       BeatsFramesConverter converter(_session, pos);
+       return converter.to(_length_beats);
+}
+
+void
+MidiSource::update_length (sframes_t pos, sframes_t cnt)
+{
+       // You're not the boss of me!
+}
+
 void
 MidiSource::invalidate ()
 {
@@ -150,7 +167,9 @@ nframes_t
 MidiSource::midi_write (MidiRingBuffer<nframes_t>& dst, sframes_t position, nframes_t cnt)
 {
        Glib::Mutex::Lock lm (_lock);
-       return write_unlocked (dst, position, cnt);
+       const nframes_t ret = write_unlocked (dst, position, cnt);
+       _last_write_end = position + cnt;
+       return ret;
 }
 
 bool
@@ -172,17 +191,21 @@ MidiSource::mark_streaming_midi_write_started (NoteMode mode, sframes_t start_fr
                _model->set_note_mode(mode);
                _model->start_write();
        }
-       
+
+       _last_write_end = start_frame;
        _writing = true;
 }
 
 void
 MidiSource::mark_streaming_write_started ()
 {
+       sframes_t start_frame = _session.transport_frame();
+
        if (_model) {
                _model->start_write();
        }
 
+       _last_write_end = start_frame;
        _writing = true;
 }
 
@@ -190,7 +213,7 @@ void
 MidiSource::mark_streaming_write_completed ()
 {
        if (_model) {
-               _model->end_write(false); // FIXME: param?
+               _model->end_write(false);
        }
 
        _writing = false;
index 70e9eba9bac85e790957afcc8dbec658323daeda..cae564832dc53f22a46f7178eb54289fcaadcd95 100644 (file)
@@ -1534,6 +1534,12 @@ Region::source_equivalent (boost::shared_ptr<const Region> other) const
        return true;
 }
 
+sframes_t
+Region::source_length(uint32_t n) const
+{
+       return _sources[n]->length(_position - _start);
+}
+
 bool
 Region::verify_length (nframes_t len)
 {
@@ -1544,7 +1550,7 @@ Region::verify_length (nframes_t len)
        nframes_t maxlen = 0;
 
        for (uint32_t n=0; n < _sources.size(); ++n) {
-               maxlen = max (maxlen, (nframes_t)_sources[n]->length() - _start);
+               maxlen = max (maxlen, (nframes_t)source_length(n) - _start);
        }
        
        len = min (len, maxlen);
@@ -1562,7 +1568,7 @@ Region::verify_start_and_length (nframes_t new_start, nframes_t& new_length)
        nframes_t maxlen = 0;
 
        for (uint32_t n=0; n < _sources.size(); ++n) {
-               maxlen = max (maxlen, (nframes_t)_sources[n]->length() - new_start);
+               maxlen = max (maxlen, (nframes_t)source_length(n) - new_start);
        }
 
        new_length = min (new_length, maxlen);
@@ -1578,7 +1584,7 @@ Region::verify_start (nframes_t pos)
        }
 
        for (uint32_t n=0; n < _sources.size(); ++n) {
-               if (pos > _sources[n]->length() - _length) {
+               if (pos > source_length(n) - _length) {
                        return false;
                }
        }
@@ -1593,8 +1599,8 @@ Region::verify_start_mutable (nframes_t& new_start)
        }
 
        for (uint32_t n=0; n < _sources.size(); ++n) {
-               if (new_start > _sources[n]->length() - _length) {
-                       new_start = _sources[n]->length() - _length;
+               if (new_start > source_length(n) - _length) {
+                       new_start = source_length(n) - _length;
                }
        }
        return true;
index 742a65962e64e4987030a8a56cc5afbf55acfbe5..0de20bfcac6a3cddc6f9419e9f8a578341c03bac 100644 (file)
@@ -109,7 +109,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs,
        */
 
        if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
-               AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(), name, layer, flags);
+               AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(srcs.front()->timeline_position()), name, layer, flags);
                boost::shared_ptr<AudioRegion> arp (ar);
                boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
                if (announce) {
index e55167ff0891a82ca2f45d69ba751e395a8a719f..b9144aa3b6a083ea3a4d35267c47cc2ad9d5ee32 100644 (file)
@@ -4087,8 +4087,9 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
 
                /* construct a region to represent the bounced material */
 
-               result = RegionFactory::create (srcs, 0, srcs.front()->length(), 
-                                               region_name_from_path (srcs.front()->name(), true));
+               result = RegionFactory::create (srcs, 0,
+                               srcs.front()->length(srcs.front()->timeline_position()), 
+                               region_name_from_path (srcs.front()->name(), true));
        }
 
   out:
index 3f9a48134067834e2c4bfbdd6c3c1424cc9c938b..beacb192f167b925165bb6757cf4d073f70ed8e4 100644 (file)
@@ -995,7 +995,7 @@ Session::state(bool full_state)
                        boost::shared_ptr<AudioFileSource> fs;
                        if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
                                if (!fs->destructive()) {
-                                       if (fs->length() == 0) {
+                                       if (fs->length(fs->timeline_position()) == 0) {
                                                continue;
                                        }
                                }
@@ -2560,7 +2560,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                   capture files.
                */
 
-               if (!i->second->used() && i->second->length() > 0) {
+               if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
                        dead_sources.push_back (i->second);
                        i->second->GoingAway();
                } 
index 7e707b1821084dbb97b6434a24442aef2e357e5e..74ee1fd6809ef00e4478716da6d0d96f58bc497f 100644 (file)
@@ -182,16 +182,17 @@ SMFSource::write_unlocked (MidiRingBuffer<nframes_t>& src, sframes_t position, n
                _model->start_write();
        }
 
-       Evoral::MIDIEvent<nframes_t> ev(0, 0.0, 4, NULL, true);
+       Evoral::MIDIEvent<nframes_t> ev;
 
        while (true) {
                bool ret = src.peek_time(&time);
-               if (!ret || time - position > _length + dur) {
+               if (!ret || time > _last_write_end + dur) {
                        break;
                }
 
                ret = src.read_prefix(&time, &type, &size);
                if (!ret) {
+                       cerr << "ERROR: Unable to read event prefix, corrupt MIDI ring buffer" << endl;
                        break;
                }
 
@@ -227,10 +228,7 @@ SMFSource::write_unlocked (MidiRingBuffer<nframes_t>& src, sframes_t position, n
        Evoral::SMF::flush();
        free(buf);
 
-       const sframes_t oldlen = _length;
-       update_length(oldlen, dur);
-
-       ViewDataRangeReady(position + oldlen, dur); /* EMIT SIGNAL */
+       ViewDataRangeReady(position + _last_write_end, dur); /* EMIT SIGNAL */
 
        return dur;
 }
@@ -254,6 +252,8 @@ SMFSource::append_event_unlocked_beats (const Evoral::Event<double>& ev)
                return;
        }
        
+       _length_beats = max(_length_beats, ev.time());
+       
        const double delta_time_beats   = ev.time() - _last_ev_time_beats;
        const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn());
 
@@ -287,6 +287,8 @@ SMFSource::append_event_unlocked_frames (const Evoral::Event<nframes_t>& ev, sfr
        
        BeatsFramesConverter converter(_session, position);
        
+       _length_beats = max(_length_beats, converter.from(ev.time()));
+       
        const sframes_t delta_time_frames = ev.time() - _last_ev_time_frames;
        const double    delta_time_beats  = converter.from(delta_time_frames);
        const uint32_t  delta_time_ticks  = (uint32_t)(lrint(delta_time_beats * (double)ppqn()));
@@ -405,6 +407,8 @@ SMFSource::load_model (bool lock, bool force_reload)
                        scratch_size = ev.size();
                }
                ev.size() = scratch_size; // ensure read_event only allocates if necessary
+               
+               _length_beats = max(_length_beats, ev.time());
        }
 
        set_default_controls_interpolation();
index 5c2ac132e11be32c6cf039bf96147cbd6dbee97e..61ace5a72b843297dd1b0fb1c66d8e2cf6d81cd8 100644 (file)
@@ -54,7 +54,6 @@ Source::Source (Session& s, DataType type, const string& name, Flag flags)
 {
        _analysed = false;
        _timestamp = 0;
-       _length = 0;
        _in_use = 0;
 }
 
@@ -65,7 +64,6 @@ Source::Source (Session& s, const XMLNode& node)
        , _timeline_position(0)
 {
        _timestamp = 0;
-       _length = 0;
        _analysed = false;
        _in_use = 0;
 
@@ -139,14 +137,6 @@ Source::set_state (const XMLNode& node)
        return 0;
 }
 
-void
-Source::update_length (sframes_t pos, sframes_t cnt)
-{
-       if (pos + cnt > _length) {
-               _length = pos + cnt;
-       }
-}
-
 void
 Source::add_playlist (boost::shared_ptr<Playlist> pl)
 {