Potential fix for lost/empty MIDI files when using snapshots #8552

* Copy flags of referenced file
* Do not share model with copied source!
This commit is contained in:
Robin Gareus
2021-03-19 16:27:16 +01:00
parent 4887350e0d
commit 4bb3a896b4
3 changed files with 17 additions and 9 deletions

View File

@@ -440,12 +440,14 @@ MidiSource::write_to (const Lock& lock, boost::shared_ptr<MidiSource> newsrc, Te
newsrc->flush_midi(newsrc_lock);
/* force a reload of the model if the range is partial */
if (begin != Temporal::Beats() || end != std::numeric_limits<Temporal::Beats>::max()) {
/* force a reload of the model if the range is partial */
newsrc->load_model (newsrc_lock, true);
} else {
newsrc->set_model (newsrc_lock, _model);
/* re-create model */
newsrc->destroy_model (newsrc_lock);
newsrc->load_model (newsrc_lock);
}
/* this file is not removable (but since it is MIDI, it is mutable) */

View File

@@ -1348,18 +1348,23 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass
const std::string base = PBD::basename_nosuffix(ancestor_name);
const string path = new_midi_source_path (base, false);
/* Session::save_state() will already have called
* ms->session_saved ();
*/
/* use SMF-API to clone data (use the midi_model, not data on disk) */
boost::shared_ptr<SMFSource> newsrc (new SMFSource (*this, path, SndFileSource::default_writable_flags));
boost::shared_ptr<SMFSource> newsrc (new SMFSource (*this, path, ms->flags()));
Source::Lock lm (ms->mutex());
// TODO special-case empty, removable() files: just create a new removable.
// (load + write flushes the model and creates the file)
if (!ms->model()) {
ms->load_model (lm);
}
/* write_to() calls newsrc->flush_midi () to write the file to disk */
if (ms->write_to (lm, newsrc, Temporal::Beats(), std::numeric_limits<Temporal::Beats>::max())) {
error << string_compose (_("Session-Save: Failed to copy MIDI Source '%1' for snapshot"), ancestor_name) << endmsg;
} else {
newsrc->session_saved (); /*< this sohuld be a no-op */
if (snapshot_type == SnapshotKeep) {
/* keep working on current session.
*
@@ -1370,7 +1375,7 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass
}
/* swap file-paths.
* ~SMFSource unlinks removable() files.
* ~SMFSource unlinks removable() files.
*/
std::string npath (ms->path ());
ms->replace_file (newsrc->path ());
@@ -1384,11 +1389,10 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass
*/
child->add_child_nocopy (ms->get_state());
}
continue;
}
continue;
}
}
child->add_child_nocopy (siter->second->get_state());
}
}

View File

@@ -212,7 +212,9 @@ SMFSource::open_for_write ()
void
SMFSource::close ()
{
/* nothing to do: file descriptor is never kept open */
/* nothing to do: file descriptor is never kept open.
* Note, keep `_open = true` regardless.
*/
}
extern PBD::Timing minsert;