annotate data/model/IntervalModel.h @ 507:0944d13689b2

* Implement proper RDF feature writing for track level features, using the feature attribute URI given in the plugin description RDF (if there is one)
author Chris Cannam
date Fri, 05 Dec 2008 14:19:04 +0000
parents 6441b31b37ac
children d7f3dfe6f9a4
rev   line source
Chris@437 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@437 2
Chris@437 3 /*
Chris@437 4 Sonic Visualiser
Chris@437 5 An audio file viewer and annotation editor.
Chris@437 6 Centre for Digital Music, Queen Mary, University of London.
Chris@437 7 This file copyright 2006-2008 Chris Cannam and QMUL.
Chris@437 8
Chris@437 9 This program is free software; you can redistribute it and/or
Chris@437 10 modify it under the terms of the GNU General Public License as
Chris@437 11 published by the Free Software Foundation; either version 2 of the
Chris@437 12 License, or (at your option) any later version. See the file
Chris@437 13 COPYING included with this distribution for more information.
Chris@437 14 */
Chris@437 15
Chris@437 16 #ifndef _INTERVAL_MODEL_H_
Chris@437 17 #define _INTERVAL_MODEL_H_
Chris@437 18
Chris@437 19 #include "SparseValueModel.h"
Chris@437 20 #include "base/RealTime.h"
Chris@437 21
Chris@437 22 /**
Chris@437 23 * Model containing sparse data (points with some properties) of which
Chris@437 24 * the properties include a duration and an arbitrary float value.
Chris@437 25 * The other properties depend on the point type.
Chris@437 26 */
Chris@437 27
Chris@437 28 template <typename PointType>
Chris@437 29 class IntervalModel : public SparseValueModel<PointType>
Chris@437 30 {
Chris@437 31 public:
Chris@437 32 IntervalModel(size_t sampleRate, size_t resolution,
Chris@437 33 bool notifyOnAdd = true) :
Chris@437 34 SparseValueModel<PointType>(sampleRate, resolution, notifyOnAdd)
Chris@437 35 { }
Chris@437 36
Chris@437 37 IntervalModel(size_t sampleRate, size_t resolution,
Chris@437 38 float valueMinimum, float valueMaximum,
Chris@437 39 bool notifyOnAdd = true) :
Chris@437 40 SparseValueModel<PointType>(sampleRate, resolution,
Chris@437 41 valueMinimum, valueMaximum,
Chris@437 42 notifyOnAdd)
Chris@437 43 { }
Chris@437 44
Chris@437 45 /**
Chris@437 46 * PointTypes have a duration, so this returns all points that span any
Chris@437 47 * of the given range (as well as the usual additional few before
Chris@437 48 * and after). Consequently this can be very slow (optimised data
Chris@437 49 * structures still to be done!).
Chris@437 50 */
Chris@437 51 virtual typename SparseValueModel<PointType>::PointList getPoints(long start, long end) const;
Chris@437 52
Chris@437 53 /**
Chris@437 54 * PointTypes have a duration, so this returns all points that span the
Chris@437 55 * given frame. Consequently this can be very slow (optimised
Chris@437 56 * data structures still to be done!).
Chris@437 57 */
Chris@437 58 virtual typename SparseValueModel<PointType>::PointList getPoints(long frame) const;
Chris@437 59
Chris@459 60 virtual const typename SparseModel<PointType>::PointList &getPoints() const {
Chris@459 61 return SparseModel<PointType>::getPoints();
Chris@459 62 }
Chris@459 63
Chris@437 64 /**
Chris@437 65 * TabularModel methods.
Chris@437 66 */
Chris@437 67
Chris@437 68 virtual QVariant getData(int row, int column, int role) const
Chris@437 69 {
Chris@437 70 if (column < 2) {
Chris@437 71 return SparseValueModel<PointType>::getData
Chris@437 72 (row, column, role);
Chris@437 73 }
Chris@437 74
Chris@437 75 typename SparseModel<PointType>::PointList::const_iterator i
Chris@437 76 = SparseModel<PointType>::getPointListIteratorForRow(row);
Chris@437 77 if (i == SparseModel<PointType>::m_points.end()) return QVariant();
Chris@437 78
Chris@437 79 switch (column) {
Chris@437 80 case 2:
Chris@437 81 if (role == Qt::EditRole || role == TabularModel::SortRole) return i->value;
Chris@437 82 else return QString("%1 %2").arg(i->value).arg
Chris@437 83 (IntervalModel<PointType>::getScaleUnits());
Chris@437 84 case 3: return int(i->duration); //!!! could be better presented
Chris@437 85 default: return QVariant();
Chris@437 86 }
Chris@437 87 }
Chris@437 88
Chris@437 89 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
Chris@437 90 {
Chris@438 91 typedef IntervalModel<PointType> I;
Chris@438 92
Chris@437 93 if (column < 2) {
Chris@437 94 return SparseValueModel<PointType>::getSetDataCommand
Chris@437 95 (row, column, value, role);
Chris@437 96 }
Chris@437 97
Chris@437 98 if (role != Qt::EditRole) return false;
Chris@438 99 typename I::PointList::const_iterator i
Chris@438 100 = I::getPointListIteratorForRow(row);
Chris@438 101 if (i == I::m_points.end()) return false;
Chris@438 102 typename I::EditCommand *command = new typename I::EditCommand
Chris@438 103 (this, I::tr("Edit Data"));
Chris@437 104
Chris@437 105 PointType point(*i);
Chris@437 106 command->deletePoint(point);
Chris@437 107
Chris@437 108 switch (column) {
Chris@437 109 case 0: case 1: point.frame = value.toInt(); break;
Chris@437 110 case 2: point.value = value.toDouble(); break;
Chris@437 111 case 3: point.duration = value.toInt(); break;
Chris@437 112 }
Chris@437 113
Chris@437 114 command->addPoint(point);
Chris@437 115 return command->finish();
Chris@437 116 }
Chris@437 117
Chris@437 118 virtual bool isColumnTimeValue(int column) const
Chris@437 119 {
Chris@437 120 return (column < 2 || column == 3);
Chris@437 121 }
Chris@437 122 };
Chris@437 123
Chris@437 124 template <typename PointType>
Chris@437 125 typename SparseValueModel<PointType>::PointList
Chris@437 126 IntervalModel<PointType>::getPoints(long start, long end) const
Chris@437 127 {
Chris@437 128 typedef IntervalModel<PointType> I;
Chris@437 129
Chris@437 130 if (start > end) return typename I::PointList();
Chris@437 131
Chris@437 132 QMutex &mutex(I::m_mutex);
Chris@437 133 QMutexLocker locker(&mutex);
Chris@437 134
Chris@437 135 PointType endPoint(end);
Chris@437 136
Chris@437 137 typename I::PointListIterator endItr = I::m_points.upper_bound(endPoint);
Chris@437 138
Chris@437 139 if (endItr != I::m_points.end()) ++endItr;
Chris@437 140 if (endItr != I::m_points.end()) ++endItr;
Chris@437 141
Chris@437 142 typename I::PointList rv;
Chris@437 143
Chris@437 144 for (typename I::PointListIterator i = endItr; i != I::m_points.begin(); ) {
Chris@437 145 --i;
Chris@437 146 if (i->frame < start) {
Chris@437 147 if (i->frame + long(i->duration) >= start) {
Chris@437 148 rv.insert(*i);
Chris@437 149 }
Chris@437 150 } else if (i->frame <= end) {
Chris@437 151 rv.insert(*i);
Chris@437 152 }
Chris@437 153 }
Chris@437 154
Chris@437 155 return rv;
Chris@437 156 }
Chris@437 157
Chris@437 158 template <typename PointType>
Chris@437 159 typename SparseValueModel<PointType>::PointList
Chris@437 160 IntervalModel<PointType>::getPoints(long frame) const
Chris@437 161 {
Chris@437 162 typedef IntervalModel<PointType> I;
Chris@437 163
Chris@437 164 QMutex &mutex(I::m_mutex);
Chris@437 165 QMutexLocker locker(&mutex);
Chris@437 166
Chris@437 167 if (I::m_resolution == 0) return typename I::PointList();
Chris@437 168
Chris@437 169 long start = (frame / I::m_resolution) * I::m_resolution;
Chris@437 170 long end = start + I::m_resolution;
Chris@437 171
Chris@437 172 PointType endPoint(end);
Chris@437 173
Chris@437 174 typename I::PointListIterator endItr = I::m_points.upper_bound(endPoint);
Chris@437 175
Chris@437 176 typename I::PointList rv;
Chris@437 177
Chris@437 178 for (typename I::PointListIterator i = endItr; i != I::m_points.begin(); ) {
Chris@437 179 --i;
Chris@437 180 if (i->frame < start) {
Chris@437 181 if (i->frame + long(i->duration) >= start) {
Chris@437 182 rv.insert(*i);
Chris@437 183 }
Chris@437 184 } else if (i->frame <= end) {
Chris@437 185 rv.insert(*i);
Chris@437 186 }
Chris@437 187 }
Chris@437 188
Chris@437 189 return rv;
Chris@437 190 }
Chris@437 191
Chris@437 192 #endif