diff options
author | David Robillard <d@drobilla.net> | 2014-11-14 23:53:59 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2014-11-14 23:53:59 -0500 |
commit | b52407043c71f9169a2a8171d07e4e1ade5f07a3 (patch) | |
tree | 4c6fc288fe3a058497f81998f02e7ecb52964a63 /libs | |
parent | 94954f852ead97bcda7afa548d543222733228ef (diff) |
Fix crash when copying MIDI regions with midi-copy-is-fork is on (#6002).
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/source.h | 4 | ||||
-rw-r--r-- | libs/ardour/midi_region.cc | 1 | ||||
-rw-r--r-- | libs/ardour/region_factory.cc | 13 | ||||
-rw-r--r-- | libs/ardour/session.cc | 2 |
4 files changed, 18 insertions, 2 deletions
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index afb6430242..e009e0ef51 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -109,6 +109,9 @@ class LIBARDOUR_API Source : public SessionObject bool used() const { return use_count() > 0; } uint32_t level() const { return _level; } + std::string ancestor_name() { return _ancestor_name.empty() ? name() : _ancestor_name; } + void set_ancestor_name(const std::string& name) { _ancestor_name = name; } + protected: DataType _type; Flag _flags; @@ -119,6 +122,7 @@ class LIBARDOUR_API Source : public SessionObject mutable Glib::Threads::Mutex _analysis_lock; gint _use_count; /* atomic */ uint32_t _level; /* how deeply nested is this source w.r.t a disk file */ + std::string _ancestor_name; private: void fix_writable_flags (); diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index e7298e7526..03db3eaaa7 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -133,6 +133,7 @@ MidiRegion::clone (string path) const boost::shared_ptr<MidiSource> newsrc; /* caller must check for pre-existing file */ + assert (!path.empty()); assert (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)); newsrc = boost::dynamic_pointer_cast<MidiSource>( SourceFactory::createWritable(DataType::MIDI, _session, diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc index 9654a4b3de..7c9f4fd228 100644 --- a/libs/ardour/region_factory.cc +++ b/libs/ardour/region_factory.cc @@ -19,6 +19,7 @@ #include <inttypes.h> +#include "pbd/basename.h" #include "pbd/error.h" #include "ardour/audioregion.h" @@ -58,7 +59,17 @@ RegionFactory::create (boost::shared_ptr<const Region> region, bool announce) } else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) { if (mr->session().config.get_midi_copy_is_fork()) { - ret = mr->clone (); + /* What we really want to do here is what Editor::fork_region() + does via Session::create_midi_source_by_stealing_name(), but we + don't have a Track. We'll just live with the skipped number, + and store the ancestral name of sources so multiple clones + generates reasonable names that don't have too many suffixes. */ + const std::string ancestor_name = mr->sources().front()->ancestor_name(); + const std::string base = PBD::basename_nosuffix(ancestor_name); + + boost::shared_ptr<MidiSource> source = mr->session().create_midi_source_for_session(base); + source->set_ancestor_name(mr->sources().front()->name()); + ret = mr->clone(source); } else { ret = boost::shared_ptr<Region> (new MidiRegion (mr, 0)); } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 2878bb8014..9c5b6fdccf 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3734,7 +3734,7 @@ Session::new_audio_source_path (const string& base, uint32_t nchan, uint32_t cha return s; } -/** Return a unique name based on \a owner_name for a new internal MIDI source */ +/** Return a unique name based on `base` for a new internal MIDI source */ string Session::new_midi_source_path (const string& base) { |