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... # or if that fails...
#libraries['flac'] = LibraryInfo (LIBS='FLAC') #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 # Check for liblo

View file

@ -874,9 +874,10 @@ ARDOUR_UI::session_add_midi_track ()
} }
void 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) { if (session == 0) {
warning << _("You cannot add a track without a session already loaded.") << endmsg; 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 { try {
if (disk) { if (disk) {
if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) { routes = session->new_audio_track (input_channels, output_channels, mode, how_many);
error << _("could not create new audio track") << endmsg;
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 { } else {
if ((route = session->new_audio_route (input_channels, output_channels)) == 0) { if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
error << _("could not create new audio bus") << endmsg; error << _("could not create new audio bus") << endmsg;
@ -2075,10 +2083,10 @@ ARDOUR_UI::add_route ()
/* XXX do something with name template */ /* XXX do something with name template */
while (count) {
if (track) { if (track) {
session_add_audio_track (input_chan, output_chan, add_route_dialog->mode()); session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
} else { } else {
while (count) {
session_add_audio_bus (input_chan, output_chan); session_add_audio_bus (input_chan, output_chan);
} }
--count; --count;

View file

@ -189,12 +189,12 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void add_route (); void add_route ();
void session_add_audio_track (int input_channels, int32_t output_channels, ARDOUR::TrackMode 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); session_add_audio_route (true, input_channels, output_channels, mode, how_many);
} }
void session_add_audio_bus (int input_channels, int32_t output_channels) { 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 (); void session_add_midi_track ();
@ -532,7 +532,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void save_template (); 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); 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)); 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_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); 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));
ActionManager::session_sensitive_actions.push_back (act); 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: case ImportAsTrack:
{ {
boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Normal)); vector<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
if (!at.empty()) {
copy = new AudioRegion (region); copy = new AudioRegion (region);
at->diskstream()->playlist()->add_region (*copy, pos); at.front()->diskstream()->playlist()->add_region (*copy, pos);
}
break; break;
} }
case ImportAsTapeTrack: case ImportAsTapeTrack:
{ {
boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Destructive)); vector<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive));
if (!at.empty()) {
copy = new AudioRegion (region); copy = new AudioRegion (region);
at->diskstream()->playlist()->add_region (*copy, pos); at.front()->diskstream()->playlist()->add_region (*copy, pos);
}
break; break;
} }
} }

View file

@ -121,6 +121,9 @@ class AudioEngine : public sigc::trackable
uint32_t n_physical_outputs () const; uint32_t n_physical_outputs () const;
uint32_t n_physical_inputs () 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) { std::string get_nth_physical_output (uint32_t n) {
return get_nth_physical (n, JackPortIsInput); return get_nth_physical (n, JackPortIsInput);
} }

View file

