diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-05-16 20:16:57 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-05-16 20:16:57 +0000 |
commit | 99aa8c6338e47b41143f799fdcb35d1699548076 (patch) | |
tree | a61140fd331b49a408894f00dcb8976cbb6543b8 /libs | |
parent | 4b848856ebc2856bf7ab10a000cc88bdd3bc4a4a (diff) |
rename join regions op as combine regions; save and restore nested playlists, sources, regions; add undo/redo for combine; fixup peakfile use/discovery
git-svn-id: svn://localhost/ardour2/branches/3.0@9528 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/playlist.h | 1 | ||||
-rw-r--r-- | libs/ardour/audio_playlist_source.cc | 29 | ||||
-rw-r--r-- | libs/ardour/playlist.cc | 60 | ||||
-rw-r--r-- | libs/ardour/playlist_source.cc | 21 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 11 | ||||
-rw-r--r-- | libs/ardour/source_factory.cc | 80 |
6 files changed, 139 insertions, 63 deletions
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 3234e4c108..72155d9981 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -376,6 +376,7 @@ public: void timestamp_layer_op (boost::shared_ptr<Region>); void _split_region (boost::shared_ptr<Region>, framepos_t position); + void load_nested_sources (const XMLNode& node); }; } /* namespace ARDOUR */ diff --git a/libs/ardour/audio_playlist_source.cc b/libs/ardour/audio_playlist_source.cc index 2160b9bd3a..882a1710e7 100644 --- a/libs/ardour/audio_playlist_source.cc +++ b/libs/ardour/audio_playlist_source.cc @@ -34,6 +34,7 @@ #include "ardour/audio_playlist_source.h" #include "ardour/audioregion.h" #include "ardour/debug.h" +#include "ardour/filename_extensions.h" #include "ardour/session.h" #include "ardour/session_directory.h" #include "ardour/session_playlists.h" @@ -52,14 +53,12 @@ AudioPlaylistSource::AudioPlaylistSource (Session& s, const std::string& name, b , PlaylistSource (s, name, p, DataType::AUDIO, begin, len, flags) , _playlist_channel (chn) { - _peak_path = Glib::build_filename (_session.session_directory().peak_path().to_string(), name); - AudioSource::_length = len; ensure_buffers_for_level (_level); } AudioPlaylistSource::AudioPlaylistSource (Session& s, const XMLNode& node) - : Source (s, DataType::AUDIO, "toBeRenamed") + : Source (s, node) , AudioSource (s, node) , PlaylistSource (s, node) { @@ -91,7 +90,6 @@ AudioPlaylistSource::get_state () snprintf (buf, sizeof (buf), "%" PRIu32, _playlist_channel); node.add_property ("channel", buf); - node.add_property ("peak-path", _peak_path); return node; } @@ -124,12 +122,6 @@ AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_desc sscanf (prop->value().c_str(), "%" PRIu32, &_playlist_channel); - if ((prop = node.property (X_("peak-path"))) == 0) { - throw failed_constructor (); - } - - _peak_path = prop->value (); - ensure_buffers_for_level (_level); return 0; @@ -224,23 +216,12 @@ AudioPlaylistSource::sample_rate () const int AudioPlaylistSource::setup_peakfile () { - /* the peak data is setup once and once only - */ - - if (!Glib::file_test (_peak_path, Glib::FILE_TEST_EXISTS)) { - /* the 2nd argument here will be passed - in to ::peak_path, and is irrelevant - since our peak file path is fixed and - not dependent on anything. - */ - return initialize_peakfile (false, string()); - } - - return 0; + _peak_path = Glib::build_filename (_session.session_directory().peak_path().to_string(), name() + ARDOUR::peakfile_suffix); + return initialize_peakfile (false, string()); } string -AudioPlaylistSource::peak_path (string /*audio_path*/) +AudioPlaylistSource::peak_path (string /*audio_path_IGNORED*/) { return _peak_path; } diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index fd9af56e80..9ceb11fe51 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -2221,6 +2221,26 @@ Playlist::update (const RegionListProperty::ChangeRecord& change) thaw (); } +void +Playlist::load_nested_sources (const XMLNode& node) +{ + XMLNodeList nlist; + XMLNodeConstIterator niter; + + nlist = node.children(); + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + if ((*niter)->name() == "Source") { + try { + SourceFactory::create (_session, **niter, true); + } + catch (failed_constructor& err) { + error << string_compose (_("Cannot reconstruct nested source for playlist %1"), name()) << endmsg; + } + } + } +} + int Playlist::set_state (const XMLNode& node, int version) { @@ -2264,6 +2284,19 @@ Playlist::set_state (const XMLNode& node, int version) nlist = node.children(); + /* find the "Nested" node, if any, and recreate the PlaylistSources + listed there + */ + + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + child = *niter; + + if (child->name() == "Nested") { + load_nested_sources (*child); + break; + } + } + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { child = *niter; @@ -2292,7 +2325,7 @@ Playlist::set_state (const XMLNode& node, int version) error << _("Playlist: cannot create region from XML") << endmsg; continue; } - + add_region (region, region->position(), 1.0); @@ -2348,6 +2381,31 @@ Playlist::state (bool full_state) if (full_state) { RegionLock rlock (this, false); + XMLNode* nested_node = 0; + + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + if ((*i)->max_source_level() > 0) { + + if (!nested_node) { + nested_node = new XMLNode (X_("Nested")); + } + + /* region is compound - get its playlist and + store that before we list the region that + needs it ... + */ + + const SourceList& sl ((*i)->sources()); + + for (SourceList::const_iterator s = sl.begin(); s != sl.end(); ++s) { + nested_node->add_child_nocopy ((*s)->get_state ()); + } + } + } + + if (nested_node) { + node->add_child_nocopy (*nested_node); + } for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { node->add_child_nocopy ((*i)->get_state()); diff --git a/libs/ardour/playlist_source.cc b/libs/ardour/playlist_source.cc index 7ac175959c..a1597a76d2 100644 --- a/libs/ardour/playlist_source.cc +++ b/libs/ardour/playlist_source.cc @@ -32,6 +32,7 @@ #include "ardour/playlist.h" #include "ardour/playlist_source.h" +#include "ardour/playlist_factory.h" #include "ardour/session.h" #include "ardour/session_playlists.h" #include "ardour/source_factory.h" @@ -84,26 +85,38 @@ PlaylistSource::add_state (XMLNode& node) node.add_property ("offset", buf); snprintf (buf, sizeof (buf), "%" PRIu64, _playlist_length); node.add_property ("length", buf); + + node.add_child_nocopy (_playlist->get_state()); } int PlaylistSource::set_state (const XMLNode& node, int version) { - /* get playlist ID */ + /* check that we have a playlist ID */ const XMLProperty *prop = node.property (X_("playlist")); if (!prop) { + error << _("No playlist ID in PlaylistSource XML!") << endmsg; throw failed_constructor (); } - PBD::ID id (prop->value()); + /* create playlist from child node */ + + XMLNodeList nlist; + XMLNodeConstIterator niter; - /* get playlist */ + nlist = node.children(); - boost::shared_ptr<Playlist> p = _session.playlists->by_id (id); + for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + if ((*niter)->name() == "Playlist") { + _playlist = PlaylistFactory::create (_session, **niter, true, false); + break; + } + } if (!_playlist) { + error << _("No playlist node in PlaylistSource XML!") << endmsg; throw failed_constructor (); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 604fc4bc52..82c2d5a31c 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -1056,20 +1056,23 @@ Session::state(bool full_state) for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) { - /* Don't save information about non-destructive file sources that are empty - and unused by any regions. + /* Don't save information about non-file Sources, or + * about non-destructive file sources that are empty + * and unused by any regions. */ boost::shared_ptr<FileSource> fs; + if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) { + if (!fs->destructive()) { if (fs->empty() && !fs->used()) { continue; } } + + child->add_child_nocopy (siter->second->get_state()); } - - child->add_child_nocopy (siter->second->get_state()); } } diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index 4d3f02b1dc..57f0fdc1ec 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -147,44 +147,66 @@ SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks) if (type == DataType::AUDIO) { - try { - Source* src = new SndFileSource (s, node); -#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (src, "Source"); -#endif - boost::shared_ptr<Source> ret (src); - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); - } - ret->check_for_analysis_data_on_disk (); - SourceCreated (ret); - return ret; - } + /* it could be nested */ - catch (failed_constructor& err) { + if (node.property ("playlist") != 0) { -#ifdef USE_COREAUDIO_FOR_FILES + try { + boost::shared_ptr<AudioPlaylistSource> ap (new AudioPlaylistSource (s, node)); + + if (setup_peakfile (ap, true)) { + return boost::shared_ptr<Source>(); + } - /* this is allowed to throw */ + ap->check_for_analysis_data_on_disk (); + SourceCreated (ap); + return ap; - Source *src = new CoreAudioSource (s, node); + } catch (failed_constructor&) { + /* oh well, so much for that then ... */ + } + + } else { + + + try { + Source* src = new SndFileSource (s, node); #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS - // boost_debug_shared_ptr_mark_interesting (src, "Source"); + // boost_debug_shared_ptr_mark_interesting (src, "Source"); #endif - boost::shared_ptr<Source> ret (src); - - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); + boost::shared_ptr<Source> ret (src); + if (setup_peakfile (ret, defer_peaks)) { + return boost::shared_ptr<Source>(); + } + ret->check_for_analysis_data_on_disk (); + SourceCreated (ret); + return ret; } - ret->check_for_analysis_data_on_disk (); - SourceCreated (ret); - return ret; + catch (failed_constructor& err) { + +#ifdef USE_COREAUDIO_FOR_FILES + + /* this is allowed to throw */ + + Source *src = new CoreAudioSource (s, node); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + // boost_debug_shared_ptr_mark_interesting (src, "Source"); +#endif + boost::shared_ptr<Source> ret (src); + + if (setup_peakfile (ret, defer_peaks)) { + return boost::shared_ptr<Source>(); + } + + ret->check_for_analysis_data_on_disk (); + SourceCreated (ret); + return ret; #else - throw; // rethrow + throw; // rethrow #endif + } } - } else if (type == DataType::MIDI) { boost::shared_ptr<SMFSource> src (new SMFSource (s, node)); src->load_model (true, true); @@ -348,9 +370,7 @@ SourceFactory::createFromPlaylist (DataType type, Session& s, boost::shared_ptr< } ret->check_for_analysis_data_on_disk (); - - /* we never announce these sources */ - + SourceCreated (ret); return ret; } } |