From 6f205f857b6ace7a63e77384f058eac191bb0de9 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 18 Feb 2020 01:26:20 +0100 Subject: Replace missing .mid files with silence This fixes a crash: missing playlist due to missing .mid, and retains regions for missing MIDI files. As opposed to missing Audio, we cannot use a SilentFileSource, because MIDI files are destructive. This also adds an API to query missing files that have been replaced with silence to report them to the user. --- libs/ardour/ardour/session.h | 2 ++ libs/ardour/ardour/source.h | 1 + libs/ardour/session.cc | 17 +++++++++++++++++ libs/ardour/smf_source.cc | 35 +++++++++++++++++++---------------- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index daaecd8a38..8fe209a552 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1161,6 +1161,8 @@ public: std::list unknown_processors () const; + std::list missing_filesources (DataType) const; + /** Emitted when a feedback cycle has been detected within Ardour's signal processing path. Until it is fixed (by the user) some (unspecified) routes will not be run. diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index 56e72acd42..9604062b8e 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -56,6 +56,7 @@ public: Destructive = 0x80, Empty = 0x100, /* used for MIDI only */ RF64_RIFF = 0x200, + Missing = 0x400, /* used for MIDI only */ }; typedef Glib::Threads::Mutex::Lock Lock; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index de68cd9830..cfc7f9b278 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -103,6 +103,7 @@ #include "ardour/route_graph.h" #include "ardour/route_group.h" #include "ardour/rt_tasklist.h" +#include "ardour/silentfilesource.h" #include "ardour/send.h" #include "ardour/selection.h" #include "ardour/session.h" @@ -6338,6 +6339,22 @@ Session::unknown_processors () const return p; } +list +Session::missing_filesources (DataType dt) const +{ + list p; + for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) { + if (dt == DataType::AUDIO && 0 != boost::dynamic_pointer_cast (i->second)) { + p.push_back (i->second->name()); + } + else if (dt == DataType::MIDI && 0 != boost::dynamic_pointer_cast (i->second) && (i->second->flags() & Source::Missing) != 0) { + p.push_back (i->second->name()); + } + } + p.sort (); + return p; +} + void Session::initialize_latencies () { diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index e0d65176c3..164b5971ab 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -156,23 +156,24 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist) } } catch (MissingSource& err) { - - if (_flags & Source::Empty) { - /* we don't care that the file was not found, because - it was empty. But FileSource::init() will have - failed to set our _path correctly, so we have to do - this ourselves. Use the first entry in the search - path for MIDI files, which is assumed to be the - correct "main" location. - */ - std::vector sdirs = s.source_search_path (DataType::MIDI); - _path = Glib::build_filename (sdirs.front(), _path); - /* This might be important, too */ - _file_is_new = true; - } else { - /* pass it on */ - throw; + if (0 == (_flags & Source::Empty)) { + /* Don't throw, create the source. + * Since MIDI is writable, we cannot use a SilentFileSource. + */ + _flags = Source::Flag (_flags | Source::Empty | Source::Missing); } + + /* we don't care that the file was not found, because + it was empty. But FileSource::init() will have + failed to set our _path correctly, so we have to do + this ourselves. Use the first entry in the search + path for MIDI files, which is assumed to be the + correct "main" location. + */ + std::vector sdirs = s.source_search_path (DataType::MIDI); + _path = Glib::build_filename (sdirs.front(), _path); + /* This might be important, too */ + _file_is_new = true; } if (!(_flags & Source::Empty)) { @@ -451,6 +452,7 @@ SMFSource::append_event_beats (const Glib::Threads::Mutex::Lock& lock, Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id); _last_ev_time_beats = time; _flags = Source::Flag (_flags & ~Empty); + _flags = Source::Flag (_flags & ~Missing); } /** Append an event with a timestamp in samples (samplepos_t) */ @@ -501,6 +503,7 @@ SMFSource::append_event_samples (const Glib::Threads::Mutex::Lock& lock, Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id); _last_ev_time_samples = ev.time(); _flags = Source::Flag (_flags & ~Empty); + _flags = Source::Flag (_flags & ~Missing); } XMLNode& -- cgit v1.2.3