Mercurial > hg > sonic-annotator
comparison runner/DefaultFeatureWriter.cpp @ 325:d5caf5e91a86 default-writer-writes-to-files
If the default writer were to be able to write to files (but this is backward-incompatible so probably unwise)
author | Chris Cannam |
---|---|
date | Fri, 18 May 2018 12:36:48 +0100 |
parents | b3d73c08b6ce |
children |
comparison
equal
deleted
inserted
replaced
324:ef03350baec7 | 325:d5caf5e91a86 |
---|---|
18 | 18 |
19 using namespace std; | 19 using namespace std; |
20 | 20 |
21 #include "DefaultFeatureWriter.h" | 21 #include "DefaultFeatureWriter.h" |
22 | 22 |
23 #include <QTextStream> | |
24 #include <QTextCodec> | |
25 | |
26 DefaultFeatureWriter::DefaultFeatureWriter() : | |
27 FileFeatureWriter(SupportStdOut, | |
28 "xml") | |
29 { | |
30 } | |
31 | |
32 DefaultFeatureWriter::~DefaultFeatureWriter() | |
33 { | |
34 } | |
35 | |
23 string | 36 string |
24 DefaultFeatureWriter::getDescription() const | 37 DefaultFeatureWriter::getDescription() const |
25 { | 38 { |
26 return "Write features in a generic XML format, with <feature> or <summary> elements containing output name and some or all of timestamp, duration, values, and label."; | 39 return "Write features in a generic XML format, with <feature> or <summary> elements containing output name and some or all of timestamp, duration, values, and label."; |
27 } | 40 } |
28 | 41 |
29 void DefaultFeatureWriter::write(QString, | 42 static QString |
30 const Transform &, | 43 toQStringAsStream(const RealTime &rt) |
44 { | |
45 // just for historical compatibility, get the same formatting as | |
46 // when streaming to an iostream | |
47 std::stringstream out; | |
48 out << rt; | |
49 std::string s = out.str(); | |
50 return QString::fromStdString(s); | |
51 } | |
52 | |
53 void DefaultFeatureWriter::write(QString trackId, | |
54 const Transform &transform, | |
31 const Vamp::Plugin::OutputDescriptor& output, | 55 const Vamp::Plugin::OutputDescriptor& output, |
32 const Vamp::Plugin::FeatureList& featureList, | 56 const Vamp::Plugin::FeatureList& features, |
33 std::string summaryType) | 57 std::string summaryType) |
34 { | 58 { |
35 // generic XML output | 59 // Select appropriate output file for our track/transform |
60 // combination | |
61 | |
62 TransformId transformId = transform.getIdentifier(); | |
63 | |
64 QTextStream *sptr = getOutputStream | |
65 (trackId, transformId, QTextCodec::codecForName("UTF-8")); | |
66 if (!sptr) { | |
67 throw FailedToOpenOutputStream(trackId, transformId); | |
68 } | |
69 | |
70 QTextStream &stream = *sptr; | |
71 | |
72 int n = int(features.size()); | |
73 | |
74 if (n == 0) return; | |
36 | 75 |
37 /* | 76 /* we write a generic XML output of the form |
38 | 77 |
39 <feature> | 78 <feature> |
40 <name>output.name</name> | 79 <name>output.name</name> |
41 <timestamp>feature.timestamp</timestamp> | 80 <timestamp>feature.timestamp</timestamp> |
42 <values>output.binName[0]:feature.value[0]...</values> | 81 <values>output.binName[0]:feature.value[0]...</values> |
43 <label>feature.label</label> | 82 <label>feature.label</label> |
44 </feature> | 83 </feature> |
45 | |
46 */ | 84 */ |
47 | 85 |
48 for (int i = 0; i < (int)featureList.size(); ++i) { | 86 for (int i = 0; i < n; ++i) { |
49 | |
50 if (summaryType == "") { | 87 if (summaryType == "") { |
51 cout << "<feature>" << endl; | 88 stream << "<feature>" << endl; |
52 } else { | 89 } else { |
53 cout << "<summary type=\"" << summaryType << "\">" << endl; | 90 stream << "<summary type=\"" << QString::fromStdString(summaryType) |
91 << "\">" << endl; | |
54 } | 92 } |
55 cout << "\t<name>" << output.name << "</name>" << endl; | 93 stream << "\t<name>" << QString::fromStdString(output.name) |
56 if (featureList[i].hasTimestamp) { | 94 << "</name>" << endl; |
57 cout << "\t<timestamp>" << featureList[i].timestamp << "</timestamp>" << endl; | 95 if (features[i].hasTimestamp) { |
96 stream << "\t<timestamp>" | |
97 << toQStringAsStream(features[i].timestamp) | |
98 << "</timestamp>" << endl; | |
58 } | 99 } |
59 if (featureList[i].hasDuration) { | 100 if (features[i].hasDuration) { |
60 cout << "\t<duration>" << featureList[i].duration << "</duration>" << endl; | 101 stream << "\t<duration>" |
102 << toQStringAsStream(features[i].duration) | |
103 << "</duration>" << endl; | |
61 } | 104 } |
62 if (featureList[i].values.size() > 0) | 105 if (features[i].values.size() > 0) |
63 { | 106 { |
64 cout << "\t<values>"; | 107 stream << "\t<values>"; |
65 for (int j = 0; j < (int)featureList[i].values.size(); ++j) { | 108 for (int j = 0; j < (int)features[i].values.size(); ++j) { |
66 if (j > 0) | 109 if (j > 0) { |
67 cout << " "; | 110 stream << " "; |
68 if (output.binNames.size() > 0) | 111 } |
69 cout << output.binNames[j] << ":"; | 112 if (output.binNames.size() > 0) { |
70 cout << featureList[i].values[j]; | 113 stream << QString::fromStdString(output.binNames[j]) << ":"; |
114 } | |
115 stream << features[i].values[j]; | |
71 } | 116 } |
72 cout << "</values>" << endl; | 117 stream << "</values>" << endl; |
73 } | 118 } |
74 if (featureList[i].label.length() > 0) | 119 if (features[i].label.length() > 0) |
75 cout << "\t<label>" << featureList[i].label << "</label>" << endl; | 120 stream << "\t<label>" |
121 << QString::fromStdString(features[i].label) | |
122 << "</label>" << endl; | |
76 if (summaryType == "") { | 123 if (summaryType == "") { |
77 cout << "</feature>" << endl; | 124 stream << "</feature>" << endl; |
78 } else { | 125 } else { |
79 cout << "</summary>" << endl; | 126 stream << "</summary>" << endl; |
80 } | 127 } |
81 } | 128 } |
82 } | 129 } |