annotate data/model/Dense3DModelPeakCache.cpp @ 1833:21c792334c2e sensible-delimited-data-strings

Rewrite all the DelimitedDataString stuff so as to return vectors of individual cell strings rather than having the classes add the delimiters themselves. Rename accordingly to names based on StringExport. Take advantage of this in the CSV writer code so as to properly quote cells that contain delimiter characters.
author Chris Cannam
date Fri, 03 Apr 2020 17:11:05 +0100
parents 59d9dcfd67c2
children
rev   line source
Chris@545 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@545 2
Chris@545 3 /*
Chris@545 4 Sonic Visualiser
Chris@545 5 An audio file viewer and annotation editor.
Chris@545 6 Centre for Digital Music, Queen Mary, University of London.
Chris@545 7 This file copyright 2009 QMUL.
Chris@545 8
Chris@545 9 This program is free software; you can redistribute it and/or
Chris@545 10 modify it under the terms of the GNU General Public License as
Chris@545 11 published by the Free Software Foundation; either version 2 of the
Chris@545 12 License, or (at your option) any later version. See the file
Chris@545 13 COPYING included with this distribution for more information.
Chris@545 14 */
Chris@545 15
Chris@545 16 #include "Dense3DModelPeakCache.h"
Chris@545 17
Chris@551 18 #include "base/Profiler.h"
Chris@551 19
Chris@1340 20 #include "base/HitCount.h"
Chris@1340 21
Chris@1739 22 Dense3DModelPeakCache::Dense3DModelPeakCache(ModelId sourceId,
Chris@1429 23 int columnsPerPeak) :
Chris@1739 24 m_source(sourceId),
Chris@1778 25 m_columnsPerPeak(columnsPerPeak),
Chris@1778 26 m_finalColumnIncomplete(false)
Chris@545 27 {
Chris@1739 28 auto source = ModelById::getAs<DenseThreeDimensionalModel>(m_source);
Chris@1739 29 if (!source) {
Chris@1739 30 SVCERR << "WARNING: Dense3DModelPeakCache constructed for unknown or wrong-type source model id " << m_source << endl;
Chris@1739 31 m_source = {};
Chris@1739 32 return;
Chris@1739 33 }
Chris@545 34
Chris@1752 35 connect(source.get(), SIGNAL(modelChanged(ModelId)),
Chris@1752 36 this, SLOT(sourceModelChanged(ModelId)));
Chris@545 37 }
Chris@545 38
Chris@545 39 Dense3DModelPeakCache::~Dense3DModelPeakCache()
Chris@545 40 {
Chris@545 41 }
Chris@545 42
Chris@545 43 Dense3DModelPeakCache::Column
Chris@929 44 Dense3DModelPeakCache::getColumn(int column) const
Chris@545 45 {
Chris@545 46 if (!haveColumn(column)) fillColumn(column);
Chris@1778 47 return m_cache.at(column);
Chris@545 48 }
Chris@545 49
Chris@545 50 float
Chris@929 51 Dense3DModelPeakCache::getValueAt(int column, int n) const
Chris@545 52 {
Chris@545 53 if (!haveColumn(column)) fillColumn(column);
Chris@1778 54 return m_cache.at(column).at(n);
Chris@545 55 }
Chris@545 56
Chris@545 57 void
Chris@1752 58 Dense3DModelPeakCache::sourceModelChanged(ModelId)
Chris@545 59 {
Chris@1778 60 if (m_finalColumnIncomplete && m_coverage.size() > 0) {
Chris@1778 61 // The last peak came from an incomplete read, which may since
Chris@1778 62 // have been filled, so reset it
Chris@1153 63 m_coverage[m_coverage.size()-1] = false;
Chris@1778 64 m_finalColumnIncomplete = false;
Chris@546 65 }
Chris@545 66 }
Chris@545 67
Chris@545 68 bool
Chris@929 69 Dense3DModelPeakCache::haveColumn(int column) const
Chris@545 70 {
Chris@1340 71 static HitCount count("Dense3DModelPeakCache");
Chris@1340 72 if (in_range_for(m_coverage, column) && m_coverage[column]) {
Chris@1340 73 count.hit();
Chris@1340 74 return true;
Chris@1340 75 } else {
Chris@1340 76 count.miss();
Chris@1340 77 return false;
Chris@1340 78 }
Chris@545 79 }
Chris@545 80
Chris@545 81 void
Chris@929 82 Dense3DModelPeakCache::fillColumn(int column) const
Chris@545 83 {
Chris@551 84 Profiler profiler("Dense3DModelPeakCache::fillColumn");
Chris@551 85
Chris@1153 86 if (!in_range_for(m_coverage, column)) {
Chris@1778 87 if (m_finalColumnIncomplete && m_coverage.size() > 0) {
Chris@1192 88 // The last peak may have come from an incomplete read, which
Chris@1192 89 // may since have been filled, so reset it
Chris@1192 90 m_coverage[m_coverage.size()-1] = false;
Chris@1778 91 m_finalColumnIncomplete = false;
Chris@1192 92 }
Chris@1153 93 m_coverage.resize(column + 1, false);
Chris@1778 94 m_cache.resize(column + 1, {});
Chris@1778 95 }
Chris@1778 96
Chris@1778 97 auto source = ModelById::getAs<DenseThreeDimensionalModel>(m_source);
Chris@1778 98 if (!source) {
Chris@1778 99 return;
Chris@1778 100 }
Chris@1778 101
Chris@1778 102 int sourceWidth = source->getWidth();
Chris@1778 103 int sourceColumn = column * m_columnsPerPeak;
Chris@1778 104 if (sourceColumn >= sourceWidth) {
Chris@1778 105 return;
Chris@551 106 }
Chris@546 107
Chris@1778 108 Column peak = source->getColumn(sourceColumn);
Chris@1778 109 int n = int(peak.size());
Chris@1739 110
Chris@1778 111 for (int i = 1; i < m_columnsPerPeak; ++i) {
Chris@1192 112
Chris@1778 113 ++sourceColumn;
Chris@1778 114 if (sourceColumn >= sourceWidth) {
Chris@1778 115 m_finalColumnIncomplete = true;
Chris@1778 116 break;
Chris@1778 117 }
Chris@1192 118
Chris@1739 119 Column here = source->getColumn(sourceColumn);
Chris@1778 120 int m = std::min(n, int(here.size()));
Chris@1778 121 for (int j = 0; j < m; ++j) {
Chris@1778 122 peak[j] = std::max(here[j], peak[j]);
Chris@545 123 }
Chris@545 124 }
Chris@546 125
Chris@1778 126 m_cache[column] = peak;
Chris@1153 127 m_coverage[column] = true;
Chris@545 128 }
Chris@545 129
Chris@545 130