# HG changeset patch # User Chris Cannam # Date 1553789016 0 # Node ID 0d89abd631ac09bb5bc97e7f8f22197139cf0856 # Parent 1078f0ef3012d2dfe572acfbe6be841b001b0159 Re-add the toDelimitedDataString stuff diff -r 1078f0ef3012 -r 0d89abd631ac base/EventSeries.cpp --- a/base/EventSeries.cpp Thu Mar 28 13:37:09 2019 +0000 +++ b/base/EventSeries.cpp Thu Mar 28 16:03:36 2019 +0000 @@ -14,6 +14,16 @@ #include "EventSeries.h" +EventSeries +EventSeries::fromEvents(const EventVector &v) +{ + EventSeries s; + for (const auto &e: v) { + s.add(e); + } + return s; +} + bool EventSeries::isEmpty() const { @@ -505,4 +515,68 @@ out << indent << "\n"; } +QString +EventSeries::toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration, + sv_samplerate_t sampleRate, + sv_frame_t resolution, + Event fillEvent) const +{ + QString s; + const sv_frame_t end = startFrame + duration; + + auto pitr = lower_bound(m_events.begin(), m_events.end(), + Event(startFrame)); + + if (!(options & DataExportFillGaps)) { + + while (pitr != m_events.end() && pitr->getFrame() < end) { + s += pitr->toDelimitedDataString(delimiter, + options, + sampleRate); + s += "\n"; + ++pitr; + } + + } else { + + // find frame time of first point in range (if any) + sv_frame_t first = startFrame; + if (pitr != m_events.end()) { + first = pitr->getFrame(); + } + + // project back to first frame time in range according to + // resolution. e.g. if f0 = 2, first = 9, resolution = 4 then + // we start at 5 (because 1 is too early and we need to arrive + // at 9 to match the first actual point). This method is + // stupid but easy to understand: + sv_frame_t f = first; + while (f >= startFrame + resolution) f -= resolution; + + // now progress, either writing the next point (if within + // distance) or a default fill point + while (f < end) { + if (pitr != m_events.end() && pitr->getFrame() <= f) { + s += pitr->toDelimitedDataString + (delimiter, + options & ~DataExportFillGaps, + sampleRate); + ++pitr; + } else { + s += fillEvent.withFrame(f).toDelimitedDataString + (delimiter, + options & ~DataExportFillGaps, + sampleRate); + } + s += "\n"; + f += resolution; + } + } + + return s; +} + diff -r 1078f0ef3012 -r 0d89abd631ac base/EventSeries.h --- a/base/EventSeries.h Thu Mar 28 13:37:09 2019 +0000 +++ b/base/EventSeries.h Thu Mar 28 16:03:36 2019 +0000 @@ -52,6 +52,8 @@ bool operator==(const EventSeries &other) const { return m_events == other.m_events; } + + static EventSeries fromEvents(const EventVector &ee); void clear(); void add(const Event &e); @@ -213,6 +215,18 @@ QString indent, QString extraAttributes, Event::ExportNameOptions) const; + + /** + * Emit events starting within the given range to a delimited + * (e.g. comma-separated) data format. + */ + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration, + sv_samplerate_t sampleRate, + sv_frame_t resolution, + Event fillEvent) const; private: /** diff -r 1078f0ef3012 -r 0d89abd631ac data/fileio/CSVStreamWriter.h --- a/data/fileio/CSVStreamWriter.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/fileio/CSVStreamWriter.h Thu Mar 28 16:03:36 2019 +0000 @@ -68,11 +68,11 @@ const auto start = readPtr; const auto end = std::min(start + blockSize, endFrame); - const auto data = model.toDelimitedDataStringSubsetWithOptions( + const auto data = model.toDelimitedDataString( delimiter, options, start, - end + end - start ).trimmed(); if ( data != "" ) { diff -r 1078f0ef3012 -r 0d89abd631ac data/fileio/test/CSVStreamWriterTest.h --- a/data/fileio/test/CSVStreamWriterTest.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/fileio/test/CSVStreamWriterTest.h Thu Mar 28 16:03:36 2019 +0000 @@ -303,7 +303,9 @@ // qDebug("Create Expected Output\n"); // NB. removed end line break - const auto expectedOutput = notes.toDelimitedDataString(",").trimmed(); + const auto expectedOutput = + notes.toDelimitedDataString(",", {}, 0, notes.getEndFrame()) + .trimmed(); StubReporter reporter { []() -> bool { return false; } }; std::ostringstream oss; @@ -321,6 +323,7 @@ // qDebug("\n->>%s<<-\n", expectedOutput.toLocal8Bit().data()); // qDebug("\n->>%s<<-\n", oss.str().c_str()); QVERIFY( wroteSparseModel == true ); + QVERIFY( oss.str() != std::string() ); QVERIFY( oss.str() == expectedOutput.toStdString() ); } }; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/AlignmentModel.h --- a/data/model/AlignmentModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/AlignmentModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -63,6 +63,11 @@ QString indent = "", QString extraAttributes = "") const override; + QString toDelimitedDataString(QString, DataExportOptions, + sv_frame_t, sv_frame_t) const override { + return ""; + } + signals: void modelChanged(); void modelChangedWithin(sv_frame_t startFrame, sv_frame_t endFrame); diff -r 1078f0ef3012 -r 0d89abd631ac data/model/Dense3DModelPeakCache.h --- a/data/model/Dense3DModelPeakCache.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/Dense3DModelPeakCache.h Thu Mar 28 16:03:36 2019 +0000 @@ -97,6 +97,11 @@ return m_source->getCompletion(); } + QString toDelimitedDataString(QString, DataExportOptions, + sv_frame_t, sv_frame_t) const override { + return ""; + } + protected slots: void sourceModelChanged(); void sourceModelAboutToBeDeleted(); diff -r 1078f0ef3012 -r 0d89abd631ac data/model/DenseTimeValueModel.cpp --- a/data/model/DenseTimeValueModel.cpp Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/DenseTimeValueModel.cpp Thu Mar 28 16:03:36 2019 +0000 @@ -29,22 +29,23 @@ } QString -DenseTimeValueModel::toDelimitedDataStringSubset(QString delimiter, sv_frame_t f0, sv_frame_t f1) const +DenseTimeValueModel::toDelimitedDataString(QString delimiter, + DataExportOptions, + sv_frame_t startFrame, + sv_frame_t duration) const { int ch = getChannelCount(); -// cerr << "f0 = " << f0 << ", f1 = " << f1 << endl; + if (duration <= 0) return ""; - if (f1 <= f0) return ""; - - auto data = getMultiChannelData(0, ch - 1, f0, f1 - f0); + auto data = getMultiChannelData(0, ch - 1, startFrame, duration); if (data.empty() || data[0].empty()) return ""; QStringList list; for (sv_frame_t i = 0; in_range_for(data[0], i); ++i) { QStringList parts; - parts << QString("%1").arg(f0 + i); + parts << QString("%1").arg(startFrame + i); for (int c = 0; in_range_for(data, c); ++c) { parts << QString("%1").arg(data[c][i]); } diff -r 1078f0ef3012 -r 0d89abd631ac data/model/DenseTimeValueModel.h --- a/data/model/DenseTimeValueModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/DenseTimeValueModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -82,8 +82,10 @@ bool canPlay() const override { return true; } QString getDefaultPlayClipId() const override { return ""; } - QString toDelimitedDataStringSubset(QString delimiter, - sv_frame_t f0, sv_frame_t f1) const override; + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override; QString getTypeName() const override { return tr("Dense Time-Value"); } }; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/EditableDenseThreeDimensionalModel.cpp --- a/data/model/EditableDenseThreeDimensionalModel.cpp Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/EditableDenseThreeDimensionalModel.cpp Thu Mar 28 16:03:36 2019 +0000 @@ -487,28 +487,16 @@ } QString -EditableDenseThreeDimensionalModel::toDelimitedDataString(QString delimiter) const -{ - QReadLocker locker(&m_lock); - QString s; - for (int i = 0; in_range_for(m_data, i); ++i) { - QStringList list; - for (int j = 0; in_range_for(m_data.at(i), j); ++j) { - list << QString("%1").arg(m_data.at(i).at(j)); - } - s += list.join(delimiter) + "\n"; - } - return s; -} - -QString -EditableDenseThreeDimensionalModel::toDelimitedDataStringSubset(QString delimiter, sv_frame_t f0, sv_frame_t f1) const +EditableDenseThreeDimensionalModel::toDelimitedDataString(QString delimiter, + DataExportOptions, + sv_frame_t startFrame, + sv_frame_t duration) const { QReadLocker locker(&m_lock); QString s; for (int i = 0; in_range_for(m_data, i); ++i) { sv_frame_t fr = m_startFrame + i * m_resolution; - if (fr >= f0 && fr < f1) { + if (fr >= startFrame && fr < startFrame + duration) { QStringList list; for (int j = 0; in_range_for(m_data.at(i), j); ++j) { list << QString("%1").arg(m_data.at(i).at(j)); diff -r 1078f0ef3012 -r 0d89abd631ac data/model/EditableDenseThreeDimensionalModel.h --- a/data/model/EditableDenseThreeDimensionalModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/EditableDenseThreeDimensionalModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -188,8 +188,10 @@ QString getTypeName() const override { return tr("Editable Dense 3-D"); } - QString toDelimitedDataString(QString delimiter) const override; - QString toDelimitedDataStringSubset(QString delimiter, sv_frame_t f0, sv_frame_t f1) const override; + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override; void toXml(QTextStream &out, QString indent = "", diff -r 1078f0ef3012 -r 0d89abd631ac data/model/FFTModel.h --- a/data/model/FFTModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/FFTModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -88,6 +88,10 @@ } virtual QString getError() const { return ""; } //!!!??? virtual sv_frame_t getFillExtent() const { return getEndFrame(); } + QString toDelimitedDataString(QString, DataExportOptions, + sv_frame_t, sv_frame_t) const override { + return ""; + } // FFTModel methods: // diff -r 1078f0ef3012 -r 0d89abd631ac data/model/ImageModel.h --- a/data/model/ImageModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/ImageModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -261,7 +261,20 @@ m_events.toXml(out, indent, QString("dimensions=\"1\""), options); } - + + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override { + return m_events.toDelimitedDataString(delimiter, + options, + startFrame, + duration, + m_sampleRate, + m_resolution, + Event().withValue(0.f)); + } + protected: sv_samplerate_t m_sampleRate; int m_resolution; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/Model.h --- a/data/model/Model.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/Model.h Thu Mar 28 16:03:36 2019 +0000 @@ -257,21 +257,10 @@ QString indent = "", QString extraAttributes = "") const override; - virtual QString toDelimitedDataString(QString delimiter) const { - return toDelimitedDataStringSubset - (delimiter, getStartFrame(), getEndFrame()); - } - virtual QString toDelimitedDataStringWithOptions(QString delimiter, DataExportOptions opts) const { - return toDelimitedDataStringSubsetWithOptions - (delimiter, opts, getStartFrame(), getEndFrame()); - } - virtual QString toDelimitedDataStringSubset(QString, sv_frame_t /* f0 */, sv_frame_t /* f1 */) const { - return ""; - } - virtual QString toDelimitedDataStringSubsetWithOptions(QString delimiter, DataExportOptions, sv_frame_t f0, sv_frame_t f1) const { - // Default implementation supports no options - return toDelimitedDataStringSubset(delimiter, f0, f1); - } + virtual QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const = 0; public slots: void aboutToDelete(); diff -r 1078f0ef3012 -r 0d89abd631ac data/model/NoteModel.h --- a/data/model/NoteModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/NoteModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -384,6 +384,20 @@ m_events.toXml(out, indent, QString("dimensions=\"3\"")); } + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override { + return m_events.toDelimitedDataString + (delimiter, + options, + startFrame, + duration, + m_sampleRate, + m_resolution, + Event().withValue(0.f).withDuration(0.f).withLevel(0.f)); + } + protected: Subtype m_subtype; sv_samplerate_t m_sampleRate; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/PathModel.h --- a/data/model/PathModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/PathModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -192,6 +192,24 @@ out << indent << "\n"; } + + QString toDelimitedDataString(QString delimiter, + DataExportOptions, + sv_frame_t startFrame, + sv_frame_t duration) const override { + + QString s; + for (PathPoint p: m_points) { + if (p.frame < startFrame) continue; + if (p.frame >= startFrame + duration) break; + s += QString("%1%2%3\n") + .arg(p.frame) + .arg(delimiter) + .arg(p.mapframe); + } + + return s; + } protected: sv_samplerate_t m_sampleRate; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/RegionModel.h --- a/data/model/RegionModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/RegionModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -326,7 +326,21 @@ m_events.toXml(out, indent, QString("dimensions=\"3\"")); } - + + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override { + return m_events.toDelimitedDataString + (delimiter, + options, + startFrame, + duration, + m_sampleRate, + m_resolution, + Event().withValue(0.f).withDuration(m_resolution)); + } + protected: sv_samplerate_t m_sampleRate; int m_resolution; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/SparseOneDimensionalModel.h --- a/data/model/SparseOneDimensionalModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/SparseOneDimensionalModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -290,6 +290,19 @@ m_events.toXml(out, indent, QString("dimensions=\"1\"")); } + + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override { + return m_events.toDelimitedDataString(delimiter, + options, + startFrame, + duration, + m_sampleRate, + m_resolution, + Event()); + } protected: sv_samplerate_t m_sampleRate; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/SparseTimeValueModel.h --- a/data/model/SparseTimeValueModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/SparseTimeValueModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -321,6 +321,19 @@ m_events.toXml(out, indent, QString("dimensions=\"2\"")); } + + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override { + return m_events.toDelimitedDataString(delimiter, + options, + startFrame, + duration, + m_sampleRate, + m_resolution, + Event().withValue(0.f)); + } protected: sv_samplerate_t m_sampleRate; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/TextModel.h --- a/data/model/TextModel.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/TextModel.h Thu Mar 28 16:03:36 2019 +0000 @@ -256,6 +256,19 @@ m_events.toXml(out, indent, QString("dimensions=\"2\""), options); } + + QString toDelimitedDataString(QString delimiter, + DataExportOptions options, + sv_frame_t startFrame, + sv_frame_t duration) const override { + return m_events.toDelimitedDataString(delimiter, + options, + startFrame, + duration, + m_sampleRate, + m_resolution, + Event().withValue(0.f)); + } protected: sv_samplerate_t m_sampleRate; diff -r 1078f0ef3012 -r 0d89abd631ac data/model/test/TestSparseModels.h --- a/data/model/test/TestSparseModels.h Thu Mar 28 13:37:09 2019 +0000 +++ b/data/model/test/TestSparseModels.h Thu Mar 28 16:03:36 2019 +0000 @@ -300,7 +300,6 @@ } QCOMPARE(xml, expected); } - }; #endif