further optimizations for multiple-track-at-once addition. as in "whoah!"
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 17 Aug 2006 02:12:20 +0000 (02:12 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 17 Aug 2006 02:12:20 +0000 (02:12 +0000)
git-svn-id: svn://localhost/ardour2/trunk@836 d708f5d6-7413-0410-9779-e7cbd77b26cf

15 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_route_list.cc
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mixer_ui.h
gtk2_ardour/route_params_ui.cc
gtk2_ardour/route_params_ui.h
gtk2_ardour/route_ui.cc
libs/ardour/ardour/session.h
libs/ardour/audioengine.cc
libs/ardour/session.cc
libs/ardour/session_state.cc

index 345f715d39d7774193ee9f1f6cfeb6fcecda6caa..66374ff4173c99ea29b859c7f73130a00bba39e8 100644 (file)
@@ -874,21 +874,21 @@ ARDOUR_UI::session_add_midi_track ()
 }
 
 void
-ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
+ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
 {
-       boost::shared_ptr<Route>          route;
-       vector<boost::shared_ptr<AudioTrack> > routes;
+       list<boost::shared_ptr<AudioTrack> > tracks;
+       Session::RouteList routes;
 
        if (session == 0) {
-               warning << _("You cannot add a track without a session already loaded.") << endmsg;
+               warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
                return;
        }
 
        try { 
-               if (disk) {
-                       routes = session->new_audio_track (input_channels, output_channels, mode, how_many);
+               if (track) {
+                       tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
 
-                       if (routes.size() != how_many) {
+                       if (tracks.size() != how_many) {
                                if (how_many == 1) {
                                        error << _("could not create a new audio track") << endmsg;
                                } else {
@@ -897,8 +897,15 @@ ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t o
                        }
 
                } else {
-                       if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
-                               error << _("could not create new audio bus") << endmsg;
+
+                       routes = session->new_audio_route (input_channels, output_channels, how_many);
+
+                       if (routes.size() != how_many) {
+                               if (how_many == 1) {
+                                       error << _("could not create a new audio track") << endmsg;
+                               } else {
+                                       error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
+                               }
                        }
                }
                
@@ -2086,14 +2093,7 @@ ARDOUR_UI::add_route ()
        if (track) {
                session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
        } else {
-               while (count) {
-                       session_add_audio_bus (input_chan, output_chan);
-               }
-               --count;
-               
-               while (Main::events_pending()) {
-                       Main::iteration ();
-               }
+               session_add_audio_bus (input_chan, output_chan, count);
        }
 }
 
index ebb5c7683860e5e0bd078f8386dabb41dddb58e6..cafa335bf23398343f53be189a138ba317863938 100644 (file)
@@ -193,8 +193,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI
                session_add_audio_route (true, input_channels, output_channels, mode, how_many);
        }
 
-       void session_add_audio_bus (int input_channels, int32_t output_channels) {
-               session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, 1);
+       void session_add_audio_bus (int input_channels, int32_t output_channels, uint32_t how_many) {
+               session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, how_many);
        }
 
        void session_add_midi_track ();
index 3d8e99ad6ef15e71d811c5e0d7352ea9f0086e88..7b461b1d5cbced8e3852a01bad2b11b32942f807 100644 (file)
@@ -196,7 +196,7 @@ ARDOUR_UI::install_actions ()
        
        act = ActionManager::register_action (common_actions, X_("AddAudioTrack"), _("Add Audio Track"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_track), 1, 1, ARDOUR::Normal, 1));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (common_actions, X_("AddAudioBus"), _("Add Audio Bus"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_bus), 1, 1));
+       act = ActionManager::register_action (common_actions, X_("AddAudioBus"), _("Add Audio Bus"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_bus), 1, 1, 1));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (common_actions, X_("Save"), _("Save"),  bind (mem_fun(*this, &ARDOUR_UI::save_state), string("")));
        ActionManager::session_sensitive_actions.push_back (act);
index 5ddb2b0d2ed56046c5fe462976e8c9061321213d..dd62a4dd75f2c66e59659000adbce54e6d34bce8 100644 (file)
@@ -466,7 +466,7 @@ class Editor : public PublicEditor
        void add_crossfade_context_items (AudioStreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many);
        void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
 
-       void handle_new_route (boost::shared_ptr<ARDOUR::Route>);
+       void handle_new_route (ARDOUR::Session::RouteList&);
        void remove_route (TimeAxisView *);
        bool route_removal;
 
