debug flag for session destruction and waf option for boost SP debug
[ardour.git] / libs / ardour / session.cc
index 031c2aa58a69cee081d0565e579d993acb9a0b85..ce1fbca84624fe5410e70f92a0412dc09ecd0f35 100644 (file)
@@ -132,7 +132,7 @@ Session::Session (AudioEngine &eng,
          pending_events (2048),
          state_tree (0),
          _butler (new Butler (this)),
-         post_transport_work((PostTransportWork)0),
+         _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
@@ -218,7 +218,7 @@ Session::Session (AudioEngine &eng,
          pending_events (2048),
          state_tree (0),
          _butler (new Butler (this)),
-         post_transport_work((PostTransportWork)0),
+         _post_transport_work (0),
          _send_timecode_update (false),
          midi_thread (pthread_t (0)),
          midi_requests (16),
@@ -871,8 +871,13 @@ Session::playlist_length_changed ()
 }
 
 void
-Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
+Session::diskstream_playlist_changed (boost::weak_ptr<Diskstream> wp)
 {
+       boost::shared_ptr<Diskstream> dstream = wp.lock ();
+       if (!dstream) {
+               return;
+       }
+       
        boost::shared_ptr<Playlist> playlist;
 
        if ((playlist = dstream->playlist()) != 0) {
@@ -1059,9 +1064,12 @@ Session::set_auto_loop_location (Location* location)
        auto_loop_end_changed_connection.disconnect();
        auto_loop_changed_connection.disconnect();
 
-       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));
+       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->set_auto_loop (true, this);
 
@@ -1229,12 +1237,12 @@ Session::maybe_enable_record ()
        set_dirty();
 }
 
-nframes_t
+nframes64_t
 Session::audible_frame () const
 {
-       nframes_t ret;
+       nframes64_t ret;
+       nframes64_t tf;
        nframes_t offset;
-       nframes_t tf;
 
        /* the first of these two possible settings for "offset"
           mean that the audible frame is stationary until
@@ -1896,7 +1904,7 @@ Session::set_remote_control_ids ()
 
 
 RouteList
-Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
+Session::new_audio_route (bool aux, int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many)
 {
        char bus_name[32];
        uint32_t bus_id = 1;
@@ -1999,6 +2007,10 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
                        bus->set_remote_control_id (control_id);
                        ++control_id;
 
+                       if (aux) {
+                               bus->add_internal_return ();
+                       }
+
                        ret.push_back (bus);
                }
 
@@ -2246,7 +2258,6 @@ Session::globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p
        add_internal_sends (dest, p, t);
 }
 
-
 void
 Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::shared_ptr<RouteList> senders)
 {
@@ -2266,6 +2277,8 @@ Session::add_internal_sends (boost::shared_ptr<Route> dest, Placement p, boost::
 
                (*i)->listen_via (dest, p, true, true);
        }
+
+       graph_reordered ();
 }
 
 void
@@ -2283,9 +2296,9 @@ Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
                /* writer goes out of scope, copies ds back to main */
        }
 
-       dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
+       dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), boost::weak_ptr<Diskstream> (dstream)));
        /* this will connect to future changes, and check the current length */
-       diskstream_playlist_changed (dstream);
+       diskstream_playlist_changed (boost::weak_ptr<Diskstream> (dstream));
 
        dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
 
@@ -2413,7 +2426,7 @@ Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
        shared_ptr<RouteList> r = routes.reader ();
        int32_t delta;
 
-       if (route->soloed()) {
+       if (route->self_soloed()) {
                delta = 1;
        } else {
                delta = -1;
@@ -2424,24 +2437,30 @@ Session::route_solo_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
        */
 
        solo_update_disabled = true;
+
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+               bool via_sends_only;
 
-               if ((*i)->feeds (route) && !(*i)->is_hidden() && !(*i)->is_master() && !(*i)->is_control()) {
-                       /* do it */
-                       (*i)->mod_solo_level (delta);
-               }
+
+               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) {
+                               (*i)->mod_solo_by_others (delta);
+                       }
+               } 
        }
 
        /* make sure master is never muted by solo */
 
-       if (_master_out && route != _master_out && _master_out->solo_level() == 0 && !_master_out->soloed()) {
-               _master_out->mod_solo_level (1);
-       }
-
+       if (_master_out && route != _master_out && _master_out->soloed_by_others() == 0 && !_master_out->soloed()) {
+               _master_out->mod_solo_by_others (1);
+       }
        /* ditto for control outs make sure master is never muted by solo */
 
-       if (_control_out && route != _control_out && _control_out && _control_out->solo_level() == 0) {
-               _control_out->mod_solo_level (1);
+       if (_control_out && route != _control_out && _control_out && _control_out->soloed_by_others() == 0) {
+               _control_out->mod_solo_by_others (1);
        }
 
        solo_update_disabled = false;
@@ -2462,7 +2481,7 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
        }
 
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-               if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->soloed()) {
+               if (!(*i)->is_master() && !(*i)->is_control() && !(*i)->is_hidden() && (*i)->self_soloed()) {
                        something_soloed = true;
                        break;
                }
@@ -2474,6 +2493,20 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
        }
 }
 
+boost::shared_ptr<RouteList> 
+Session::get_routes_with_internal_returns() const
+{
+       shared_ptr<RouteList> r = routes.reader ();
+       boost::shared_ptr<RouteList> rl (new RouteList);
+
+       for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+               if ((*i)->internal_return ()) {
+                       rl->push_back (*i);
+               }
+       }
+       return rl;
+}
+
 shared_ptr<Route>
 Session::route_by_name (string name)
 {
@@ -3517,7 +3550,7 @@ void
 Session::set_audition (boost::shared_ptr<Region> r)
 {
        pending_audition_region = r;
-       post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
+       add_post_transport_work (PostTransportAudition);
        _butler->schedule_transport_work ();
 }
 
@@ -4443,3 +4476,21 @@ Session::route_group_changed ()
 {
        RouteGroupChanged (); /* EMIT SIGNAL */
 }
+
+vector<SyncSource>
+Session::get_available_sync_options () const
+{
+       vector<SyncSource> ret;
+       
+       ret.push_back (JACK);
+
+       if (mtc_port()) {
+               ret.push_back (MTC);
+       } 
+
+       if (midi_clock_port()) {
+               ret.push_back (MIDIClock);
+       } 
+
+       return ret;
+}