summaryrefslogtreecommitdiff
path: root/libs/ardour/session.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-07-01 09:46:18 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-07-01 09:46:18 -0400
commit23e7cf10191270d70357ccf0ed9294f020c7b7ab (patch)
treeddc1fc4d1914fe3de3de79c194c5dd859915bd2a /libs/ardour/session.cc
parent4244ea65460b865f946551aace9b74191b26be4b (diff)
parentb660bc8ae92d19aedf0165815432b77a0c6170c4 (diff)
merge with master.
Manually resolved conflicts in import.cc and session.cc
Diffstat (limited to 'libs/ardour/session.cc')
-rw-r--r--libs/ardour/session.cc195
1 files changed, 85 insertions, 110 deletions
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 36c43f0c06..ae39d7c468 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -36,6 +36,7 @@
#include <boost/algorithm/string/erase.hpp>
+#include "pbd/convert.h"
#include "pbd/error.h"
#include "pbd/boost_debug.h"
#include "pbd/stl_delete.h"
@@ -3435,30 +3436,6 @@ Session::count_sources_by_origin (const string& path)
return cnt;
}
-/** Return the full path (in some session directory) for a new within-session source.
- * \a name must be a session-unique name that does not contain slashes
- * (e.g. as returned by new_*_source_name)
- */
-string
-Session::new_source_path_from_name (DataType type, const string& name)
-{
- assert(name.find("/") == string::npos);
-
- SessionDirectory sdir(get_best_session_directory_for_new_source());
-
- std::string p;
- if (type == DataType::AUDIO) {
- p = sdir.sound_path();
- } else if (type == DataType::MIDI) {
- p = sdir.midi_path();
- } else {
- error << "Unknown source type, unable to create file path" << endmsg;
- return "";
- }
-
- return Glib::build_filename (p, name);
-}
-
string
Session::peak_path (string base) const
{
@@ -3467,18 +3444,20 @@ Session::peak_path (string base) const
/** Return a unique name based on \a base for a new internal audio source */
string
-Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
+Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t chan, bool destructive, bool take_required)
{
uint32_t cnt;
- char buf[PATH_MAX+1];
- const uint32_t limit = 10000;
+ string possible_name;
+ const uint32_t limit = 9999; // arbitrary limit on number of files with the same basic name
string legalized;
string ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
+ bool some_related_source_name_exists = false;
- buf[0] = '\0';
+ possible_name[0] = '\0';
legalized = legalize_for_path (base);
// Find a "version" of the base 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;
@@ -3486,47 +3465,37 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
- if (destructive) {
-
- if (nchan < 2) {
- 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), "T%04d-%s%%L%s",
- cnt, legalized.c_str(), ext.c_str());
- } else {
- snprintf (buf, sizeof(buf), "T%04d-%s%%R%s",
- cnt, legalized.c_str(), ext.c_str());
- }
- } else if (nchan < 26) {
- snprintf (buf, sizeof(buf), "T%04d-%s%%%c%s",
- cnt, legalized.c_str(), 'a' + chan, ext.c_str());
- } else {
- snprintf (buf, sizeof(buf), "T%04d-%s%s",
- cnt, legalized.c_str(), ext.c_str());
- }
+ ostringstream sstr;
+ if (destructive) {
+ sstr << 'T';
+ sstr << setfill ('0') << setw (4) << cnt;
+ sstr << legalized;
} else {
-
- if (nchan < 2) {
- 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", legalized.c_str(), cnt, ext.c_str());
- } else {
- 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", legalized.c_str(), cnt, 'a' + chan, ext.c_str());
- } else {
- snprintf (buf, sizeof(buf), "%s-%u%s", legalized.c_str(), cnt, ext.c_str());
+ sstr << legalized;
+
+ if (take_required || some_related_source_name_exists) {
+ sstr << '-';
+ sstr << cnt;
}
}
+
+ if (nchan == 2) {
+ if (chan == 0) {
+ sstr << "%L";
+ } else {
+ sstr << "%R";
+ }
+ } else if (nchan > 2 && nchan < 26) {
+ sstr << '%';
+ sstr << 'a' + chan;
+ }
- SessionDirectory sdir((*i).path);
+ sstr << ext;
- string spath = sdir.sound_path();
+ possible_name = sstr.str();
+ SessionDirectory sdir((*i).path);
+ const string spath = sdir.sound_path();
/* note that we search *without* the extension so that
we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
@@ -3534,7 +3503,7 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
a file format change.
*/
- if (matching_unsuffixed_filename_exists_in (spath, buf)) {
+ if (matching_unsuffixed_filename_exists_in (spath, possible_name)) {
existing++;
break;
}
@@ -3548,7 +3517,7 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
* notions of their removability.
*/
- string possible_path = Glib::build_filename (spath, buf);
+ string possible_path = Glib::build_filename (spath, possible_name);
if (audio_source_by_path_and_channel (possible_path, chan)) {
existing++;
@@ -3560,6 +3529,8 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
break;
}
+ some_related_source_name_exists = true;
+
if (cnt > limit) {
error << string_compose(
_("There are already %1 recordings for %2, which I consider too many."),
@@ -3569,32 +3540,31 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
}
}
- return Glib::path_get_basename (buf);
-}
+ /* We've established that the new name does not exist in any session
+ * directory, so now find out which one we should use for this new
+ * audio source.
+ */
-/** Create a new within-session audio source */
-boost::shared_ptr<AudioFileSource>
-Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
-{
- const string name = new_audio_source_name (n, n_chans, chan, destructive);
- const string path = new_source_path_from_name(DataType::AUDIO, name);
+ SessionDirectory sdir (get_best_session_directory_for_new_audio());
+
+ std::string s = Glib::build_filename (sdir.sound_path(), possible_name);
- return boost::dynamic_pointer_cast<AudioFileSource> (
- SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
+ return s;
}
/** Return a unique name based on \a owner_name for a new internal MIDI source */
string
-Session::new_midi_source_name (const string& owner_name)
+Session::new_midi_source_path (const string& base)
{
uint32_t cnt;
char buf[PATH_MAX+1];
const uint32_t limit = 10000;
string legalized;
+ string possible_path;
string possible_name;
buf[0] = '\0';
- legalized = legalize_for_path (owner_name);
+ legalized = legalize_for_path (base);
// Find a "version" of the file name that doesn't exist in any of the possible directories.
@@ -3602,7 +3572,7 @@ Session::new_midi_source_name (const string& owner_name)
vector<space_and_path>::iterator i;
uint32_t existing = 0;
-
+
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
SessionDirectory sdir((*i).path);
@@ -3610,7 +3580,7 @@ Session::new_midi_source_name (const string& owner_name)
snprintf (buf, sizeof(buf), "%s-%u.mid", legalized.c_str(), cnt);
possible_name = buf;
- std::string possible_path = Glib::build_filename (sdir.midi_path(), possible_name);
+ possible_path = Glib::build_filename (sdir.midi_path(), possible_name);
if (Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
existing++;
@@ -3628,31 +3598,47 @@ Session::new_midi_source_name (const string& owner_name)
if (cnt > limit) {
error << string_compose(
_("There are already %1 recordings for %2, which I consider too many."),
- limit, owner_name) << endmsg;
+ limit, base) << endmsg;
destroy ();
- throw failed_constructor();
+ return 0;
}
}
- return possible_name;
+ /* No need to "find best location" for software/app-based RAID, because
+ MIDI is so small that we always put it in the same place.
+ */
+
+ return possible_path;
}
+/** Create a new within-session audio source */
+boost::shared_ptr<AudioFileSource>
+Session::create_audio_source_for_session (size_t n_chans, string const & base, uint32_t chan, bool destructive)
+{
+ const string path = new_audio_source_path (base, n_chans, chan, destructive, true);
+
+ if (!path.empty()) {
+ return boost::dynamic_pointer_cast<AudioFileSource> (
+ SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
+ } else {
+ throw failed_constructor ();
+ }
+}
+
/** Create a new within-session MIDI source */
boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (string const & basic_name)
{
- std::string name;
-
- if (name.empty()) {
- name = new_midi_source_name (basic_name);
+ const string path = new_midi_source_path (basic_name);
+
+ if (!path.empty()) {
+ return boost::dynamic_pointer_cast<SMFSource> (
+ SourceFactory::createWritable (
+ DataType::MIDI, *this, path, false, frame_rate()));
+ } else {
+ throw failed_constructor ();
}
-
- const string path = new_source_path_from_name (DataType::MIDI, name);
-
- return boost::dynamic_pointer_cast<SMFSource> (
- SourceFactory::createWritable (
- DataType::MIDI, *this, path, false, frame_rate()));
}
/** Create a new within-session MIDI source */
@@ -3686,7 +3672,7 @@ Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
return boost::shared_ptr<MidiSource>();
}
- const string path = new_source_path_from_name (DataType::MIDI, name);
+ const string path = new_midi_source_path (name);
return boost::dynamic_pointer_cast<SMFSource> (
SourceFactory::createWritable (
@@ -4195,18 +4181,14 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
boost::shared_ptr<Region> result;
boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<AudioFileSource> fsource;
- uint32_t x;
ChanCount diskstream_channels (track.n_channels());
framepos_t position;
framecnt_t this_chunk;
framepos_t to_do;
framepos_t latency_skip;
BufferSet buffers;
- SessionDirectory sdir(get_best_session_directory_for_new_source ());
- const string sound_dir = sdir.sound_path();
framepos_t len = end - start;
bool need_block_size_reset = false;
- string ext;
ChanCount const max_proc = track.max_processor_streams ();
string legal_playlist_name;
string possible_path;
@@ -4247,29 +4229,22 @@ Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
legal_playlist_name = legalize_for_path (playlist->name());
- ext = native_header_format_extension (config.get_native_file_header_format(), DataType::AUDIO);
-
for (uint32_t chan_n = 0; chan_n < diskstream_channels.n_audio(); ++chan_n) {
- for (x = 0; x < 99999; ++x) {
- possible_path = Glib::build_filename (sound_dir, string_compose ("%1-%2-bounce-%3%4", legal_playlist_name.c_str(), chan_n, x+1, ext.c_str()));
- if (!Glib::file_test (possible_path, Glib::FILE_TEST_EXISTS)) {
- break;
- }
- }
-
- if (x == 99999) {
- error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
+ string base_name = string_compose ("%1-%2-bounce", playlist->name(), chan_n);
+ string path = new_audio_source_path (legal_playlist_name, diskstream_channels.n_audio(), chan_n, false, true);
+
+ if (path.empty()) {
goto out;
}
try {
fsource = boost::dynamic_pointer_cast<AudioFileSource> (
- SourceFactory::createWritable (DataType::AUDIO, *this, possible_path, false, frame_rate()));
+ SourceFactory::createWritable (DataType::AUDIO, *this, path, false, frame_rate()));
}
catch (failed_constructor& err) {
- error << string_compose (_("cannot create new audio file \"%1\" for %2"), possible_path, track.name()) << endmsg;
+ error << string_compose (_("cannot create new audio file \"%1\" for %2"), path, track.name()) << endmsg;
goto out;
}