tentative fix for losing (empty) MIDI files. Incomplete because testing shows issues with some workflows
This commit is contained in:
parent
dbc34ab4da
commit
c96ec968c7
|
@ -47,7 +47,8 @@ class LIBARDOUR_API 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));
|
||||
|
|
|
@ -443,6 +443,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);
|
||||
|
|
|
@ -3761,7 +3761,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 (
|
||||
|
|
|
@ -72,6 +72,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) {
|
||||
|
@ -132,12 +134,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 ();
|
||||
|
@ -380,6 +393,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) */
|
||||
|
@ -426,6 +440,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&
|
||||
|
@ -668,10 +683,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 ();
|
||||
|
@ -703,9 +720,6 @@ SMFSource::ensure_disk_file ()
|
|||
if (!_open) {
|
||||
open_for_write ();
|
||||
}
|
||||
|
||||
/* Flush, which will definitely put something on disk */
|
||||
flush_midi ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue