annotate data/model/SparseValueModel.h @ 299:576be0d0d218

* Merge transform directory from sv-match-alignment branch (the previous comment included notes for this stuff, but I missed it in the actual merge) * Fix crash when a transform fails to create an output model and the thread that created the transform then deletes its input model thinking it's no longer needed, even though the transform run thread is still using it -- fix is to wait() on the transform before returning the null output model
author Chris Cannam
date Fri, 28 Sep 2007 16:15:06 +0000
parents 2b6c99b607f1
children 73537d900d4b
rev   line source
Chris@147 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@147 2
Chris@147 3 /*
Chris@147 4 Sonic Visualiser
Chris@147 5 An audio file viewer and annotation editor.
Chris@147 6 Centre for Digital Music, Queen Mary, University of London.
Chris@147 7 This file copyright 2006 Chris Cannam.
Chris@147 8
Chris@147 9 This program is free software; you can redistribute it and/or
Chris@147 10 modify it under the terms of the GNU General Public License as
Chris@147 11 published by the Free Software Foundation; either version 2 of the
Chris@147 12 License, or (at your option) any later version. See the file
Chris@147 13 COPYING included with this distribution for more information.
Chris@147 14 */
Chris@147 15
Chris@147 16 #ifndef _SPARSE_VALUE_MODEL_H_
Chris@147 17 #define _SPARSE_VALUE_MODEL_H_
Chris@147 18
Chris@147 19 #include "SparseModel.h"
Chris@150 20 #include "base/UnitDatabase.h"
Chris@147 21
Chris@257 22 #include <cmath>
Chris@257 23
Chris@147 24 /**
Chris@147 25 * Model containing sparse data (points with some properties) of which
Chris@147 26 * one of the properties is an arbitrary float value. The other
Chris@147 27 * properties depend on the point type.
Chris@147 28 */
Chris@147 29
Chris@147 30 template <typename PointType>
Chris@147 31 class SparseValueModel : public SparseModel<PointType>
Chris@147 32 {
Chris@147 33 public:
Chris@147 34 SparseValueModel(size_t sampleRate, size_t resolution,
Chris@256 35 bool notifyOnAdd = true) :
Chris@256 36 SparseModel<PointType>(sampleRate, resolution, notifyOnAdd),
Chris@256 37 m_valueMinimum(0.f),
Chris@256 38 m_valueMaximum(0.f),
Chris@256 39 m_haveExtents(false)
Chris@256 40 { }
Chris@256 41
Chris@256 42 SparseValueModel(size_t sampleRate, size_t resolution,
Chris@147 43 float valueMinimum, float valueMaximum,
Chris@147 44 bool notifyOnAdd = true) :
Chris@147 45 SparseModel<PointType>(sampleRate, resolution, notifyOnAdd),
Chris@147 46 m_valueMinimum(valueMinimum),
Chris@256 47 m_valueMaximum(valueMaximum),
Chris@256 48 m_haveExtents(true)
Chris@147 49 { }
Chris@147 50
Chris@147 51 using SparseModel<PointType>::m_points;
Chris@147 52 using SparseModel<PointType>::modelChanged;
Chris@147 53
Chris@147 54 virtual float getValueMinimum() const { return m_valueMinimum; }
Chris@147 55 virtual float getValueMaximum() const { return m_valueMaximum; }
Chris@147 56
Chris@147 57 virtual QString getScaleUnits() const { return m_units; }
Chris@147 58 virtual void setScaleUnits(QString units) {
Chris@147 59 m_units = units;
Chris@147 60 UnitDatabase::getInstance()->registerUnit(units);
Chris@147 61 }
Chris@147 62
Chris@147 63 virtual void addPoint(const PointType &point)
Chris@147 64 {
Chris@147 65 bool allChange = false;
Chris@256 66
Chris@257 67 if (!std::isnan(point.value) && !std::isinf(point.value)) {
Chris@256 68 if (!m_haveExtents || point.value < m_valueMinimum) {
Chris@256 69 m_valueMinimum = point.value; allChange = true;
Chris@296 70 // std::cerr << "addPoint: value min = " << m_valueMinimum << std::endl;
Chris@256 71 }
Chris@256 72 if (!m_haveExtents || point.value > m_valueMaximum) {
Chris@256 73 m_valueMaximum = point.value; allChange = true;
Chris@296 74 // std::cerr << "addPoint: value max = " << m_valueMaximum << " (min = " << m_valueMinimum << ")" << std::endl;
Chris@256 75 }
Chris@256 76 m_haveExtents = true;
Chris@256 77 }
Chris@147 78
Chris@147 79 SparseModel<PointType>::addPoint(point);
Chris@147 80 if (allChange) emit modelChanged();
Chris@147 81 }
Chris@147 82
Chris@147 83 virtual void deletePoint(const PointType &point)
Chris@147 84 {
Chris@147 85 SparseModel<PointType>::deletePoint(point);
Chris@147 86
Chris@147 87 if (point.value == m_valueMinimum ||
Chris@147 88 point.value == m_valueMaximum) {
Chris@147 89
Chris@147 90 float formerMin = m_valueMinimum, formerMax = m_valueMaximum;
Chris@147 91
Chris@147 92 for (typename SparseModel<PointType>::PointList::const_iterator i
Chris@147 93 = m_points.begin();
Chris@147 94 i != m_points.end(); ++i) {
Chris@147 95
Chris@147 96 if (i == m_points.begin() || i->value < m_valueMinimum) {
Chris@147 97 m_valueMinimum = i->value;
Chris@296 98 // std::cerr << "deletePoint: value min = " << m_valueMinimum << std::endl;
Chris@147 99 }
Chris@147 100 if (i == m_points.begin() || i->value > m_valueMaximum) {
Chris@147 101 m_valueMaximum = i->value;
Chris@296 102 // std::cerr << "deletePoint: value max = " << m_valueMaximum << std::endl;
Chris@147 103 }
Chris@147 104 }
Chris@147 105
Chris@147 106 if (formerMin != m_valueMinimum || formerMax != m_valueMaximum) {
Chris@147 107 emit modelChanged();
Chris@147 108 }
Chris@147 109 }
Chris@147 110 }
Chris@147 111
Chris@147 112 virtual QString toXmlString(QString indent = "",
Chris@147 113 QString extraAttributes = "") const
Chris@147 114 {
Chris@147 115 return SparseModel<PointType>::toXmlString
Chris@147 116 (indent,
Chris@147 117 QString("%1 minimum=\"%2\" maximum=\"%3\" units=\"%4\"")
Chris@147 118 .arg(extraAttributes).arg(m_valueMinimum).arg(m_valueMaximum)
Chris@147 119 .arg(this->encodeEntities(m_units)));
Chris@147 120 }
Chris@147 121
Chris@147 122 protected:
Chris@147 123 float m_valueMinimum;
Chris@147 124 float m_valueMaximum;
Chris@256 125 bool m_haveExtents;
Chris@147 126 QString m_units;
Chris@147 127 };
Chris@147 128
Chris@147 129
Chris@147 130 #endif
Chris@147 131