annotate data/model/EditableDenseThreeDimensionalModel.cpp @ 181:9c652f2c39b1

* Various improvements to colour 3d plot layer, particularly for large and/or dense plots. Still a work in progress
author Chris Cannam
date Fri, 06 Oct 2006 16:53:25 +0000
parents 21792a550ec9
children f75f8a1cd7b1
rev   line source
Chris@152 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@152 2
Chris@152 3 /*
Chris@152 4 Sonic Visualiser
Chris@152 5 An audio file viewer and annotation editor.
Chris@152 6 Centre for Digital Music, Queen Mary, University of London.
Chris@152 7 This file copyright 2006 Chris Cannam.
Chris@152 8
Chris@152 9 This program is free software; you can redistribute it and/or
Chris@152 10 modify it under the terms of the GNU General Public License as
Chris@152 11 published by the Free Software Foundation; either version 2 of the
Chris@152 12 License, or (at your option) any later version. See the file
Chris@152 13 COPYING included with this distribution for more information.
Chris@152 14 */
Chris@152 15
Chris@152 16 #include "EditableDenseThreeDimensionalModel.h"
Chris@152 17
Chris@152 18 #include <QTextStream>
Chris@152 19
Chris@181 20 #include <iostream>
Chris@181 21
Chris@152 22 EditableDenseThreeDimensionalModel::EditableDenseThreeDimensionalModel(size_t sampleRate,
Chris@152 23 size_t resolution,
Chris@152 24 size_t yBinCount,
Chris@152 25 bool notifyOnAdd) :
Chris@152 26 m_sampleRate(sampleRate),
Chris@152 27 m_resolution(resolution),
Chris@152 28 m_yBinCount(yBinCount),
Chris@152 29 m_minimum(0.0),
Chris@152 30 m_maximum(0.0),
Chris@152 31 m_notifyOnAdd(notifyOnAdd),
Chris@152 32 m_sinceLastNotifyMin(-1),
Chris@152 33 m_sinceLastNotifyMax(-1),
Chris@152 34 m_completion(100)
Chris@152 35 {
Chris@152 36 }
Chris@152 37
Chris@152 38 bool
Chris@152 39 EditableDenseThreeDimensionalModel::isOK() const
Chris@152 40 {
Chris@152 41 return true;
Chris@152 42 }
Chris@152 43
Chris@152 44 size_t
Chris@152 45 EditableDenseThreeDimensionalModel::getSampleRate() const
Chris@152 46 {
Chris@152 47 return m_sampleRate;
Chris@152 48 }
Chris@152 49
Chris@152 50 size_t
Chris@152 51 EditableDenseThreeDimensionalModel::getStartFrame() const
Chris@152 52 {
Chris@152 53 return 0;
Chris@152 54 }
Chris@152 55
Chris@152 56 size_t
Chris@152 57 EditableDenseThreeDimensionalModel::getEndFrame() const
Chris@152 58 {
Chris@152 59 return m_resolution * m_data.size() + (m_resolution - 1);
Chris@152 60 }
Chris@152 61
Chris@152 62 Model *
Chris@152 63 EditableDenseThreeDimensionalModel::clone() const
Chris@152 64 {
Chris@152 65 EditableDenseThreeDimensionalModel *model =
Chris@152 66 new EditableDenseThreeDimensionalModel
Chris@152 67 (m_sampleRate, m_resolution, m_yBinCount);
Chris@152 68
Chris@152 69 model->m_minimum = m_minimum;
Chris@152 70 model->m_maximum = m_maximum;
Chris@152 71
Chris@152 72 for (size_t i = 0; i < m_data.size(); ++i) {
Chris@152 73 model->setBinValues(i * m_resolution, m_data[i]);
Chris@152 74 }
Chris@152 75
Chris@152 76 return model;
Chris@152 77 }
Chris@152 78
Chris@152 79 size_t
Chris@152 80 EditableDenseThreeDimensionalModel::getResolution() const
Chris@152 81 {
Chris@152 82 return m_resolution;
Chris@152 83 }
Chris@152 84
Chris@152 85 void
Chris@152 86 EditableDenseThreeDimensionalModel::setResolution(size_t sz)
Chris@152 87 {
Chris@152 88 m_resolution = sz;
Chris@152 89 }
Chris@152 90
Chris@152 91 size_t
Chris@152 92 EditableDenseThreeDimensionalModel::getYBinCount() const
Chris@152 93 {
Chris@152 94 return m_yBinCount;
Chris@152 95 }
Chris@152 96
Chris@152 97 void
Chris@152 98 EditableDenseThreeDimensionalModel::setYBinCount(size_t sz)
Chris@152 99 {
Chris@152 100 m_yBinCount = sz;
Chris@152 101 }
Chris@152 102
Chris@152 103 float
Chris@152 104 EditableDenseThreeDimensionalModel::getMinimumLevel() const
Chris@152 105 {
Chris@152 106 return m_minimum;
Chris@152 107 }
Chris@152 108
Chris@152 109 void
Chris@152 110 EditableDenseThreeDimensionalModel::setMinimumLevel(float level)
Chris@152 111 {
Chris@152 112 m_minimum = level;
Chris@152 113 }
Chris@152 114
Chris@152 115 float
Chris@152 116 EditableDenseThreeDimensionalModel::getMaximumLevel() const
Chris@152 117 {
Chris@152 118 return m_maximum;
Chris@152 119 }
Chris@152 120
Chris@152 121 void
Chris@152 122 EditableDenseThreeDimensionalModel::setMaximumLevel(float level)
Chris@152 123 {
Chris@152 124 m_maximum = level;
Chris@152 125 }
Chris@152 126
Chris@152 127 void
Chris@152 128 EditableDenseThreeDimensionalModel::getBinValues(long windowStart,
Chris@181 129 BinValueSet &result) const
Chris@152 130 {
Chris@152 131 QMutexLocker locker(&m_mutex);
Chris@152 132
Chris@152 133 long index = windowStart / m_resolution;
Chris@152 134
Chris@152 135 if (index >= 0 && index < long(m_data.size())) {
Chris@152 136 result = m_data[index];
Chris@152 137 } else {
Chris@152 138 result.clear();
Chris@152 139 }
Chris@152 140
Chris@152 141 while (result.size() < m_yBinCount) result.push_back(m_minimum);
Chris@152 142 }
Chris@152 143
Chris@152 144 float
Chris@152 145 EditableDenseThreeDimensionalModel::getBinValue(long windowStart,
Chris@181 146 size_t n) const
Chris@152 147 {
Chris@152 148 QMutexLocker locker(&m_mutex);
Chris@152 149
Chris@152 150 long index = windowStart / m_resolution;
Chris@152 151
Chris@152 152 if (index >= 0 && index < long(m_data.size())) {
Chris@152 153 const BinValueSet &s = m_data[index];
Chris@181 154 std::cerr << "index " << index << ", n " << n << ", res " << m_resolution << ", size " << s.size()
Chris@181 155 << std::endl;
Chris@152 156 if (n < s.size()) return s[n];
Chris@152 157 }
Chris@152 158
Chris@152 159 return m_minimum;
Chris@152 160 }
Chris@152 161
Chris@152 162 void
Chris@152 163 EditableDenseThreeDimensionalModel::setBinValues(long windowStart,
Chris@152 164 const BinValueSet &values)
Chris@152 165 {
Chris@152 166 QMutexLocker locker(&m_mutex);
Chris@152 167
Chris@152 168 long index = windowStart / m_resolution;
Chris@152 169
Chris@152 170 while (index >= long(m_data.size())) {
Chris@152 171 m_data.push_back(BinValueSet());
Chris@152 172 }
Chris@152 173
Chris@152 174 bool newExtents = (m_data.empty() && (m_minimum == m_maximum));
Chris@152 175 bool allChange = false;
Chris@152 176
Chris@152 177 for (size_t i = 0; i < values.size(); ++i) {
Chris@152 178 if (newExtents || values[i] < m_minimum) {
Chris@152 179 m_minimum = values[i];
Chris@152 180 allChange = true;
Chris@152 181 }
Chris@152 182 if (newExtents || values[i] > m_maximum) {
Chris@152 183 m_maximum = values[i];
Chris@152 184 allChange = true;
Chris@152 185 }
Chris@152 186 }
Chris@152 187
Chris@152 188 m_data[index] = values;
Chris@152 189
Chris@152 190 if (m_notifyOnAdd) {
Chris@152 191 if (allChange) {
Chris@152 192 emit modelChanged();
Chris@152 193 } else {
Chris@152 194 emit modelChanged(windowStart, windowStart + m_resolution);
Chris@152 195 }
Chris@152 196 } else {
Chris@152 197 if (allChange) {
Chris@152 198 m_sinceLastNotifyMin = -1;
Chris@152 199 m_sinceLastNotifyMax = -1;
Chris@152 200 emit modelChanged();
Chris@152 201 } else {
Chris@152 202 if (m_sinceLastNotifyMin == -1 ||
Chris@152 203 windowStart < m_sinceLastNotifyMin) {
Chris@152 204 m_sinceLastNotifyMin = windowStart;
Chris@152 205 }
Chris@152 206 if (m_sinceLastNotifyMax == -1 ||
Chris@152 207 windowStart > m_sinceLastNotifyMax) {
Chris@152 208 m_sinceLastNotifyMax = windowStart;
Chris@152 209 }
Chris@152 210 }
Chris@152 211 }
Chris@152 212 }
Chris@152 213
Chris@152 214 QString
Chris@152 215 EditableDenseThreeDimensionalModel::getBinName(size_t n) const
Chris@152 216 {
Chris@152 217 if (m_binNames.size() > n) return m_binNames[n];
Chris@152 218 else return "";
Chris@152 219 }
Chris@152 220
Chris@152 221 void
Chris@152 222 EditableDenseThreeDimensionalModel::setBinName(size_t n, QString name)
Chris@152 223 {
Chris@152 224 while (m_binNames.size() <= n) m_binNames.push_back("");
Chris@152 225 m_binNames[n] = name;
Chris@152 226 emit modelChanged();
Chris@152 227 }
Chris@152 228
Chris@152 229 void
Chris@152 230 EditableDenseThreeDimensionalModel::setBinNames(std::vector<QString> names)
Chris@152 231 {
Chris@152 232 m_binNames = names;
Chris@152 233 emit modelChanged();
Chris@152 234 }
Chris@152 235
Chris@152 236 void
Chris@152 237 EditableDenseThreeDimensionalModel::setCompletion(int completion)
Chris@152 238 {
Chris@152 239 if (m_completion != completion) {
Chris@152 240 m_completion = completion;
Chris@152 241
Chris@152 242 if (completion == 100) {
Chris@152 243
Chris@152 244 m_notifyOnAdd = true; // henceforth
Chris@152 245 emit modelChanged();
Chris@152 246
Chris@152 247 } else if (!m_notifyOnAdd) {
Chris@152 248
Chris@152 249 if (m_sinceLastNotifyMin >= 0 &&
Chris@152 250 m_sinceLastNotifyMax >= 0) {
Chris@152 251 emit modelChanged(m_sinceLastNotifyMin,
Chris@152 252 m_sinceLastNotifyMax + m_resolution);
Chris@152 253 m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1;
Chris@152 254 } else {
Chris@152 255 emit completionChanged();
Chris@152 256 }
Chris@152 257 } else {
Chris@152 258 emit completionChanged();
Chris@152 259 }
Chris@152 260 }
Chris@152 261 }
Chris@152 262
Chris@152 263 void
Chris@152 264 EditableDenseThreeDimensionalModel::toXml(QTextStream &out,
Chris@152 265 QString indent,
Chris@152 266 QString extraAttributes) const
Chris@152 267 {
Chris@152 268 // For historical reasons we read and write "resolution" as "windowSize"
Chris@152 269
Chris@152 270 out << Model::toXmlString
Chris@152 271 (indent, QString("type=\"dense\" dimensions=\"3\" windowSize=\"%1\" yBinCount=\"%2\" minimum=\"%3\" maximum=\"%4\" dataset=\"%5\" %6")
Chris@152 272 .arg(m_resolution)
Chris@152 273 .arg(m_yBinCount)
Chris@152 274 .arg(m_minimum)
Chris@152 275 .arg(m_maximum)
Chris@152 276 .arg(getObjectExportId(&m_data))
Chris@152 277 .arg(extraAttributes));
Chris@152 278
Chris@152 279 out << indent;
Chris@152 280 out << QString("<dataset id=\"%1\" dimensions=\"3\" separator=\" \">\n")
Chris@152 281 .arg(getObjectExportId(&m_data));
Chris@152 282
Chris@152 283 for (size_t i = 0; i < m_binNames.size(); ++i) {
Chris@152 284 if (m_binNames[i] != "") {
Chris@152 285 out << indent + " ";
Chris@152 286 out << QString("<bin number=\"%1\" name=\"%2\"/>\n")
Chris@152 287 .arg(i).arg(m_binNames[i]);
Chris@152 288 }
Chris@152 289 }
Chris@152 290
Chris@152 291 for (size_t i = 0; i < m_data.size(); ++i) {
Chris@152 292 out << indent + " ";
Chris@152 293 out << QString("<row n=\"%1\">").arg(i);
Chris@152 294 for (size_t j = 0; j < m_data[i].size(); ++j) {
Chris@152 295 if (j > 0) out << " ";
Chris@152 296 out << m_data[i][j];
Chris@152 297 }
Chris@152 298 out << QString("</row>\n");
Chris@152 299 }
Chris@152 300
Chris@152 301 out << indent + "</dataset>\n";
Chris@152 302 }
Chris@152 303
Chris@152 304 QString
Chris@152 305 EditableDenseThreeDimensionalModel::toXmlString(QString indent,
Chris@152 306 QString extraAttributes) const
Chris@152 307 {
Chris@152 308 QString s;
Chris@152 309
Chris@152 310 {
Chris@152 311 QTextStream out(&s);
Chris@152 312 toXml(out, indent, extraAttributes);
Chris@152 313 }
Chris@152 314
Chris@152 315 return s;
Chris@152 316 }
Chris@152 317
Chris@152 318 #ifdef INCLUDE_MOCFILES
Chris@152 319 #include "EditableDenseThreeDimensionalModel.moc.cpp"
Chris@152 320 #endif
Chris@152 321