annotate data/model/SparseOneDimensionalModel.h @ 458:f60360209e5c

* Fix race condition in FFTFileCache when reading from the same FFT model from multiple threads (e.g. when applying more than one plugin at once)
author Chris Cannam
date Wed, 15 Oct 2008 12:08:02 +0000
parents 72ec275e458b
children e43368ec5ff0
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_ONE_DIMENSIONAL_MODEL_H_
Chris@147 17 #define _SPARSE_ONE_DIMENSIONAL_MODEL_H_
Chris@147 18
Chris@147 19 #include "SparseModel.h"
Chris@150 20 #include "base/PlayParameterRepository.h"
Chris@147 21 #include "base/RealTime.h"
Chris@147 22
Chris@387 23 #include <QStringList>
Chris@387 24
Chris@147 25 struct OneDimensionalPoint
Chris@147 26 {
Chris@147 27 public:
Chris@147 28 OneDimensionalPoint(long _frame) : frame(_frame) { }
Chris@147 29 OneDimensionalPoint(long _frame, QString _label) : frame(_frame), label(_label) { }
Chris@147 30
Chris@147 31 int getDimensions() const { return 1; }
Chris@147 32
Chris@147 33 long frame;
Chris@147 34 QString label;
Chris@338 35
Chris@338 36 QString getLabel() const { return label; }
Chris@338 37
Chris@314 38 void toXml(QTextStream &stream,
Chris@314 39 QString indent = "",
Chris@314 40 QString extraAttributes = "") const
Chris@147 41 {
Chris@314 42 stream << QString("%1<point frame=\"%2\" label=\"%3\" %4/>\n")
Chris@147 43 .arg(indent).arg(frame).arg(label).arg(extraAttributes);
Chris@147 44 }
Chris@147 45
Chris@147 46 QString toDelimitedDataString(QString delimiter, size_t sampleRate) const
Chris@147 47 {
Chris@147 48 QStringList list;
Chris@147 49 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@318 50 if (label != "") list << label;
Chris@147 51 return list.join(delimiter);
Chris@147 52 }
Chris@147 53
Chris@147 54 struct Comparator {
Chris@147 55 bool operator()(const OneDimensionalPoint &p1,
Chris@147 56 const OneDimensionalPoint &p2) const {
Chris@147 57 if (p1.frame != p2.frame) return p1.frame < p2.frame;
Chris@147 58 return p1.label < p2.label;
Chris@147 59 }
Chris@147 60 };
Chris@147 61
Chris@147 62 struct OrderComparator {
Chris@147 63 bool operator()(const OneDimensionalPoint &p1,
Chris@147 64 const OneDimensionalPoint &p2) const {
Chris@147 65 return p1.frame < p2.frame;
Chris@147 66 }
Chris@147 67 };
Chris@147 68 };
Chris@147 69
Chris@147 70
Chris@147 71 class SparseOneDimensionalModel : public SparseModel<OneDimensionalPoint>
Chris@147 72 {
Chris@423 73 Q_OBJECT
Chris@423 74
Chris@147 75 public:
Chris@147 76 SparseOneDimensionalModel(size_t sampleRate, size_t resolution,
Chris@147 77 bool notifyOnAdd = true) :
Chris@147 78 SparseModel<OneDimensionalPoint>(sampleRate, resolution, notifyOnAdd)
Chris@147 79 {
Chris@391 80 PlayParameterRepository::getInstance()->addPlayable(this);
Chris@391 81 }
Chris@391 82
Chris@391 83 virtual ~SparseOneDimensionalModel()
Chris@391 84 {
Chris@391 85 PlayParameterRepository::getInstance()->removePlayable(this);
Chris@391 86 }
Chris@391 87
Chris@391 88 virtual bool canPlay() const { return true; }
Chris@391 89
Chris@391 90 virtual QString getDefaultPlayPluginId() const
Chris@391 91 {
Chris@391 92 return "dssi:_builtin:sample_player";
Chris@391 93 }
Chris@391 94
Chris@391 95 virtual QString getDefaultPlayPluginConfiguration() const
Chris@391 96 {
Chris@391 97 return "<plugin program=\"tap\"/>";
Chris@147 98 }
Chris@147 99
Chris@420 100 int getIndexOf(const Point &point)
Chris@420 101 {
Chris@147 102 // slow
Chris@147 103 int i = 0;
Chris@147 104 Point::Comparator comparator;
Chris@147 105 for (PointList::const_iterator j = m_points.begin();
Chris@147 106 j != m_points.end(); ++j, ++i) {
Chris@147 107 if (!comparator(*j, point) && !comparator(point, *j)) return i;
Chris@147 108 }
Chris@147 109 return -1;
Chris@147 110 }
Chris@345 111
Chris@345 112 QString getTypeName() const { return tr("Sparse 1-D"); }
Chris@420 113
Chris@420 114 /**
Chris@420 115 * TabularModel methods.
Chris@420 116 */
Chris@420 117
Chris@420 118 virtual int getColumnCount() const
Chris@420 119 {
Chris@420 120 return 3;
Chris@420 121 }
Chris@420 122
Chris@420 123 virtual QString getHeading(int column) const
Chris@420 124 {
Chris@420 125 switch (column) {
Chris@420 126 case 0: return tr("Time");
Chris@420 127 case 1: return tr("Frame");
Chris@420 128 case 2: return tr("Label");
Chris@420 129 default: return tr("Unknown");
Chris@420 130 }
Chris@420 131 }
Chris@420 132
Chris@420 133 virtual QVariant getData(int row, int column, int role) const
Chris@420 134 {
Chris@425 135 if (column < 2) {
Chris@425 136 return SparseModel<OneDimensionalPoint>::getData
Chris@425 137 (row, column, role);
Chris@425 138 }
Chris@425 139
Chris@420 140 PointListIterator i = getPointListIteratorForRow(row);
Chris@420 141 if (i == m_points.end()) return QVariant();
Chris@420 142
Chris@420 143 switch (column) {
Chris@422 144 case 2: return i->label;
Chris@420 145 default: return QVariant();
Chris@420 146 }
Chris@420 147 }
Chris@420 148
Chris@424 149 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
Chris@424 150 {
Chris@425 151 if (column < 2) {
Chris@425 152 return SparseModel<OneDimensionalPoint>::getSetDataCommand
Chris@425 153 (row, column, value, role);
Chris@425 154 }
Chris@425 155
Chris@424 156 if (role != Qt::EditRole) return false;
Chris@424 157 PointListIterator i = getPointListIteratorForRow(row);
Chris@424 158 if (i == m_points.end()) return false;
Chris@424 159 EditCommand *command = new EditCommand(this, tr("Edit Data"));
Chris@424 160
Chris@424 161 Point point(*i);
Chris@424 162 command->deletePoint(point);
Chris@424 163
Chris@424 164 switch (column) {
Chris@424 165 case 2: point.label = value.toString(); break;
Chris@424 166 }
Chris@424 167
Chris@424 168 command->addPoint(point);
Chris@424 169 return command->finish();
Chris@424 170 }
Chris@424 171
Chris@427 172
Chris@420 173 virtual bool isColumnTimeValue(int column) const
Chris@420 174 {
Chris@420 175 return (column < 2);
Chris@420 176 }
Chris@422 177
Chris@422 178 virtual SortType getSortType(int column) const
Chris@422 179 {
Chris@422 180 if (column == 2) return SortAlphabetical;
Chris@422 181 return SortNumeric;
Chris@422 182 }
Chris@147 183 };
Chris@147 184
Chris@147 185 #endif
Chris@147 186
Chris@147 187
Chris@147 188