mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
update session-utils
* use target name in help text * add options and documentation to copy-mixer
This commit is contained in:
parent
360f87b217
commit
f43ccd7321
5 changed files with 128 additions and 39 deletions
|
|
@ -125,18 +125,18 @@ static Session * _load_session (string dir, string state)
|
||||||
if (Session::get_info_from_path (s, sr, sf) == 0) {
|
if (Session::get_info_from_path (s, sr, sf) == 0) {
|
||||||
if (engine->set_sample_rate (sr)) {
|
if (engine->set_sample_rate (sr)) {
|
||||||
std::cerr << "Cannot set session's samplerate.\n";
|
std::cerr << "Cannot set session's samplerate.\n";
|
||||||
::exit (EXIT_FAILURE);
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Cannot get samplerate from session.\n";
|
std::cerr << "Cannot get samplerate from session.\n";
|
||||||
::exit (EXIT_FAILURE);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_post_engine ();
|
init_post_engine ();
|
||||||
|
|
||||||
if (engine->start () != 0) {
|
if (engine->start () != 0) {
|
||||||
std::cerr << "Cannot start Audio/MIDI engine\n";
|
std::cerr << "Cannot start Audio/MIDI engine\n";
|
||||||
::exit (EXIT_FAILURE);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Session* session = new Session (*engine, dir, state);
|
Session* session = new Session (*engine, dir, state);
|
||||||
|
|
@ -145,7 +145,7 @@ static Session * _load_session (string dir, string state)
|
||||||
}
|
}
|
||||||
|
|
||||||
Session *
|
Session *
|
||||||
SessionUtils::load_session (string dir, string state)
|
SessionUtils::load_session (string dir, string state, bool exit_at_failure)
|
||||||
{
|
{
|
||||||
Session* s = 0;
|
Session* s = 0;
|
||||||
try {
|
try {
|
||||||
|
|
@ -163,6 +163,9 @@ SessionUtils::load_session (string dir, string state)
|
||||||
cerr << "unknown exception.\n";
|
cerr << "unknown exception.\n";
|
||||||
::exit (EXIT_FAILURE);
|
::exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (!s && exit_at_failure) {
|
||||||
|
::exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace SessionUtils {
|
||||||
/** @param dir Session directory.
|
/** @param dir Session directory.
|
||||||
* @param state Session state file, without .ardour suffix.
|
* @param state Session state file, without .ardour suffix.
|
||||||
*/
|
*/
|
||||||
ARDOUR::Session * load_session (std::string dir, std::string state);
|
ARDOUR::Session * load_session (std::string dir, std::string state, bool exit_at_failure = true);
|
||||||
|
|
||||||
/** close session and stop engine
|
/** close session and stop engine
|
||||||
* @param s Session to close (may me NULL)
|
* @param s Session to close (may me NULL)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <glibmm.h>
|
||||||
|
|
||||||
|
#include "pbd/basename.h"
|
||||||
#include "pbd/stateful.h"
|
#include "pbd/stateful.h"
|
||||||
|
#include "ardour/filename_extensions.h"
|
||||||
#include "ardour/send.h"
|
#include "ardour/send.h"
|
||||||
#include "ardour/track.h"
|
#include "ardour/track.h"
|
||||||
|
|
||||||
|
|
@ -14,6 +17,11 @@ using namespace std;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace SessionUtils;
|
using namespace SessionUtils;
|
||||||
|
|
||||||
|
static bool opt_debug_dump = false;
|
||||||
|
static bool opt_copy_busses = false;
|
||||||
|
static bool opt_verbose = false;
|
||||||
|
static bool opt_log = false;
|
||||||
|
|
||||||
/* this is copied from Session::new_route_from_template */
|
/* this is copied from Session::new_route_from_template */
|
||||||
static void
|
static void
|
||||||
trim_state_for_mixer_copy (Session*s, XMLNode& node)
|
trim_state_for_mixer_copy (Session*s, XMLNode& node)
|
||||||
|
|
@ -84,7 +92,9 @@ copy_mixer_settings (Session*s, boost::shared_ptr<Route> dst, XMLNode& state)
|
||||||
trim_state_for_mixer_copy (s, state);
|
trim_state_for_mixer_copy (s, state);
|
||||||
state.remove_nodes_and_delete ("Diskstream");
|
state.remove_nodes_and_delete ("Diskstream");
|
||||||
state.remove_nodes_and_delete ("Automation");
|
state.remove_nodes_and_delete ("Automation");
|
||||||
state.dump (cerr);
|
if (opt_debug_dump) {
|
||||||
|
state.dump (cout);
|
||||||
|
}
|
||||||
|
|
||||||
dst->set_state (state, PBD::Stateful::loading_state_version);
|
dst->set_state (state, PBD::Stateful::loading_state_version);
|
||||||
}
|
}
|
||||||
|
|
@ -94,17 +104,17 @@ copy_session_routes (
|
||||||
const std::string& src_path, const std::string& src_name,
|
const std::string& src_path, const std::string& src_name,
|
||||||
const std::string& dst_path, const std::string& dst_load, const std::string& dst_save)
|
const std::string& dst_path, const std::string& dst_load, const std::string& dst_save)
|
||||||
{
|
{
|
||||||
SessionUtils::init (false);
|
SessionUtils::init (opt_log);
|
||||||
Session* s = 0;
|
Session* s = 0;
|
||||||
|
|
||||||
typedef std::map<std::string,XMLNode*> StateMap;
|
typedef std::map<std::string,XMLNode*> StateMap;
|
||||||
StateMap routestate;
|
StateMap routestate;
|
||||||
StateMap buslist;
|
StateMap buslist;
|
||||||
|
|
||||||
s = SessionUtils::load_session (src_path, src_name);
|
s = SessionUtils::load_session (src_path, src_name, false);
|
||||||
|
|
||||||
if (!s) {
|
if (!s) {
|
||||||
printf ("Cannot load source session %s/%s.\n", src_path.c_str (), src_name.c_str ());
|
fprintf (stderr, "Cannot load source session %s/%s.\n", src_path.c_str (), src_name.c_str ());
|
||||||
SessionUtils::cleanup ();
|
SessionUtils::cleanup ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -130,13 +140,13 @@ copy_session_routes (
|
||||||
/* open target session */
|
/* open target session */
|
||||||
s = SessionUtils::load_session (dst_path, dst_load);
|
s = SessionUtils::load_session (dst_path, dst_load);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
printf ("Cannot load target session %s/%s.\n", dst_path.c_str (), dst_load.c_str ());
|
fprintf (stderr, "Cannot load target session %s/%s.\n", dst_path.c_str (), dst_load.c_str ());
|
||||||
SessionUtils::cleanup ();
|
SessionUtils::cleanup ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iterate over all busses in the src session, add missing ones to target */
|
/* iterate over all busses in the src session, add missing ones to target */
|
||||||
// TODO: make optional
|
if (opt_copy_busses) {
|
||||||
rl = s->get_routes ();
|
rl = s->get_routes ();
|
||||||
for (StateMap::const_iterator i = buslist.begin (); i != buslist.end (); ++i) {
|
for (StateMap::const_iterator i = buslist.begin (); i != buslist.end (); ++i) {
|
||||||
if (s->route_by_name (i->first)) {
|
if (s->route_by_name (i->first)) {
|
||||||
|
|
@ -145,6 +155,7 @@ copy_session_routes (
|
||||||
XMLNode& rs (*(i->second));
|
XMLNode& rs (*(i->second));
|
||||||
s->new_route_from_template (1, rs, rs.property (X_("name"))->value (), NewPlaylist);
|
s->new_route_from_template (1, rs, rs.property (X_("name"))->value (), NewPlaylist);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* iterate over all *busses* in the target session.
|
/* iterate over all *busses* in the target session.
|
||||||
* setup internal return targets.
|
* setup internal return targets.
|
||||||
|
|
@ -162,10 +173,14 @@ copy_session_routes (
|
||||||
/* find matching route by name */
|
/* find matching route by name */
|
||||||
std::map<std::string,XMLNode*>::iterator it = routestate.find (r->name ());
|
std::map<std::string,XMLNode*>::iterator it = routestate.find (r->name ());
|
||||||
if (it == routestate.end ()) {
|
if (it == routestate.end ()) {
|
||||||
|
if (opt_verbose) {
|
||||||
printf (" -- no match for '%s'\n", (*i)->name ().c_str ());
|
printf (" -- no match for '%s'\n", (*i)->name ().c_str ());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (opt_verbose) {
|
||||||
printf ("-- found match '%s'\n", (*i)->name ().c_str ());
|
printf ("-- found match '%s'\n", (*i)->name ().c_str ());
|
||||||
|
}
|
||||||
XMLNode *state = it->second;
|
XMLNode *state = it->second;
|
||||||
// copy state
|
// copy state
|
||||||
copy_mixer_settings (s, r, *state);
|
copy_mixer_settings (s, r, *state);
|
||||||
|
|
@ -186,10 +201,14 @@ copy_session_routes (
|
||||||
/* find matching route by name */
|
/* find matching route by name */
|
||||||
std::map<std::string,XMLNode*>::iterator it = routestate.find (r->name ());
|
std::map<std::string,XMLNode*>::iterator it = routestate.find (r->name ());
|
||||||
if (it == routestate.end ()) {
|
if (it == routestate.end ()) {
|
||||||
|
if (opt_verbose) {
|
||||||
printf (" -- no match for '%s'\n", (*i)->name ().c_str ());
|
printf (" -- no match for '%s'\n", (*i)->name ().c_str ());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (opt_verbose) {
|
||||||
printf ("-- found match '%s'\n", (*i)->name ().c_str ());
|
printf ("-- found match '%s'\n", (*i)->name ().c_str ());
|
||||||
|
}
|
||||||
XMLNode *state = it->second;
|
XMLNode *state = it->second;
|
||||||
/* copy state */
|
/* copy state */
|
||||||
copy_mixer_settings (s, r, *state);
|
copy_mixer_settings (s, r, *state);
|
||||||
|
|
@ -213,14 +232,24 @@ copy_session_routes (
|
||||||
|
|
||||||
static void usage (int status) {
|
static void usage (int status) {
|
||||||
// help2man compatible format (standard GNU help-text)
|
// help2man compatible format (standard GNU help-text)
|
||||||
printf ("copy-mixer - copy mixer settings from one session to another.\n\n");
|
printf (UTILNAME " - copy mixer settings from one session to another.\n\n");
|
||||||
printf ("Usage: copy-mixer [ OPTIONS ] <src-path> <name> <dst-path> <name> [name]\n\n");
|
printf ("Usage: " UTILNAME " [ OPTIONS ] <src> <dst>\n\n");
|
||||||
|
|
||||||
printf ("Options:\n\
|
printf ("Options:\n\
|
||||||
-h, --help display this help and exit\n\
|
-h, --help display this help and exit\n\
|
||||||
|
-b, --bus-copy add busses present in src to dst\n\
|
||||||
|
-d, --debug print pre-processed XML for each route\n\
|
||||||
|
-l, --log-messages display libardour log messages\n\
|
||||||
|
-s, --snapshot <name> create a new snapshot in dst\n\
|
||||||
|
-v, --verbose show perfomed copy opeations\n\
|
||||||
-V, --version print version information and exit\n\
|
-V, --version print version information and exit\n\
|
||||||
\n");
|
\n");
|
||||||
|
|
||||||
printf ("\n\
|
printf ("\n\
|
||||||
.. not yet documented..\n\
|
This utility copies mixer-settings from the src-session to the dst-session.\n\
|
||||||
|
Both <src> and <dst> are paths to .ardour session files.\n\
|
||||||
|
If --snapshot is not given, the <dst> session file is overwritten.\n\
|
||||||
|
When --snapshot is set, a new snaphot in the <dst> session is created.\n\
|
||||||
\n");
|
\n");
|
||||||
|
|
||||||
printf ("Report bugs to <http://tracker.ardour.org/>\n"
|
printf ("Report bugs to <http://tracker.ardour.org/>\n"
|
||||||
|
|
@ -228,34 +257,62 @@ static void usage (int status) {
|
||||||
::exit (status);
|
::exit (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ends_with (std::string const& value, std::string const& ending)
|
||||||
|
{
|
||||||
|
if (ending.size() > value.size()) return false;
|
||||||
|
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||||
|
}
|
||||||
|
|
||||||
int main (int argc, char* argv[])
|
int main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
const char *optstring = "hV";
|
const char *optstring = "bhls:Vv";
|
||||||
|
|
||||||
// TODO add some arguments. (save snapshot, copy busses...)
|
|
||||||
|
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
{ "help", 0, 0, 'h' },
|
{ "bus-copy", required_argument, 0, 'b' },
|
||||||
{ "version", 0, 0, 'V' },
|
{ "debug", no_argument, 0, 'd' },
|
||||||
|
{ "help", no_argument, 0, 'h' },
|
||||||
|
{ "log-messages", no_argument, 0, 'l' },
|
||||||
|
{ "snapshot", no_argument, 0, 's' },
|
||||||
|
{ "version", no_argument, 0, 'V' },
|
||||||
|
{ "vebose", no_argument, 0, 'v' },
|
||||||
};
|
};
|
||||||
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
std::string dst_snapshot_name = "";
|
||||||
|
|
||||||
while (EOF != (c = getopt_long (argc, argv,
|
while (EOF != (c = getopt_long (argc, argv,
|
||||||
optstring, longopts, (int *) 0))) {
|
optstring, longopts, (int *) 0))) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'b':
|
||||||
|
opt_copy_busses = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'V':
|
case 'd':
|
||||||
printf ("ardour-utils version %s\n\n", VERSIONSTRING);
|
opt_debug_dump = true;
|
||||||
printf ("Copyright (C) GPL 2015 Robin Gareus <robin@gareus.org>\n");
|
|
||||||
exit (0);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
usage (0);
|
usage (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
opt_log = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
dst_snapshot_name = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
printf ("ardour-utils version %s\n\n", VERSIONSTRING);
|
||||||
|
printf ("Copyright (C) GPL 2016 Robin Gareus <robin@gareus.org>\n");
|
||||||
|
exit (0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
opt_verbose = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usage (EXIT_FAILURE);
|
usage (EXIT_FAILURE);
|
||||||
break;
|
break;
|
||||||
|
|
@ -264,12 +321,40 @@ int main (int argc, char* argv[])
|
||||||
|
|
||||||
// TODO parse path/name from a single argument.
|
// TODO parse path/name from a single argument.
|
||||||
|
|
||||||
if (optind + 4 > argc) {
|
if (optind + 2 > argc) {
|
||||||
usage (EXIT_FAILURE);
|
usage (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string src = argv[optind];
|
||||||
|
std::string dst = argv[optind + 1];
|
||||||
|
|
||||||
|
// statefile_suffix
|
||||||
|
|
||||||
|
if (!ends_with (src, statefile_suffix)) {
|
||||||
|
fprintf (stderr, "source is not a .ardour session file.\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!ends_with (dst, statefile_suffix)) {
|
||||||
|
fprintf (stderr, "target is not a .ardour session file.\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!Glib::file_test (src, Glib::FILE_TEST_IS_REGULAR)) {
|
||||||
|
fprintf (stderr, "source is not a regular file.\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!Glib::file_test (dst, Glib::FILE_TEST_IS_REGULAR)) {
|
||||||
|
fprintf (stderr, "target is not a regular file.\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string src_path = Glib::path_get_dirname (src);
|
||||||
|
std::string src_name = PBD::basename_nosuffix (src);
|
||||||
|
std::string dst_path = Glib::path_get_dirname (dst);
|
||||||
|
std::string dst_name = PBD::basename_nosuffix (dst);
|
||||||
|
|
||||||
|
// TODO check if src != dst ..
|
||||||
return copy_session_routes (
|
return copy_session_routes (
|
||||||
argv[optind], argv[optind + 1],
|
src_path, src_name,
|
||||||
argv[optind + 2], argv[optind + 3],
|
dst_path, dst_name,
|
||||||
(optind + 4 < argc) ? argv[optind + 4] : "");
|
dst_snapshot_name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,8 @@ static int export_session (Session *session,
|
||||||
|
|
||||||
static void usage (int status) {
|
static void usage (int status) {
|
||||||
// help2man compatible format (standard GNU help-text)
|
// help2man compatible format (standard GNU help-text)
|
||||||
printf ("export - export an ardour session from the commandline.\n\n");
|
printf (UTILNAME " - export an ardour session from the commandline.\n\n");
|
||||||
printf ("Usage: export [ OPTIONS ] <session-dir> <session-name>\n\n");
|
printf ("Usage: " UTILNAME " [ OPTIONS ] <session-dir> <session/snapshot-name>\n\n");
|
||||||
printf ("Options:\n\
|
printf ("Options:\n\
|
||||||
-h, --help display this help and exit\n\
|
-h, --help display this help and exit\n\
|
||||||
-n, --normalize normalize signal level (to 0dBFS)\n\
|
-n, --normalize normalize signal level (to 0dBFS)\n\
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ def build_ardour_util(bld, util):
|
||||||
]
|
]
|
||||||
obj.defines = [
|
obj.defines = [
|
||||||
'VERSIONSTRING="' + str(bld.env['VERSION']) + '"',
|
'VERSIONSTRING="' + str(bld.env['VERSION']) + '"',
|
||||||
|
'UTILNAME="' + str(pgmprefix + '-' + util) + '"',
|
||||||
'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
|
'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
|
||||||
'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
|
'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
|
||||||
'LOCALEDIR="' + os.path.join(os.path.normpath(bld.env['DATADIR']), 'locale') + '"',
|
'LOCALEDIR="' + os.path.join(os.path.normpath(bld.env['DATADIR']), 'locale') + '"',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue