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:
parent
279128c81e
commit
199dce57f3
10
SConstruct
10
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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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&);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -111,8 +111,6 @@ Route::init ()
|
||||
|
||||
Route::~Route ()
|
||||
{
|
||||
cerr << "deleting route " << _name << endl;
|
||||
|
||||
clear_redirects (this);
|
||||
|
||||
if (_control_outs) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user