#include <sys/stat.h>
#include <glibmm/miscutils.h>
-
+#include <glibmm/thread.h>
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/utils.h>
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)
{
case FormatInt24:
fmt |= SF_FORMAT_PCM_24;
break;
+
+ case FormatInt16:
+ fmt |= SF_FORMAT_PCM_16;
+ break;
}
_info.channels = 1;
// 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;
update_length (oldlen, cnt);
if (_build_peakfiles) {
- compute_and_write_peaks (data, frame_pos, cnt, false);
+ compute_and_write_peaks (data, frame_pos, cnt, false, true);
}
_write_data_count = cnt;
update_length (file_pos, cnt);
if (_build_peakfiles) {
- compute_and_write_peaks (data, file_pos, cnt, false);
+ compute_and_write_peaks (data, file_pos, cnt, false, true);
}
file_pos += cnt;
return;
}
- _broadcast_info->time_reference_high = (timeline_position >> 32);
- _broadcast_info->time_reference_low = (timeline_position & 0xffffffff);
+ _broadcast_info->time_reference_high = (timeline_position >> 32);
+ _broadcast_info->time_reference_low = (timeline_position & 0xffffffff);
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
ret |= (uint32_t) binfo->time_reference_low;
return ret;
}
+
+bool
+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);
+ }
+
+ if (ssb->size < size) {
+ ssb = new SizedSampleBuffer (size);
+ thread_interleave_buffer.set (ssb);
+ }
+
+ return ssb->buf;
+}