index 4128348e3a3a4c29b087c0a6a3faf1738d745722..71e28c9a1db4843da5a10cf11c2013142e7d79f4 100644 (file)
@@ -332,7 +332,7 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
                
        case ImportAsTrack:
        { 
-               vector<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
+               list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
                if (!at.empty()) {
                        copy = new AudioRegion (region);
                        at.front()->diskstream()->playlist()->add_region (*copy, pos);
@@ -342,7 +342,7 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
 
        case ImportAsTapeTrack:
        {
-               vector<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive));
+               list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive));
                if (!at.empty()) {
                        copy = new AudioRegion (region);
                        at.front()->diskstream()->playlist()->add_region (*copy, pos);
index c93cf9aba290f64ec80a3cacba65f80d46737574..573dec0fd5e78835eb60beedf9701fa858cbfc07 100644 (file)
@@ -39,72 +39,76 @@ using namespace PBD;
 using namespace Gtk;
 
 void
-Editor::handle_new_route (boost::shared_ptr<Route> route)
+Editor::handle_new_route (Session::RouteList& routes)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), route));
+       ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), routes));
        
        TimeAxisView *tv;
        AudioTimeAxisView *atv;
        TreeModel::Row parent;
        TreeModel::Row row;
 
-       if (route->hidden()) {
-               return;
-       }
-       
-       tv = new AudioTimeAxisView (*this, *session, route, track_canvas);
+       for (Session::RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
+               boost::shared_ptr<Route> route = (*x);
 
+               if (route->hidden()) {
+                       return;
+               }
+               
+               tv = new AudioTimeAxisView (*this, *session, route, track_canvas);
+               
 #if 0
-       if (route_display_model->children().size() == 0) {
+               if (route_display_model->children().size() == 0) {
+                       
+                       /* set up basic entries */
+                       
+                       TreeModel::Row row;
+                       
+                       row = *(route_display_model->append());  // path = "0"
+                       row[route_display_columns.text] = _("Busses");
+                       row[route_display_columns.tv] = 0;
+                       row = *(route_display_model->append());  // path = "1"
+                       row[route_display_columns.text] = _("Tracks");
+                       row[route_display_columns.tv] = 0;
+                       
+               }
                
-                /* set up basic entries */
-
-               TreeModel::Row row;
+               if (dynamic_cast<AudioTrack*>(route.get()) != 0) {
+                       TreeModel::iterator iter = route_display_model->get_iter ("1");  // audio tracks 
+                       parent = *iter;
+               } else {
+                       TreeModel::iterator iter = route_display_model->get_iter ("0");  // busses
+                       parent = *iter;
+               }
                
-               row = *(route_display_model->append());  // path = "0"
-               row[route_display_columns.text] = _("Busses");
-               row[route_display_columns.tv] = 0;
-               row = *(route_display_model->append());  // path = "1"
-               row[route_display_columns.text] = _("Tracks");
-               row[route_display_columns.tv] = 0;
-
-       }
-
-       if (dynamic_cast<AudioTrack*>(route.get()) != 0) {
-               TreeModel::iterator iter = route_display_model->get_iter ("1");  // audio tracks 
-               parent = *iter;
-       } else {
-               TreeModel::iterator iter = route_display_model->get_iter ("0");  // busses
-               parent = *iter;
-       }
-       
-
-       row = *(route_display_model->append (parent.children()));
+               
+               row = *(route_display_model->append (parent.children()));
 #else 
-       row = *(route_display_model->append ());
+               row = *(route_display_model->append ());
 #endif
-
-       row[route_display_columns.text] = route->name();
-       row[route_display_columns.visible] = tv->marked_for_display();
-       row[route_display_columns.tv] = tv;
-       
-       track_views.push_back (tv);
-
-       ignore_route_list_reorder = true;
-       
-       if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
-               /* added a new fresh one at the end */
-               if (atv->route()->order_key(N_("editor")) == -1) {
-                       atv->route()->set_order_key (N_("editor"), route_display_model->children().size()-1);
+               
+               row[route_display_columns.text] = route->name();
+               row[route_display_columns.visible] = tv->marked_for_display();
+               row[route_display_columns.tv] = tv;
+               
+               track_views.push_back (tv);
+               
+               ignore_route_list_reorder = true;
+               
+               if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
+                       /* added a new fresh one at the end */
+                       if (atv->route()->order_key(N_("editor")) == -1) {
+                               atv->route()->set_order_key (N_("editor"), route_display_model->children().size()-1);
+                       }
                }
+               
+               ignore_route_list_reorder = false;
+               
+               route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
+               
+               tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv));
        }
 
