Mercurial > hg > sonic-annotator
changeset 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 | ef03350baec7 |
children | |
files | runner/DefaultFeatureWriter.cpp runner/DefaultFeatureWriter.h tests/test-as-advertised/test-as-advertised.sh |
diffstat | 3 files changed, 97 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/runner/DefaultFeatureWriter.cpp Fri May 18 11:27:02 2018 +0100 +++ b/runner/DefaultFeatureWriter.cpp Fri May 18 12:36:48 2018 +0100 @@ -20,63 +20,110 @@ #include "DefaultFeatureWriter.h" +#include <QTextStream> +#include <QTextCodec> + +DefaultFeatureWriter::DefaultFeatureWriter() : + FileFeatureWriter(SupportStdOut, + "xml") +{ +} + +DefaultFeatureWriter::~DefaultFeatureWriter() +{ +} + string DefaultFeatureWriter::getDescription() const { 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."; } -void DefaultFeatureWriter::write(QString, - const Transform &, +static QString +toQStringAsStream(const RealTime &rt) +{ + // just for historical compatibility, get the same formatting as + // when streaming to an iostream + std::stringstream out; + out << rt; + std::string s = out.str(); + return QString::fromStdString(s); +} + +void DefaultFeatureWriter::write(QString trackId, + const Transform &transform, const Vamp::Plugin::OutputDescriptor& output, - const Vamp::Plugin::FeatureList& featureList, + const Vamp::Plugin::FeatureList& features, std::string summaryType) { - // generic XML output + // Select appropriate output file for our track/transform + // combination + + TransformId transformId = transform.getIdentifier(); + + QTextStream *sptr = getOutputStream + (trackId, transformId, QTextCodec::codecForName("UTF-8")); + if (!sptr) { + throw FailedToOpenOutputStream(trackId, transformId); + } + + QTextStream &stream = *sptr; + + int n = int(features.size()); + + if (n == 0) return; - /* + /* we write a generic XML output of the form - <feature> - <name>output.name</name> - <timestamp>feature.timestamp</timestamp> - <values>output.binName[0]:feature.value[0]...</values> - <label>feature.label</label> - </feature> - + <feature> + <name>output.name</name> + <timestamp>feature.timestamp</timestamp> + <values>output.binName[0]:feature.value[0]...</values> + <label>feature.label</label> + </feature> */ - for (int i = 0; i < (int)featureList.size(); ++i) { - + for (int i = 0; i < n; ++i) { if (summaryType == "") { - cout << "<feature>" << endl; + stream << "<feature>" << endl; } else { - cout << "<summary type=\"" << summaryType << "\">" << endl; + stream << "<summary type=\"" << QString::fromStdString(summaryType) + << "\">" << endl; } - cout << "\t<name>" << output.name << "</name>" << endl; - if (featureList[i].hasTimestamp) { - cout << "\t<timestamp>" << featureList[i].timestamp << "</timestamp>" << endl; + stream << "\t<name>" << QString::fromStdString(output.name) + << "</name>" << endl; + if (features[i].hasTimestamp) { + stream << "\t<timestamp>" + << toQStringAsStream(features[i].timestamp) + << "</timestamp>" << endl; } - if (featureList[i].hasDuration) { - cout << "\t<duration>" << featureList[i].duration << "</duration>" << endl; + if (features[i].hasDuration) { + stream << "\t<duration>" + << toQStringAsStream(features[i].duration) + << "</duration>" << endl; } - if (featureList[i].values.size() > 0) + if (features[i].values.size() > 0) { - cout << "\t<values>"; - for (int j = 0; j < (int)featureList[i].values.size(); ++j) { - if (j > 0) - cout << " "; - if (output.binNames.size() > 0) - cout << output.binNames[j] << ":"; - cout << featureList[i].values[j]; + stream << "\t<values>"; + for (int j = 0; j < (int)features[i].values.size(); ++j) { + if (j > 0) { + stream << " "; + } + if (output.binNames.size() > 0) { + stream << QString::fromStdString(output.binNames[j]) << ":"; + } + stream << features[i].values[j]; } - cout << "</values>" << endl; + stream << "</values>" << endl; } - if (featureList[i].label.length() > 0) - cout << "\t<label>" << featureList[i].label << "</label>" << endl; + if (features[i].label.length() > 0) + stream << "\t<label>" + << QString::fromStdString(features[i].label) + << "</label>" << endl; if (summaryType == "") { - cout << "</feature>" << endl; + stream << "</feature>" << endl; } else { - cout << "</summary>" << endl; + stream << "</summary>" << endl; } } }
--- a/runner/DefaultFeatureWriter.h Fri May 18 11:27:02 2018 +0100 +++ b/runner/DefaultFeatureWriter.h Fri May 18 12:36:48 2018 +0100 @@ -13,23 +13,27 @@ COPYING included with this distribution for more information. */ -#ifndef _DEFAULT_FEATURE_WRITER_H_ -#define _DEFAULT_FEATURE_WRITER_H_ +#ifndef DEFAULT_FEATURE_WRITER_H +#define DEFAULT_FEATURE_WRITER_H +#include "transform/FileFeatureWriter.h" -#include "transform/FeatureWriter.h" - -class DefaultFeatureWriter : public FeatureWriter +class DefaultFeatureWriter : public FileFeatureWriter { public: - virtual ~DefaultFeatureWriter() { } + DefaultFeatureWriter(); + virtual ~DefaultFeatureWriter(); + virtual string getDescription() const; + virtual void write(QString trackid, const Transform &transform, const Vamp::Plugin::OutputDescriptor &output, const Vamp::Plugin::FeatureList &features, std::string summaryType = ""); + virtual void finish() { } + virtual QString getWriterTag() const { return "default"; } };
--- a/tests/test-as-advertised/test-as-advertised.sh Fri May 18 11:27:02 2018 +0100 +++ b/tests/test-as-advertised/test-as-advertised.sh Fri May 18 12:36:48 2018 +0100 @@ -22,10 +22,7 @@ mkdir -p $tmpdir cp $infile $tmpwav - # Some of these are special cases: - # - # * The "default" writer type always prints to stdout instead of - # to a file. + # Special cases: # # * The "audiodb" writer will not print any output for features # that have no values (but are only point events). I don't know @@ -36,32 +33,28 @@ audiodb) mkdir -p $adbdir $r -t $df -w $type $tmpwav --audiodb-basedir $tmpdir --audiodb-catid `basename $adbdir` 2>/dev/null || \ - fail "Fails to run with reader type \"$type\" and default options" - ;; - default) - $r -t $onsets -w $type $tmpwav > $tmpdir/test.out 2>/dev/null || \ - fail "Fails to run with reader type \"$type\" and default options" + fail "Fails to run with writer type \"$type\" and default options" ;; *) $r -t $onsets -w $type $tmpwav 2>/dev/null || \ - fail "Fails to run with reader type \"$type\" and default options" + fail "Fails to run with writer type \"$type\" and default options" ;; esac newfiles=`ls $tmpdir | fgrep -v .wav` if [ "$type" = audiodb ]; then newfiles=`ls $adbdir`; fi [ -n "$newfiles" ] || \ - fail "Fails to create output file for reader \"$type\" with default options" + fail "Fails to create output file for writer \"$type\" with default options" case `echo $newfiles | wc -w` in [2-9]) if [ "$type" != audiodb ]; then - fail "Produces more than one output file for reader \"$type\" with default options" + fail "Produces more than one output file for writer \"$type\" with default options" fi ;; 1) if [ "$type" = audiodb ]; then - fail "Produces only one output file for reader \"$type\" with default options (expected two)" + fail "Produces only one output file for writer \"$type\" with default options (expected two)" fi ;; esac