X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=blobdiff_plain;f=libs%2Fardour%2Faudio_track_importer.cc;h=dd77cb370e4cce491e9a17a425f0801d6df6bd07;hp=016f133bb00b3211c19f45e15d7e808840ecbf76;hb=c8c6bca6587450ff64303dbc994a4cd28d6ce7aa;hpb=38382b792113cbf23881c1dca64e16c2d0207d45 diff --git a/libs/ardour/audio_track_importer.cc b/libs/ardour/audio_track_importer.cc index 016f133bb0..dd77cb370e 100644 --- a/libs/ardour/audio_track_importer.cc +++ b/libs/ardour/audio_track_importer.cc @@ -18,37 +18,40 @@ */ -#include +#include "ardour/audio_track_importer.h" -#include -#include +#include "ardour/audio_playlist_importer.h" +#include "ardour/audio_diskstream.h" +#include "ardour/session.h" -#include -#include +#include "pbd/controllable.h" +#include "pbd/convert.h" +#include "pbd/failed_constructor.h" #include +#include -#include "i18n.h" +#include "pbd/i18n.h" +using namespace std; using namespace PBD; using namespace ARDOUR; /*** AudioTrackImportHandler ***/ AudioTrackImportHandler::AudioTrackImportHandler (XMLTree const & source, Session & session, AudioPlaylistImportHandler & pl_handler) : - ElementImportHandler (source, session), - pl_handler (pl_handler) + ElementImportHandler (source, session) { XMLNode const * root = source.root(); XMLNode const * routes; - + if (!(routes = root->child ("Routes"))) { throw failed_constructor(); } - + XMLNodeList const & route_list = routes->children(); for (XMLNodeList::const_iterator it = route_list.begin(); it != route_list.end(); ++it) { - const XMLProperty* type = (*it)->property("default-type"); + XMLProperty const * type = (*it)->property("default-type"); if ( (!type || type->value() == "audio") && ((*it)->property ("diskstream") != 0 || (*it)->property ("diskstream-id") != 0)) { try { elements.push_back (ElementPtr ( new AudioTrackImporter (source, session, *this, **it, pl_handler))); @@ -70,7 +73,7 @@ AudioTrackImportHandler::get_info () const AudioTrackImporter::AudioTrackImporter (XMLTree const & source, Session & session, - AudioTrackImportHandler & handler, + AudioTrackImportHandler & track_handler, XMLNode const & node, AudioPlaylistImportHandler & pl_handler) : ElementImporter (source, session), @@ -83,23 +86,28 @@ AudioTrackImporter::AudioTrackImporter (XMLTree const & source, if (!parse_route_xml ()) { throw failed_constructor(); } - + if (!parse_io ()) { throw failed_constructor(); } - - XMLNodeList const & controllables = node.children ("controllable"); + + XMLNodeList const & controllables = node.children (Controllable::xml_node_name); for (XMLNodeList::const_iterator it = controllables.begin(); it != controllables.end(); ++it) { parse_controllable (**it); } - - XMLNode * remote_control = xml_track.child ("remote_control"); + + XMLNode * remote_control = xml_track.child ("RemoteControl"); if (remote_control && (prop = remote_control->property ("id"))) { uint32_t control_id = session.ntracks() + session.nbusses() + 1; prop->set_value (to_string (control_id, std::dec)); } - - xml_track.remove_nodes_and_delete ("extra"); + + xml_track.remove_nodes_and_delete ("Extra"); +} + +AudioTrackImporter::~AudioTrackImporter () +{ + playlists.clear (); } bool @@ -128,12 +136,12 @@ AudioTrackImporter::parse_route_xml () std::cerr << string_compose (X_("AudioTrackImporter: did not recognise XML-property \"%1\""), prop) << endmsg; } } - + if (!ds_ok) { error << X_("AudioTrackImporter: did not find necessary XML-property \"diskstream-id\"") << endmsg; return false; } - + return true; } @@ -147,7 +155,7 @@ AudioTrackImporter::parse_io () if (!(io = xml_track.child ("IO"))) { return false; } - + XMLPropertyList const & props = io->properties(); for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) { @@ -162,39 +170,48 @@ AudioTrackImporter::parse_io () (*it)->set_value (id.to_s()); id_ok = true; } else if (!prop.compare("inputs")) { - // TODO Let the IO class do it's thing for now... + // TODO Handle this properly! + /* Input and output ports are counted and added empty, so that no in/output connecting function fails. */ + uint32_t num_inputs = std::count ((*it)->value().begin(), (*it)->value().end(), '{'); + std::string value; + for (uint32_t i = 0; i < num_inputs; i++) { value += "{}"; } + (*it)->set_value (value); } else if (!prop.compare("outputs")) { - // TODO Let the IO class do it's thing for now... + // TODO See comments above + uint32_t num_outputs = std::count ((*it)->value().begin(), (*it)->value().end(), '{'); + std::string value; + for (uint32_t i = 0; i < num_outputs; i++) { value += "{}"; } + (*it)->set_value (value); } else { std::cerr << string_compose (X_("AudioTrackImporter: did not recognise XML-property \"%1\""), prop) << endmsg; } } - + if (!name_ok) { error << X_("AudioTrackImporter: did not find necessary XML-property \"name\"") << endmsg; return false; } - + if (!id_ok) { error << X_("AudioTrackImporter: did not find necessary XML-property \"id\"") << endmsg; return false; } - - XMLNodeList const & controllables = io->children ("controllable"); + + XMLNodeList const & controllables = io->children (Controllable::xml_node_name); for (XMLNodeList::const_iterator it = controllables.begin(); it != controllables.end(); ++it) { parse_controllable (**it); } - + XMLNodeList const & processors = io->children ("Processor"); for (XMLNodeList::const_iterator it = processors.begin(); it != processors.end(); ++it) { parse_processor (**it); } - + XMLNodeList const & automations = io->children ("Automation"); for (XMLNodeList::const_iterator it = automations.begin(); it != automations.end(); ++it) { parse_automation (**it); } - + return true; } @@ -205,13 +222,14 @@ AudioTrackImporter::get_info () const return name; } +/** @return true if everything is ok */ bool AudioTrackImporter::_prepare_move () { /* Copy dependent playlists */ pl_handler.playlists_by_diskstream (old_ds_id, playlists); - + for (PlaylistList::iterator it = playlists.begin(); it != playlists.end(); ++it) { if (!(*it)->prepare_move ()) { playlists.clear (); @@ -219,20 +237,33 @@ AudioTrackImporter::_prepare_move () } (*it)->set_diskstream (new_ds_id); } - + /* Rename */ - + while (session.route_by_name (name) || !track_handler.check_name (name)) { - std::pair rename_pair = Rename (_("A playlist with this name already exists, please rename it."), name); + std::pair rename_pair = *Rename (_("A playlist with this name already exists, please rename it."), name); if (!rename_pair.first) { return false; } name = rename_pair.second; } - xml_track.child ("IO")->property ("name")->set_value (name); + + XMLNode* c = xml_track.child ("IO"); + if (!c) { + error << _("badly-formed XML in imported track") << endmsg; + return false; + } + + XMLProperty * p = c->property ("name"); + if (!p) { + error << _("badly-formed XML in imported track") << endmsg; + return false; + } + + p->set_value (name); + track_handler.add_name (name); - - // TODO + return true; } @@ -241,13 +272,43 @@ AudioTrackImporter::_cancel_move () { track_handler.remove_name (name); playlists.clear (); - // TODO } void AudioTrackImporter::_move () { - // TODO + /* Add diskstream */ + + boost::shared_ptr ds_node_list; + string xpath = "/Session/DiskStreams/AudioDiskstream[@id='" + old_ds_id.to_s() + "']"; + ds_node_list = source.find (xpath); + + if (ds_node_list->size() != 1) { + error << string_compose (_("Error Importing Audio track %1"), name) << endmsg; + return; + } + + boost::shared_ptr ds_node = ds_node_list->front(); + XMLProperty * p = ds_node->property (X_("id")); + assert (p); + p->set_value (new_ds_id.to_s()); + + boost::shared_ptr new_ds (new AudioDiskstream (session, *ds_node)); + new_ds->set_name (name); + new_ds->do_refill_with_alloc (); + new_ds->set_block_size (session.get_block_size ()); + + /* Import playlists */ + + for (PlaylistList::const_iterator it = playlists.begin(); it != playlists.end(); ++it) { + (*it)->move (); + } + + /* Import track */ + + XMLNode routes ("Routes"); + routes.add_child_copy (xml_track); + session.load_routes (routes, 3000); } bool @@ -257,7 +318,7 @@ AudioTrackImporter::parse_processor (XMLNode & node) if (automation) { parse_automation (*automation); } - + return true; } @@ -265,7 +326,7 @@ bool AudioTrackImporter::parse_controllable (XMLNode & node) { XMLProperty * prop; - + if ((prop = node.property ("id"))) { PBD::ID new_id; prop->set_value (new_id.to_s()); @@ -283,12 +344,12 @@ AudioTrackImporter::parse_automation (XMLNode & node) XMLNodeList const & lists = node.children ("AutomationList"); for (XMLNodeList::const_iterator it = lists.begin(); it != lists.end(); ++it) { XMLProperty * prop; - + if ((prop = (*it)->property ("id"))) { PBD::ID id; prop->set_value (id.to_s()); } - + if (!(*it)->name().compare ("events")) { rate_convert_events (**it); } @@ -309,14 +370,14 @@ AudioTrackImporter::rate_convert_events (XMLNode & node) if (content_node->content().empty()) { return false; } - + std::stringstream str (content_node->content()); std::ostringstream new_content; - - nframes_t x; + + framecnt_t x; double y; bool ok = true; - + while (str) { str >> x; if (!str) { @@ -327,10 +388,10 @@ AudioTrackImporter::rate_convert_events (XMLNode & node) ok = false; break; } - + new_content << rate_convert_samples (x) << ' ' << y; } - + if (!ok) { error << X_("AudioTrackImporter: error in rate converting automation events") << endmsg; return false;