diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 44ef80553b..e2b889d030 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -175,6 +175,7 @@ class LIBARDOUR_API AudioDiskstream : public Diskstream Sample *speed_buffer; boost::shared_ptr write_source; + boost::shared_ptr replication_source; /** Information about the Port that our audio data comes from */ ChannelSource source; @@ -262,7 +263,7 @@ class LIBARDOUR_API AudioDiskstream : public Diskstream int add_channel_to (boost::shared_ptr, uint32_t how_many); int remove_channel_from (boost::shared_ptr, uint32_t how_many); - void reset_replication_sources (); + int reset_replication_sources (); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index d2edf5edac..b3dcb72a07 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -183,7 +183,7 @@ class LIBARDOUR_API Diskstream : public SessionObject, public PublicDiskstream static PBD::Signal0 DiskOverrun; static PBD::Signal0 DiskUnderrun; - static PBD::Signal0 ReplicationPathChange; + static PBD::Signal0 ReplicationPathChange; protected: friend class Session; @@ -339,7 +339,7 @@ class LIBARDOUR_API Diskstream : public SessionObject, public PublicDiskstream void route_going_away (); - virtual void reset_replication_sources () = 0; + virtual int reset_replication_sources () = 0; }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 4b8e93687a..715b5ca07e 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -182,7 +182,7 @@ class LIBARDOUR_API MidiDiskstream : public Diskstream MidiBuffer _gui_feed_buffer; mutable Glib::Threads::Mutex _gui_feed_buffer_mutex; - void reset_replication_sources () { /* no replication for MIDI */ } + int reset_replication_sources () { return 0; /* no replication for MIDI */ } }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index d9b8089d75..7ef285d481 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -613,6 +613,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop boost::shared_ptr create_audio_source_for_session ( size_t, std::string const &, uint32_t, bool destructive); + boost::shared_ptr create_replicated_audio_source (boost::shared_ptr original, const std::string& replication_parent_folder); boost::shared_ptr create_midi_source_for_session (std::string const &); boost::shared_ptr create_midi_source_by_stealing_name (boost::shared_ptr); diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index bcddc175d4..c56419d161 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -1932,6 +1932,8 @@ AudioDiskstream::use_new_write_source (uint32_t n) chan->write_source->set_allow_remove_if_empty (!destructive()); + reset_replication_sources (); + return 0; } @@ -2499,8 +2501,23 @@ AudioDiskstream::set_write_source_name (const std::string& str) { return true; } -void +int AudioDiskstream::reset_replication_sources () { - + RCUWriter writer (channels); + boost::shared_ptr c = writer.get_copy(); + + try { + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + if (!_replication_path.empty()) { + // (*chan)->replication_source = session.create_replicated_audio_source ((*c)->write_source, _replication_path); + } else { + (*chan)->replication_source.reset (); + } + } + return 0; + } catch (...) { + error << string_compose (_("%1: cannot create replication sources @ %2"), _name, _replication_path) << endmsg; + return -1; + } } diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 4e597c3fd9..fe304a3688 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -63,7 +63,7 @@ string Diskstream::_replication_path; PBD::Signal0 Diskstream::DiskOverrun; PBD::Signal0 Diskstream::DiskUnderrun; -PBD::Signal0 Diskstream::ReplicationPathChange; +PBD::Signal0 Diskstream::ReplicationPathChange; Diskstream::Diskstream (Session &sess, const string &name, Flag flag) : SessionObject(sess, name) @@ -753,6 +753,9 @@ void Diskstream::set_replication_path (const std::string& path) { _replication_path = path; - ReplicationPathChange (); /* EMIT SIGNAL */ + + if (ReplicationPathChange ()) { /* EMIT SIGNAL */ + // error + } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 035db144be..fa70270770 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -4120,6 +4120,40 @@ Session::create_audio_source_for_session (size_t n_chans, string const & base, u } } +/** Create a new within-session audio source */ +boost::shared_ptr +Session::create_replicated_audio_source (boost::shared_ptr original, const std::string& replication_parent_folder) +{ + if (!Glib::file_test (replication_parent_folder.c_str(), Glib::FileTest (G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR))) { + throw failed_constructor (); + } + + string session_dirname = Glib::path_get_basename (_path); + + vector v; + v.push_back (replication_parent_folder); + v.push_back (session_dirname); + v.push_back (X_("audio")); + + string repdir = Glib::build_filename (v); + + if (!Glib::file_test (repdir.c_str(), Glib::FileTest (G_FILE_TEST_EXISTS|G_FILE_TEST_IS_DIR))) { + if (g_mkdir_with_parents (repdir.c_str(), 0755) < 0) { + throw failed_constructor (); + } + } + + string file = Glib::path_get_basename (original->path()); + string path = Glib::build_filename (repdir, file); + + if (!path.empty()) { + return boost::dynamic_pointer_cast ( + SourceFactory::createWritable (DataType::AUDIO, *this, path, false, frame_rate())); + } else { + throw failed_constructor (); + } +} + /** Create a new within-session MIDI source */ boost::shared_ptr Session::create_midi_source_for_session (string const & basic_name)