merge with master.
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 1 Jul 2014 13:46:18 +0000 (09:46 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 1 Jul 2014 13:46:18 +0000 (09:46 -0400)
Manually resolved conflicts in import.cc and session.cc

14 files changed:
gtk2_ardour/editor.h
gtk2_ardour/editor_audio_import.cc
libs/ardour/ardour/file_source.h
libs/ardour/ardour/session.h
libs/ardour/ardour/smf_source.h
libs/ardour/audiofilesource.cc
libs/ardour/diskstream.cc
libs/ardour/file_source.cc
libs/ardour/filter.cc
libs/ardour/import.cc
libs/ardour/midi_diskstream.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/smf_source.cc

index dad59cd6641afca1b636fb04eb99013768f2fdc5..3013e3605110dffc1f81563291e48dd423b91f39 100644 (file)
@@ -1251,7 +1251,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
                         int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::Track>&, bool add_channel_suffix);
 
        int finish_bringing_in_material (boost::shared_ptr<ARDOUR::Region> region, uint32_t, uint32_t,  framepos_t& pos, Editing::ImportMode mode,
-                                     boost::shared_ptr<ARDOUR::Track>& existing_track);
+                                        boost::shared_ptr<ARDOUR::Track>& existing_track, const std::string& new_track_name);
 
        boost::shared_ptr<ARDOUR::AudioTrack> get_nth_selected_audio_track (int nth) const;
        boost::shared_ptr<ARDOUR::MidiTrack> get_nth_selected_midi_track (int nth) const;
index 3b9fe20727f1d3425e3c07283cb3c6059c4d16ff..647abae1530fa3e0f759650ea1b370df8cc663bf 100644 (file)
@@ -654,7 +654,8 @@ Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos,
        uint32_t input_chan = 0;
        uint32_t output_chan = 0;
        bool use_timestamp;
-       
+       vector<string> track_names;
+
        use_timestamp = (pos == -1);
 
        // kludge (for MIDI we're abusing "channel" for "track" here)
@@ -691,6 +692,11 @@ Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos,
 
                regions.push_back (r);
 
+               /* if we're creating a new track, name it after the cleaned-up
+                * and "merged" region name.
+                */
+
+               track_names.push_back (region_name);
 
        } else if (target_regions == -1 || target_regions > 1) {
 
@@ -721,29 +727,26 @@ Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos,
                                        region_name = (*x)->name();
                                }
                                
-                               switch (sources.size()) {
-                                       /* zero and one channel handled
-                                          by previous if() condition
-                                       */
-                               case 2:
+                               if (sources.size() == 2) {
                                        if (n == 0) {
                                                region_name += "-L";
                                        } else {
                                                region_name += "-R";
                                        }
-                                       break;
-                               default:
-                                       region_name += (char) '-';
-                                       region_name += (char) ('1' + n);
-                                       break;
+                               } else if (sources.size() > 2) {
+                                       region_name += string_compose ("-%1", n+1);
                                }
                                
+                               track_names.push_back (region_name);
+                               
                        } else {
                                if (fs) {
                                        region_name = region_name_from_path (fs->path(), false, false, sources.size(), n);
-                               } else{
+                               } else {
                                        region_name = (*x)->name();
                                }
+
+                               track_names.push_back (PBD::basename_nosuffix (paths[n]));
                        }
 
                        PropertyList plist;
@@ -795,6 +798,12 @@ Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos,
        framepos_t rlen = 0;
 
        begin_reversible_command (Operations::insert_file);
+
+       /* we only use tracks names when importing to new tracks, but we
+        * require that one is defined for every region, just to keep
+        * the API simpler.
+        */
+       assert (regions.size() == track_names.size());
        
        for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
                boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (*r);
@@ -827,9 +836,8 @@ Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos,
                                 pos = get_preferred_edit_position ();
                         }
                 }
-
-
-               finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track);
+               
+               finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track, track_names[n]);
 
                rlen = (*r)->length();
 
@@ -856,7 +864,7 @@ Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos,
 
 int
 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t in_chans, uint32_t out_chans, framepos_t& pos,
-                                    ImportMode mode, boost::shared_ptr<Track>& existing_track)
+                                    ImportMode mode, boost::shared_ptr<Track>& existing_track, const string& new_track_name)
 {
        boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
        boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
@@ -913,7 +921,11 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t
                                existing_track = mt.front();
                        }
 
