From be0da8ff5c1a3bfbdf0a2934a79aeeed26ade3bc Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 14 Apr 2014 03:03:35 -0400 Subject: merge 5764970709f15e85ec30c9cea89c318eb8114c58 from cairocanvas as final(?) change related to data loss --- libs/ardour/ardour/file_source.h | 1 + libs/ardour/coreaudiosource.cc | 15 +++++++++++++- libs/ardour/file_source.cc | 27 +++++++++++-------------- libs/ardour/session.cc | 9 +++++++++ libs/ardour/smf_source.cc | 10 ++++++++-- libs/ardour/sndfilesource.cc | 43 +++++++++++++++++++++++++++++----------- 6 files changed, 75 insertions(+), 30 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h index f1b42aa2ae..3acc62ed20 100644 --- a/libs/ardour/ardour/file_source.h +++ b/libs/ardour/ardour/file_source.h @@ -84,6 +84,7 @@ public: virtual void prevent_deletion (); + void existence_check (); virtual void prevent_deletion (); protected: diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index 947c66e756..010905d120 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -28,6 +28,8 @@ #include #include +#include + #include "i18n.h" #include @@ -36,21 +38,32 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +/** Create a new CoreAudioSource using session state, which implies that the + * file must already exist. + */ CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node) : Source (s, node) , AudioFileSource (s, node) { init_cafile (); + + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); } +/** Create a new CoreAudioSource from an existing file. Sources created with this + * method are never writable or removable. + */ CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags) - /* files created this way are never writable or removable */ : Source (s, DataType::AUDIO, path, Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))), AudioFileSource (s, path, Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { _channel = chn; init_cafile (); + + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); } void diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index f9abda0ab3..de2783a1ac 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -62,8 +62,6 @@ FileSource::FileSource (Session& session, DataType type, const string& path, con , _open (false) { set_within_session_from_path (path); - - prevent_deletion (); } FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/) @@ -77,8 +75,6 @@ FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist _path = _name; _within_session = true; - - prevent_deletion (); } FileSource::~FileSource() @@ -86,20 +82,21 @@ FileSource::~FileSource() } void -FileSource::prevent_deletion () +FileSource::existence_check () { - /* if this file already exists, it cannot be removed, ever - */ - if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)) { - cerr << " ... " << _path << " already exists, marking immutable\n"; + prevent_deletion (); + } +} - if (!(_flags & Destructive)) { - mark_immutable (); - } else { - _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); - } - } +void +FileSource::prevent_deletion () +{ + if (!(_flags & Destructive)) { + mark_immutable (); + } else { + _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy)); + } } bool diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index c9e0068431..1de5730a95 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3470,6 +3470,15 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha break; } + /* it is possible that we have the path already + * assigned to a source that has not yet been written + * (ie. the write source for a diskstream). we have to + * check this in order to make sure that our candidate + * path isn't used again, because that can lead to + * two Sources point to the same file with different + * notions of their removability. + */ + string possible_path = Glib::build_filename (spath, buf); if (source_by_path (possible_path)) { diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index ad238e27e1..90e50e6f44 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -62,9 +62,12 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags) { /* note that origin remains empty */ - if (init(_path, false)) { + if (init (_path, false)) { throw failed_constructor (); } + + assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); /* file is not opened until write */ @@ -93,10 +96,13 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist) throw failed_constructor (); } - if (init(_path, true)) { + if (init (_path, true)) { throw failed_constructor (); } + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + if (open(_path)) { throw failed_constructor (); } diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index cf75cffba3..6b019f6fd0 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -30,6 +30,10 @@ #include #include +#ifdef PLATFORM_WINDOWS +#include +#endif +#include #include #include "ardour/sndfilesource.h" @@ -56,9 +60,18 @@ const Source::Flag SndFileSource::default_writable_flags = Source::Flag ( SndFileSource::SndFileSource (Session& s, const XMLNode& node) : Source(s, node) , AudioFileSource (s, node) + , _descriptor (0) + , _broadcast_info (0) + , _capture_start (false) + , _capture_end (false) + , file_pos (0) + , xfade_buf (0) { init_sndfile (); + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + if (open()) { throw failed_constructor (); } @@ -69,11 +82,20 @@ SndFileSource::SndFileSource (Session& s, const string& path, int chn, Flag flag : Source(s, DataType::AUDIO, path, flags) /* note that the origin of an external file is itself */ , AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) + , _descriptor (0) + , _broadcast_info (0) + , _capture_start (false) + , _capture_end (false) + , file_pos (0) + , xfade_buf (0) { _channel = chn; init_sndfile (); + assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + if (open()) { throw failed_constructor (); } @@ -84,11 +106,20 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig SampleFormat sfmt, HeaderFormat hf, framecnt_t rate, Flag flags) : Source(s, DataType::AUDIO, path, flags) , AudioFileSource (s, path, origin, flags, sfmt, hf) + , _descriptor (0) + , _broadcast_info (0) + , _capture_start (false) + , _capture_end (false) + , file_pos (0) + , xfade_buf (0) { int fmt = 0; init_sndfile (); + assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS)); + existence_check (); + _file_is_new = true; switch (hf) { @@ -155,24 +186,12 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig void SndFileSource::init_sndfile () { - string file; - - _descriptor = 0; - - // lets try to keep the object initalizations here at the top - xfade_buf = 0; - _broadcast_info = 0; - /* although libsndfile says we don't need to set this, valgrind and source code shows us that we do. */ memset (&_info, 0, sizeof(_info)); - _capture_start = false; - _capture_end = false; - file_pos = 0; - if (destructive()) { xfade_buf = new Sample[xfade_frames]; _timeline_position = header_position_offset; -- cgit v1.2.3