13
0
livetrax/session_utils/copy_mix.cc

160 lines
4.5 KiB
C++

#include <iostream>
#include <cstdlib>
#include "pbd/stateful.h"
#include "ardour/send.h"
#include "ardour/track.h"
#include "common.h"
#define X_(Text) Text
using namespace std;
using namespace ARDOUR;
using namespace SessionUtils;
/* this is copied from Session::new_route_from_template */
void trim_state_for_mixer_copy (Session*s, XMLNode& node)
{
/* trim bitslots from listen sends so that new ones are used */
XMLNodeList children = node.children ();
for (XMLNodeList::iterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == X_("Processor")) {
/* ForceIDRegeneration does not catch the following */
XMLProperty const * role = (*i)->property (X_("role"));
XMLProperty const * type = (*i)->property (X_("type"));
if (role && role->value() == X_("Aux")) {
/* check if the target bus exists.
* we should not save aux-sends in templates.
*/
XMLProperty const * target = (*i)->property (X_("target"));
if (!target) {
(*i)->add_property ("type", "dangling-aux-send");
continue;
}
boost::shared_ptr<Route> r = s->route_by_id (target->value());
if (!r || boost::dynamic_pointer_cast<Track>(r)) {
(*i)->add_property ("type", "dangling-aux-send");
continue;
}
}
if (role && role->value() == X_("Listen")) {
(*i)->remove_property (X_("bitslot"));
}
else if (role && (role->value() == X_("Send") || role->value() == X_("Aux"))) {
char buf[32];
Delivery::Role xrole;
uint32_t bitslot = 0;
xrole = Delivery::Role (string_2_enum (role->value(), xrole));
std::string name = Send::name_and_id_new_send(*s, xrole, bitslot, false);
snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
(*i)->remove_property (X_("bitslot"));
(*i)->remove_property (X_("name"));
(*i)->add_property ("bitslot", buf);
(*i)->add_property ("name", name);
}
else if (type && type->value() == X_("return")) {
// Return::set_state() generates a new one
(*i)->remove_property (X_("bitslot"));
}
else if (type && type->value() == X_("port")) {
// PortInsert::set_state() handles the bitslot
(*i)->remove_property (X_("bitslot"));
(*i)->add_property ("ignore-name", "1");
}
}
}
}
static void copy_mixer_settings (Session*s, boost::shared_ptr<Route> dst, XMLNode& state)
{
PBD::Stateful::ForceIDRegeneration force_ids;
trim_state_for_mixer_copy (s, state);
state.remove_nodes_and_delete ("Diskstream");
state.remove_nodes_and_delete ("Automation");
//state.dump (cerr);
dst->set_state (state, PBD::Stateful::loading_state_version);
}
int main (int argc, char* argv[])
{
if (argc < 5) {
printf ("Usage: copy-mix <session1-dir> <session1-name> <session2-dir> <session2-name>\n");
return -1;
}
std::string session1_dir (argv[1]);
std::string session1_name (argv[2]);
std::string session2_dir = (argv[3]);
std::string session2_name = (argv[4]);
SessionUtils::init();
Session* s = 0;
std::map<std::string,XMLNode*> routestate;
s = SessionUtils::load_session ( session1_dir, session1_name);
if (!s) {
printf("Cannot load source session.\n");
SessionUtils::cleanup();
return 0;
}
// get route state from first session
boost::shared_ptr<RouteList> rl = s->get_routes ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
XMLNode& state ((*i)->get_state());
routestate[(*i)->name()] = &state;
}
rl.reset();
SessionUtils::unload_session(s);
// open target session
s = SessionUtils::load_session (session2_dir, session2_name);
if (!s) {
printf("Cannot load target session.\n");
SessionUtils::cleanup();
return 0;
}
// iterate over all routes in the target session..
rl = s->get_routes ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Route> r = *i;
// skip special busses
if (r->is_master() || r->is_monitor() || r->is_auditioner()) {
continue;
}
// find matching route by name
std::map<std::string,XMLNode*>::iterator it = routestate.find (r->name ());
if (it == routestate.end()) {
printf (" -- no match for '%s'\n", (*i)->name().c_str());
continue;
}
printf ("-- found match '%s'\n", (*i)->name().c_str());
XMLNode *state = it->second;
// copy state
copy_mixer_settings (s, r, *state);
}
s->save_state ("");
rl.reset();
SessionUtils::unload_session(s);
// clean up.
for (std::map<std::string,XMLNode*>::iterator i = routestate.begin(); i != routestate.end(); ++i) {
XMLNode *state = i->second;
delete state;
}
SessionUtils::cleanup();
return 0;
}