#include <sys/time.h>
#include <sys/stat.h>
+#include <stdio.h> // for rename(), sigh
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <pbd/convert.h>
+#include <pbd/basename.h>
#include <pbd/mountpoint.h>
#include <pbd/pathscanner.h>
#include <pbd/stl_delete.h>
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
+#include <glibmm/thread.h>
#include <ardour/audiofilesource.h>
#include <ardour/sndfile_helpers.h>
/* XXX maybe this too */
char AudioFileSource::bwf_serial_number[13] = "000000000000";
+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;
+
AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags)
: AudioSource (s, path), _flags (flags),
_channel (0)
int
AudioFileSource::init (ustring pathstr, bool must_exist)
{
- bool is_new = false;
-
_length = 0;
timeline_position = 0;
_peaks_built = false;
- file_is_new = false;
- if (!find (pathstr, must_exist, is_new, _channel)) {
+ if (!find (pathstr, must_exist, file_is_new, _channel)) {
throw non_existent_source ();
}
- if (is_new && must_exist) {
+ if (file_is_new && must_exist) {
return -1;
}
ustring
AudioFileSource::peak_path (ustring audio_path)
{
- return _session.peak_path_from_audio_path (audio_path);
+ ustring base;
+
+ base = PBD::basename_nosuffix (audio_path);
+ base += '%';
+ base += (char) ('A' + _channel);
+
+ return _session.peak_path (base);
+}
+
+ustring
+AudioFileSource::find_broken_peakfile (ustring peak_path, ustring audio_path)
+{
+ ustring str;
+
+ /* check for the broken location in use by 2.0 for several months */
+
+ str = broken_peak_path (audio_path);
+
+ if (Glib::file_test (str, Glib::FILE_TEST_EXISTS)) {
+
+ if (is_embedded()) {
+
+ /* it would be nice to rename it but the nature of
+ the bug means that we can't reliably use it.
+ */
+
+ peak_path = str;
+
+ } else {
+ /* all native files are mono, so we can just rename
+ it.
+ */
+ ::rename (str.c_str(), peak_path.c_str());
+ }
+
+ } else {
+ /* Nasty band-aid for older sessions that were created before we
+ used libsndfile for all audio files.
+ */
+
+
+ str = old_peak_path (audio_path);
+ if (Glib::file_test (str, Glib::FILE_TEST_EXISTS)) {
+ peak_path = str;
+ }
+ }
+
+ return peak_path;
+}
+
+ustring
+AudioFileSource::broken_peak_path (ustring audio_path)
+{
+ ustring res;
+
+ res = _session.peak_dir ();
+ res += PBD::basename_nosuffix (audio_path);
+ res += ".peak";
+
+ return res;
}
ustring
bool
AudioFileSource::is_empty (Session& s, ustring path)
{
- bool ret = false;
- boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (s, path, 0, NoPeakFile, false));
-
- if (afs) {
- ret = (afs->length() == 0);
+ SoundFileInfo info;
+ string err;
+
+ if (!get_soundfile_info (path, info, err)) {
+ /* dangerous: we can't get info, so assume that its not empty */
+ return false;
}
- return ret;
+ return info.length == 0;
}
int
{
return !(file.rfind(".wav") == ustring::npos &&
file.rfind(".aiff")== ustring::npos &&
+ file.rfind(".caf")== ustring::npos &&
file.rfind(".aif") == ustring::npos &&
+ file.rfind(".amb") == ustring::npos &&
file.rfind(".snd") == ustring::npos &&
file.rfind(".au") == ustring::npos &&
file.rfind(".raw") == ustring::npos &&
_flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename));
}
}
+
+
+Sample*
+AudioFileSource::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;
+}