SF_INFO _info;
SF_BROADCAST_INFO *_broadcast_info;
- mutable float *interleave_buf;
- mutable nframes_t interleave_bufsize;
-
void init ();
int open();
void close();
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
#include <sys/stat.h>
#include <glibmm/miscutils.h>
+#include <glibmm/thread.h>
#include <pbd/stacktrace.h>
#include <ardour/sndfilesource.h>
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<SizedSampleBuffer> thread_interleave_buffer = GLIBMM_STATIC_PRIVATE_INIT;
SndFileSource::SndFileSource (Session& s, const XMLNode& node)
: AudioFileSource (s, node)
// 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;
touch_peakfile ();
}
- if (interleave_buf) {
- delete [] interleave_buf;
- }
-
if (_broadcast_info) {
delete _broadcast_info;
}
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;
{
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;
+}