-                       existing_track->set_name (region->name());
+                       if (!new_track_name.empty()) {
+                               existing_track->set_name (new_track_name);
+                       } else {
+                               existing_track->set_name (region->name());
+                       }
                }
 
                boost::shared_ptr<Playlist> playlist = existing_track->playlist();
index 37a7e67d2ef4c35a460ba151941c84f15ce41c14..8b8adfeb669813f7bb4a4d82f6d47f021e1e0101 100644 (file)
@@ -85,6 +85,10 @@ public:
        void existence_check ();
        virtual void prevent_deletion ();
 
+       /** Rename the file on disk referenced by this source to \param newname
+        */
+       int rename (const std::string& name);
+
 protected:
        FileSource (Session& session, DataType type,
                    const std::string& path,
index a7ca2d00eec719a0384869e7ae9cfc504749e18e..03eccd40a32dd45ea29e3758fa94894d339090c6 100644 (file)
@@ -196,10 +196,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        std::string peak_path (std::string) const;
 
        std::string peak_path_from_audio_path (std::string) const;
-       std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive);
-       std::string new_midi_source_name (const std::string&);
-       std::string new_source_path_from_name (DataType type, const std::string&);
+       std::string new_audio_source_path (const std::string&, uint32_t nchans, uint32_t chan, bool destructive, bool take_required);
+       std::string new_midi_source_path (const std::string&);
         RouteList new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name);
+       std::vector<std::string> get_paths_for_new_sources (bool allow_replacing, const std::string& import_file_path, uint32_t channels);
 
        void process (pframes_t nframes);
 
@@ -549,8 +549,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
 
-       std::string path_from_region_name (DataType type, std::string name, std::string identifier);
-
        boost::shared_ptr<Region>      XMLRegionFactory (const XMLNode&, bool full);
        boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
        boost::shared_ptr<MidiRegion>  XMLMidiRegionFactory (const XMLNode&, bool full);
@@ -1485,7 +1483,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        bool no_questions_about_missing_files;
 
-       std::string get_best_session_directory_for_new_source ();
+       std::string get_best_session_directory_for_new_audio ();
 
        mutable gint _playback_load;
        mutable gint _capture_load;
index 93adfd71f97ab91ad76ca3eb61925f5028331c73..84c45f9b3cf342be199c2e552c58daa74c715f12 100644 (file)
@@ -47,15 +47,6 @@ public:
 
        virtual ~SMFSource ();
 
-       /** Rename the file on disk referenced by this source to \param newname
-        *
-        * This method exists only for MIDI file sources, not for audio, which 
-        * can never be renamed. It exists for MIDI so that we can get
-        * consistent and sane region/source numbering when regions are added
-        * manually (which never happens with audio).
-        */
-       int rename (const std::string& name);
-
         bool safe_file_extension (const std::string& path) const {
                return safe_midi_file_extension(path);
        }
index 299b5a2bb5480ccaecdbaa22a3ba9a249193c3b9..7d34b9d9a52c5aabb81fa4bbfa7d11c13acbb774 100644 (file)
@@ -36,6 +36,7 @@
 #include "pbd/stl_delete.h"
 #include "pbd/strsplit.h"
 #include "pbd/shortpath.h"
+#include "pbd/stacktrace.h"
 #include "pbd/enumwriter.h"
 
 #include <sndfile.h>
index aacb0ce1c998596098850c477afbe4b8564f4234..0e05ffabf488e588da9b123764002a21a4a55346 100644 (file)
@@ -744,4 +744,3 @@ Diskstream::disengage_record_enable ()
 {
        g_atomic_int_set (&_record_enabled, 0);
 }
-
index ae63bd55b13588f0e81976defff05792d52e3317..8c41f981b9b480ac5da359096659f294ec313298 100644 (file)
@@ -214,7 +214,7 @@ FileSource::move_to_trash (const string& trash_dir_name)
 
        if (move_dependents_to_trash() != 0) {
                /* try to back out */
-               rename (newpath.c_str(), _path.c_str());
+               ::rename (newpath.c_str(), _path.c_str());
                return -1;
        }
 
