putative fix for crashes related to diskstream playback buffer refills with compound...
authorPaul Davis <paul@linuxaudiosystems.com>
Sat, 28 May 2011 00:59:53 +0000 (00:59 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 28 May 2011 00:59:53 +0000 (00:59 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@9620 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/audiosource.h
libs/ardour/audio_playlist_source.cc
libs/ardour/audioregion.cc
libs/ardour/audiosource.cc
libs/ardour/session_state.cc

index d0d34a55c4054dfe072b6c1fd7bbbf87149d3aad..93ad5d0767e027ea2eb68560c017fe1834a14d87 100644 (file)
@@ -106,7 +106,7 @@ class AudioSource : virtual public Source,
        /** @return true if the each source sample s must be clamped to -1 < s < 1 */
        virtual bool clamped_at_unity () const = 0;
 
-       static void allocate_working_buffers ();
+       static void allocate_working_buffers (framecnt_t framerate);
     
   protected:
        static bool _build_missing_peakfiles;
@@ -124,7 +124,7 @@ class AudioSource : virtual public Source,
        static std::vector<gain_t*> _gain_buffers;
        static Glib::StaticMutex    _level_buffer_lock;
 
-       static void ensure_buffers_for_level (uint32_t);
+       static void ensure_buffers_for_level (uint32_t, framecnt_t);
 
        framecnt_t           _length;
        std::string         peakpath;
index 393f90938b4e920acb2dd24b622b787cbd3ce339..09b30ff87a628434b3d752673b0c9fd70159add0 100644 (file)
@@ -54,7 +54,7 @@ AudioPlaylistSource::AudioPlaylistSource (Session& s, const ID& orig, const std:
        , _playlist_channel (chn)
 {
        AudioSource::_length = len;
-       ensure_buffers_for_level (_level);
+       ensure_buffers_for_level (_level, _session.frame_rate());
 }
 
 AudioPlaylistSource::AudioPlaylistSource (Session& s, const XMLNode& node)
@@ -122,7 +122,7 @@ AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_desc
 
        sscanf (prop->value().c_str(), "%" PRIu32, &_playlist_channel);
 
-       ensure_buffers_for_level (_level);
+       ensure_buffers_for_level (_level, _session.frame_rate());
 
        return 0;
 }
index bb67268a4aea6aa95e28c4cb7c77f2de2839657e..447e4b8d953c8ec5fd9c6d6ac0f2afe2d311f8e9 100644 (file)
@@ -384,17 +384,6 @@ AudioRegion::_read_at (const SourceList& /*srcs*/, framecnt_t limit,
        framecnt_t to_read;
        bool raw = (rops == ReadOpsNone);
 
-       cerr << name() << " _read_at, limit = " << limit
-            << " pos " << position 
-            << " cnt " << cnt
-            << " chan " << chan_n
-            << " rops " << hex << rops << dec
-            << endl;
-       
-       if (cnt > 64 * 1024) {
-               abort ();
-       }
-
        if (n_channels() == 0) {
                return 0;
        }
index ffb8068ea57a846a44bc4d257dfa4afe3f542f2f..9555f18fbe8833666419a3e5de91ec8e40e464c6 100644 (file)
@@ -965,24 +965,45 @@ AudioSource::mark_streaming_write_completed ()
 }
 
 void
-AudioSource::allocate_working_buffers()
+AudioSource::allocate_working_buffers (framecnt_t framerate)
 {
-       assert(AudioDiskstream::disk_io_frames() > 0);
-       _working_buffers_size = AudioDiskstream::disk_io_frames();
-       /* we don't need any buffers allocated until
+       uint32_t current_level;
+       
+       {
+               Glib::Mutex::Lock lm (_level_buffer_lock);
+               current_level = _mixdown_buffers.size();
+       }
+
+       /* Note: we don't need any buffers allocated until
           a level 1 audiosource is created, at which
           time we'll call ::ensure_buffers_for_level()
           with the right value and do the right thing.
        */
+       
+       if (current_level) {
+               ensure_buffers_for_level (current_level, framerate);
+       }
 }
 
 void
-AudioSource::ensure_buffers_for_level (uint32_t level) 
+AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate
 {
+       framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
+
+       cerr << "audiosource: allocate buffers for level " << level << " size = " << nframes << endl;
+
        Glib::Mutex::Lock lm (_level_buffer_lock);
 
+       /* this will leak memory. oh well. rather complex
+          to stop it from doing that without using shared_ptrs,
+          which i might do next. paul - may 27th 2011
+        */
+
+       _mixdown_buffers.clear ();
+       _gain_buffers.clear ();
+
        while (_mixdown_buffers.size() < level) {
-               _mixdown_buffers.push_back (new Sample[_working_buffers_size]);
-               _gain_buffers.push_back (new gain_t[_working_buffers_size]);
+               _mixdown_buffers.push_back (new Sample[nframes]);
+               _gain_buffers.push_back (new gain_t[nframes]);
        }
 }
index 3c2496eba591d3567c14b9703bd19c25070ed368..2db17f1e58910dbcf73f30db5caf6e8f0f2c2e1c 100644 (file)
@@ -221,7 +221,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
         _speakers.reset (new Speakers);
 
        AudioDiskstream::allocate_working_buffers();
-       AudioSource::allocate_working_buffers ();
 
        /* default short fade = 15ms */
 
@@ -3559,6 +3558,8 @@ Session::config_changed (std::string p, bool ours)
                solo_control_mode_changed ();
        } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
                last_timecode_valid = false;
+       } else if (p == "playback-buffer-seconds") {
+               AudioSource::allocate_working_buffers (frame_rate());
        }
 
        set_dirty ();