summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-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
5 files changed, 154 insertions, 81 deletions
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