summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-08-16 20:22:44 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-08-16 20:22:44 +0000
commit199dce57f35014189f21c76fff32e0752bcc8c15 (patch)
tree8e70c240c4551236f63dc086d310586e52c057a8
parent279128c81e3d0756db961cdf8da770b2b92afddd (diff)
make adding multiple tracks more efficient (a *lot* more efficient)
git-svn-id: svn://localhost/ardour2/trunk@834 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--SConstruct10
-rw-r--r--gtk2_ardour/ardour_ui.cc24
-rw-r--r--gtk2_ardour/ardour_ui.h8
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc2
-rw-r--r--gtk2_ardour/editor_audio_import.cc16
-rw-r--r--libs/ardour/ardour/audioengine.h3
-rw-r--r--libs/ardour/ardour/session.h4
-rw-r--r--libs/ardour/audioengine.cc46
-rw-r--r--libs/ardour/route.cc2
-rw-r--r--libs/ardour/session.cc180
10 files changed, 195 insertions, 100 deletions
diff --git a/SConstruct b/SConstruct
index fcc5382e92..85d8b56224 100644
--- a/SConstruct
+++ b/SConstruct
@@ -457,6 +457,16 @@ libraries['flac'] = conf.Finish ()
# or if that fails...
#libraries['flac'] = LibraryInfo (LIBS='FLAC')
+# boost (we don't link against boost, just use some header files)
+
+libraries['boost'] = LibraryInfo ()
+conf = Configure (libraries['boost'])
+if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == 0:
+ print "Boost header files do not appear to be installed."
+ sys.exit (1)
+
+libraries['boost'] = conf.Finish ()
+
#
# Check for liblo
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index bca27c7231..345f715d39 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -874,9 +874,10 @@ 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)
+ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
{
- boost::shared_ptr<Route> route;
+ boost::shared_ptr<Route> route;
+ vector<boost::shared_ptr<AudioTrack> > routes;
if (session == 0) {
warning << _("You cannot add a track without a session already loaded.") << endmsg;
@@ -885,9 +886,16 @@ ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t o
try {
if (disk) {
- if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) {
- error << _("could not create new audio track") << endmsg;
+ routes = session->new_audio_track (input_channels, output_channels, mode, 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;
+ }
}
+
} else {
if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
error << _("could not create new audio bus") << endmsg;
@@ -2075,10 +2083,10 @@ ARDOUR_UI::add_route ()
/* XXX do something with name template */
- while (count) {
- if (track) {
- session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
- } else {
+ 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;
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index c8d0d70a7d..ebb5c76838 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -189,12 +189,12 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void add_route ();
- void session_add_audio_track (int input_channels, int32_t output_channels, ARDOUR::TrackMode mode) {
- session_add_audio_route (true, input_channels, output_channels, mode);
+ void session_add_audio_track (int input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many) {
+ 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);
+ session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, 1);
}
void session_add_midi_track ();
@@ -532,7 +532,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void save_template ();
- void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode);
+ void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many);
void set_transport_sensitivity (bool);
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 238f81dd4f..3d8e99ad6e 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -194,7 +194,7 @@ ARDOUR_UI::install_actions ()
ActionManager::register_action (common_actions, X_("About"), _("About"), mem_fun(*this, &ARDOUR_UI::show_splash));
act = ActionManager::register_toggle_action (common_actions, X_("ToggleColorManager"), _("Colors"), mem_fun(*this, &ARDOUR_UI::toggle_color_manager));
- 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));
+ 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));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index b6fdefa4d3..4128348e3a 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -332,17 +332,21 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
case ImportAsTrack:
{
- boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Normal));
- copy = new AudioRegion (region);
- at->diskstream()->playlist()->add_region (*copy, pos);
+ vector<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);
+ }
break;
}
case ImportAsTapeTrack:
{
- boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Destructive));
- copy = new AudioRegion (region);
- at->diskstream()->playlist()->add_region (*copy, pos);
+ vector<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);
+ }
break;
}
}
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 00a0ce6b19..d13e917ff0 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -121,6 +121,9 @@ class AudioEngine : public sigc::trackable
uint32_t n_physical_outputs () const;
uint32_t n_physical_inputs () const;
+ void get_physical_outputs (std::vector<std::string>&);
+ void get_physical_inputs (std::vector<std::string>&);
+
std::string get_nth_physical_output (uint32_t n) {
return get_nth_physical (n, JackPortIsInput);
}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 3763ebe91e..757d13f79b 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -536,7 +536,7 @@ class Session : public sigc::trackable, public Stateful
/* fundamental operations. duh. */
- boost::shared_ptr<AudioTrack> new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal);
+ 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);
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>);
+ void add_route (boost::shared_ptr<Route>, bool save = true);
uint32_t destructive_index;
int load_routes (const XMLNode&);
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 4a4659d1df..5f86f21762 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -742,6 +742,52 @@ AudioEngine::n_physical_inputs () const
return i;
}
+void
+AudioEngine::get_physical_inputs (vector<string>& ins)
+{
+ const char ** ports;
+ uint32_t i = 0;
+
+ if (!_jack) {
+ return;
+ }
+
+ if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
+ return;
+ }
+
+ if (ports) {
+ for (i = 0; ports[i]; ++i) {
+ ins.push_back (ports[i]);
+ }
+ cerr << "got " << ins.size() << " physical ins\n";
+ free (ports);
+ }
+}
+
+void
+AudioEngine::get_physical_outputs (vector<string>& outs)
+{
+ const char ** ports;
+ uint32_t i = 0;
+
+ if (!_jack) {
+ return;
+ }
+
+ if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
+ return;
+ }
+
+ if (ports) {
+ for (i = 0; ports[i]; ++i) {
+ outs.push_back (ports[i]);
+ }
+ cerr << "got " << outs.size() << " physical outs\n";
+ free (ports);
+ }
+}
+
string
AudioEngine::get_nth_physical (uint32_t n, int flag)
{
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 02c62eefa1..107fae2585 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -111,8 +111,6 @@ Route::init ()
Route::~Route ()
{
- cerr << "deleting route " << _name << endl;
-
clear_redirects (this);
if (_control_outs) {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 378d4763bc..dfa7468725 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -450,9 +450,7 @@ Session::~Session ()
RouteList::iterator tmp;
tmp = i;
++tmp;
- cerr << "BEFORE: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
(*i)->drop_references ();
- cerr << "AFTER: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
i = tmp;
}
r->clear ();
@@ -1671,15 +1669,15 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
}
-shared_ptr<AudioTrack>
-Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
+vector<boost::shared_ptr<AudioTrack> >
+Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
{
char track_name[32];
+ uint32_t track_id = 0;
uint32_t n = 0;
uint32_t channels_used = 0;
string port;
- uint32_t nphysical_in;
- uint32_t nphysical_out;
+ vector<boost::shared_ptr<AudioTrack> > ret;
/* count existing audio tracks */
@@ -1696,97 +1694,125 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
}
}
- /* check for duplicate route names, since we might have pre-existing
- routes with this name (e.g. create Audio1, Audio2, delete Audio1,
- save, close,restart,add new route - first named route is now
- Audio2)
- */
+ vector<string> physinputs;
+ vector<string> physoutputs;
+ uint32_t nphysical_in;
+ uint32_t nphysical_out;
- do {
- snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
- if (route_by_name (track_name) == 0) {
- break;
- }
- n++;
+ _engine.get_physical_outputs (physoutputs);
+ _engine.get_physical_inputs (physinputs);
- } while (n < (UINT_MAX-1));
+ while (how_many) {
- if (input_auto_connect & AutoConnectPhysical) {
- nphysical_in = n_physical_inputs;
- } else {
- nphysical_in = 0;
- }
+ /* check for duplicate route names, since we might have pre-existing
+ routes with this name (e.g. create Audio1, Audio2, delete Audio1,
+ save, close,restart,add new route - first named route is now
+ Audio2)
+ */
+
- if (output_auto_connect & AutoConnectPhysical) {
- nphysical_out = n_physical_outputs;
- } else {
- nphysical_out = 0;
- }
+ do {
+ ++track_id;
- try {
- shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
+ snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
- if (track->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;
- }
+ if (route_by_name (track_name) == 0) {
+ break;
+ }
+
+ } while (track_id < (UINT_MAX-1));
- if (nphysical_in) {
- for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
+ if (input_auto_connect & AutoConnectPhysical) {
+ nphysical_in = min (n_physical_inputs, physinputs.size());
+ } else {
+ nphysical_in = 0;
+ }
+
+ if (output_auto_connect & AutoConnectPhysical) {
+ nphysical_out = min (n_physical_outputs, physinputs.size());
+ } else {
+ nphysical_out = 0;
+ }
+
+ try {
+ shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
+
+ if (track->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;
+ }
+
+ if (nphysical_in) {
+ for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
+
+ port = "";
+
+ if (input_auto_connect & AutoConnectPhysical) {
+ port = physinputs[(channels_used+x)%nphysical_in];
+ }
+
+ if (port.length() && track->connect_input (track->input (x), port, this)) {
+ break;
+ }
+ }
+ }
+
+ for (uint32_t x = 0; x < track->n_outputs(); ++x) {
port = "";
- if (input_auto_connect & AutoConnectPhysical) {
- port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
- }
+ if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
+ port = physoutputs[(channels_used+x)%nphysical_out];
+ } else if (output_auto_connect & AutoConnectMaster) {
+ if (_master_out) {
+ port = _master_out->input (x%_master_out->n_inputs())->name();
+ }
+ }
- if (port.length() && track->connect_input (track->input (x), port, this)) {
+ if (port.length() && track->connect_output (track->output (x), port, this)) {
break;
}
}
- }
-
- for (uint32_t x = 0; x < track->n_outputs(); ++x) {
- port = "";
+ channels_used += track->n_inputs ();
- if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
- port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
- } else if (output_auto_connect & AutoConnectMaster) {
- if (_master_out) {
- port = _master_out->input (x%_master_out->n_inputs())->name();
+ if (_control_out) {
+ vector<string> cports;
+ uint32_t ni = _control_out->n_inputs();
+
+ for (n = 0; n < ni; ++n) {
+ cports.push_back (_control_out->input(n)->name());
}
+
+ track->set_control_outs (cports);
}
+
+ track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
+ track->set_remote_control_id (ntracks());
- if (port.length() && track->connect_output (track->output (x), port, this)) {
- break;
- }
+ ret.push_back (track);
}
- if (_control_out) {
- vector<string> cports;
- uint32_t ni = _control_out->n_inputs();
-
- for (n = 0; n < ni; ++n) {
- cports.push_back (_control_out->input(n)->name());
- }
-
- track->set_control_outs (cports);
+ catch (failed_constructor &err) {
+ error << _("Session: could not create new audio track.") << endmsg;
+ // XXX should we delete the tracks already created?
+ ret.clear ();
+ return ret;
}
-
- track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
-
- add_route (track);
-
- track->set_remote_control_id (ntracks());
- return track;
+
+ --how_many;
}
- catch (failed_constructor &err) {
- error << _("Session: could not create new audio track.") << endmsg;
- return shared_ptr<AudioTrack> ((AudioTrack*) 0);
+ if (!ret.empty()) {
+ for (vector<boost::shared_ptr<AudioTrack> >::iterator x = ret.begin(); x != ret.end(); ++x) {
+ add_route ((*x), false);
+ }
+
+ save_state (_current_snapshot_name);
}
+
+ return ret;
}
shared_ptr<Route>
@@ -1879,7 +1905,7 @@ Session::new_audio_route (int input_channels, int output_channels)
}
void
-Session::add_route (boost::shared_ptr<Route> route)
+Session::add_route (boost::shared_ptr<Route> route, bool save)
{
{
RCUWriter<RouteList> writer (routes);
@@ -1902,7 +1928,10 @@ Session::add_route (boost::shared_ptr<Route> route)
}
set_dirty();
- save_state (_current_snapshot_name);
+
+ if (save) {
+ save_state (_current_snapshot_name);
+ }
RouteAdded (route); /* EMIT SIGNAL */
}
@@ -1926,9 +1955,6 @@ Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
diskstream_playlist_changed (dstream);
dstream->prepare ();
-
- set_dirty();
- save_state (_current_snapshot_name);
}
void