-       ignore_route_list_reorder = false;
-       
-       route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
-
-       tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv));
-       
        editor_mixer_button.set_sensitive(true);
 }
 
@@ -491,9 +495,7 @@ Editor::initial_route_list_display ()
 
        route_display_model->clear ();
 
-       for (Session::RouteList::iterator i = r.begin(); i != r.end(); ++i) {
-               handle_new_route (*i);
-       }
+       handle_new_route (r);
 
        no_route_list_redisplay = false;
 
index c2eb588b2f2744865d085574155f36aff585e3cf..84fade54726e69085f8fae31c3e50236718e4790 100644 (file)
@@ -251,38 +251,42 @@ Mixer_UI::show_window ()
 }
 
 void
-Mixer_UI::add_strip (boost::shared_ptr<Route> route)
+Mixer_UI::add_strip (Session::RouteList& routes)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun(*this, &Mixer_UI::add_strip), route));
+       ENSURE_GUI_THREAD(bind (mem_fun(*this, &Mixer_UI::add_strip), routes));
        
        MixerStrip* strip;
 
-       if (route->hidden()) {
-               return;
-       }
-
-       strip = new MixerStrip (*this, *session, route);
-       strips.push_back (strip);
-
-       strip->set_width (_strip_width);
-       show_strip (strip);
-
-       no_track_list_redisplay = true;
-
-       TreeModel::Row row = *(track_model->append());
-       row[track_columns.text] = route->name();
-
-       row[track_columns.visible] = true;
-       row[track_columns.route] = route;
-       row[track_columns.strip] = strip;
-
-       no_track_list_redisplay = false;
-       redisplay_track_list ();
-
-       route->name_changed.connect (bind (mem_fun(*this, &Mixer_UI::strip_name_changed), strip));
-       strip->GoingAway.connect (bind (mem_fun(*this, &Mixer_UI::remove_strip), strip));
+       for (Session::RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
+               boost::shared_ptr<Route> route = (*x);
 
-       strip->signal_button_release_event().connect (bind (mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
+               if (route->hidden()) {
+                       return;
+               }
+               
+               strip = new MixerStrip (*this, *session, route);
+               strips.push_back (strip);
+               
+               strip->set_width (_strip_width);
+               show_strip (strip);
+               
+               no_track_list_redisplay = true;
+               
+               TreeModel::Row row = *(track_model->append());
+               row[track_columns.text] = route->name();
+               
+               row[track_columns.visible] = true;
+               row[track_columns.route] = route;
+               row[track_columns.strip] = strip;
+               
+               no_track_list_redisplay = false;
+               redisplay_track_list ();
+               
+               route->name_changed.connect (bind (mem_fun(*this, &Mixer_UI::strip_name_changed), strip));
+               strip->GoingAway.connect (bind (mem_fun(*this, &Mixer_UI::remove_strip), strip));
+               
+               strip->signal_button_release_event().connect (bind (mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
+       }
 }
 
 void
@@ -623,9 +627,7 @@ Mixer_UI::initial_track_display ()
 
        track_model->clear ();
 
-       for (Session::RouteList::iterator i = copy.begin(); i != copy.end(); ++i) {
-               add_strip (*i);
-       }
+       add_strip (copy);
 
        no_track_list_redisplay = false;
 
index 6fe41204279cc840ce0a12007cec0c729d3d1418..77021dc8feb5b9795df0205a3f4df637ae6bcbfb 100644 (file)
@@ -111,7 +111,7 @@ class Mixer_UI : public Gtk::Window
 
        bool strip_scroller_button_release (GdkEventButton*);
 
-       void add_strip (boost::shared_ptr<ARDOUR::Route>);
+       void add_strip (ARDOUR::Session::RouteList&);
        void remove_strip (MixerStrip *);
 
        void hide_all_strips (bool with_select);
index 8d8efad8a277040b849626428dc1aef60829e577..c23ed272e193eefacd1ae35d68f25cbe88d552e8 100644 (file)
@@ -159,22 +159,26 @@ RouteParams_UI::~RouteParams_UI ()
 }
 
 void
-RouteParams_UI::add_route (boost::shared_ptr<Route> route)
+RouteParams_UI::add_routes (Session::RouteList& routes)
 {
-       ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::add_route), route));
+       ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::add_routes), routes));
        
