annotate transform/CSVFeatureWriter.cpp @ 823:f0558e69a074

Rename Resampling- to DecodingWavFileReader, and use it whenever we have an audio file that is not quickly seekable using libsndfile. Avoids very slow performance when analysing ogg files.
author Chris Cannam
date Wed, 17 Jul 2013 15:40:01 +0100
parents 1424aa29ae95
children 06579b8ffb7b
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@498 32 SupportOneFileTotal,
Chris@498 33 "csv"),
Chris@669 34 m_separator(","),
Chris@669 35 m_sampleTiming(false)
Chris@498 36 {
Chris@498 37 }
Chris@498 38
Chris@498 39 CSVFeatureWriter::~CSVFeatureWriter()
Chris@498 40 {
Chris@498 41 }
Chris@498 42
Chris@498 43 CSVFeatureWriter::ParameterList
Chris@498 44 CSVFeatureWriter::getSupportedParameters() const
Chris@498 45 {
Chris@498 46 ParameterList pl = FileFeatureWriter::getSupportedParameters();
Chris@498 47 Parameter p;
Chris@498 48
Chris@498 49 p.name = "separator";
Chris@498 50 p.description = "Column separator for output. Default is \",\" (comma).";
Chris@498 51 p.hasArg = true;
Chris@498 52 pl.push_back(p);
Chris@669 53
Chris@669 54 p.name = "sample-timing";
Chris@669 55 p.description = "Show timings as sample frame counts instead of in seconds.";
Chris@669 56 p.hasArg = false;
Chris@669 57 pl.push_back(p);
Chris@498 58
Chris@498 59 return pl;
Chris@498 60 }
Chris@498 61
Chris@498 62 void
Chris@498 63 CSVFeatureWriter::setParameters(map<string, string> &params)
Chris@498 64 {
Chris@498 65 FileFeatureWriter::setParameters(params);
Chris@498 66
Chris@690 67 SVDEBUG << "CSVFeatureWriter::setParameters" << endl;
Chris@498 68 for (map<string, string>::iterator i = params.begin();
Chris@498 69 i != params.end(); ++i) {
Chris@498 70 cerr << i->first << " -> " << i->second << endl;
Chris@498 71 if (i->first == "separator") {
Chris@498 72 m_separator = i->second.c_str();
Chris@669 73 } else if (i->first == "sample-timing") {
Chris@669 74 m_sampleTiming = true;
Chris@498 75 }
Chris@498 76 }
Chris@498 77 }
Chris@498 78
Chris@498 79 void
Chris@498 80 CSVFeatureWriter::write(QString trackId,
Chris@498 81 const Transform &transform,
Chris@498 82 const Plugin::OutputDescriptor& output,
Chris@498 83 const Plugin::FeatureList& features,
Chris@498 84 std::string summaryType)
Chris@498 85 {
Chris@498 86 // Select appropriate output file for our track/transform
Chris@498 87 // combination
Chris@498 88
Chris@498 89 QTextStream *sptr = getOutputStream(trackId, transform.getIdentifier());
Chris@604 90 if (!sptr) {
Chris@604 91 throw FailedToOpenOutputStream(trackId, transform.getIdentifier());
Chris@604 92 }
Chris@498 93
Chris@498 94 QTextStream &stream = *sptr;
Chris@498 95
Chris@498 96 for (unsigned int i = 0; i < features.size(); ++i) {
Chris@498 97
Chris@514 98 if (m_stdout || m_singleFileName != "") {
Chris@514 99 if (trackId != m_prevPrintedTrackId) {
Chris@514 100 stream << "\"" << trackId << "\"" << m_separator;
Chris@514 101 m_prevPrintedTrackId = trackId;
Chris@514 102 } else {
Chris@514 103 stream << m_separator;
Chris@514 104 }
Chris@514 105 }
Chris@514 106
Chris@669 107 if (m_sampleTiming) {
Chris@498 108
Chris@669 109 stream << Vamp::RealTime::realTime2Frame
Chris@669 110 (features[i].timestamp, transform.getSampleRate());
Chris@669 111
Chris@669 112 if (features[i].hasDuration) {
Chris@669 113 stream << m_separator;
Chris@669 114 stream << Vamp::RealTime::realTime2Frame
Chris@669 115 (features[i].duration, transform.getSampleRate());
Chris@669 116 }
Chris@669 117
Chris@669 118 } else {
Chris@669 119
Chris@669 120 QString timestamp = features[i].timestamp.toString().c_str();
Chris@669 121 timestamp.replace(QRegExp("^ +"), "");
Chris@669 122 stream << timestamp;
Chris@669 123
Chris@669 124 if (features[i].hasDuration) {
Chris@669 125 QString duration = features[i].duration.toString().c_str();
Chris@669 126 duration.replace(QRegExp("^ +"), "");
Chris@669 127 stream << m_separator << duration;
Chris@669 128 }
Chris@669 129 }
Chris@498 130
Chris@498 131 if (summaryType != "") {
Chris@498 132 stream << m_separator << summaryType.c_str();
Chris@498 133 }
Chris@498 134
Chris@498 135 for (unsigned int j = 0; j < features[i].values.size(); ++j) {
Chris@498 136 stream << m_separator << features[i].values[j];
Chris@498 137 }
Chris@498 138
Chris@514 139 if (features[i].label != "") {
Chris@514 140 stream << m_separator << "\"" << features[i].label.c_str() << "\"";
Chris@514 141 }
Chris@514 142
Chris@498 143 stream << "\n";
Chris@498 144 }
Chris@498 145 }
Chris@498 146
Chris@498 147