#include "ardour/midi_track.h"
#include "ardour/pannable.h"
#include "ardour/playlist_factory.h"
+#include "ardour/playlist_source.h"
#include "ardour/port.h"
#include "ardour/processor.h"
#include "ardour/proxy_controllable.h"
initialize_latencies ();
+ _locations->added.connect_same_thread (*this, boost::bind (&Session::location_added, this, _1));
+ _locations->removed.connect_same_thread (*this, boost::bind (&Session::location_removed, this, _1));
_locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
- _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
-
-
} catch (AudioEngine::PortRegistrationFailure& err) {
/* handle this one in a different way than all others, so that its clear what happened */
// send_full_time_code (0);
_engine.transport_locate (0);
- _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
- _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
+ send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
+ send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
MIDI::Name::MidiPatchManager::instance().set_session (this);
/* Copy plugin state files from template to new session */
std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
- copy_files (template_plugins, plugins_dir ());
+ copy_recurse (template_plugins, plugins_dir ());
return 0;
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- boost::shared_ptr<Source> source;
+ boost::shared_ptr<Source> source; /* don't need this but it stops some
+ * versions of gcc complaining about
+ * discarded return values.
+ */
nlist = node.children();
int user_choice;
+ if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
+ error << string_compose (_("A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
+ PROGRAM_NAME) << endmsg;
+ return -1;
+ }
+
if (!no_questions_about_missing_files) {
- user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
- } else {
+ user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
+ } else {
user_choice = -2;
}
switch (err.type) {
case DataType::AUDIO:
- warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
break;
case DataType::MIDI:
- warning << string_compose (_("A MIDI file is missing. %1 cannot currently recover from missing MIDI files"),
- PROGRAM_NAME) << endmsg;
- return -1;
+ /* The MIDI file is actually missing so
+ * just create a new one in the same
+ * location. Do not announce its
+ */
+ string fullpath;
+
+ if (!Glib::path_is_absolute (err.path)) {
+ fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
+ } else {
+ /* this should be an unrecoverable error: we would be creating a MIDI file outside
+ the session tree.
+ */
+ return -1;
+ }
+ /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
+ source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_frame_rate, false, false);
+ /* reset ID to match the missing one */
+ source->set_id (**niter);
+ /* Now we can announce it */
+ SourceFactory::SourceCreated (source);
break;
}
break;
}
catch (failed_constructor& err) {
- error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
+ error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
return boost::shared_ptr<Source>();
}
}
return -1;
}
- copy_files (plugins_dir(), template_plugin_state_path);
+ copy_recurse (plugins_dir(), template_plugin_state_path);
return 0;
}
void
Session::cleanup_regions ()
{
+ bool removed = false;
const RegionFactory::RegionMap& regions (RegionFactory::regions());
for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
uint32_t used = playlists->region_use_count (i->second);
if (used == 0 && !i->second->automatic ()) {
+ removed = true;
RegionFactory::map_remove (i->second);
}
}
+ if (removed) {
+ // re-check to remove parent references of compound regions
+ for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+ if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
+ continue;
+ }
+ assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
+ if (0 == playlists->region_use_count (i->second)) {
+ RegionFactory::map_remove (i->second);
+ }
+ }
+ }
+
/* dump the history list */
_history.clear ();
listen_position_changed ();
} else if (p == "solo-control-is-listen-control") {
solo_control_mode_changed ();
+ } else if (p == "solo-mute-gain") {
+ _solo_cut_control->Changed();
} else if (p == "timecode-offset" || p == "timecode-offset-negative") {
last_timecode_valid = false;
} else if (p == "playback-buffer-seconds") {
AudioSource::allocate_working_buffers (frame_rate());
- } else if (p == "automation-thinning-factor") {
- Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
} else if (p == "ltc-source-port") {
reconnect_ltc_input ();
} else if (p == "ltc-sink-port") {