X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession.cc;h=decb2603fe98a73fd7268a7eea62c16a646d269f;hb=7720d0d109ca47c2a0a23883d5831de1ff32005d;hp=9cb4cc32849506a0fd00e14bd0c2afc1ad76e658;hpb=478fd92039443743babec98812f10921209f1e5a;p=ardour.git diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 9cb4cc3284..decb2603fe 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -28,21 +28,20 @@ #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" #include "pbd/basename.h" #include "pbd/stacktrace.h" #include "pbd/file_utils.h" +#include "pbd/convert.h" #include "ardour/amp.h" #include "ardour/analyser.h" @@ -71,6 +70,7 @@ #include "ardour/midi_playlist.h" #include "ardour/midi_region.h" #include "ardour/midi_track.h" +#include "ardour/midi_ui.h" #include "ardour/named_selection.h" #include "ardour/playlist.h" #include "ardour/plugin_insert.h" @@ -94,6 +94,8 @@ #include "ardour/tempo.h" #include "ardour/utils.h" +#include "midi++/jack.h" + #include "i18n.h" using namespace std; @@ -104,17 +106,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, @@ -134,11 +140,9 @@ 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), - midi_thread (pthread_t (0)), - midi_requests (128), // the size of this should match the midi request pool size diskstreams (new DiskstreamList), routes (new RouteList), _total_free_4k_blocks (0), @@ -189,8 +193,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 */ @@ -221,11 +225,9 @@ 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), - midi_thread (pthread_t (0)), - midi_requests (16), diskstreams (new DiskstreamList), routes (new RouteList), _total_free_4k_blocks (0), @@ -280,7 +282,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); @@ -293,7 +297,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++); @@ -324,7 +330,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 () @@ -347,11 +353,9 @@ Session::destroy () _engine.remove_session (); - GoingAway (); /* EMIT SIGNAL */ + /* clear region map. it doesn't hold references, but lets just be sensible here */ - /* do this */ - - notify_callbacks (); + RegionFactory::clear_map (); /* clear history so that no references to objects are held any more */ @@ -365,8 +369,8 @@ Session::destroy () Stateful::loading_state_version = 0; - _butler->terminate_thread (); - //terminate_midi_thread (); + delete _butler; + delete midi_control_ui; if (click_data != default_click) { delete [] click_data; @@ -390,32 +394,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"); @@ -429,15 +420,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); @@ -446,28 +441,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; } @@ -513,12 +502,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 (); @@ -805,6 +797,7 @@ Session::hookup_io () /* Tell all IO objects to connect themselves together */ IO::enable_connecting (); + MIDI::JACK_MidiPort::MakeConnections (); /* Now reset all panners */ @@ -872,7 +865,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 () */ @@ -988,9 +981,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); @@ -1008,17 +999,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); @@ -1030,9 +1018,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); @@ -1051,16 +1037,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); @@ -1164,8 +1145,9 @@ Session::disable_record (bool rt_context, bool force) // FIXME: timestamp correct? [DR] // FIXME FIXME FIXME: rt_context? this must be called in the process thread. // does this /need/ to be sent in all cases? - if (rt_context) + if (rt_context) { deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame); + } if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) { boost::shared_ptr dsl = diskstreams.reader(); @@ -1649,9 +1631,11 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m */ track->midi_diskstream()->non_realtime_input_change(); - track->set_route_group (route_group, 0); + 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); @@ -1764,7 +1748,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)) { @@ -1820,11 +1804,13 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod channels_used += track->n_inputs ().n_audio(); - track->set_route_group (route_group, 0); + 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; @@ -1882,20 +1868,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(); + } } @@ -1952,7 +1945,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"), @@ -1999,7 +1994,9 @@ Session::new_audio_route (bool aux, int input_channels, int output_channels, Rou channels_used += bus->n_inputs ().n_audio(); - bus->set_route_group (route_group, 0); + if (route_group) { + route_group->add (bus); + } bus->set_remote_control_id (control_id); ++control_id; @@ -2146,20 +2143,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 (hide (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; } } @@ -2184,6 +2182,7 @@ Session::add_routes (RouteList& new_routes, bool save) } RouteAdded (new_routes); /* EMIT SIGNAL */ + Route::RemoteControlIDChange (); /* EMIT SIGNAL */ } void @@ -2292,11 +2291,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 (); @@ -2386,6 +2385,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)) { @@ -2449,8 +2450,7 @@ Session::route_solo_changed (void* /*src*/, boost::weak_ptr wpr) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { bool via_sends_only; - - if ((*i) == route || !(*i)->solo_isolated() || !(*i)->is_master() || !(*i)->is_control() || (*i)->is_hidden()) { + if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_control() || (*i)->is_hidden()) { continue; } else if ((*i)->feeds (route, &via_sends_only)) { if (!via_sends_only) { @@ -2810,9 +2810,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->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr(region))); update_region_name_map (region); } @@ -2842,7 +2840,7 @@ Session::update_region_name_map (boost::shared_ptr region) } void -Session::region_changed (Change what_changed, boost::weak_ptr weak_region) +Session::region_changed (const PropertyChange& what_changed, boost::weak_ptr weak_region) { boost::shared_ptr region (weak_region.lock ()); @@ -2850,12 +2848,12 @@ Session::region_changed (Change what_changed, boost::weak_ptr weak_regio return; } - if (what_changed & Region::HiddenChanged) { + if (what_changed.contains (Properties::hidden)) { /* relay hidden changes */ RegionHiddenChange (region); } - if (what_changed & NameChanged) { + if (what_changed.contains (Properties::name)) { update_region_name_map (region); } } @@ -2968,6 +2966,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); @@ -2999,7 +3001,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(); } @@ -3388,10 +3389,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(); @@ -3481,8 +3479,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()); @@ -3516,48 +3514,6 @@ Session::is_auditioning () const } } -void -Session::set_all_solo (bool yn) -{ - shared_ptr r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_solo (yn, this); - } - } - - set_dirty(); -} - -void -Session::set_all_listen (bool yn) -{ - shared_ptr r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_listen (yn, this); - } - } - - set_dirty(); -} - -void -Session::set_all_mute (bool yn) -{ - shared_ptr r = routes.reader (); - - 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 { @@ -3603,63 +3559,14 @@ Session::graph_reordered () } } -void -Session::record_disenable_all () -{ - if (!writable()) { - return; - } - - record_enable_change_all (false); -} - -void -Session::record_enable_all () -{ - if (!writable()) { - return; - } - - record_enable_change_all (true); -} - -void -Session::record_enable_change_all (bool yn) -{ - shared_ptr r = routes.reader (); - RouteList* tracks = new RouteList; - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - boost::shared_ptr t; - - if (boost::dynamic_pointer_cast(*i) != 0) { - tracks->push_back (*i); - } - } - - SessionEvent* ev = new SessionEvent (SessionEvent::SetRecordEnable, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, yn); - - ev->routes = tracks; - ev->Complete.connect (mem_fun (*this, &Session::cleanup_event)); - queue_event (ev); -} - -void -Session::do_record_enable_change_all (RouteList* rl, bool yn) -{ - for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { - boost::shared_ptr t; - - if ((t = boost::dynamic_pointer_cast(*i)) != 0) { - t->set_record_enable (yn, this); - } - } -} - 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(); } @@ -3768,7 +3675,7 @@ Session::bundle_by_name (string name) const } void -Session::tempo_map_changed (Change) +Session::tempo_map_changed (const PropertyChange&) { clear_clicks (); @@ -3903,37 +3810,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; @@ -3943,7 +3846,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; @@ -4063,8 +3965,7 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end, return result; } - // any bigger than this seems to cause stack overflows in called functions - const nframes_t chunk_size = (128 * 1024)/4; + const nframes_t chunk_size = (256 * 1024)/4; // block all process callback handling @@ -4168,9 +4069,14 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end, /* construct a region to represent the bounced material */ - result = RegionFactory::create (srcs, 0, - srcs.front()->length(srcs.front()->timeline_position()), - region_name_from_path (srcs.front()->name(), true)); + PropertyList plist; + + plist.add (Properties::start, 0); + plist.add (Properties::length, srcs.front()->length(srcs.front()->timeline_position())); + plist.add (Properties::name, region_name_from_path (srcs.front()->name(), true)); + + result = RegionFactory::create (srcs, plist); + } out: @@ -4280,6 +4186,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; @@ -4292,8 +4202,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 @@ -4349,9 +4262,9 @@ Session::solo_control_mode_changed () /* cancel all solo or all listen when solo control mode changes */ if (Config->get_solo_control_is_listen_control()) { - set_all_solo (false); + set_solo (routes.reader(), false); } else { - set_all_listen (false); + set_listen (routes.reader(), false); } }