annotate transform/CSVFeatureWriter.cpp @ 998:e25dc8d57565

Add descriptions for writers; add housekeeping options to Sonic Annotator to list writers and formats
author Chris Cannam
date Mon, 13 Oct 2014 14:44:51 +0100
parents 2104ea2204d2
children ec6e69373997
rev   line source
Chris@498 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@498 2
Chris@498 3 /*
Chris@498 4 Sonic Visualiser
Chris@498 5 An audio file viewer and annotation editor.
Chris@498 6
Chris@498 7 Sonic Annotator
Chris@498 8 A utility for batch feature extraction from audio files.
Chris@498 9
Chris@498 10 Mark Levy, Chris Sutton and Chris Cannam, Queen Mary, University of London.
Chris@498 11 Copyright 2007-2008 QMUL.
Chris@498 12
Chris@498 13 This program is free software; you can redistribute it and/or
Chris@498 14 modify it under the terms of the GNU General Public License as
Chris@498 15 published by the Free Software Foundation; either version 2 of the
Chris@498 16 License, or (at your option) any later version. See the file
Chris@498 17 COPYING included with this distribution for more information.
Chris@498 18 */
Chris@498 19
Chris@498 20 #include "CSVFeatureWriter.h"
Chris@498 21
Chris@498 22 #include <iostream>
Chris@498 23
Chris@498 24 #include <QRegExp>
Chris@498 25 #include <QTextStream>
Chris@498 26
Chris@498 27 using namespace std;
Chris@498 28 using namespace Vamp;
Chris@498 29
Chris@498 30 CSVFeatureWriter::CSVFeatureWriter() :
Chris@498 31 FileFeatureWriter(SupportOneFilePerTrackTransform |
Chris@997 32 SupportOneFileTotal |
Chris@997 33 SupportStdOut,
Chris@498 34 "csv"),
Chris@669 35 m_separator(","),
Chris@669 36 m_sampleTiming(false)
Chris@498 37 {
Chris@498 38 }
Chris@498 39
Chris@498 40 CSVFeatureWriter::~CSVFeatureWriter()
Chris@498 41 {
Chris@498 42 }
Chris@498 43
Chris@998 44 string
Chris@998 45 CSVFeatureWriter::getDescription() const
Chris@998 46 {
Chris@998 47 return "Write features in comma-separated (CSV) format. If transforms are being written to a single file or to stdout, the first column in the output will contain the input audio filename, or an empty string if the feature hails from the same audio file as its predecessor. If transforms are being written to multiple files, the audio filename column will be omitted. Subsequent columns will contain the feature timestamp, then any or all of duration, values, and label.";
Chris@998 48 }
Chris@998 49
Chris@498 50 CSVFeatureWriter::ParameterList
Chris@498 51 CSVFeatureWriter::getSupportedParameters() const
Chris@498 52 {
Chris@498 53 ParameterList pl = FileFeatureWriter::getSupportedParameters();
Chris@498 54 Parameter p;
Chris@498 55
Chris@498 56 p.name = "separator";
Chris@498 57 p.description = "Column separator for output. Default is \",\" (comma).";
Chris@498 58 p.hasArg = true;
Chris@498 59 pl.push_back(p);
Chris@669 60
Chris@669 61 p.name = "sample-timing";
Chris@669 62 p.description = "Show timings as sample frame counts instead of in seconds.";
Chris@669 63 p.hasArg = false;
Chris@669 64 pl.push_back(p);
Chris@498 65
Chris@498 66 return pl;
Chris@498 67 }
Chris@498 68
Chris@498 69 void
Chris@498 70 CSVFeatureWriter::setParameters(map<string, string> &params)
Chris@498 71 {
Chris@498 72 FileFeatureWriter::setParameters(params);
Chris@498 73
Chris@690 74 SVDEBUG << "CSVFeatureWriter::setParameters" << endl;
Chris@498 75 for (map<string, string>::iterator i = params.begin();
Chris@498 76 i != params.end(); ++i) {
Chris@498 77 cerr << i->first << " -> " << i->second << endl;
Chris@498 78 if (i->first == "separator") {
Chris@498 79 m_separator = i->second.c_str();
Chris@669 80 } else if (i->first == "sample-timing") {
Chris@669 81 m_sampleTiming = true;
Chris@498 82 }
Chris@498 83 }
Chris@498 84 }
Chris@498 85
Chris@498 86 void
Chris@498 87 CSVFeatureWriter::write(QString trackId,
Chris@498 88 const Transform &transform,
Chris@930 89 const Plugin::OutputDescriptor& ,
Chris@498 90 const Plugin::FeatureList& features,
Chris@498 91 std::string summaryType)
Chris@498 92 {
Chris@498 93 // Select appropriate output file for our track/transform
Chris@498 94 // combination
Chris@498 95
Chris@498 96 QTextStream *sptr = getOutputStream(trackId, transform.getIdentifier());
Chris@604 97 if (!sptr) {
Chris@604 98 throw FailedToOpenOutputStream(trackId, transform.getIdentifier());
Chris@604 99 }
Chris@498 100
Chris@498 101 QTextStream &stream = *sptr;
Chris@498 102
Chris@498 103 for (unsigned int i = 0; i < features.size(); ++i) {
Chris@498 104
Chris@514 105 if (m_stdout || m_singleFileName != "") {
Chris@514 106 if (trackId != m_prevPrintedTrackId) {
Chris@514 107 stream << "\"" << trackId << "\"" << m_separator;
Chris@514 108 m_prevPrintedTrackId = trackId;
Chris@514 109 } else {
Chris@514 110 stream << m_separator;
Chris@514 111 }
Chris@514 112 }
Chris@514 113
Chris@669 114 if (m_sampleTiming) {
Chris@498 115
Chris@669 116 stream << Vamp::RealTime::realTime2Frame
Chris@669 117 (features[i].timestamp, transform.getSampleRate());
Chris@669 118
Chris@669 119 if (features[i].hasDuration) {
Chris@669 120 stream << m_separator;
Chris@669 121 stream << Vamp::RealTime::realTime2Frame
Chris@669 122 (features[i].duration, transform.getSampleRate());
Chris@669 123 }
Chris@669 124
Chris@669 125 } else {
Chris@669 126
Chris@669 127 QString timestamp = features[i].timestamp.toString().c_str();
Chris@669 128 timestamp.replace(QRegExp("^ +"), "");
Chris@669 129 stream << timestamp;
Chris@669 130
Chris@669 131 if (features[i].hasDuration) {
Chris@669 132 QString duration = features[i].duration.toString().c_str();
Chris@669 133 duration.replace(QRegExp("^ +"), "");
Chris@669 134 stream << m_separator << duration;
Chris@669 135 }
Chris@669 136 }
Chris@498 137
Chris@498 138 if (summaryType != "") {
Chris@498 139 stream << m_separator << summaryType.c_str();
Chris@498 140 }
Chris@498 141
Chris@498 142 for (unsigned int j = 0; j < features[i].values.size(); ++j) {
Chris@498 143 stream << m_separator << features[i].values[j];
Chris@498 144 }
Chris@498 145
Chris@514 146 if (features[i].label != "") {
Chris@514 147 stream << m_separator << "\"" << features[i].label.c_str() << "\"";
Chris@514 148 }
Chris@514 149
Chris@498 150 stream << "\n";
Chris@498 151 }
Chris@498 152 }
Chris@498 153
Chris@498 154