lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2006 Chris Cannam. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #ifndef _SPARSE_VALUE_MODEL_H_ lbajardsilogic@0: #define _SPARSE_VALUE_MODEL_H_ lbajardsilogic@0: lbajardsilogic@0: #include "system/System.h" lbajardsilogic@0: #include "SparseModel.h" lbajardsilogic@0: #include "base/UnitDatabase.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: /** lbajardsilogic@0: * Model containing sparse data (points with some properties) of which lbajardsilogic@0: * one of the properties is an arbitrary float value. The other lbajardsilogic@0: * properties depend on the point type. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: template lbajardsilogic@0: class SparseValueModel : public SparseModel lbajardsilogic@0: { lbajardsilogic@0: public: lbajardsilogic@0: SparseValueModel(size_t sampleRate, size_t resolution, lbajardsilogic@0: bool notifyOnAdd = true) : lbajardsilogic@0: SparseModel(sampleRate, resolution, notifyOnAdd), lbajardsilogic@0: m_valueMinimum(0.f), lbajardsilogic@0: m_valueMaximum(0.f), lbajardsilogic@0: m_haveExtents(false) lbajardsilogic@0: { } lbajardsilogic@0: lbajardsilogic@0: SparseValueModel(size_t sampleRate, size_t resolution, lbajardsilogic@0: float valueMinimum, float valueMaximum, lbajardsilogic@0: bool notifyOnAdd = true) : lbajardsilogic@0: SparseModel(sampleRate, resolution, notifyOnAdd), lbajardsilogic@0: m_valueMinimum(valueMinimum), lbajardsilogic@0: m_valueMaximum(valueMaximum), lbajardsilogic@0: m_haveExtents(true) lbajardsilogic@0: { } lbajardsilogic@0: lbajardsilogic@0: using SparseModel::m_points; lbajardsilogic@0: using SparseModel::modelChanged; lbajardsilogic@0: lbajardsilogic@0: virtual float getValueMinimum() const { return m_valueMinimum; } lbajardsilogic@0: virtual float getValueMaximum() const { return m_valueMaximum; } lbajardsilogic@0: lbajardsilogic@0: virtual QString getScaleUnits() const { return m_units; } lbajardsilogic@0: virtual void setScaleUnits(QString units) { lbajardsilogic@0: m_units = units; lbajardsilogic@0: UnitDatabase::getInstance()->registerUnit(units); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: virtual void addPoint(const PointType &point) lbajardsilogic@0: { lbajardsilogic@0: bool allChange = false; lbajardsilogic@0: lbajardsilogic@0: if (!isnan(point.value) && !isinf(point.value)) { lbajardsilogic@0: if (!m_haveExtents || point.value < m_valueMinimum) { lbajardsilogic@0: m_valueMinimum = point.value; allChange = true; lbajardsilogic@0: } lbajardsilogic@0: if (!m_haveExtents || point.value > m_valueMaximum) { lbajardsilogic@0: m_valueMaximum = point.value; allChange = true; lbajardsilogic@0: } lbajardsilogic@0: m_haveExtents = true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: SparseModel::addPoint(point); lbajardsilogic@0: if (allChange) emit modelChanged(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: virtual void deletePoint(const PointType &point) lbajardsilogic@0: { lbajardsilogic@0: SparseModel::deletePoint(point); lbajardsilogic@0: lbajardsilogic@0: if (point.value == m_valueMinimum || lbajardsilogic@0: point.value == m_valueMaximum) { lbajardsilogic@0: lbajardsilogic@0: float formerMin = m_valueMinimum, formerMax = m_valueMaximum; lbajardsilogic@0: lbajardsilogic@0: for (typename SparseModel::PointList::const_iterator i lbajardsilogic@0: = m_points.begin(); lbajardsilogic@0: i != m_points.end(); ++i) { lbajardsilogic@0: lbajardsilogic@0: if (i == m_points.begin() || i->value < m_valueMinimum) { lbajardsilogic@0: m_valueMinimum = i->value; lbajardsilogic@0: } lbajardsilogic@0: if (i == m_points.begin() || i->value > m_valueMaximum) { lbajardsilogic@0: m_valueMaximum = i->value; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (formerMin != m_valueMinimum || formerMax != m_valueMaximum) { lbajardsilogic@0: emit modelChanged(); lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: virtual QString toXmlString(QString indent = "", lbajardsilogic@0: QString extraAttributes = "") const lbajardsilogic@0: { lbajardsilogic@0: return SparseModel::toXmlString lbajardsilogic@0: (indent, lbajardsilogic@0: QString("%1 minimum=\"%2\" maximum=\"%3\" units=\"%4\"") lbajardsilogic@0: .arg(extraAttributes).arg(m_valueMinimum).arg(m_valueMaximum) lbajardsilogic@0: .arg(this->encodeEntities(m_units))); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: protected: lbajardsilogic@0: float m_valueMinimum; lbajardsilogic@0: float m_valueMaximum; lbajardsilogic@0: bool m_haveExtents; lbajardsilogic@0: QString m_units; lbajardsilogic@0: }; lbajardsilogic@0: lbajardsilogic@0: lbajardsilogic@0: #endif lbajardsilogic@0: