ExportHandler::finish_timespan ()
{
while (config_map.begin() != timespan_bounds.second) {
+
+ ExportFormatSpecPtr fmt = config_map.begin()->second.format;
+
+ if (fmt->with_cue()) {
+ export_cd_marker_file (current_timespan, fmt, config_map.begin()->second.filename->get_path(fmt), CDMarkerCUE);
+ }
+
+ if (fmt->with_toc()) {
+ export_cd_marker_file (current_timespan, fmt, config_map.begin()->second.filename->get_path(fmt), CDMarkerTOC);
+ }
+
config_map.erase (config_map.begin());
}
ExportHandler::export_cd_marker_file (ExportTimespanPtr timespan, ExportFormatSpecPtr file_format,
std::string filename, CDMarkerFormat format)
{
- string filepath;
- string basename = Glib::path_get_basename(filename);
-
- size_t ext_pos = basename.rfind('.');
- if (ext_pos != string::npos) {
- basename = basename.substr(0, ext_pos); /* strip file extension, if there is one */
- }
+ string filepath = get_cd_marker_filename(filename, format);
void (ExportHandler::*header_func) (CDMarkerStatus &);
void (ExportHandler::*track_func) (CDMarkerStatus &);
switch (format) {
case CDMarkerTOC:
- filepath = Glib::build_filename(Glib::path_get_dirname(filename), basename + ".toc");
header_func = &ExportHandler::write_toc_header;
track_func = &ExportHandler::write_track_info_toc;
index_func = &ExportHandler::write_index_info_toc;
break;
case CDMarkerCUE:
- filepath = Glib::build_filename(Glib::path_get_dirname(filename), basename + ".cue");
header_func = &ExportHandler::write_cue_header;
track_func = &ExportHandler::write_track_info_cue;
index_func = &ExportHandler::write_index_info_cue;
}
}
+string
+ExportHandler::get_cd_marker_filename(std::string filename, CDMarkerFormat format)
+{
+ /* do not strip file suffix because there may be more than one format,
+ and we do not want the CD marker file from one format to overwrite
+ another (e.g. foo.wav.cue > foo.aiff.cue)
+ */
+
+ switch (format) {
+ case CDMarkerTOC:
+ return filename + ".toc";
+ case CDMarkerCUE:
+ return filename + ".cue";
+ default:
+ return filename + ".marker"; // Should not be reached when actually creating a file
+ }
+}
+
void
ExportHandler::write_cue_header (CDMarkerStatus & status)
{
status.out << "CD_DA" << endl;
status.out << "CD_TEXT {" << endl << " LANGUAGE_MAP {" << endl << " 0 : EN" << endl << " }" << endl;
- status.out << " LANGUAGE 0 {" << endl << " TITLE \"" << title << "\"" << endl << " }" << endl << "}" << endl;
+ status.out << " LANGUAGE 0 {" << endl << " TITLE " << toc_escape_string (title) << endl ;
+ status.out << " PERFORMER \"\"" << endl << " }" << endl << "}" << endl;
}
void
status.out << " PERFORMER \"" << status.marker->cd_info["performer"] << "\"" << endl;
}
- if (status.marker->cd_info.find("string_composer") != status.marker->cd_info.end()) {
- status.out << " SONGWRITER \"" << status.marker->cd_info["string_composer"] << "\"" << endl;
+ if (status.marker->cd_info.find("composer") != status.marker->cd_info.end()) {
+ status.out << " SONGWRITER \"" << status.marker->cd_info["composer"] << "\"" << endl;
}
if (status.track_position != status.track_start_frame) {
status.out << "ISRC \"" << status.marker->cd_info["isrc"] << "\"" << endl;
}
- status.out << "CD_TEXT {" << endl << " LANGUAGE 0 {" << endl << " TITLE \"" << status.marker->name() << "\"" << endl;
+ status.out << "CD_TEXT {" << endl << " LANGUAGE 0 {" << endl << " TITLE "
+ << toc_escape_string (status.marker->name()) << endl;
+
if (status.marker->cd_info.find("performer") != status.marker->cd_info.end()) {
- status.out << " PERFORMER \"" << status.marker->cd_info["performer"] << "\"" << endl;
+ status.out << " PERFORMER " << toc_escape_string (status.marker->cd_info["performer"]);
+ } else {
+ status.out << " PERFORMER \"\"";
}
- if (status.marker->cd_info.find("string_composer") != status.marker->cd_info.end()) {
- status.out << " COMPOSER \"" << status.marker->cd_info["string_composer"] << "\"" << endl;
+
+ if (status.marker->cd_info.find("composer") != status.marker->cd_info.end()) {
+ status.out << " COMPOSER " << toc_escape_string (status.marker->cd_info["composer"]) << endl;
}
if (status.marker->cd_info.find("isrc") != status.marker->cd_info.end()) {
status.out << " }" << endl << "}" << endl;
frames_to_cd_frames_string (buf, status.track_position);
- status.out << "FILE \"" << status.filename << "\" " << buf;
+ status.out << "FILE " << toc_escape_string (status.filename) << ' ' << buf;
frames_to_cd_frames_string (buf, status.track_duration);
status.out << buf << endl;
sprintf (buf, " %02d:%02d:%02d", mins, secs, frames);
}
+std::string
+ExportHandler::toc_escape_string (const std::string& txt)
+{
+ Glib::ustring utxt (txt);
+ Glib::ustring out;
+ char buf[5];
+
+ out = '"';
+
+ for (Glib::ustring::iterator c = utxt.begin(); c != utxt.end(); ++c) {
+
+ if ((*c) == '"') {
+ out += "\\\"";
+ } else if (g_unichar_isprint (*c)) {
+ out += *c;
+ } else {
+ /* this isn't really correct */
+ snprintf (buf, sizeof (buf), "\\%03o", *c);
+ out += buf;
+ }
+ }
+
+ out += '"';
+
+ return std::string (out);
+}
+
} // namespace ARDOUR