8 #include "pbd/basename.h"
10 #include "ardour/export_handler.h"
11 #include "ardour/export_status.h"
12 #include "ardour/export_timespan.h"
13 #include "ardour/export_channel_configuration.h"
14 #include "ardour/export_format_specification.h"
15 #include "ardour/export_filename.h"
16 #include "ardour/route.h"
17 #include "ardour/session_metadata.h"
18 #include "ardour/broadcast_info.h"
21 using namespace ARDOUR;
22 using namespace SessionUtils;
24 static int export_session (Session *session,
26 std::string samplerate,
29 ExportTimespanPtr tsp = session->get_export_handler()->add_timespan();
30 boost::shared_ptr<ExportChannelConfiguration> ccp = session->get_export_handler()->add_channel_config();
31 boost::shared_ptr<ARDOUR::ExportFilename> fnp = session->get_export_handler()->add_filename();
32 boost::shared_ptr<AudioGrapher::BroadcastInfo> b;
36 tree.read_buffer(std::string(
37 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
38 "<ExportFormatSpecification name=\"UTIL-WAV-16\" id=\"14792644-44ab-4209-a4f9-7ce6c2910cac\">"
39 " <Encoding id=\"F_WAV\" type=\"T_Sndfile\" extension=\"wav\" name=\"WAV\" has-sample-format=\"true\" channel-limit=\"256\"/>"
40 " <SampleRate rate=\""+ samplerate +"\"/>"
41 " <SRCQuality quality=\"SRC_SincBest\"/>"
43 " <Option name=\"sample-format\" value=\"SF_16\"/>"
44 " <Option name=\"dithering\" value=\"D_None\"/>"
45 " <Option name=\"tag-metadata\" value=\"true\"/>"
46 " <Option name=\"tag-support\" value=\"false\"/>"
47 " <Option name=\"broadcast-info\" value=\"false\"/>"
50 " <Normalize enabled=\""+ (normalize ? "true" : "false") +"\" target=\"0\"/>"
53 " <Trim enabled=\"false\"/>"
54 " <Add enabled=\"false\">"
55 " <Duration format=\"Timecode\" hours=\"0\" minutes=\"0\" seconds=\"0\" frames=\"0\"/>"
59 " <Trim enabled=\"false\"/>"
60 " <Add enabled=\"false\">"
61 " <Duration format=\"Timecode\" hours=\"0\" minutes=\"0\" seconds=\"0\" frames=\"0\"/>"
66 "</ExportFormatSpecification>"
69 boost::shared_ptr<ExportFormatSpecification> fmp = session->get_export_handler()->add_format(*tree.root());
72 framepos_t start, end;
73 start = session->current_start_frame();
74 end = session->current_end_frame();
75 tsp->set_range (start, end);
76 tsp->set_range_id ("session");
78 /* add master outs as default */
79 IO* master_out = session->master_out()->output().get();
81 PBD::warning << _("Export Util: No Master Out Ports to Connect for Audio Export") << endmsg;
85 for (uint32_t n = 0; n < master_out->n_ports().n_audio(); ++n) {
86 PortExportChannel * channel = new PortExportChannel ();
87 channel->add_port (master_out->audio (n));
88 ExportChannelPtr chan_ptr (channel);
89 ccp->register_channel (chan_ptr);
93 if (outfile.empty ()) {
94 tsp->set_name ("session");
96 std::string dirname = Glib::path_get_dirname (outfile);
97 std::string basename = Glib::path_get_basename (outfile);
99 if (basename.size() > 4 && !basename.compare (basename.size() - 4, 4, ".wav")) {
100 basename = PBD::basename_nosuffix (basename);
103 fnp->set_folder(dirname);
104 tsp->set_name (basename);
107 cout << "* Writing " << Glib::build_filename (fnp->get_folder(), tsp->name() + ".wav") << endl;
111 fnp->set_timespan(tsp);
112 fnp->include_label = false;
114 /* do audio export */
115 fmp->set_soundcloud_upload(false);
116 session->get_export_handler()->add_export_config (tsp, ccp, fmp, fnp, b);
117 session->get_export_handler()->do_export();
119 boost::shared_ptr<ARDOUR::ExportStatus> status = session->get_export_status ();
121 // TODO trap SIGINT -> status->abort();
123 while (status->running ()) {
124 double progress = 0.0;
125 switch (status->active_job) {
126 case ExportStatus::Normalizing:
127 progress = ((float) status->current_normalize_cycle) / status->total_normalize_cycles;
128 printf ("* Normalizing %.1f%% \r", 100. * progress); fflush (stdout);
130 case ExportStatus::Exporting:
131 progress = ((float) status->processed_frames_current_timespan) / status->total_frames_current_timespan;
132 printf ("* Exporting Audio %.1f%% \r", 100. * progress); fflush (stdout);
135 printf ("* Exporting... \r");
138 Glib::usleep (1000000);
144 printf ("* Done.\n");
148 static void usage (int status) {
149 // help2man compatible format (standard GNU help-text)
150 printf ("export - export an ardour session from the commandline.\n\n");
151 printf ("Usage: export [ OPTIONS ] <session-dir> <session-name>\n\n");
153 -h, --help display this help and exit\n\
154 -n, --normalize normalize signal level (to 0dBFS)\n\
155 -o, --output <file> set expected [initial] framerate\n\
156 -s, --samplerate <rate> samplerate to use (default: 48000)\n\
157 -V, --version print version information and exit\n\
160 The session is exported as 16bit wav.\n\
161 If the no output file is given, the session's export dir is used.\n\
164 printf ("Report bugs to <http://tracker.ardour.org/>\n"
165 "Website: <http://ardour.org/>\n");
169 int main (int argc, char* argv[])
171 std::string rate = "48000";
173 bool normalize = false;
175 const char *optstring = "hno:r:V";
177 const struct option longopts[] = {
178 { "help", 0, 0, 'h' },
179 { "normalize", 0, 0, 'n' },
180 { "output", 1, 0, 'o' },
181 { "samplerate", 1, 0, 'r' },
182 { "version", 0, 0, 'V' },
186 while (EOF != (c = getopt_long (argc, argv,
187 optstring, longopts, (int *) 0))) {
200 const int sr = atoi (optarg);
201 if (sr >= 8000 && sr <= 192000) {
206 fprintf(stderr, "Invalid Samplerate\n");
212 printf ("ardour-utils version %s\n\n", VERSIONSTRING);
213 printf ("Copyright (C) GPL 2015 Robin Gareus <robin@gareus.org>\n");
222 usage (EXIT_FAILURE);
227 if (optind + 2 > argc) {
228 usage (EXIT_FAILURE);
231 SessionUtils::init();
234 s = SessionUtils::load_session (argv[optind], argv[optind+1]);
236 export_session (s, outfile, rate, normalize);
238 SessionUtils::unload_session(s);
239 SessionUtils::cleanup();