mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-15 19:16:40 +01:00
prototype tool to copy mixer/route settings between sessions
This commit is contained in:
parent
79a9be434c
commit
1fd04a37c1
1 changed files with 159 additions and 0 deletions
159
session_utils/copy_mix.cc
Normal file
159
session_utils/copy_mix.cc
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue