diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 916e9da49e..54964608ee 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -76,9 +76,6 @@ class SndFileSource : public AudioFileSource { SF_INFO _info; SF_BROADCAST_INFO *_broadcast_info; - mutable float *interleave_buf; - mutable nframes_t interleave_bufsize; - void init (); int open(); void close(); @@ -105,6 +102,8 @@ class SndFileSource : public AudioFileSource { void handle_header_position_change (); static int64_t get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists); + + static Sample* get_interleave_buffer (nframes_t size); }; } // namespace ARDOUR diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 9b0d5fabb3..9700f7f571 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -45,6 +46,20 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou AudioFileSource::Removable| AudioFileSource::RemovableIfEmpty| AudioFileSource::CanRename); +struct SizedSampleBuffer { + nframes_t size; + Sample* buf; + + SizedSampleBuffer (nframes_t sz) : size (sz) { + buf = new Sample[size]; + } + + ~SizedSampleBuffer() { + delete [] buf; + } +}; + +Glib::StaticPrivate thread_interleave_buffer = GLIBMM_STATIC_PRIVATE_INIT; SndFileSource::SndFileSource (Session& s, const XMLNode& node) : AudioFileSource (s, node) @@ -187,8 +202,6 @@ SndFileSource::init () // lets try to keep the object initalizations here at the top xfade_buf = 0; - interleave_buf = 0; - interleave_bufsize = 0; sf = 0; _broadcast_info = 0; @@ -273,10 +286,6 @@ SndFileSource::~SndFileSource () touch_peakfile (); } - if (interleave_buf) { - delete [] interleave_buf; - } - if (_broadcast_info) { delete _broadcast_info; } @@ -342,14 +351,7 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const real_cnt = cnt * _info.channels; - if (interleave_bufsize < real_cnt) { - - if (interleave_buf) { - delete [] interleave_buf; - } - interleave_bufsize = real_cnt; - interleave_buf = new float[interleave_bufsize]; - } + Sample* interleave_buf = get_interleave_buffer (real_cnt); nread = sf_read_float (sf, interleave_buf, real_cnt); ptr = interleave_buf + _channel; @@ -905,3 +907,24 @@ SndFileSource::one_of_several_channels () const { return _info.channels > 1; } + +Sample* +SndFileSource::get_interleave_buffer (nframes_t size) +{ + SizedSampleBuffer* ssb; + + if ((ssb = thread_interleave_buffer.get()) == 0) { + ssb = new SizedSampleBuffer (size); + thread_interleave_buffer.set (ssb); + cerr << pthread_self() << " new IB of " << size << endl; + } + + if (ssb->size < size) { + delete ssb; + ssb = new SizedSampleBuffer (size); + thread_interleave_buffer.set (ssb); + cerr << pthread_self() << " resized IB to " << size << endl; + } + + return ssb->buf; +}