annotate 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
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 Sonic Annotator
Chris@0 5 A utility for batch feature extraction from audio files.
Chris@0 6 Mark Levy, Chris Sutton and Chris Cannam, Queen Mary, University of London.
Chris@0 7 Copyright 2007-2008 QMUL.
Chris@0 8
Chris@0 9 This program is free software; you can redistribute it and/or
Chris@0 10 modify it under the terms of the GNU General Public License as
Chris@0 11 published by the Free Software Foundation; either version 2 of the
Chris@0 12 License, or (at your option) any later version. See the file
Chris@0 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include <iostream>
Chris@0 17 #include <map>
Chris@0 18
Chris@0 19 using namespace std;
Chris@0 20
Chris@0 21 #include "DefaultFeatureWriter.h"
Chris@0 22
Chris@325 23 #include <QTextStream>
Chris@325 24 #include <QTextCodec>
Chris@325 25
Chris@325 26 DefaultFeatureWriter::DefaultFeatureWriter() :
Chris@325 27 FileFeatureWriter(SupportStdOut,
Chris@325 28 "xml")
Chris@325 29 {
Chris@325 30 }
Chris@325 31
Chris@325 32 DefaultFeatureWriter::~DefaultFeatureWriter()
Chris@325 33 {
Chris@325 34 }
Chris@325 35
Chris@144 36 string
Chris@144 37 DefaultFeatureWriter::getDescription() const
Chris@144 38 {
Chris@144 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.";
Chris@144 40 }
Chris@144 41
Chris@325 42 static QString
Chris@325 43 toQStringAsStream(const RealTime &rt)
Chris@325 44 {
Chris@325 45 // just for historical compatibility, get the same formatting as
Chris@325 46 // when streaming to an iostream
Chris@325 47 std::stringstream out;
Chris@325 48 out << rt;
Chris@325 49 std::string s = out.str();
Chris@325 50 return QString::fromStdString(s);
Chris@325 51 }
Chris@325 52
Chris@325 53 void DefaultFeatureWriter::write(QString trackId,
Chris@325 54 const Transform &transform,
Chris@0 55 const Vamp::Plugin::OutputDescriptor& output,
Chris@325 56 const Vamp::Plugin::FeatureList& features,
Chris@0 57 std::string summaryType)
Chris@0 58 {
Chris@325 59 // Select appropriate output file for our track/transform
Chris@325 60 // combination
Chris@325 61
Chris@325 62 TransformId transformId = transform.getIdentifier();
Chris@325 63
Chris@325 64 QTextStream *sptr = getOutputStream
Chris@325 65 (trackId, transformId, QTextCodec::codecForName("UTF-8"));
Chris@325 66 if (!sptr) {
Chris@325 67 throw FailedToOpenOutputStream(trackId, transformId);
Chris@325 68 }
Chris@325 69
Chris@325 70 QTextStream &stream = *sptr;
Chris@325 71
Chris@325 72 int n = int(features.size());
Chris@325 73
Chris@325 74 if (n == 0) return;
Chris@0 75
Chris@325 76 /* we write a generic XML output of the form
Chris@0 77
Chris@325 78 <feature>
Chris@325 79 <name>output.name</name>
Chris@325 80 <timestamp>feature.timestamp</timestamp>
Chris@325 81 <values>output.binName[0]:feature.value[0]...</values>
Chris@325 82 <label>feature.label</label>
Chris@325 83 </feature>
Chris@0 84 */
Chris@0 85
Chris@325 86 for (int i = 0; i < n; ++i) {
Chris@0 87 if (summaryType == "") {
Chris@325 88 stream << "<feature>" << endl;
Chris@0 89 } else {
Chris@325 90 stream << "<summary type=\"" << QString::fromStdString(summaryType)
Chris@325 91 << "\">" << endl;
Chris@0 92 }
Chris@325 93 stream << "\t<name>" << QString::fromStdString(output.name)
Chris@325 94 << "</name>" << endl;
Chris@325 95 if (features[i].hasTimestamp) {
Chris@325 96 stream << "\t<timestamp>"
Chris@325 97 << toQStringAsStream(features[i].timestamp)
Chris@325 98 << "</timestamp>" << endl;
Chris@0 99 }
Chris@325 100 if (features[i].hasDuration) {
Chris@325 101 stream << "\t<duration>"
Chris@325 102 << toQStringAsStream(features[i].duration)
Chris@325 103 << "</duration>" << endl;
Chris@0 104 }
Chris@325 105 if (features[i].values.size() > 0)
Chris@0 106 {
Chris@325 107 stream << "\t<values>";
Chris@325 108 for (int j = 0; j < (int)features[i].values.size(); ++j) {
Chris@325 109 if (j > 0) {
Chris@325 110 stream << " ";
Chris@325 111 }
Chris@325 112 if (output.binNames.size() > 0) {
Chris@325 113 stream << QString::fromStdString(output.binNames[j]) << ":";
Chris@325 114 }
Chris@325 115 stream << features[i].values[j];
Chris@0 116 }
Chris@325 117 stream << "</values>" << endl;
Chris@0 118 }
Chris@325 119 if (features[i].label.length() > 0)
Chris@325 120 stream << "\t<label>"
Chris@325 121 << QString::fromStdString(features[i].label)
Chris@325 122 << "</label>" << endl;
Chris@0 123 if (summaryType == "") {
Chris@325 124 stream << "</feature>" << endl;
Chris@0 125 } else {
Chris@325 126 stream << "</summary>" << endl;
Chris@0 127 }
Chris@0 128 }
Chris@0 129 }