# HG changeset patch # User Chris Cannam # Date 1578666594 0 # Node ID c546429d4c2f06090de42a39301faf16bd7aac92 # Parent 1318e069906b0fea33d2bdd53a34481a098c6ba0 Add optional ability to write a header on delimited data output, & to write times in frames diff -r 1318e069906b -r c546429d4c2f base/DataExportOptions.h --- a/base/DataExportOptions.h Wed Jan 08 15:26:49 2020 +0000 +++ b/base/DataExportOptions.h Fri Jan 10 14:29:54 2020 +0000 @@ -20,6 +20,7 @@ DataExportDefaults = 0x0, DataExportFillGaps = 0x1, DataExportOmitLevels = 0x2, + DataExportWriteTimeInFrames = 0x4 // otherwise in seconds }; typedef int DataExportOptions; diff -r 1318e069906b -r c546429d4c2f base/Event.h --- a/base/Event.h Wed Jan 08 15:26:49 2020 +0000 +++ b/base/Event.h Fri Jan 10 14:29:54 2020 +0000 @@ -366,21 +366,67 @@ return n; } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions opts, + ExportNameOptions nameOpts) const { + + QStringList list; + + // These are considered API rather than human-readable text - + // they shouldn't be translated + + if (opts & DataExportWriteTimeInFrames) { + list << "frame"; + } else { + list << "time"; + } + + if (m_haveValue) { + list << nameOpts.valueAttributeName; + } + + if (m_haveDuration) { + list << "duration"; + } + + if (m_haveLevel) { + if (!(opts & DataExportOmitLevels)) { + list << nameOpts.levelAttributeName; + } + } + + if (m_uri != "") { + list << nameOpts.uriAttributeName; + } + + list << "label"; + + return list.join(delimiter).toUpper(); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions opts, sv_samplerate_t sampleRate) const { QStringList list; - list << RealTime::frame2RealTime(m_frame, sampleRate) - .toString().c_str(); + if (opts & DataExportWriteTimeInFrames) { + list << QString("%1").arg(m_frame); + } else { + list << RealTime::frame2RealTime(m_frame, sampleRate) + .toString().c_str(); + } if (m_haveValue) { list << QString("%1").arg(m_value); } if (m_haveDuration) { - list << RealTime::frame2RealTime(m_duration, sampleRate) - .toString().c_str(); + if (opts & DataExportWriteTimeInFrames) { + list << QString("%1").arg(m_duration); + } else { + list << RealTime::frame2RealTime(m_duration, sampleRate) + .toString().c_str(); + } } if (m_haveLevel) { diff -r 1318e069906b -r c546429d4c2f base/EventSeries.cpp --- a/base/EventSeries.cpp Wed Jan 08 15:26:49 2020 +0000 +++ b/base/EventSeries.cpp Fri Jan 10 14:29:54 2020 +0000 @@ -598,6 +598,20 @@ } QString +EventSeries::getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions opts, + Event::ExportNameOptions nopts) const +{ + if (m_events.empty()) { + return QString(); + } else { + return m_events.begin()->getDelimitedDataHeaderLine(delimiter, + opts, + nopts); + } +} + +QString EventSeries::toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f base/EventSeries.h --- a/base/EventSeries.h Wed Jan 08 15:26:49 2020 +0000 +++ b/base/EventSeries.h Fri Jan 10 14:29:54 2020 +0000 @@ -221,6 +221,14 @@ Event::ExportNameOptions) const; /** + * Emit a label for each column that would be written by + * toDelimitedDataString, separated by the given delimiter. + */ + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options, + Event::ExportNameOptions) const; + + /** * Emit events starting within the given range to a delimited * (e.g. comma-separated) data format. */ diff -r 1318e069906b -r c546429d4c2f data/fileio/CSVFileWriter.cpp --- a/data/fileio/CSVFileWriter.cpp Wed Jan 08 15:26:49 2020 +0000 +++ b/data/fileio/CSVFileWriter.cpp Fri Jan 10 14:29:54 2020 +0000 @@ -85,6 +85,9 @@ QTextStream out(&file); +// out << m_model->getDelimitedDataHeaderLine(m_delimiter, m_options) +// << endl; + sv_frame_t blockSize = 65536; if (m_model->isSparse()) { diff -r 1318e069906b -r c546429d4c2f data/model/AlignmentModel.h --- a/data/model/AlignmentModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/AlignmentModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -77,6 +77,10 @@ QString indent = "", QString extraAttributes = "") const override; + QString getDelimitedDataHeaderLine(QString, DataExportOptions) const override { + return ""; + } + QString toDelimitedDataString(QString, DataExportOptions, sv_frame_t, sv_frame_t) const override { return ""; diff -r 1318e069906b -r c546429d4c2f data/model/BasicCompressedDenseThreeDimensionalModel.cpp --- a/data/model/BasicCompressedDenseThreeDimensionalModel.cpp Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/BasicCompressedDenseThreeDimensionalModel.cpp Fri Jan 10 14:29:54 2020 +0000 @@ -499,6 +499,17 @@ } QString +BasicCompressedDenseThreeDimensionalModel::getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions) const +{ + QStringList list; + for (int i = 0; i < m_yBinCount; ++i) { + list << QString("Bin%1").arg(i+1); + } + return list.join(delimiter); +} + +QString BasicCompressedDenseThreeDimensionalModel::toDelimitedDataString(QString delimiter, DataExportOptions, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/BasicCompressedDenseThreeDimensionalModel.h --- a/data/model/BasicCompressedDenseThreeDimensionalModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/BasicCompressedDenseThreeDimensionalModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -181,6 +181,9 @@ QString getTypeName() const override { return tr("Editable Dense 3-D"); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions opts) const override; + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/BoxModel.h --- a/data/model/BoxModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/BoxModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -348,8 +348,26 @@ m_events.toXml(out, indent, QString("dimensions=\"2\""), options); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions opts) const override { + QStringList list; + + // These are considered API rather than human-readable text - + // they shouldn't be translated + + if (opts & DataExportWriteTimeInFrames) { + list << "startframe" << "endframe"; + } else { + list << "start" << "end"; + } + + list << "extent start" << "extent end" << "label"; + + return list.join(delimiter).toUpper(); + } + QString toDelimitedDataString(QString delimiter, - DataExportOptions, + DataExportOptions opts, sv_frame_t startFrame, sv_frame_t duration) const override { @@ -363,14 +381,25 @@ QStringList list; - list << RealTime::frame2RealTime - (e.getFrame(), getSampleRate()) - .toString().c_str() - << RealTime::frame2RealTime - (e.getFrame() + e.getDuration(), getSampleRate()) - .toString().c_str() - << QString("%1").arg(e.getValue()) - << QString("%1").arg(e.getValue() + fabsf(e.getLevel())); + if (opts & DataExportWriteTimeInFrames) { + + list << QString("%1").arg(e.getFrame()); + list << QString("%1").arg(e.getFrame() + e.getDuration()); + + } else { + + list << RealTime::frame2RealTime + (e.getFrame(), getSampleRate()) + .toString().c_str(); + + list << RealTime::frame2RealTime + (e.getFrame() + e.getDuration(), getSampleRate()) + .toString().c_str(); + } + + list << QString("%1").arg(e.getValue()); + + list << QString("%1").arg(e.getValue() + fabsf(e.getLevel())); if (e.getLabel() != "") { list << e.getLabel(); diff -r 1318e069906b -r c546429d4c2f data/model/Dense3DModelPeakCache.h --- a/data/model/Dense3DModelPeakCache.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/Dense3DModelPeakCache.h Fri Jan 10 14:29:54 2020 +0000 @@ -119,6 +119,10 @@ return source ? source->getCompletion() : 100; } + QString getDelimitedDataHeaderLine(QString, DataExportOptions) const override { + return ""; + } + QString toDelimitedDataString(QString, DataExportOptions, sv_frame_t, sv_frame_t) const override { return ""; diff -r 1318e069906b -r c546429d4c2f data/model/DenseTimeValueModel.cpp --- a/data/model/DenseTimeValueModel.cpp Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/DenseTimeValueModel.cpp Fri Jan 10 14:29:54 2020 +0000 @@ -16,7 +16,19 @@ #include "DenseTimeValueModel.h" #include - + +QString +DenseTimeValueModel::getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions) const +{ + int ch = getChannelCount(); + QStringList list; + for (int i = 0; i < ch; ++i) { + list << QString("Channel%1").arg(i+1); + } + return list.join(delimiter); +} + QString DenseTimeValueModel::toDelimitedDataString(QString delimiter, DataExportOptions, diff -r 1318e069906b -r c546429d4c2f data/model/DenseTimeValueModel.h --- a/data/model/DenseTimeValueModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/DenseTimeValueModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -82,6 +82,9 @@ bool canPlay() const override { return true; } QString getDefaultPlayClipId() const override { return ""; } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override; + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/EditableDenseThreeDimensionalModel.cpp --- a/data/model/EditableDenseThreeDimensionalModel.cpp Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/EditableDenseThreeDimensionalModel.cpp Fri Jan 10 14:29:54 2020 +0000 @@ -352,6 +352,17 @@ } QString +EditableDenseThreeDimensionalModel::getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions) const +{ + QStringList list; + for (int i = 0; i < m_yBinCount; ++i) { + list << QString("Bin%1").arg(i+1); + } + return list.join(delimiter); +} + +QString EditableDenseThreeDimensionalModel::toDelimitedDataString(QString delimiter, DataExportOptions, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/EditableDenseThreeDimensionalModel.h --- a/data/model/EditableDenseThreeDimensionalModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/EditableDenseThreeDimensionalModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -172,6 +172,9 @@ QString getTypeName() const override { return tr("Editable Dense 3-D"); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions opts) const override; + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/FFTModel.h --- a/data/model/FFTModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/FFTModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -99,6 +99,9 @@ float getBinValue(int n) const override; QString getBinName(int n) const override; + QString getDelimitedDataHeaderLine(QString, DataExportOptions) const override { + return ""; + } QString toDelimitedDataString(QString, DataExportOptions, sv_frame_t, sv_frame_t) const override { return ""; diff -r 1318e069906b -r c546429d4c2f data/model/ImageModel.h --- a/data/model/ImageModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/ImageModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -275,6 +275,16 @@ m_events.toXml(out, indent, QString("dimensions=\"1\""), options); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override { + Event::ExportNameOptions nameOpts; + nameOpts.uriAttributeName = "image"; + + return m_events.getDelimitedDataHeaderLine(delimiter, + options, + nameOpts); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/Model.h --- a/data/model/Model.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/Model.h Fri Jan 10 14:29:54 2020 +0000 @@ -274,6 +274,17 @@ QString indent = "", QString extraAttributes = "") const override; + /** + * Emit a label for each column that would be written by + * toDelimitedDataString, separated by the given delimiter. + */ + virtual QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const = 0; + + /** + * Emit the contents of the model within the given range to a + * delimited (e.g. comma-separated) data format. + */ virtual QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/NoteModel.h --- a/data/model/NoteModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/NoteModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -408,6 +408,13 @@ m_events.toXml(out, indent, QString("dimensions=\"3\"")); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override { + return m_events.getDelimitedDataHeaderLine(delimiter, + options, + Event::ExportNameOptions()); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/RegionModel.h --- a/data/model/RegionModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/RegionModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -340,6 +340,13 @@ m_events.toXml(out, indent, QString("dimensions=\"3\"")); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override { + return m_events.getDelimitedDataHeaderLine(delimiter, + options, + Event::ExportNameOptions()); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/SparseOneDimensionalModel.h --- a/data/model/SparseOneDimensionalModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/SparseOneDimensionalModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -308,6 +308,13 @@ m_events.toXml(out, indent, QString("dimensions=\"1\"")); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override { + return m_events.getDelimitedDataHeaderLine(delimiter, + options, + Event::ExportNameOptions()); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/SparseTimeValueModel.h --- a/data/model/SparseTimeValueModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/SparseTimeValueModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -347,6 +347,13 @@ m_events.toXml(out, indent, QString("dimensions=\"2\"")); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override { + return m_events.getDelimitedDataHeaderLine(delimiter, + options, + Event::ExportNameOptions()); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame, diff -r 1318e069906b -r c546429d4c2f data/model/TextModel.h --- a/data/model/TextModel.h Wed Jan 08 15:26:49 2020 +0000 +++ b/data/model/TextModel.h Fri Jan 10 14:29:54 2020 +0000 @@ -278,6 +278,15 @@ m_events.toXml(out, indent, QString("dimensions=\"2\""), options); } + QString getDelimitedDataHeaderLine(QString delimiter, + DataExportOptions options) const override { + Event::ExportNameOptions nameOpts; + nameOpts.valueAttributeName = "height"; + return m_events.getDelimitedDataHeaderLine(delimiter, + options, + nameOpts); + } + QString toDelimitedDataString(QString delimiter, DataExportOptions options, sv_frame_t startFrame,