tentative fix for losing (empty) MIDI files. Incomplete because testing shows issues...
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 28 Aug 2014 18:01:52 +0000 (14:01 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 15 Sep 2014 22:23:02 +0000 (18:23 -0400)
libs/ardour/ardour/source.h
libs/ardour/enums.cc
libs/ardour/session.cc
libs/ardour/smf_source.cc

index 5e851702d4114944e6a1ee40b80c873933575eeb..4427d65cc1cc2966f536a534fb13d1f2b7ff8873 100644 (file)
@@ -47,7 +47,8 @@ class Source : public SessionObject
                RemovableIfEmpty = 0x10,
                RemoveAtDestroy = 0x20,
                NoPeakFile = 0x40,
-               Destructive = 0x80
+               Destructive = 0x80,
+               Empty = 0x100, /* used for MIDI only */
        };
 
        Source (Session&, DataType type, const std::string& name, Flag flags=Flag(0));
index e32fe329af16ba2693fa425cfe1b54f54d759803..142ce2cc5f648828dee7d31511b65a3601b42189 100644 (file)
@@ -447,6 +447,7 @@ setup_enum_writer ()
        REGISTER_CLASS_ENUM (Source, RemoveAtDestroy);
        REGISTER_CLASS_ENUM (Source, NoPeakFile);
        REGISTER_CLASS_ENUM (Source, Destructive);
+       REGISTER_CLASS_ENUM (Source, Empty);
        REGISTER_BITS (_Source_Flag);
 
        REGISTER_ENUM (FadeLinear);
index 0e4a10f76b8eb5197135373eeefb6e1cddd99262..2d26cb73b45a803e9e918c484077dcb1aee31064 100644 (file)
@@ -3603,7 +3603,11 @@ Session::create_midi_source_by_stealing_name (boost::shared_ptr<Track> track)
                return boost::shared_ptr<MidiSource>();
        }
 
-       const string path = new_midi_source_path (name);
+       /* MIDI files are small, just put them in the first location of the
+          session source search path.
+       */
+
+       const string path = Glib::build_filename (source_search_path (DataType::MIDI).front(), name);
 
        return boost::dynamic_pointer_cast<SMFSource> (
                SourceFactory::createWritable (
index 1cd456ee58421205efb4da5a651ee0528d823af5..be141ef1927bdd9761d2e36e3de21c68399d0efa 100644 (file)
@@ -71,6 +71,8 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
         assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
        existence_check ();
 
+       _flags = Source::Flag (_flags | Empty);
+
        /* file is not opened until write */
 
        if (flags & Writable) {
@@ -131,12 +133,23 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
                throw failed_constructor ();
        }
 
-       if (init (_path, true)) {
+       /* we expect the file to exist, but if no MIDI data was ever added
+          it will have been removed at last session close. so, we don't
+          require it to exist if it was marked Empty.
+       */
+
+       if (init (_path, !(_flags & Source::Empty))) {
                throw failed_constructor ();
        }
 
-        assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
-       existence_check ();
+       if (!(_flags & Source::Empty)) {
+               assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
+               existence_check ();
+       } else {
+               assert (_flags & Source::Writable);
+               /* file will be opened on write */
+               return;
+       }
 
        if (open(_path)) {
                throw failed_constructor ();
@@ -379,6 +392,7 @@ SMFSource::append_event_unlocked_beats (const Evoral::Event<double>& ev)
 
        Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
        _last_ev_time_beats = ev.time();
+       _flags = Source::Flag (_flags & ~Empty);
 }
 
 /** Append an event with a timestamp in frames (framepos_t) */
@@ -425,6 +439,7 @@ SMFSource::append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, fr
 
        Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
        _last_ev_time_frames = ev.time();
+       _flags = Source::Flag (_flags & ~Empty);
 }
 
 XMLNode&
@@ -667,10 +682,12 @@ SMFSource::destroy_model ()
 void
 SMFSource::flush_midi ()
 {
-       if (!writable() || (writable() && !_open)) {
+       if (!writable() || _length_beats == 0.0) {
                return;
        }
 
+       ensure_disk_file ();
+
        Evoral::SMF::end_write ();
        /* data in the file means its no longer removable */
        mark_nonremovable ();
@@ -702,9 +719,6 @@ SMFSource::ensure_disk_file ()
                if (!_open) {
                        open_for_write ();
                }
-
-               /* Flush, which will definitely put something on disk */
-               flush_midi ();
        }
 }