-       if (route->hidden()) {
-               return;
-       }
-
-       TreeModel::Row row = *(route_display_model->append());
-       row[route_display_columns.text] = route->name();
-       row[route_display_columns.route] = route;
+       for (Session::RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
+               boost::shared_ptr<Route> route = (*x);
 
-       //route_select_list.rows().back().select ();
-       
-       route->name_changed.connect (bind (mem_fun(*this, &RouteParams_UI::route_name_changed), route));
-       route->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::route_removed), route));
+               if (route->hidden()) {
+                       return;
+               }
+               
+               TreeModel::Row row = *(route_display_model->append());
+               row[route_display_columns.text] = route->name();
+               row[route_display_columns.route] = route;
+               
+               //route_select_list.rows().back().select ();
+               
+               route->name_changed.connect (bind (mem_fun(*this, &RouteParams_UI::route_name_changed), route));
+               route->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::route_removed), route));
+       }
 }
 
 
@@ -355,9 +359,10 @@ RouteParams_UI::set_session (Session *sess)
        route_display_model->clear();
 
        if (session) {
-               session->foreach_route (this, &RouteParams_UI::add_route);
+               boost::shared_ptr<Session::RouteList> r = session->get_routes();
+               add_routes (*r);
                session->going_away.connect (mem_fun(*this, &ArdourDialog::session_gone));
-               session->RouteAdded.connect (mem_fun(*this, &RouteParams_UI::add_route));
+               session->RouteAdded.connect (mem_fun(*this, &RouteParams_UI::add_routes));
                start_updating ();
        } else {
                stop_updating ();
index 5f487d6e5cfbbe44e30d642e40f1b8f93927465b..eff31023f7e7e7bd2bf9a0d8d340b67da8b66937 100644 (file)
@@ -159,7 +159,7 @@ class RouteParams_UI : public ArdourDialog
        Glib::RefPtr<Gtk::ListStore> route_display_model;
 
        
-       void add_route (boost::shared_ptr<ARDOUR::Route>);
+       void add_routes (ARDOUR::Session::RouteList&);
 
        void route_name_changed (void *src, boost::shared_ptr<ARDOUR::Route> route);
        void route_removed (boost::shared_ptr<ARDOUR::Route> route);
index b2fdcaf7d4b9c1e9c7570db31c33ee4b14fa496d..2b95ff9cfb2804a3f94f5eb088812cead5530ee9 100644 (file)
@@ -733,7 +733,6 @@ void
 RouteUI::route_removed ()
 {
        ENSURE_GUI_THREAD(mem_fun (*this, &RouteUI::route_removed));
-       cerr << "Route UI @ " << this << " destroyed by impending end of route\n";
        delete this;
 }
 
index 757d13f79ba20c022b29becdb7f69ccd72b08016..78f601136965924f03e2ea3f1bcd0b7c6ae27ab9 100644 (file)
@@ -345,7 +345,7 @@ class Session : public sigc::trackable, public Stateful
        sigc::signal<void> DurationChanged;
        sigc::signal<void> HaltOnXrun;
 
-       sigc::signal<void,boost::shared_ptr<Route> > RouteAdded;
+       sigc::signal<void,RouteList&> RouteAdded;
 
        void request_roll ();
        void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
@@ -536,8 +536,8 @@ class Session : public sigc::trackable, public Stateful
 
        /* fundamental operations. duh. */
 
-       std::vector<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1);
-       boost::shared_ptr<Route>      new_audio_route (int input_channels, int output_channels);
+       std::list<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1);
+       RouteList new_audio_route (int input_channels, int output_channels, uint32_t how_many);
 
        void   remove_route (boost::shared_ptr<Route>);
 
@@ -1517,7 +1517,7 @@ class Session : public sigc::trackable, public Stateful
 
        SerializedRCUManager<RouteList>  routes;
 
-       void   add_route (boost::shared_ptr<Route>, bool save = true);
+       void   add_routes (RouteList&, bool save = true);
        uint32_t destructive_index;
 
        int load_routes (const XMLNode&);
