From 43495d7f2b4ee4189e7b5497539ebe8eb126a3aa Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 28 May 2011 00:59:53 +0000 Subject: [PATCH] putative fix for crashes related to diskstream playback buffer refills with compound regions git-svn-id: svn://localhost/ardour2/branches/3.0@9620 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audiosource.h | 4 ++-- libs/ardour/audio_playlist_source.cc | 4 ++-- libs/ardour/audioregion.cc | 11 --------- libs/ardour/audiosource.cc | 35 ++++++++++++++++++++++------ libs/ardour/session_state.cc | 3 ++- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index d0d34a55c4..93ad5d0767 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -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_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; diff --git a/libs/ardour/audio_playlist_source.cc b/libs/ardour/audio_playlist_source.cc index 393f90938b..09b30ff87a 100644 --- a/libs/ardour/audio_playlist_source.cc +++ b/libs/ardour/audio_playlist_source.cc @@ -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; } diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index bb67268a4a..447e4b8d95 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -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; } diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index ffb8068ea5..9555f18fbe 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -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]); } } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 3c2496eba5..2db17f1e58 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -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 (); -- 2.30.2