X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession.cc;h=9df9f1940730ea15a9e300a5b9b9097b3b66dfc4;hb=4.1-78-g11e371c;hp=b1b0b1e1b54d62fa8d9d1c417d229c89923c1664;hpb=445d742af187a27f035c120545b4fb3a1e4dadd3;p=ardour.git diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index b1b0b1e1b5..9df9f19407 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -78,6 +78,7 @@ #include "ardour/plugin.h" #include "ardour/plugin_insert.h" #include "ardour/process_thread.h" +#include "ardour/profile.h" #include "ardour/rc_configuration.h" #include "ardour/recent_sessions.h" #include "ardour/region.h" @@ -243,6 +244,7 @@ Session::Session (AudioEngine &eng, , _all_route_group (new RouteGroup (*this, "all")) , routes (new RouteList) , _adding_routes_in_progress (false) + , _route_deletion_in_progress (false) , destructive_index (0) , _track_number_decimals(1) , solo_update_disabled (false) @@ -268,6 +270,7 @@ Session::Session (AudioEngine &eng, , first_file_header_format_reset (true) , have_looped (false) , _have_rec_enabled_track (false) + , _have_rec_disabled_track (true) , _step_editors (0) , _suspend_timecode_transmission (0) , _speakers (new Speakers) @@ -1604,6 +1607,15 @@ Session::location_added (Location *location) _session_range_location = location; } + if (location->is_mark()) { + /* listen for per-location signals that require us to do any * global updates for marks */ + + location->StartChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location)); + location->EndChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location)); + location->Changed.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location)); + location->FlagsChanged.connect_same_thread (skip_update_connections, boost::bind (&Session::update_marks, this, location)); + } + if (location->is_skip()) { /* listen for per-location signals that require us to update skip-locate events */ @@ -1614,7 +1626,7 @@ Session::location_added (Location *location) update_skips (location, true); } - + set_dirty (); } @@ -2198,7 +2210,11 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost: failed: if (!new_routes.empty()) { StateProtector sp (this); - add_routes (new_routes, true, true, true); + if (Profile->get_trx()) { + add_routes (new_routes, false, false, false); + } else { + add_routes (new_routes, true, true, false); + } if (instrument) { for (RouteList::iterator r = new_routes.begin(); r != new_routes.end(); ++r) { @@ -2360,6 +2376,43 @@ Session::reconnect_existing_routes (bool withLock, bool reconnect_master, bool r */ } +#ifdef USE_TRACKS_CODE_FEATURES + +void +Session::reconnect_midi_scene_ports(bool inputs) +{ + if (inputs) { + scene_in()->disconnect_all (); + + std::vector midi_port_states; + EngineStateController::instance()->get_physical_midi_input_states (midi_port_states); + + std::vector::iterator state_iter = midi_port_states.begin(); + + for (; state_iter != midi_port_states.end(); ++state_iter) { + if (state_iter->active && state_iter->available && state_iter->connected) { + scene_in()->connect (state_iter->name); + } + } + + } else { + scene_out()->disconnect_all (); + + std::vector midi_port_states; + EngineStateController::instance()->get_physical_midi_output_states (midi_port_states); + + std::vector::iterator state_iter = midi_port_states.begin(); + + for (; state_iter != midi_port_states.end(); ++state_iter) { + if (state_iter->active && state_iter->available && state_iter->connected) { + scene_out()->connect (state_iter->name); + } + } + + } +} + +#endif /** Caller must not hold process lock * @param name_template string to use for the start of the name, or "" to use "Audio". @@ -2374,10 +2427,19 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod RouteList new_routes; list > ret; - bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio"); + string name_pattern; + if (Profile->get_trx() ) { + name_pattern = "Track "; + } else { + name_pattern = "Audio "; + } + + bool const use_number = (how_many != 1) || name_template.empty () || name_template == _(name_pattern.c_str() ); + while (how_many) { - if (!find_route_name (name_template.empty() ? _("Audio") : name_template, ++track_id, track_name, sizeof(track_name), use_number)) { + + if (!find_route_name (name_template.empty() ? _(name_pattern.c_str()) : name_template, ++track_id, track_name, sizeof(track_name), use_number)) { error << "cannot find name for new audio track" << endmsg; goto failed; } @@ -2448,7 +2510,11 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod failed: if (!new_routes.empty()) { StateProtector sp (this); - add_routes (new_routes, true, true, true); + if (Profile->get_trx()) { + add_routes (new_routes, false, false, false); + } else { + add_routes (new_routes, true, true, false); + } } return ret; @@ -2534,7 +2600,11 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r failure: if (!ret.empty()) { StateProtector sp (this); - add_routes (ret, false, true, true); // autoconnect outputs only + if (Profile->get_trx()) { + add_routes (ret, false, false, false); + } else { + add_routes (ret, false, true, true); // autoconnect // outputs only + } } return ret; @@ -2651,7 +2721,11 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template out: if (!ret.empty()) { StateProtector sp (this); - add_routes (ret, true, true, true); + if (Profile->get_trx()) { + add_routes (ret, false, false, false); + } else { + add_routes (ret, true, true, false); + } IO::enable_connecting (); } @@ -2682,6 +2756,8 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output reassign_track_numbers(); + update_route_record_state (); + RouteAdded (new_routes); /* EMIT SIGNAL */ } @@ -2739,7 +2815,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool if (tr) { tr->PlaylistChanged.connect_same_thread (*this, boost::bind (&Session::track_playlist_changed, this, boost::weak_ptr (tr))); track_playlist_changed (boost::weak_ptr (tr)); - tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_have_rec_enabled_track, this)); + tr->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Session::update_route_record_state, this)); boost::shared_ptr mt = boost::dynamic_pointer_cast (tr); if (mt) { @@ -2873,100 +2949,128 @@ Session::add_internal_send (boost::shared_ptr dest, boost::shared_ptr route) +Session::remove_routes (boost::shared_ptr routes_to_remove) { - if (route == _master_out) { - return; - } - - route->set_solo (false, this); - - { + { // RCU Writer scope RCUWriter writer (routes); boost::shared_ptr rs = writer.get_copy (); - - rs->remove (route); - - /* deleting the master out seems like a dumb - idea, but its more of a UI policy issue - than our concern. - */ - - if (route == _master_out) { - _master_out = boost::shared_ptr (); - } - - if (route == _monitor_out) { - _monitor_out.reset (); - } - - /* writer goes out of scope, forces route list update */ - } - - update_route_solo_state (); - - // We need to disconnect the route's inputs and outputs - - route->input()->disconnect (0); - route->output()->disconnect (0); - - /* if the route had internal sends sending to it, remove them */ - if (route->internal_return()) { - - boost::shared_ptr r = routes.reader (); - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - boost::shared_ptr s = (*i)->internal_send_for (route); - if (s) { - (*i)->remove_processor (s); + + + for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) { + + if (*iter == _master_out) { + continue; + } + + (*iter)->set_solo (false, this); + + rs->remove (*iter); + + /* deleting the master out seems like a dumb + idea, but its more of a UI policy issue + than our concern. + */ + + if (*iter == _master_out) { + _master_out = boost::shared_ptr (); + } + + if (*iter == _monitor_out) { + _monitor_out.reset (); } - } - } - /* if the monitoring section had a pointer to this route, remove it */ - if (_monitor_out && !route->is_master() && !route->is_monitor()) { - Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); - PBD::Unwinder uw (ignore_route_processor_changes, true); - route->remove_aux_or_listen (_monitor_out); - } + update_route_solo_state (); + + // We need to disconnect the route's inputs and outputs + + (*iter)->input()->disconnect (0); + (*iter)->output()->disconnect (0); + + /* if the route had internal sends sending to it, remove them */ + if ((*iter)->internal_return()) { + + boost::shared_ptr r = routes.reader (); + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + boost::shared_ptr s = (*i)->internal_send_for (*iter); + if (s) { + (*i)->remove_processor (s); + } + } + } + + /* if the monitoring section had a pointer to this route, remove it */ + if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) { + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + PBD::Unwinder uw (ignore_route_processor_changes, true); + (*iter)->remove_aux_or_listen (_monitor_out); + } + + boost::shared_ptr mt = boost::dynamic_pointer_cast (*iter); + if (mt && mt->step_editing()) { + if (_step_editors > 0) { + _step_editors--; + } + } - boost::shared_ptr mt = boost::dynamic_pointer_cast (route); - if (mt && mt->step_editing()) { - if (_step_editors > 0) { - _step_editors--; + RouteAddedOrRemoved (false); /* EMIT SIGNAL */ } - } + + /* writer goes out of scope, forces route list update */ + } // end of RCU Writer scope + update_latency_compensation (); set_dirty(); - + /* Re-sort routes to remove the graph's current references to the one that is * going away, then flush old references out of the graph. + * Wave Tracks: reconnect routes */ - resort_routes (); + if (ARDOUR::Profile->get_trx () ) { + reconnect_existing_routes(true, false); + } else { + resort_routes (); + } + if (_process_graph) { _process_graph->clear_other_chain (); } - + /* get rid of it from the dead wood collection in the route list manager */ - /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */ - + routes.flush (); + + /* try to cause everyone to drop their references + * and unregister ports from the backend + */ + PBD::Unwinder uw_flag (_route_deletion_in_progress, true); - /* try to cause everyone to drop their references */ - - route->drop_references (); - + for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) { + (*iter)->drop_references (); + } + Route::RemoteControlIDChange(); /* EMIT SIGNAL */ - + /* save the new state of the world */ - + if (save_state (_current_snapshot_name)) { save_history (_current_snapshot_name); } + reassign_track_numbers(); + update_route_record_state (); +} + +void +Session::remove_route (boost::shared_ptr route) +{ + boost::shared_ptr rl (new RouteList); + rl->push_back (route); + remove_routes (rl); } void @@ -4951,9 +5055,15 @@ Session::have_rec_enabled_track () const return g_atomic_int_get (const_cast(&_have_rec_enabled_track)) == 1; } +bool +Session::have_rec_disabled_track () const +{ + return g_atomic_int_get (const_cast(&_have_rec_disabled_track)) == 1; +} + /** Update the state of our rec-enabled tracks flag */ void -Session::update_have_rec_enabled_track () +Session::update_route_record_state () { boost::shared_ptr rl = routes.reader (); RouteList::iterator i = rl->begin(); @@ -4974,6 +5084,20 @@ Session::update_have_rec_enabled_track () if (g_atomic_int_get (&_have_rec_enabled_track) != old) { RecordStateChanged (); /* EMIT SIGNAL */ } + + + i = rl->begin(); + while (i != rl->end ()) { + + boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); + if (tr && !tr->record_enabled ()) { + break; + } + + ++i; + } + + g_atomic_int_set (&_have_rec_disabled_track, i != rl->end () ? 1 : 0); } void @@ -5016,7 +5140,8 @@ Session::route_added_to_route_group (RouteGroup* rg, boost::weak_ptr r) void Session::route_removed_from_route_group (RouteGroup* rg, boost::weak_ptr r) { - RouteRemovedFromRouteGroup (rg, r); + update_route_record_state (); + RouteRemovedFromRouteGroup (rg, r); /* EMIT SIGNAL */ } boost::shared_ptr