index 5f86f217628d96205fde46ec99c8873e048a000b..14593d97120f0b9fb3b880ab76850cc587c835e5 100644 (file)
@@ -760,7 +760,6 @@ AudioEngine::get_physical_inputs (vector<string>& ins)
                for (i = 0; ports[i]; ++i) {
                        ins.push_back (ports[i]);
                }
-               cerr << "got " << ins.size() << " physical ins\n";
                free (ports);
        }
 }
@@ -783,7 +782,6 @@ AudioEngine::get_physical_outputs (vector<string>& outs)
                for (i = 0; ports[i]; ++i) {
                        outs.push_back (ports[i]);
                }
-               cerr << "got " << outs.size() << " physical outs\n";
                free (ports);
        }
 }
index dfa7468725b2784f2251b6d0fa60eac805ae0ad1..43311e77e41358660592607cef12cd94aac63cd8 100644 (file)
@@ -327,13 +327,17 @@ Session::Session (AudioEngine &eng,
 
        if (control_out_channels) {
                shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
-               add_route (r);
+               RouteList rl;
+               rl.push_back (r);
+               add_routes (rl);
                _control_out = r;
        }
 
        if (master_out_channels) {
                shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
-               add_route (r);
+               RouteList rl;
+               rl.push_back (r);
+               add_routes (rl);
                _master_out = r;
        } else {
                /* prohibit auto-connect to master, because there isn't one */
@@ -1669,7 +1673,7 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
        
 }
 
-vector<boost::shared_ptr<AudioTrack> >
+list<boost::shared_ptr<AudioTrack> >
 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
 {
        char track_name[32];
@@ -1677,7 +1681,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
        uint32_t n = 0;
        uint32_t channels_used = 0;
        string port;
-       vector<boost::shared_ptr<AudioTrack> > ret;
+       RouteList new_routes;
+       list<boost::shared_ptr<AudioTrack> > ret;
 
        /* count existing audio tracks */
 
@@ -1791,6 +1796,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
                        track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
                        track->set_remote_control_id (ntracks());
 
+                       new_routes.push_back (track);
                        ret.push_back (track);
                }
 
@@ -1804,23 +1810,22 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
                --how_many;
        }
 
-       if (!ret.empty()) {
-               for (vector<boost::shared_ptr<AudioTrack> >::iterator x = ret.begin(); x != ret.end(); ++x) {
-                       add_route ((*x), false);
-               }
-               
+       if (!new_routes.empty()) {
+               add_routes (new_routes, false);
                save_state (_current_snapshot_name);
        }
 
        return ret;
 }
 
-shared_ptr<Route>
-Session::new_audio_route (int input_channels, int output_channels)
+Session::RouteList
+Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
 {
        char bus_name[32];
+       uint32_t bus_id = 1;
        uint32_t n = 0;
        string port;
+       RouteList ret;
 
        /* count existing audio busses */
 
@@ -1830,101 +1835,125 @@ Session::new_audio_route (int input_channels, int output_channels)
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                        if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
                                if (!(*i)->hidden()) {
-                                       n++;
+                                       bus_id++;
                                }
                        }
                }
        }
 
-       do {
-               snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
-               if (route_by_name (bus_name) == 0) {
-                       break;
-               }
-               n++;
+       vector<string> physinputs;
+       vector<string> physoutputs;
 
-       } while (n < (UINT_MAX-1));
+       _engine.get_physical_outputs (physoutputs);
+       _engine.get_physical_inputs (physinputs);
 
