+ return source;
+}
+
+
+boost::shared_ptr<Source>
+Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
+{
+ Glib::Mutex::Lock lm (source_lock);
+
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
+ cerr << "comparing " << path << " with " << i->second->name() << endl;
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
+
+ if (afs && afs->path() == path && chn == afs->channel()) {
+ return afs;
+ }
+
+ }
+ return boost::shared_ptr<Source>();
+}
+
+Glib::ustring
+Session::peak_path (Glib::ustring base) const
+{
+ sys::path peakfile_path(_session_dir->peak_path());
+ peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
+ return peakfile_path.to_string();
+}
+
+string
+Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
+{
+ string look_for;
+ string old_basename = PBD::basename_nosuffix (oldname);
+ string new_legalized = legalize_for_path (newname);
+
+ /* note: we know (or assume) the old path is already valid */
+
+ if (destructive) {
+
+ /* destructive file sources have a name of the form:
+
+ /path/to/Tnnnn-NAME(%[LR])?.wav
+
+ the task here is to replace NAME with the new name.
+ */
+
+ /* find last slash */
+
+ string dir;
+ string prefix;
+ string::size_type slash;
+ string::size_type dash;
+
+ if ((slash = path.find_last_of ('/')) == string::npos) {
+ return "";
+ }
+
+ dir = path.substr (0, slash+1);
+
+ /* '-' is not a legal character for the NAME part of the path */
+
+ if ((dash = path.find_last_of ('-')) == string::npos) {
+ return "";
+ }
+
+ prefix = path.substr (slash+1, dash-(slash+1));
+
+ path = dir;
+ path += prefix;
+ path += '-';
+ path += new_legalized;
+ path += ".wav"; /* XXX gag me with a spoon */
+
+ } else {
+
+ /* non-destructive file sources have a name of the form:
+
+ /path/to/NAME-nnnnn(%[LR])?.wav
+
+ the task here is to replace NAME with the new name.
+ */
+
+ string dir;
+ string suffix;
+ string::size_type slash;
+ string::size_type dash;
+ string::size_type postfix;
+
+ /* find last slash */
+
+ if ((slash = path.find_last_of ('/')) == string::npos) {
+ return "";
+ }
+
+ dir = path.substr (0, slash+1);
+
+ /* '-' is not a legal character for the NAME part of the path */
+
+ if ((dash = path.find_last_of ('-')) == string::npos) {
+ return "";
+ }
+
+ suffix = path.substr (dash+1);
+
+ // Suffix is now everything after the dash. Now we need to eliminate
+ // the nnnnn part, which is done by either finding a '%' or a '.'
+
+ postfix = suffix.find_last_of ("%");
+ if (postfix == string::npos) {
+ postfix = suffix.find_last_of ('.');
+ }
+
+ if (postfix != string::npos) {
+ suffix = suffix.substr (postfix);
+ } else {
+ error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
+ return "";
+ }
+
+ const uint32_t limit = 10000;
+ char buf[PATH_MAX+1];
+
+ for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
+
+ snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
+
+ if (access (buf, F_OK) != 0) {
+ path = buf;
+ break;
+ }
+ path = "";
+ }
+
+ if (path == "") {
+ error << "FATAL ERROR! Could not find a " << endl;
+ }
+
+ }
+
+ return path;
+}
+
+string
+Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
+{
+ string spath;
+ uint32_t cnt;
+ char buf[PATH_MAX+1];
+ const uint32_t limit = 10000;
+ string legalized;
+
+ buf[0] = '\0';
+ legalized = legalize_for_path (name);
+
+ /* find a "version" of the file name that doesn't exist in
+ any of the possible directories.
+ */
+
+ for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
+
+ vector<space_and_path>::iterator i;
+ uint32_t existing = 0;
+
+ 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.wav", spath.c_str(), cnt, legalized.c_str());
+ } else if (nchan == 2) {
+ if (chan == 0) {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
+ } else {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
+ }
+ } else if (nchan < 26) {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
+ } else {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
+ }
+
+ } else {
+
+ spath += '/';
+ spath += legalized;
+
+ if (nchan < 2) {
+ snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
+ } else if (nchan == 2) {
+ if (chan == 0) {
+ snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
+ } else {
+ snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
+ }
+ } else if (nchan < 26) {
+ snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
+ } else {
+ snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
+ }
+ }
+
+ if (sys::exists(buf)) {
+ existing++;
+ }
+
+ }
+
+ if (existing == 0) {
+ break;
+ }
+
+ if (cnt > limit) {
+ error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
+ destroy ();
+ throw failed_constructor();
+ }
+ }
+
+ /* we now have a unique name for the file, but figure out where to
+ actually put it.
+ */