tentative fix for losing (empty) MIDI files. Incomplete because testing shows issues with some workflows

This commit is contained in:
Paul Davis 2014-08-28 14:01:52 -04:00
parent dbc34ab4da
commit c96ec968c7
4 changed files with 29 additions and 9 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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 (

View File

@ -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 ();
}
}