-       try {
-               shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
+       while (how_many) {
 
-               if (bus->ensure_io (input_channels, output_channels, false, this)) {
-                       error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
-                                         input_channels, output_channels)
-                             << endmsg;
-               }
+               do {
+                       ++bus_id;
 
-               for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
-                       
-                       port = "";
+                       snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
 
-                       if (input_auto_connect & AutoConnectPhysical) {
-                               port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
-                       } 
-                       
-                       if (port.length() && bus->connect_input (bus->input (x), port, this)) {
+                       if (route_by_name (bus_name) == 0) {
                                break;
                        }
-               }
 
-               for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
-                       
-                       port = "";
+               } while (bus_id < (UINT_MAX-1));
 
-                       if (output_auto_connect & AutoConnectPhysical) {
-                               port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
-                       } else if (output_auto_connect & AutoConnectMaster) {
-                               if (_master_out) {
-                                       port = _master_out->input (x%_master_out->n_inputs())->name();
+               try {
+                       shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
+                       
+                       if (bus->ensure_io (input_channels, output_channels, false, this)) {
+                               error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
+                                                        input_channels, output_channels)
+                                     << endmsg;
+                       }
+                       
+                       for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
+                               
+                               port = "";
+                               
+                               if (input_auto_connect & AutoConnectPhysical) {
+                                       port = physinputs[((n+x)%n_physical_inputs)];
+                               } 
+                               
+                               if (port.length() && bus->connect_input (bus->input (x), port, this)) {
+                                       break;
                                }
                        }
-
-                       if (port.length() && bus->connect_output (bus->output (x), port, this)) {
-                               break;
+                       
+                       for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
+                               
+                               port = "";
+                               
+                               if (output_auto_connect & AutoConnectPhysical) {
+                                       port = physoutputs[((n+x)%n_physical_outputs)];
+                               } else if (output_auto_connect & AutoConnectMaster) {
+                                       if (_master_out) {
+                                               port = _master_out->input (x%_master_out->n_inputs())->name();
+                                       }
+                               }
+                               
+                               if (port.length() && bus->connect_output (bus->output (x), port, this)) {
+                                       break;
+                               }
+                       }
+                       
+                       if (_control_out) {
+                               vector<string> cports;
+                               uint32_t ni = _control_out->n_inputs();
+                               
+                               for (uint32_t n = 0; n < ni; ++n) {
+                                       cports.push_back (_control_out->input(n)->name());
+                               }
+                               bus->set_control_outs (cports);
                        }
-               }
 
-               if (_control_out) {
-                       vector<string> cports;
-                       uint32_t ni = _control_out->n_inputs();
+                       ret.push_back (bus);
+               }
+       
 
-                       for (uint32_t n = 0; n < ni; ++n) {
-                               cports.push_back (_control_out->input(n)->name());
-                       }
-                       bus->set_control_outs (cports);
+               catch (failed_constructor &err) {
+                       error << _("Session: could not create new audio route.") << endmsg;
+                       ret.clear ();
+                       return ret;
                }
-               
-               add_route (bus);
-               return bus;
+
+               --how_many;
        }
 
-       catch (failed_constructor &err) {
-               error << _("Session: could not create new audio route.") << endmsg;
-               return shared_ptr<Route> ((Route*) 0);
+       if (!ret.empty()) {
+               add_routes (ret, false);
+               save_state (_current_snapshot_name);
        }
+
+       return ret;
+
 }
 
 void
-Session::add_route (boost::shared_ptr<Route> route, bool save)
+Session::add_routes (RouteList& new_routes, bool save)
 {
        { 
                RCUWriter<RouteList> writer (routes);
                shared_ptr<RouteList> r = writer.get_copy ();
-               r->push_front (route);
+               r->insert (r->end(), new_routes.begin(), new_routes.end());
                resort_routes_using (r);
        }
 
-       route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
-       route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
-       route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
-       route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
-
-       if (route->master()) {
-               _master_out = route;
-       }
-
-       if (route->control()) {
-               _control_out = route;
+       for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
+               (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
+               (*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)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
+               
+               if ((*x)->master()) {
+                       _master_out = (*x);
+               }
+               
+               if ((*x)->control()) {
+                       _control_out = (*x);
+               }
        }
 
        set_dirty();
@@ -1933,7 +1962,7 @@ Session::add_route (boost::shared_ptr<Route> route, bool save)
                save_state (_current_snapshot_name);
        }
 
-       RouteAdded (route); /* EMIT SIGNAL */
+       RouteAdded (new_routes); /* EMIT SIGNAL */
 }
 
 void
index 6770428c65e8e22929ea62e84a6a1a1b721206f0..6f2ad965b41e9e43502d98f3736be2d4917cb243 100644 (file)
@@ -1707,6 +1707,7 @@ Session::load_routes (const XMLNode& node)
 {
        XMLNodeList nlist;
        XMLNodeConstIterator niter;
+       RouteList new_routes;
 
        nlist = node.children();
 
@@ -1721,9 +1722,11 @@ Session::load_routes (const XMLNode& node)
                        return -1;
                }
 
-               add_route (route);
+               new_routes.push_back (route);
        }
 
+       add_routes (new_routes);
+
        return 0;
 }