#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;
}
}
- SaveSession (); /* EMIT SIGNAL */
+ SessionSaveUnderway (); /* EMIT SIGNAL */
tree.set_root (&get_state());
int
Session::load_options (const XMLNode& node)
{
- LocaleGuard lg (X_("POSIX"));
+ LocaleGuard lg (X_("C"));
config.set_variables (node);
return 0;
}
new_routes.push_back (route);
}
+ BootMessage (_("Tracks/busses loaded; Adding to Session"));
+
add_routes (new_routes, false, false, false);
+ BootMessage (_("Finished adding tracks/busses"));
+
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;
}
statename = statename.substr (start+1);
}
- if ((end = statename.rfind(".ardour")) == string::npos) {
+ if ((end = statename.rfind(statefile_suffix)) == string::npos) {
end = statename.length();
}
_current_trans_quarks.push_front (q);
}
+void
+Session::abort_reversible_command ()
+{
+ if (_current_trans != 0) {
+ _current_trans->clear();
+ delete _current_trans;
+ _current_trans = 0;
+ _current_trans_quarks.clear();
+ }
+}
+
void
Session::commit_reversible_command (Command *cmd)
{
static bool
accept_all_state_files (const string& path, void* /*arg*/)
{
- if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
- return false;
- }
+ if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
+ return false;
+ }
- return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
+ std::string const statefile_ext (statefile_suffix);
+ if (path.length() >= statefile_ext.length()) {
+ return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
+ } else {
+ return false;
+ }
}
int
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") {