13
0

make adding multiple tracks more efficient (a *lot* more efficient)

git-svn-id: svn://localhost/ardour2/trunk@834 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2006-08-16 20:22:44 +00:00
parent 279128c81e
commit 199dce57f3
10 changed files with 205 additions and 110 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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&);

View File

@ -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)
{

View File

@ -111,8 +111,6 @@ Route::init ()
Route::~Route ()
{
cerr << "deleting route " << _name << endl;
clear_redirects (this);
if (_control_outs) {

View File

@ -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;
_engine.get_physical_outputs (physoutputs);
_engine.get_physical_inputs (physinputs);
while (how_many) {
/* 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)
*/
do {
++track_id;
snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
if (route_by_name (track_name) == 0) {
break;
}
} while (track_id < (UINT_MAX-1));
if (input_auto_connect & AutoConnectPhysical) {
nphysical_in = min (n_physical_inputs, physinputs.size());
} else {
nphysical_in = 0;
}
n++;
} while (n < (UINT_MAX-1));
if (input_auto_connect & AutoConnectPhysical) {
nphysical_in = n_physical_inputs;
} else {
nphysical_in = 0;
}
if (output_auto_connect & AutoConnectPhysical) {
nphysical_out = n_physical_outputs;
} 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 (output_auto_connect & AutoConnectPhysical) {
nphysical_out = min (n_physical_outputs, physinputs.size());
} else {
nphysical_out = 0;
}
if (nphysical_in) {
for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
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;
}
}
channels_used += track->n_inputs ();
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());
ret.push_back (track);
}
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;
}
for (uint32_t x = 0; x < track->n_outputs(); ++x) {
port = "";
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 (port.length() && track->connect_output (track->output (x), port, this)) {
break;
}
}
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));
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