@@ -572,3 +572,28 @@ FileSource::is_stub () const
        return true;
 }
                
+int
+FileSource::rename (const string& newpath)
+{
+       Glib::Threads::Mutex::Lock lm (_lock);
+       string oldpath = _path;
+
+       // Test whether newpath exists, if yes notify the user but continue.
+       if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
+               error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg;
+               return -1;
+       }
+
+       if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) { 
+               /* rename only needed if file exists on disk */
+               if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
+                       error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg;
+                       return -1;
+               }
+       }
+
+       _name = Glib::path_get_basename (newpath);
+       _path = newpath;
+
+       return 0;
+}
index b085ec946b3d09305d52b3b8871e8a05a29f1e30..b723de1e56508af42ada0c7c7932e477bf0d4d32 100644 (file)
@@ -59,10 +59,9 @@ Filter::make_new_sources (boost::shared_ptr<Region> region, SourceList& nsrcs, s
                        }
                }
 
-               string path = session.path_from_region_name (region->data_type(),
-                               PBD::basename_nosuffix (names[i]), string (""));
+               string path = session.new_audio_source_path (name, region->n_channels(), i, false, false);
 
-               if (path.length() == 0) {
+               if (path.empty()) {
                        error << string_compose (_("filter: error creating name for new file based on %1"), region->name())
                              << endmsg;
                        return -1;
index 04a62b06e1c8c1aa66da8f5e9724101fe8c1f0b3..e86e500ed93ff6d12308e5c8db4b289a749c5aee 100644 (file)
@@ -117,78 +117,31 @@ open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQu
        }
 }
 
-static std::string
-get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint32_t channel, uint32_t channels)
-{
-       char buf[PATH_MAX+1];
-       bool goodfile = false;
-       string base = basename;
-       string ext = native_header_format_extension (hf, type);
-       uint32_t cnt = 1;
-
-       do {
-
-               if (type == DataType::AUDIO && channels == 2) {
-                       if (channel == 0) {
-                               if (cnt == 1) {
-                                       snprintf (buf, sizeof(buf), "%s-L%s", base.c_str(), ext.c_str());
-                               } else {
-                                       snprintf (buf, sizeof(buf), "%s-%d-L%s", base.c_str(), cnt, ext.c_str());
-                               }
-                       } else {
-                               if (cnt == 1) {
-                                       snprintf (buf, sizeof(buf), "%s-R%s", base.c_str(), ext.c_str());
-                               } else {
-                                       snprintf (buf, sizeof(buf), "%s-%d-R%s", base.c_str(), cnt, ext.c_str());
-                               }
-                       }
-               } else if (channels > 1) {
-                       if (cnt == 1) {
-                               snprintf (buf, sizeof(buf), "%s-c%d%s", base.c_str(), channel, ext.c_str());
-                       } else {
-                               snprintf (buf, sizeof(buf), "%s-%d-c%d%s", base.c_str(), cnt, channel, ext.c_str());
-                       }
-               } else {
-                       if (cnt == 1) {
-                               snprintf (buf, sizeof(buf), "%s%s", base.c_str(), ext.c_str());
-                       } else {
-                               snprintf (buf, sizeof(buf), "%s-%d%s", base.c_str(), cnt, ext.c_str());
-                       }
-               }
-
-               string tempname = destdir + "/" + buf;
-
-               if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
-
-                       cnt++;
-
-               } else {
-
-                       goodfile = true;
-               }
-
-       } while (!goodfile);
-
-       return buf;
-}
-
-static vector<string>
-get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint32_t channels)
+vector<string>
+Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels)
 {
        vector<string> new_paths;
        const string basename = basename_nosuffix (import_file_path);
 
-       SessionDirectory sdir(session_dir);
-
        for (uint32_t n = 0; n < channels; ++n) {
 
                const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
+               string filepath;
 
-               std::string filepath = (type == DataType::MIDI)
-                       ? sdir.midi_path() : sdir.sound_path();
+               switch (type) {
+                 case DataType::MIDI:
+                       filepath = new_midi_source_path (basename);
+                       break;
+               case DataType::AUDIO:
+                       filepath = new_audio_source_path (basename, channels, n, false, false);
+                       break;
+               }
+
+               if (filepath.empty()) {
+                       error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
+                       return vector<string>();
+               }
 
-               filepath = Glib::build_filename (filepath,
-                                                get_non_existent_filename (hf, type, allow_replacing, filepath, basename, n, channels));
                new_paths.push_back (filepath);
        }
 
@@ -325,7 +278,7 @@ write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
                progress_base = 0.5;
        }
 
