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 if (status->normalizing) {
125 double progress = ((float) status->current_normalize_cycle) / status->total_normalize_cycles;
126 printf ("* Normalizing %.1f%% \r", 100. * progress); fflush (stdout);
128 double progress = ((float) status->processed_frames_current_timespan) / status->total_frames_current_timespan;
129 printf ("* Exporting Audio %.1f%% \r", 100. * progress); fflush (stdout);
131 Glib::usleep (1000000);
137 printf ("* Done.\n");
141 static void usage (int status) {
142 // help2man compatible format (standard GNU help-text)
143 printf ("export - export an ardour session from the commandline.\n\n");
144 printf ("Usage: export [ OPTIONS ] <session-dir> <session-name>\n\n");
146 -h, --help display this help and exit\n\
147 -n, --normalize normalize signal level (to 0dBFS)\n\
148 -o, --output <file> set expected [initial] framerate\n\
149 -s, --samplerate <rate> samplerate to use (default: 48000)\n\
150 -V, --version print version information and exit\n\
153 The session is exported as 16bit wav.\n\
154 If the no output file is given, the session's export dir is used.\n\
157 printf ("Report bugs to <http://tracker.ardour.org/>\n"
158 "Website: <http://ardour.org/>\n");
162 int main (int argc, char* argv[])
164 std::string rate = "48000";
166 bool normalize = false;
168 const char *optstring = "hno:r:V";
170 const struct option longopts[] = {
171 { "help", 0, 0, 'h' },
172 { "normalize", 0, 0, 'n' },
173 { "output", 1, 0, 'o' },
174 { "samplerate", 1, 0, 'r' },
175 { "version", 0, 0, 'V' },
179 while (EOF != (c = getopt_long (argc, argv,
180 optstring, longopts, (int *) 0))) {
193 const int sr = atoi (optarg);
194 if (sr >= 8000 && sr <= 192000) {
199 fprintf(stderr, "Invalid Samplerate\n");
205 printf ("ardour-utils version %s\n\n", VERSIONSTRING);
206 printf ("Copyright (C) GPL 2015 Robin Gareus <robin@gareus.org>\n");
215 usage (EXIT_FAILURE);
220 if (optind + 2 > argc) {
221 usage (EXIT_FAILURE);
224 SessionUtils::init();
227 s = SessionUtils::load_session (argv[optind], argv[optind+1]);
229 export_session (s, outfile, rate, normalize);
231 SessionUtils::unload_session(s);
232 SessionUtils::cleanup();