Fix session-archive edge-cases, prepare uncompressed archives
authorRobin Gareus <robin@gareus.org>
Mon, 2 Oct 2017 23:06:07 +0000 (01:06 +0200)
committerRobin Gareus <robin@gareus.org>
Tue, 3 Oct 2017 00:24:10 +0000 (02:24 +0200)
* don't fork/clone midi regions (default snapshot)
* properly handle encoding embedded/external multi-channel files
* use dedicated file-extension (prepare for uncompressed archive)

libs/ardour/ardour/filename_extensions.h
libs/ardour/filename_extensions.cc
libs/ardour/session_state.cc
libs/ardour/sndfilesource.cc

index 2eb933d936b89eeebf3846facabbdeac1afd3f88..6d50de65703ed3111e3f6478d3d3f4936143d6d4 100644 (file)
@@ -34,6 +34,7 @@ namespace ARDOUR {
        LIBARDOUR_API extern const char* const history_suffix;
        LIBARDOUR_API extern const char* const export_preset_suffix;
        LIBARDOUR_API extern const char* const export_format_suffix;
+       LIBARDOUR_API extern const char* const session_archive_suffix;
 
 }
 
index c575f1295e9a7d667c425c4582a3bdb5c44ffbbd..31f07d5578ea6d67d19e330555c61afc9aacac78 100644 (file)
@@ -32,5 +32,6 @@ const char* const temp_suffix = X_(".tmp");
 const char* const history_suffix = X_(".history");
 const char* const export_preset_suffix = X_(".preset");
 const char* const export_format_suffix = X_(".format");
+const char* const session_archive_suffix = X_(".ardourzip");
 
 }
index 5265e517bd41c955bde4f64025caa3153470a13c..7cc2607e755199c62fe0cc2211eadc9206f804ac 100644 (file)
@@ -67,7 +67,6 @@
 #include "pbd/debug.h"
 #include "pbd/enumwriter.h"
 #include "pbd/error.h"
-#include "pbd/file_archive.h"
 #include "pbd/file_utils.h"
 #include "pbd/pathexpand.h"
 #include "pbd/pthread_utils.h"
@@ -842,7 +841,9 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
        std::string tmp_path(_session_dir->root_path());
        tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
 
+#ifndef NDEBUG
        cerr << "actually writing state to " << tmp_path << endl;
+#endif
 
        if (!tree.write (tmp_path)) {
                error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
@@ -854,7 +855,9 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
 
        } else {
 
+#ifndef NDEBUG
                cerr << "renaming state to " << xml_path << endl;
+#endif
 
                if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
                        error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
@@ -5277,7 +5280,7 @@ Session::archive_session (const std::string& dest,
        }
 
        /* prepare archive */
-       string archive = Glib::build_filename (dest, name + ".tar.xz");
+       string archive = Glib::build_filename (dest, name + session_archive_suffix);
 
        PBD::ScopedConnectionList progress_connection;
        PBD::FileArchive ar (archive);
@@ -5374,9 +5377,16 @@ Session::archive_session (const std::string& dest,
                        orig_gain[afs]    = afs->gain();
 
                        std::string new_path = make_new_media_path (afs->path (), to_dir, name);
-                       new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + ".flac");
+
+                       std::string channelsuffix = "";
+                       if (afs->channel() > 0) {  /* n_channels() is /wrongly/ 1. */
+                               /* embedded external multi-channel files are converted to multiple-mono */
+                               channelsuffix = string_compose ("-c%1", afs->channel ());
+                       }
+                       new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + channelsuffix + ".flac");
                        g_mkdir_with_parents (Glib::path_get_dirname (new_path).c_str (), 0755);
 
+
                        if (progress) {
                                progress->descend ((float)afs->readable_length () / total_size);
                        }
@@ -5461,7 +5471,20 @@ Session::archive_session (const std::string& dest,
 #ifdef LV2_SUPPORT
        PBD::Unwinder<bool> uw (LV2Plugin::force_state_save, true);
 #endif
-       save_state (name);
+       save_state (name, /*pending, don't fork MIDI, don't mark clean */ true);
+
+#ifndef NDEBUG
+       cerr << "archiving state from "
+               << Glib::build_filename (to_dir, legalize_for_path (name) + pending_suffix)
+               << " to "
+               << Glib::build_filename (to_dir, legalize_for_path (name) + statefile_suffix)
+               << endl;
+#endif
+
+       ::g_rename (
+                       Glib::build_filename (to_dir, legalize_for_path (name) + pending_suffix).c_str(),
+                       Glib::build_filename (to_dir, legalize_for_path (name) + statefile_suffix).c_str());
+
        save_default_options ();
 
        size_t prefix_len = _path.size();
@@ -5516,7 +5539,7 @@ Session::archive_session (const std::string& dest,
                i->first->set_gain (i->second, true);
        }
 
-       int rv = ar.create (filemap);
+       int rv = ar.create (filemap, PBD::FileArchive::CompressGood);
        remove_directory (to_dir);
 
        return rv;
index c69325741ed96529e8222bd62a9017c83ff5412f..b34bbaa9d26527af37c6b6fd9e7cb80513a572d1 100644 (file)
@@ -250,12 +250,12 @@ SndFileSource::SndFileSource (Session& s, const AudioFileSource& other, const st
 
        assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
 
-       _channel = other.channel ();
+       _channel = 0;
        init_sndfile ();
 
        _file_is_new = true;
 
-       _info.channels = other.n_channels();
+       _info.channels = 1;
        _info.samplerate = other.sample_rate ();
        _info.format = SF_FORMAT_FLAC | (use16bits ? SF_FORMAT_PCM_16 : SF_FORMAT_PCM_24);
 
@@ -297,11 +297,11 @@ SndFileSource::SndFileSource (Session& s, const AudioFileSource& other, const st
        float norm = 1.f;
 
        /* normalize before converting to fixed point, calc gain factor */
-       samplecnt_t len = other.read (buf, off, 8192, /*channel*/0);
+       samplecnt_t len = other.read (buf, off, 8192, other.channel ());
        while (len > 0) {
                peak = compute_peak (buf, len, peak);
                off += len;
-               len = other.read (buf, off, 8192, /*channel*/0);
+               len = other.read (buf, off, 8192, other.channel ());
                if (progress) {
                        progress->set_progress (0.5f * (float) off / other.readable_length ());
                }
@@ -314,7 +314,7 @@ SndFileSource::SndFileSource (Session& s, const AudioFileSource& other, const st
 
        /* copy file */
        off = 0;
-       len = other.read (buf, off, 8192, /*channel*/0);
+       len = other.read (buf, off, 8192, other.channel ());
        while (len > 0) {
                if (norm != 1.f) {
                        for (samplecnt_t i = 0; i < len; ++i) {
@@ -323,7 +323,7 @@ SndFileSource::SndFileSource (Session& s, const AudioFileSource& other, const st
                }
                write (buf, len);
                off += len;
-               len = other.read (buf, off, 8192, /*channel*/0);
+               len = other.read (buf, off, 8192, other.channel ());
                if (progress) {
                        progress->set_progress (0.5f + 0.5f * (float) off / other.readable_length ());
                }