*/
-#include <ardour/audio_track_importer.h>
+#include "ardour/audio_track_importer.h"
-#include <ardour/audio_playlist_importer.h>
-#include <ardour/audio_diskstream.h>
-#include <ardour/session.h>
+#include "ardour/audio_playlist_importer.h"
+#include "ardour/disk_reader.h"
+#include "ardour/session.h"
-#include <pbd/failed_constructor.h>
-#include <pbd/convert.h>
+#include "pbd/controllable.h"
+#include "pbd/failed_constructor.h"
+#include "pbd/string_convert.h"
#include <sstream>
+#include <algorithm>
-#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)));
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));
+ prop->set_value (to_string (control_id));
}
-
- xml_track.remove_nodes_and_delete ("extra");
+
+ xml_track.remove_nodes_and_delete ("Extra");
}
AudioTrackImporter::~AudioTrackImporter ()
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;
}
if (!(io = xml_track.child ("IO"))) {
return false;
}
-
- // TODO
- io->remove_property ("inputs");
- io->remove_property ("outputs");
-
+
XMLPropertyList const & props = io->properties();
for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
(*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;
}
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 ();
}
(*it)->set_diskstream (new_ds_id);
}
-
+
/* Rename */
-
+
while (session.route_by_name (name) || !track_handler.check_name (name)) {
- std::pair<bool, string> rename_pair = Rename (_("A playlist with this name already exists, please rename it."), name);
+ std::pair<bool, string> 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);
-
+
return true;
}
void
AudioTrackImporter::_move ()
-{
+{
+ /* XXX DISK */
+#if 0
/* Add diskstream */
-
+
boost::shared_ptr<XMLSharedNodeList> ds_node_list;
string xpath = "/Session/DiskStreams/AudioDiskstream[@id='" + old_ds_id.to_s() + "']";
- ds_node_list = source.root()->find (xpath);
-
+ 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<XMLNode> ds_node = ds_node_list->front();
- ds_node->property ("id")->set_value (new_ds_id.to_s());
-
- boost::shared_ptr<Diskstream> new_ds (new AudioDiskstream (session, *ds_node));
+ XMLProperty * p = ds_node->property (X_("id"));
+ assert (p);
+ p->set_value (new_ds_id.to_s());
+
+ boost::shared_ptr<DiskReader> new_ds (new DiskReader (session, *ds_node));
new_ds->set_name (name);
- session.add_diskstream (new_ds);
+ new_ds->do_refill_with_alloc ();
+ new_ds->set_block_size (session.get_block_size ());
/* Import playlists */
XMLNode routes ("Routes");
routes.add_child_copy (xml_track);
- session.load_routes (routes);
+ session.load_routes (routes, 3000);
+#endif
}
bool
if (automation) {
parse_automation (*automation);
}
-
+
return true;
}
AudioTrackImporter::parse_controllable (XMLNode & node)
{
XMLProperty * prop;
-
+
if ((prop = node.property ("id"))) {
PBD::ID new_id;
prop->set_value (new_id.to_s());
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);
}
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) {
ok = false;
break;
}
-
+
new_content << rate_convert_samples (x) << ' ' << y;
}
-
+
if (!ok) {
error << X_("AudioTrackImporter: error in rate converting automation events") << endmsg;
return false;