when renaming redirects, scan all routes AND sends AND port inserts for the name...
[ardour.git] / libs / ardour / audiofilter.cc
index a26d9674bd06f1395fa09820ca304d4f2d32fbe0..a85ce16821689ba664d737ea85aa2b95a1009fbd 100644 (file)
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <time.h>
@@ -26,6 +25,9 @@
 #include <ardour/session.h>
 #include <ardour/audioregion.h>
 #include <ardour/audiofilter.h>
+#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
+#include <ardour/analyser.h>
 
 #include "i18n.h"
 
@@ -33,25 +35,42 @@ using namespace ARDOUR;
 using namespace PBD;
 
 int
-AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsrcs)
+AudioFilter::make_new_sources (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs, string suffix)
 {
-       vector<string> names = region.master_source_names();
+       vector<string> names = region->master_source_names();
 
-       for (uint32_t i = 0; i < region.n_channels(); ++i) {
+       if (names.size() != region->n_channels()) {
+               warning << _("This is an old Ardour session that does not have\n\
+sufficient information for rendered FX") << endmsg;
+               return -1;
+       }
+
+       for (uint32_t i = 0; i < region->n_channels(); ++i) {
+
+               string name = PBD::basename_nosuffix (names[i]);
+
+               /* remove any existing version of suffix by assuming it starts
+                  with some kind of "special" character.
+               */
+
+               if (!suffix.empty()) {
+                       string::size_type pos = name.find (suffix[0]);
+                       if (pos != string::npos && pos > 2) {
+                               name = name.substr (0, pos - 1);
+                       }
+               }
 
-               string path = session.path_from_region_name (PBD::basename_nosuffix (names[i]), string (""));
+               string path = session.path_from_region_name (name, suffix);
 
                if (path.length() == 0) {
-                       error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region.name()) 
+                       error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region->name()) 
                              << endmsg;
                        return -1;
                }
 
                try {
-                       nsrcs.push_back (new SndFileSource (path, 
-                                                           Config->get_native_file_data_format(),
-                                                           Config->get_native_file_header_format(),
-                                                           session.frame_rate()));
+                       nsrcs.push_back (boost::dynamic_pointer_cast<AudioSource> (SourceFactory::createWritable (session, path, false, session.frame_rate())));
+                       nsrcs.back()->prepare_for_peakfile_writes ();
                } 
 
                catch (failed_constructor& err) {
@@ -64,10 +83,8 @@ AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsr
 }
 
 int
-AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
+AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs, string region_name)
 {
-       string region_name;
-
        /* update headers on new sources */
 
        time_t xnow;
@@ -76,19 +93,62 @@ AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
        time (&xnow);
        now = localtime (&xnow);
 
-       for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
-               AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*si);
+       for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
+               boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*si);
+               boost::shared_ptr<AudioSource> as = boost::dynamic_pointer_cast<AudioSource>(*si);
+
+               if (as) {
+                       as->done_with_peakfile_writes ();
+               }
+
                if (afs) {
-                       afs->update_header (region.position(), *now, xnow);
+                       afs->update_header (region->position(), *now, xnow);
+                       afs->mark_immutable ();
+               }
+               
+               /* now that there is data there, requeue the file for analysis */
+               
+               if (Config->get_auto_analyse_audio()) {
+                       Analyser::queue_source_for_analysis (*si, false);
                }
        }
 
+
+       /* make a new whole-file region that copies almost everything from the old one, but
+          uses the new sources (and new length and name)
+       */
+
+       boost::shared_ptr<AudioRegion> ar;
+       boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(nsrcs.front());
+
+       string whole_file_region_name = region_name_from_path (afs->path(), true);
+
+       ar = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create 
+                                                      (nsrcs, 0, nsrcs.front()->length(), whole_file_region_name, 0, 
+                                                       Region::Flag (Region::WholeFile|Region::DefaultFlags)));
+       
+       /* now make a copy of the region that copies almost everything from the old one, but
+          uses the new sources (and new length and name)
+       */
+
        /* create a new region */
 
-       region_name = session.new_region_name (region.name());
+       if (region_name.empty()) {
+               region_name = session.new_region_name (region->name());
+       }
+
        results.clear ();
-       results.push_back (new AudioRegion (nsrcs, 0, region.length(), region_name, 0, 
-                                           Region::Flag (Region::WholeFile|Region::DefaultFlags)));
 
+       ar = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create 
+                                                      (region, nsrcs, region_name, 0, region->flags()));
+
+       /* if we changed the length, fix up the envelope */
+
+       if (region->length() != ar->length()) {
+               ar->envelope().extend_to (ar->length());
+       }
+
+       results.push_back (ar);
+       
        return 0;
 }