@ -536,7 +536,7 @@ class Session : public sigc::trackable, public Stateful
/* fundamental operations. duh. */ /* 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); boost::shared_ptr<Route> new_audio_route (int input_channels, int output_channels);
void remove_route (boost::shared_ptr<Route>); void remove_route (boost::shared_ptr<Route>);
@ -1517,7 +1517,7 @@ class Session : public sigc::trackable, public Stateful
SerializedRCUManager<RouteList> routes; SerializedRCUManager<RouteList> routes;
void add_route (boost::shared_ptr<Route>); void add_route (boost::shared_ptr<Route>, bool save = true);
uint32_t destructive_index; uint32_t destructive_index;
int load_routes (const XMLNode&); int load_routes (const XMLNode&);

View file

@ -742,6 +742,52 @@ AudioEngine::n_physical_inputs () const
return i; 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 string
AudioEngine::get_nth_physical (uint32_t n, int flag) AudioEngine::get_nth_physical (uint32_t n, int flag)
{ {

View file

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

View file

@ -450,9 +450,7 @@ Session::~Session ()
RouteList::iterator tmp; RouteList::iterator tmp;
tmp = i; tmp = i;
++tmp; ++tmp;
cerr << "BEFORE: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
(*i)->drop_references (); (*i)->drop_references ();
cerr << "AFTER: use count on route " << (*i)->name() << " = " << (*i).use_count() << endl;
i = tmp; i = tmp;
} }
r->clear (); r->clear ();
@ -1671,15 +1669,15 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
} }
shared_ptr<AudioTrack> vector<boost::shared_ptr<AudioTrack> >
Session::new_audio_track (int input_channels, int output_channels, TrackMode mode) Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
{ {
char track_name[32]; char track_name[32];
uint32_t track_id = 0;
uint32_t n = 0; uint32_t n = 0;
uint32_t channels_used = 0; uint32_t channels_used = 0;
string port; string port;
uint32_t nphysical_in; vector<boost::shared_ptr<AudioTrack> > ret;
uint32_t nphysical_out;
/* count existing audio tracks */ /* count existing audio tracks */
@ -1696,29 +1694,42 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
} }
} }
vector<string> physinputs;
vector<string> physoutputs;
uint32_t nphysical_in;
uint32_t nphysical_out;
_engine.get_physical_outputs (physoutputs);
_engine.get_physical_inputs (physinputs);
while (how_many) {
/* check for duplicate route names, since we might have pre-existing /* check for duplicate route names, since we might have pre-existing
routes with this name (e.g. create Audio1, Audio2, delete Audio1, routes with this name (e.g. create Audio1, Audio2, delete Audio1,
save, close,restart,add new route - first named route is now save, close,restart,add new route - first named route is now
Audio2) Audio2)
*/ */
do { do {
snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1); ++track_id;
snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
if (route_by_name (track_name) == 0) { if (route_by_name (track_name) == 0) {
break; break;
} }
n++;
} while (n < (UINT_MAX-1)); } while (track_id < (UINT_MAX-1));
if (input_auto_connect & AutoConnectPhysical) { if (input_auto_connect & AutoConnectPhysical) {
nphysical_in = n_physical_inputs; nphysical_in = min (n_physical_inputs, physinputs.size());
} else { } else {
nphysical_in = 0; nphysical_in = 0;
} }
if (output_auto_connect & AutoConnectPhysical) { if (output_auto_connect & AutoConnectPhysical) {
nphysical_out = n_physical_outputs; nphysical_out = min (n_physical_outputs, physinputs.size());
} else { } else {
nphysical_out = 0; nphysical_out = 0;
} }
@ -1738,7 +1749,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
port = ""; port = "";
if (input_auto_connect & AutoConnectPhysical) { if (input_auto_connect & AutoConnectPhysical) {
port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in); port = physinputs[(channels_used+x)%nphysical_in];
} }
if (port.length() && track->connect_input (track->input (x), port, this)) { if (port.length() && track->connect_input (track->input (x), port, this)) {
@ -1752,7 +1763,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
port = ""; port = "";
if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) { if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out); port = physoutputs[(channels_used+x)%nphysical_out];
} else if (output_auto_connect & AutoConnectMaster) { } else if (output_auto_connect & AutoConnectMaster) {
if (_master_out) { if (_master_out) {
port = _master_out->input (x%_master_out->n_inputs())->name(); port = _master_out->input (x%_master_out->n_inputs())->name();
@ -1764,6 +1775,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
} }
} }
channels_used += track->n_inputs ();
if (_control_out) { if (_control_out) {
vector<string> cports; vector<string> cports;
uint32_t ni = _control_out->n_inputs(); uint32_t ni = _control_out->n_inputs();
@ -1776,17 +1789,30 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
} }
track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
add_route (track);
track->set_remote_control_id (ntracks()); track->set_remote_control_id (ntracks());
return track;
ret.push_back (track);
} }
catch (failed_constructor &err) { catch (failed_constructor &err) {
error << _("Session: could not create new audio track.") << endmsg; error << _("Session: could not create new audio track.") << endmsg;
return shared_ptr<AudioTrack> ((AudioTrack*) 0); // XXX should we delete the tracks already created?
ret.clear ();
return ret;
} }
--how_many;
}
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> shared_ptr<Route>
@ -1879,7 +1905,7 @@ Session::new_audio_route (int input_channels, int output_channels)
} }
void void
Session::add_route (boost::shared_ptr<Route> route) Session::add_route (boost::shared_ptr<Route> route, bool save)
{ {
{ {
RCUWriter<RouteList> writer (routes); RCUWriter<RouteList> writer (routes);
@ -1902,7 +1928,10 @@ Session::add_route (boost::shared_ptr<Route> route)
} }
set_dirty(); set_dirty();
if (save) {
save_state (_current_snapshot_name); save_state (_current_snapshot_name);
}
RouteAdded (route); /* EMIT SIGNAL */ RouteAdded (route); /* EMIT SIGNAL */
} }
@ -1926,9 +1955,6 @@ Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
diskstream_playlist_changed (dstream); diskstream_playlist_changed (dstream);
dstream->prepare (); dstream->prepare ();
set_dirty();
save_state (_current_snapshot_name);
} }
void void