-       uint32_t read_count = 0;
+       framecnt_t read_count = 0;
 
        while (!status.cancel) {
 
@@ -521,16 +474,13 @@ Session::import_files (ImportStatus& status)
                                return;
                        }
                }
-
+               
                if (channels == 0) {
                        error << _("Import: file contains no channels.") << endmsg;
                        continue;
                }
 
-               vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
-                                                                     status.replace_existing_source, *p,
-                                                                     get_best_session_directory_for_new_source (),
-                                                                     channels);
+               vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels);
                Sources newfiles;
                framepos_t natural_position = source ? source->natural_position() : 0;
 
index a104d98f266fe1f1c34e8169b0b2d858299ebae8..69eca996aaeda92cf56c47643f34f4d966d82265 100644 (file)
@@ -1258,9 +1258,9 @@ MidiDiskstream::steal_write_source_name ()
         */
 
        try {
-               string new_name = _session.new_midi_source_name (name());
+               string new_path = _session.new_midi_source_path (name());
                
-               if (_write_source->rename (new_name)) {
+               if (_write_source->rename (new_path)) {
                        return string();
                }
        } catch (...) {
index 36c43f0c069200fd34a6ebbeb3b953685cbd309b..ae39d7c46841959ee6fcc7243590c09d9d419f0e 100644 (file)
@@ -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;
                }
 
index cf0852f5a31b8be681126dd77f0ad31815c102e7..eaf9f08b257693702e57771d618fcc9720b17cfb 100644 (file)
@@ -1850,41 +1850,6 @@ Session::get_sources_as_xml ()
        return *node;
 }
 
-string
-Session::path_from_region_name (DataType type, string name, string identifier)
-{
-       char buf[PATH_MAX+1];
-       uint32_t n;
-       SessionDirectory sdir(get_best_session_directory_for_new_source());
-       std::string source_dir = ((type == DataType::AUDIO)
-               ? sdir.sound_path() : sdir.midi_path());
-
-        string ext = native_header_format_extension (config.get_native_file_header_format(), type);
-
-       for (n = 0; n < 999999; ++n) {
-               if (identifier.length()) {
-                       snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
-                                 identifier.c_str(), n, ext.c_str());
-               } else {
-                       snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
-                                       n, ext.c_str());
-               }
-
-               std::string source_path = Glib::build_filename (source_dir, buf);
-
-               if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
-                       return source_path;
-               }
-       }
-
-       error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
-                                name, identifier)
-             << endmsg;
-
-       return "";
-}
-
-
 int
 Session::load_sources (const XMLNode& node)
 {
@@ -2121,7 +2086,7 @@ Session::refresh_disk_space ()
 }
 
 string
-Session::get_best_session_directory_for_new_source ()
+Session::get_best_session_directory_for_new_audio ()
 {
        vector<space_and_path>::iterator i;
        string result = _session_dir->root_path();
index b0ba6c9bfcc6d187615fe860a98589162102b838..e39ef3f548408aa36e2681279710b6f2f8cbafbd 100644 (file)
@@ -718,34 +718,3 @@ SMFSource::prevent_deletion ()
        _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
 }
 
-int
-SMFSource::rename (const string& newname)
-{
-       Glib::Threads::Mutex::Lock lm (_lock);
-       string oldpath = _path;
-       string newpath = _session.new_source_path_from_name (DataType::MIDI, newname);
-
-       if (newpath.empty()) {
-               error << string_compose (_("programming error: %1"), "cannot generate a changed file path") << endmsg;
-               return -1;
-       }
-
-       // Test whether newpath exists, if yes notify the user but continue.
-       if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
-               error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg;
-               return -1;
-       }
-
-       if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) { 
-               /* rename only needed if file exists on disk */
-               if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
-                       error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg;
-                       return -1;
-               }
-       }
-
-       _name = Glib::path_get_basename (newpath);
-       _path = newpath;
-
-       return 0;
-}