second (and hopefully) final part of changes to respond to header format changes sensibly: lookup existing files correctly, and don't end up with gapped "take" numbers for successive files since we now remove ::removable() sources when switching to new ones (for audio)

git-svn-id: svn://localhost/ardour2/branches/3.0@7470 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2010-07-22 14:52:05 +00:00
parent 5c17bd3df2
commit 1c1b359ff2
5 changed files with 107 additions and 37 deletions

View File

@@ -61,6 +61,7 @@ public:
Glib::ustring& found_path);
void inc_use_count ();
bool removable () const;
protected:
FileSource (Session& session, DataType type,
@@ -75,8 +76,6 @@ protected:
virtual int move_dependents_to_trash() { return 0; }
void set_within_session_from_path (const std::string&);
bool removable () const;
Glib::ustring _path;
Glib::ustring _take_id;
bool _file_is_new;

View File

@@ -105,6 +105,7 @@ ARDOUR::MeterFalloff meter_falloff_from_float (float);
float meter_falloff_to_db_per_sec (float);
const char* native_header_format_extension (ARDOUR::HeaderFormat, const ARDOUR::DataType& type);
bool matching_unsuffixed_filename_exists_in (const std::string& dir, const std::string& name);
#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS)
std::string CFStringRefToStdString(CFStringRef stringRef);

View File

@@ -1931,11 +1931,22 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
capturing_sources.clear ();
for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
if (!destructive()) {
if ((*chan)->write_source && mark_write_complete) {
(*chan)->write_source->mark_streaming_write_completed ();
}
if ((*chan)->write_source) {
if ((*chan)->write_source->removable()) {
(*chan)->write_source->mark_for_remove ();
(*chan)->write_source->drop_references ();
_session.remove_source ((*chan)->write_source);
}
(*chan)->write_source.reset ();
}
use_new_write_source (n);
if (record_enabled()) {
@@ -1943,6 +1954,7 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
}
} else {
if ((*chan)->write_source == 0) {
use_new_write_source (n);
}

View File

@@ -2746,17 +2746,18 @@ Session::change_source_path_by_name (string path, string oldname, string newname
snprintf (buf, sizeof(buf), "%s-%u%s", newname.c_str(), cnt, suffix.c_str());
string p = Glib::build_filename (dir, buf);
if (!Glib::file_test (p, Glib::FILE_TEST_EXISTS)) {
path = p;
if (!matching_unsuffixed_filename_exists_in (dir, buf)) {
path = Glib::build_filename (dir, buf);
break;
}
path = "";
}
if (path == "") {
error << "FATAL ERROR! Could not find a " << endl;
if (path.empty()) {
fatal << string_compose (_("FATAL ERROR! Could not find a suitable version of %1 for a rename"),
newname) << endl;
/*NOTREACHED*/
}
}
@@ -2800,7 +2801,6 @@ Session::peak_path (Glib::ustring base) const
string
Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
{
string spath;
uint32_t cnt;
char buf[PATH_MAX+1];
const uint32_t limit = 10000;
@@ -2818,55 +2818,60 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
SessionDirectory sdir((*i).path);
spath = sdir.sound_path().to_string();
if (destructive) {
if (nchan < 2) {
snprintf (buf, sizeof(buf), "%s/T%04d-%s%s",
spath.c_str(), cnt, legalized.c_str(), ext.c_str());
snprintf (buf, sizeof(buf), "T%04d-%s%s",
cnt, legalized.c_str(), ext.c_str());
} else if (nchan == 2) {
if (chan == 0) {
snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L%s",
spath.c_str(), cnt, legalized.c_str(), ext.c_str());
snprintf (buf, sizeof(buf), "T%04d-%s%%L%s",
cnt, legalized.c_str(), ext.c_str());
} else {
snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R%s",
spath.c_str(), cnt, legalized.c_str(), ext.c_str());
snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
cnt, legalized.c_str(), ext.c_str());
}
} else if (nchan < 26) {
snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c%s",
spath.c_str(), cnt, legalized.c_str(), 'a' + chan, ext.c_str());
snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
cnt, legalized.c_str(), 'a' + chan, ext.c_str());
} else {
snprintf (buf, sizeof(buf), "%s/T%04d-%s%s",
spath.c_str(), cnt, legalized.c_str(), ext.c_str());
snprintf (buf, sizeof(buf), "T%04d-%s%s",
cnt, legalized.c_str(), ext.c_str());
}
} else {
spath += '/';
spath += legalized;
if (nchan < 2) {
snprintf (buf, sizeof(buf), "%s-%u%s", spath.c_str(), cnt, ext.c_str());
snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
} else if (nchan == 2) {
if (chan == 0) {
snprintf (buf, sizeof(buf), "%s-%u%%L%s", spath.c_str(), cnt, ext.c_str());
snprintf (buf, sizeof(buf), "%s-%u%%L%s", legalized.c_str(), cnt, ext.c_str());
} else {
snprintf (buf, sizeof(buf), "%s-%u%%R%s", spath.c_str(), cnt, ext.c_str());
snprintf (buf, sizeof(buf), "%s-%u%%R%s", legalized.c_str(), cnt, ext.c_str());
}
} else if (nchan < 26) {
snprintf (buf, sizeof(buf), "%s-%u%%%c%s", spath.c_str(), cnt, 'a' + chan, ext.c_str());
snprintf (buf, sizeof(buf), "%s-%u%%%c%s", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
} else {
snprintf (buf, sizeof(buf), "%s-%u%s", spath.c_str(), cnt, ext.c_str());
snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
}
}
if (sys::exists(buf)) {
existing++;
}
SessionDirectory sdir((*i).path);
string spath = sdir.sound_path().to_string();
string spath_stubs = sdir.sound_stub_path().to_string();
/* note that we search *without* the extension so that
we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
in the event that this new name is required for
a file format change.
*/
if (matching_unsuffixed_filename_exists_in (spath, buf) ||
matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
existing++;
break;
}
}
if (existing == 0) {
@@ -2881,8 +2886,8 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
throw failed_constructor();
}
}
return Glib::path_get_basename(buf);
return Glib::path_get_basename (buf);
}
/** Create a new within-session audio source */
@@ -3398,7 +3403,12 @@ Session::reset_native_file_format ()
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr) {
/* don't save state as we do this, there's no point
*/
_state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
tr->reset_write_sources (false);
_state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
}
}
}

View File

@@ -35,7 +35,10 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <glibmm/miscutils.h>
#ifdef HAVE_WORDEXP
#include <wordexp.h>
@@ -538,6 +541,51 @@ native_header_format_extension (HeaderFormat hf, const DataType& type)
return ".wav";
}
bool
matching_unsuffixed_filename_exists_in (const string& dir, const string& path)
{
string bws = basename_nosuffix (path);
struct dirent* dentry;
struct stat statbuf;
DIR* dead;
bool ret = false;
if ((dead = ::opendir (dir.c_str())) == 0) {
error << string_compose (_("cannot open directory %1 (%2)"), dir, strerror (errno)) << endl;
return false;
}
while ((dentry = ::readdir (dead)) != 0) {
/* avoid '.' and '..' */
if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
(dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
continue;
}
string fullpath = Glib::build_filename (dir, dentry->d_name);
if (::stat (fullpath.c_str(), &statbuf)) {
continue;
}
if (!S_ISREG (statbuf.st_mode)) {
continue;
}
string bws2 = basename_nosuffix (dentry->d_name);
if (bws2 == bws) {
ret = true;
break;
}
}
::closedir (dead);
return ret;
}
extern "C" {
void c_stacktrace() { stacktrace (cerr); }
}