X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession.cc;h=31693daff39d715ae5384e123f1d7cfcf7f6b3ce;hb=7d96960b162d25da87c388a3083775e8770bba56;hp=0bf161bb5daadaa360ed7a75c39e0536240a18cc;hpb=61cade6d59118288e90a405e0f4fbc24d0108814;p=ardour.git diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 0bf161bb5d..31693daff3 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -28,15 +28,13 @@ #include #include -#include -#include #include #include #include +#include #include "pbd/error.h" -#include #include "pbd/boost_debug.h" #include "pbd/pathscanner.h" #include "pbd/stl_delete.h" @@ -95,6 +93,8 @@ #include "ardour/tempo.h" #include "ardour/utils.h" +#include "midi++/jack.h" + #include "i18n.h" using namespace std; @@ -105,17 +105,21 @@ using boost::weak_ptr; bool Session::_disable_all_loaded_plugins = false; -sigc::signal Session::Dialog; -sigc::signal Session::AskAboutPendingState; -sigc::signal Session::AskAboutSampleRateMismatch; -sigc::signal Session::SendFeedback; +PBD::Signal1 Session::Dialog; +PBD::Signal0 Session::AskAboutPendingState; +PBD::Signal2 Session::AskAboutSampleRateMismatch; +PBD::Signal0 Session::SendFeedback; + +PBD::Signal0 Session::TimecodeOffsetChanged; +PBD::Signal0 Session::StartTimeChanged; +PBD::Signal0 Session::EndTimeChanged; +PBD::Signal0 Session::AutoBindingOn; +PBD::Signal0 Session::AutoBindingOff; +PBD::Signal2 Session::Exported; +PBD::Signal1 > Session::AskAboutPlaylistDeletion; -sigc::signal Session::TimecodeOffsetChanged; -sigc::signal Session::StartTimeChanged; -sigc::signal Session::EndTimeChanged; -sigc::signal Session::AutoBindingOn; -sigc::signal Session::AutoBindingOff; -sigc::signal Session::Exported; +static void clean_up_session_event (SessionEvent* ev) { delete ev; } +const SessionEvent::RTeventCallback Session::rt_cleanup (clean_up_session_event); Session::Session (AudioEngine &eng, const string& fullpath, @@ -135,7 +139,7 @@ Session::Session (AudioEngine &eng, _midi_clock_port (default_midi_clock_port), _session_dir (new SessionDirectory(fullpath)), state_tree (0), - _butler (new Butler (this)), + _butler (new Butler (*this)), _post_transport_work (0), _send_timecode_update (false), diskstreams (new DiskstreamList), @@ -188,8 +192,8 @@ Session::Session (AudioEngine &eng, _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false)); - config.ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), true)); + Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false)); + config.ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, true)); if (was_dirty) { DirtyChanged (); /* EMIT SIGNAL */ @@ -220,7 +224,7 @@ Session::Session (AudioEngine &eng, _midi_clock_port (default_midi_clock_port), _session_dir ( new SessionDirectory(fullpath)), state_tree (0), - _butler (new Butler (this)), + _butler (new Butler (*this)), _post_transport_work (0), _send_timecode_update (false), diskstreams (new DiskstreamList), @@ -277,7 +281,9 @@ Session::Session (AudioEngine &eng, if (master_out_channels) { ChanCount count(DataType::AUDIO, master_out_channels); - shared_ptr r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO)); + Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO); + boost_debug_shared_ptr_mark_interesting (rt, "Route"); + boost::shared_ptr r (rt); r->input()->ensure_io (count, false, this); r->output()->ensure_io (count, false, this); r->set_remote_control_id (control_id); @@ -290,7 +296,9 @@ Session::Session (AudioEngine &eng, if (control_out_channels) { ChanCount count(DataType::AUDIO, control_out_channels); - shared_ptr r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO)); + Route* rt = new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO); + boost_debug_shared_ptr_mark_interesting (rt, "Route"); + shared_ptr r (rt); r->input()->ensure_io (count, false, this); r->output()->ensure_io (count, false, this); r->set_remote_control_id (control_id++); @@ -321,7 +329,7 @@ Session::Session (AudioEngine &eng, _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - Config->ParameterChanged.connect (bind (mem_fun (*this, &Session::config_changed), false)); + Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Session::config_changed, this, _1, false)); } Session::~Session () @@ -344,12 +352,6 @@ Session::destroy () _engine.remove_session (); - GoingAway (); /* EMIT SIGNAL */ - - /* do this */ - - notify_callbacks (); - /* clear history so that no references to objects are held any more */ _history.clear (); @@ -362,8 +364,7 @@ Session::destroy () Stateful::loading_state_version = 0; - _butler->terminate_thread (); - + delete _butler; delete midi_control_ui; if (click_data != default_click) { @@ -388,32 +389,19 @@ Session::destroy () AudioDiskstream::free_working_buffers(); - Route::SyncOrderKeys.clear(); - - DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n"); - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) { - NamedSelectionList::iterator tmp; + /* tell everyone who is still standing that we're about to die */ + drop_references (); - tmp = i; - ++tmp; + /* tell everyone to drop references and delete objects as we go */ - delete *i; - i = tmp; - } + DEBUG_TRACE (DEBUG::Destruction, "delete named selections\n"); + named_selections.clear (); DEBUG_TRACE (DEBUG::Destruction, "delete regions\n"); - for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { - RegionList::iterator tmp; - - tmp = i; - ++tmp; - - DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 (%2); pre-ref = %2\n", i->second->name(), i->second.get(), i->second.use_count())); + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count())); i->second->drop_references (); - DEBUG_TRACE(DEBUG::Destruction, string_compose ("region post ref = %1\n", i->second.use_count())); - i = tmp; } - regions.clear (); DEBUG_TRACE (DEBUG::Destruction, "delete routes\n"); @@ -427,15 +415,19 @@ Session::destroy () { RCUWriter writer (routes); boost::shared_ptr r = writer.get_copy (); + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for route %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); (*i)->drop_references (); } + r->clear (); /* writer goes out of scope and updates master */ } routes.flush (); + boost::shared_ptr r = routes.reader (); + DEBUG_TRACE (DEBUG::Destruction, "delete diskstreams\n"); { RCUWriter dwriter (diskstreams); @@ -444,28 +436,22 @@ Session::destroy () DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for diskstream %1 ; pre-ref = %2\n", (*i)->name(), (*i).use_count())); (*i)->drop_references (); } + dsl->clear (); } diskstreams.flush (); DEBUG_TRACE (DEBUG::Destruction, "delete sources\n"); - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) { - SourceMap::iterator tmp; - - tmp = i; - ++tmp; - + for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) { DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for source %1 ; pre-ref = %2\n", i->second->path(), i->second.use_count())); i->second->drop_references (); - - i = tmp; } sources.clear (); - DEBUG_TRACE (DEBUG::Destruction, "delete route groups\n"); for (list::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) { + delete *i; } @@ -511,12 +497,15 @@ Session::when_engine_running () BootMessage (_("Using configuration")); - Config->map_parameters (bind (mem_fun (*this, &Session::config_changed), false)); - config.map_parameters (bind (mem_fun (*this, &Session::config_changed), true)); + boost::function ff (boost::bind (&Session::config_changed, this, _1, false)); + boost::function ft (boost::bind (&Session::config_changed, this, _1, true)); + + Config->map_parameters (ff); + config.map_parameters (ft); /* every time we reconnect, recompute worst case output latencies */ - _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies)); + _engine.Running.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies, this)); if (synced_to_jack()) { _engine.transport_stop (); @@ -803,6 +792,7 @@ Session::hookup_io () /* Tell all IO objects to connect themselves together */ IO::enable_connecting (); + MIDI::JACK_MidiPort::MakeConnections (); /* Now reset all panners */ @@ -870,7 +860,7 @@ Session::diskstream_playlist_changed (boost::weak_ptr wp) boost::shared_ptr playlist; if ((playlist = dstream->playlist()) != 0) { - playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed)); + playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this)); } /* see comment in playlist_length_changed () */ @@ -986,9 +976,7 @@ Session::set_auto_punch_location (Location* location) Location* existing; if ((existing = _locations.auto_punch_location()) != 0 && existing != location) { - auto_punch_start_changed_connection.disconnect(); - auto_punch_end_changed_connection.disconnect(); - auto_punch_changed_connection.disconnect(); + punch_connections.drop_connections(); existing->set_auto_punch (false, this); remove_event (existing->start(), SessionEvent::PunchIn); clear_events (SessionEvent::PunchOut); @@ -1006,17 +994,14 @@ Session::set_auto_punch_location (Location* location) return; } - auto_punch_start_changed_connection.disconnect(); - auto_punch_end_changed_connection.disconnect(); - auto_punch_changed_connection.disconnect(); + punch_connections.drop_connections (); - auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed)); - auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed)); - auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed)); + location->start_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_start_changed, this, _1)); + location->end_changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_end_changed, this, _1)); + location->changed.connect_same_thread (punch_connections, boost::bind (&Session::auto_punch_changed, this, _1)); location->set_auto_punch (true, this); - auto_punch_changed (location); auto_punch_location_changed (location); @@ -1028,9 +1013,7 @@ Session::set_auto_loop_location (Location* location) Location* existing; if ((existing = _locations.auto_loop_location()) != 0 && existing != location) { - auto_loop_start_changed_connection.disconnect(); - auto_loop_end_changed_connection.disconnect(); - auto_loop_changed_connection.disconnect(); + loop_connections.drop_connections (); existing->set_auto_loop (false, this); remove_event (existing->end(), SessionEvent::AutoLoop); auto_loop_location_changed (0); @@ -1049,16 +1032,11 @@ Session::set_auto_loop_location (Location* location) last_loopend = location->end(); - auto_loop_start_changed_connection.disconnect(); - auto_loop_end_changed_connection.disconnect(); - auto_loop_changed_connection.disconnect(); + loop_connections.drop_connections (); - auto_loop_start_changed_connection = location->start_changed.connect ( - mem_fun (this, &Session::auto_loop_changed)); - auto_loop_end_changed_connection = location->end_changed.connect ( - mem_fun (this, &Session::auto_loop_changed)); - auto_loop_changed_connection = location->changed.connect ( - mem_fun (this, &Session::auto_loop_changed)); + location->start_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1)); + location->end_changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1)); + location->changed.connect_same_thread (loop_connections, boost::bind (&Session::auto_loop_changed, this, _1)); location->set_auto_loop (true, this); @@ -1648,9 +1626,11 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m */ track->midi_diskstream()->non_realtime_input_change(); - route_group->add (track); + if (route_group) { + route_group->add (track); + } - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); + track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this)); //track->set_remote_control_id (control_id); new_routes.push_back (track); @@ -1763,7 +1743,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod try { AudioTrack* at = new AudioTrack (*this, track_name, Route::Flag (0), mode); - // boost_debug_shared_ptr_mark_interesting (at, typeid (at).name()); + boost_debug_shared_ptr_mark_interesting (at, "Track"); track = boost::shared_ptr(at); if (track->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) { @@ -1819,11 +1799,13 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod channels_used += track->n_inputs ().n_audio(); - route_group->add (track); + if (route_group) { + route_group->add (track); + } track->audio_diskstream()->non_realtime_input_change(); - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); + track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this)); track->set_remote_control_id (control_id); ++control_id; @@ -1881,20 +1863,27 @@ void Session::set_remote_control_ids () { RemoteModel m = Config->get_remote_model(); + bool emit_signal = false; shared_ptr r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ( MixerOrdered == m) { + if (MixerOrdered == m) { long order = (*i)->order_key(N_("signal")); - (*i)->set_remote_control_id( order+1 ); - } else if ( EditorOrdered == m) { + (*i)->set_remote_control_id (order+1, false); + emit_signal = true; + } else if (EditorOrdered == m) { long order = (*i)->order_key(N_("editor")); - (*i)->set_remote_control_id( order+1 ); - } else if ( UserOrdered == m) { + (*i)->set_remote_control_id (order+1, false); + emit_signal = true; + } else if (UserOrdered == m) { //do nothing ... only changes to remote id's are initiated by user } } + + if (emit_signal) { + Route::RemoteControlIDChange(); + } } @@ -1951,7 +1940,9 @@ Session::new_audio_route (bool aux, int input_channels, int output_channels, Rou } while (bus_id < (UINT_MAX-1)); try { - shared_ptr bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO)); + Route* rt = new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO); + boost_debug_shared_ptr_mark_interesting (rt, "Route"); + shared_ptr bus (rt); if (bus->input()->ensure_io (ChanCount(DataType::AUDIO, input_channels), false, this)) { error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), @@ -1998,7 +1989,9 @@ Session::new_audio_route (bool aux, int input_channels, int output_channels, Rou channels_used += bus->n_inputs ().n_audio(); - route_group->add (bus); + if (route_group) { + route_group->add (bus); + } bus->set_remote_control_id (control_id); ++control_id; @@ -2145,20 +2138,21 @@ Session::add_routes (RouteList& new_routes, bool save) for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { boost::weak_ptr wpr (*x); + boost::shared_ptr r (*x); - (*x)->listen_changed.connect (sigc::bind (mem_fun (*this, &Session::route_listen_changed), wpr)); - (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr)); - (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed)); - (*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x)); - (*x)->processors_changed.connect (mem_fun (*this, &Session::route_processors_changed)); - (*x)->route_group_changed.connect (mem_fun (*this, &Session::route_group_changed)); + r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr)); + r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, wpr)); + r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1)); + r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2)); + r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1)); + r->route_group_changed.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this)); - if ((*x)->is_master()) { - _master_out = (*x); + if (r->is_master()) { + _master_out = r; } - if ((*x)->is_control()) { - _control_out = (*x); + if (r->is_control()) { + _control_out = r; } } @@ -2183,6 +2177,7 @@ Session::add_routes (RouteList& new_routes, bool save) } RouteAdded (new_routes); /* EMIT SIGNAL */ + Route::RemoteControlIDChange (); /* EMIT SIGNAL */ } void @@ -2291,11 +2286,11 @@ Session::add_diskstream (boost::shared_ptr dstream) /* writer goes out of scope, copies ds back to main */ } - dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr (dstream))); + dstream->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::diskstream_playlist_changed, this, boost::weak_ptr (dstream))); /* this will connect to future changes, and check the current length */ diskstream_playlist_changed (boost::weak_ptr (dstream)); - dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream)); + dstream->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_diskstream, this)); dstream->prepare (); @@ -2385,6 +2380,8 @@ Session::remove_route (shared_ptr route) sync_order_keys (N_("session")); + Route::RemoteControlIDChange(); /* EMIT SIGNAL */ + /* save the new state of the world */ if (save_state (_current_snapshot_name)) { @@ -2809,9 +2806,7 @@ Session::add_regions (vector >& new_regions) } } - region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr(region))); - region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr(region))); - + region->StateChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr(region))); update_region_name_map (region); } @@ -2967,6 +2962,10 @@ Session::remove_last_capture () } } + for (list >::iterator i = r.begin(); i != r.end(); ++i) { + remove_region (*i); + } + destroy_regions (r); save_state (_current_snapshot_name); @@ -2998,7 +2997,6 @@ Session::add_source (boost::shared_ptr source) } if (result.second) { - source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr (source))); set_dirty(); } @@ -3387,10 +3385,7 @@ Session::add_playlist (boost::shared_ptr playlist, bool unused) return; } - bool existing = playlists->add (playlist); - if (!existing) { - playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr(playlist))); - } + playlists->add (playlist); if (unused) { playlist->release(); @@ -3480,8 +3475,8 @@ Session::remove_empty_sounds () TapeFileMatcher tape_file_matcher; remove_if (audio_filenames.begin(), audio_filenames.end(), - sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches)); - + boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1)); + for (vector::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) { sys::path audio_file_path (_session_dir->sound_path()); @@ -3515,42 +3510,6 @@ Session::is_auditioning () const } } -void -Session::set_solo (boost::shared_ptr r, bool yn) -{ - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_solo (yn, this); - } - } - - set_dirty(); -} - -void -Session::set_listen (boost::shared_ptr r, bool yn) -{ - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_listen (yn, this); - } - } - - set_dirty(); -} - -void -Session::set_mute (boost::shared_ptr r, bool yn) -{ - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_mute (yn, this); - } - } - - set_dirty(); -} - uint32_t Session::n_diskstreams () const { @@ -3596,36 +3555,14 @@ Session::graph_reordered () } } -void -Session::set_record_enable (boost::shared_ptr rl, bool yn) -{ - if (!writable()) { - return; - } - - for (RouteList::iterator i = rl->begin(); i != rl->end(); ) { - boost::shared_ptr t; - - if ((t = boost::dynamic_pointer_cast(*i)) != 0) { - t->set_record_enable (yn, this); - if (t->meter_point() == MeterCustom) { - /* don't change metering for this track */ - i = rl->erase (i); - } else { - ++i; - } - } else { - ++i; - } - } - - set_dirty (); -} - void Session::add_processor (Processor* processor) { - processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor)); + /* Session does not own Processors (they belong to a Route) but we do want to track + the arrival and departure of port inserts, sends and returns for naming + purposes. + */ + processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor)); set_dirty(); } @@ -3869,37 +3806,33 @@ Session::mark_insert_id (uint32_t id) /* Named Selection management */ -NamedSelection * +boost::shared_ptr Session::named_selection_by_name (string name) { Glib::Mutex::Lock lm (named_selection_lock); for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) { if ((*i)->name == name) { - return* i; + return *i; } } - return 0; + return boost::shared_ptr(); } void -Session::add_named_selection (NamedSelection* named_selection) +Session::add_named_selection (boost::shared_ptr named_selection) { { Glib::Mutex::Lock lm (named_selection_lock); named_selections.insert (named_selections.begin(), named_selection); } - for (list >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) { - add_playlist (*i); - } - set_dirty(); NamedSelectionAdded (); /* EMIT SIGNAL */ } void -Session::remove_named_selection (NamedSelection* named_selection) +Session::remove_named_selection (boost::shared_ptr named_selection) { bool removed = false; @@ -3909,7 +3842,6 @@ Session::remove_named_selection (NamedSelection* named_selection) NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection); if (i != named_selections.end()) { - delete (*i); named_selections.erase (i); set_dirty(); removed = true; @@ -4245,6 +4177,10 @@ Session::compute_initial_length () void Session::sync_order_keys (std::string const & base) { + if (deletion_in_progress()) { + return; + } + if (!Config->get_sync_all_route_ordering()) { /* leave order keys as they are */ return; @@ -4257,8 +4193,11 @@ Session::sync_order_keys (std::string const & base) } Route::SyncOrderKeys (base); // EMIT SIGNAL -} + /* this might not do anything */ + + set_remote_control_ids (); +} /** @return true if there is at least one record-enabled diskstream, otherwise false */ bool