annotate data/model/RegionModel.h @ 1520:954d0cf29ca7 import-audio-data

Switch the normalisation option in WritableWaveFileModel from normalising on read to normalising on write, so that the saved file is already normalised and therefore can be read again without having to remember to normalise it
author Chris Cannam
date Wed, 12 Sep 2018 13:56:56 +0100
parents 48e9f538e6e9
children c01cbe41aeb5
rev   line source
Chris@441 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@441 2
Chris@441 3 /*
Chris@441 4 Sonic Visualiser
Chris@441 5 An audio file viewer and annotation editor.
Chris@441 6 Centre for Digital Music, Queen Mary, University of London.
Chris@441 7 This file copyright 2006 Chris Cannam.
Chris@441 8
Chris@441 9 This program is free software; you can redistribute it and/or
Chris@441 10 modify it under the terms of the GNU General Public License as
Chris@441 11 published by the Free Software Foundation; either version 2 of the
Chris@441 12 License, or (at your option) any later version. See the file
Chris@441 13 COPYING included with this distribution for more information.
Chris@441 14 */
Chris@441 15
Chris@441 16 #ifndef _REGION_MODEL_H_
Chris@441 17 #define _REGION_MODEL_H_
Chris@441 18
Chris@441 19 #include "IntervalModel.h"
Chris@441 20 #include "base/RealTime.h"
Chris@441 21
Chris@441 22 /**
Chris@441 23 * RegionModel -- a concrete IntervalModel for intervals associated
Chris@441 24 * with a value, which we call regions for no very compelling reason.
Chris@441 25 */
Chris@441 26
Chris@441 27 /**
Chris@441 28 * Region "point" type. A region is something that has an onset time,
Chris@441 29 * a single value, and a duration. Like other points, it can also
Chris@441 30 * have a label.
Chris@441 31 *
Chris@441 32 * This is called RegionRec instead of Region to avoid name collisions
Chris@441 33 * with the X11 Region struct. Bah.
Chris@441 34 */
Chris@441 35
Chris@441 36 struct RegionRec
Chris@441 37 {
Chris@441 38 public:
Chris@631 39 RegionRec() : frame(0), value(0.f), duration(0) { }
Chris@1038 40 RegionRec(sv_frame_t _frame) : frame(_frame), value(0.0f), duration(0) { }
Chris@1038 41 RegionRec(sv_frame_t _frame, float _value, sv_frame_t _duration, QString _label) :
Chris@1429 42 frame(_frame), value(_value), duration(_duration), label(_label) { }
Chris@441 43
Chris@441 44 int getDimensions() const { return 3; }
Chris@441 45
Chris@1038 46 sv_frame_t frame;
Chris@441 47 float value;
Chris@1038 48 sv_frame_t duration;
Chris@441 49 QString label;
Chris@441 50
Chris@441 51 QString getLabel() const { return label; }
Chris@441 52
Chris@441 53 void toXml(QTextStream &stream,
Chris@441 54 QString indent = "",
Chris@441 55 QString extraAttributes = "") const
Chris@441 56 {
Chris@1429 57 stream <<
Chris@441 58 QString("%1<point frame=\"%2\" value=\"%3\" duration=\"%4\" label=\"%5\" %6/>\n")
Chris@1429 59 .arg(indent).arg(frame).arg(value).arg(duration)
Chris@627 60 .arg(XmlExportable::encodeEntities(label)).arg(extraAttributes);
Chris@441 61 }
Chris@441 62
Chris@1060 63 QString toDelimitedDataString(QString delimiter, DataExportOptions, sv_samplerate_t sampleRate) const
Chris@441 64 {
Chris@441 65 QStringList list;
Chris@441 66 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@441 67 list << QString("%1").arg(value);
Chris@441 68 list << RealTime::frame2RealTime(duration, sampleRate).toString().c_str();
Chris@441 69 if (label != "") list << label;
Chris@441 70 return list.join(delimiter);
Chris@441 71 }
Chris@441 72
Chris@441 73 struct Comparator {
Chris@1429 74 bool operator()(const RegionRec &p1,
Chris@1429 75 const RegionRec &p2) const {
Chris@1429 76 if (p1.frame != p2.frame) return p1.frame < p2.frame;
Chris@1429 77 if (p1.value != p2.value) return p1.value < p2.value;
Chris@1429 78 if (p1.duration != p2.duration) return p1.duration < p2.duration;
Chris@1429 79 return p1.label < p2.label;
Chris@1429 80 }
Chris@441 81 };
Chris@441 82
Chris@441 83 struct OrderComparator {
Chris@1429 84 bool operator()(const RegionRec &p1,
Chris@1429 85 const RegionRec &p2) const {
Chris@1429 86 return p1.frame < p2.frame;
Chris@1429 87 }
Chris@441 88 };
Chris@441 89 };
Chris@441 90
Chris@441 91
Chris@441 92 class RegionModel : public IntervalModel<RegionRec>
Chris@441 93 {
Chris@441 94 Q_OBJECT
Chris@441 95
Chris@441 96 public:
Chris@1040 97 RegionModel(sv_samplerate_t sampleRate, int resolution,
Chris@441 98 bool notifyOnAdd = true) :
Chris@1429 99 IntervalModel<RegionRec>(sampleRate, resolution, notifyOnAdd),
Chris@1429 100 m_valueQuantization(0),
Chris@442 101 m_haveDistinctValues(false)
Chris@441 102 {
Chris@441 103 }
Chris@441 104
Chris@1040 105 RegionModel(sv_samplerate_t sampleRate, int resolution,
Chris@459 106 float valueMinimum, float valueMaximum,
Chris@459 107 bool notifyOnAdd = true) :
Chris@1429 108 IntervalModel<RegionRec>(sampleRate, resolution,
Chris@441 109 valueMinimum, valueMaximum,
Chris@441 110 notifyOnAdd),
Chris@1429 111 m_valueQuantization(0),
Chris@442 112 m_haveDistinctValues(false)
Chris@441 113 {
Chris@441 114 }
Chris@441 115
Chris@441 116 virtual ~RegionModel()
Chris@441 117 {
Chris@441 118 }
Chris@441 119
Chris@441 120 float getValueQuantization() const { return m_valueQuantization; }
Chris@441 121 void setValueQuantization(float q) { m_valueQuantization = q; }
Chris@441 122
Chris@442 123 bool haveDistinctValues() const { return m_haveDistinctValues; }
Chris@442 124
Chris@441 125 QString getTypeName() const { return tr("Region"); }
Chris@441 126
Chris@441 127 virtual void toXml(QTextStream &out,
Chris@441 128 QString indent = "",
Chris@441 129 QString extraAttributes = "") const
Chris@441 130 {
Chris@441 131 std::cerr << "RegionModel::toXml: extraAttributes = \""
Chris@441 132 << extraAttributes.toStdString() << std::endl;
Chris@441 133
Chris@441 134 IntervalModel<RegionRec>::toXml
Chris@1429 135 (out,
Chris@441 136 indent,
Chris@1429 137 QString("%1 subtype=\"region\" valueQuantization=\"%2\"")
Chris@1429 138 .arg(extraAttributes).arg(m_valueQuantization));
Chris@441 139 }
Chris@441 140
Chris@441 141 /**
Chris@441 142 * TabularModel methods.
Chris@441 143 */
Chris@441 144
Chris@441 145 virtual int getColumnCount() const
Chris@441 146 {
Chris@618 147 return 5;
Chris@441 148 }
Chris@441 149
Chris@441 150 virtual QString getHeading(int column) const
Chris@441 151 {
Chris@441 152 switch (column) {
Chris@441 153 case 0: return tr("Time");
Chris@441 154 case 1: return tr("Frame");
Chris@441 155 case 2: return tr("Value");
Chris@441 156 case 3: return tr("Duration");
Chris@441 157 case 4: return tr("Label");
Chris@441 158 default: return tr("Unknown");
Chris@441 159 }
Chris@441 160 }
Chris@441 161
Chris@441 162 virtual QVariant getData(int row, int column, int role) const
Chris@441 163 {
Chris@441 164 if (column < 4) {
Chris@441 165 return IntervalModel<RegionRec>::getData(row, column, role);
Chris@441 166 }
Chris@441 167
Chris@608 168 PointListConstIterator i = getPointListIteratorForRow(row);
Chris@441 169 if (i == m_points.end()) return QVariant();
Chris@441 170
Chris@441 171 switch (column) {
Chris@441 172 case 4: return i->label;
Chris@441 173 default: return QVariant();
Chris@441 174 }
Chris@441 175 }
Chris@441 176
Chris@441 177 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
Chris@441 178 {
Chris@441 179 if (column < 4) {
Chris@441 180 return IntervalModel<RegionRec>::getSetDataCommand
Chris@441 181 (row, column, value, role);
Chris@441 182 }
Chris@441 183
Chris@740 184 if (role != Qt::EditRole) return 0;
Chris@441 185 PointListIterator i = getPointListIteratorForRow(row);
Chris@740 186 if (i == m_points.end()) return 0;
Chris@441 187 EditCommand *command = new EditCommand(this, tr("Edit Data"));
Chris@441 188
Chris@441 189 Point point(*i);
Chris@441 190 command->deletePoint(point);
Chris@441 191
Chris@441 192 switch (column) {
Chris@441 193 case 4: point.label = value.toString(); break;
Chris@441 194 }
Chris@441 195
Chris@441 196 command->addPoint(point);
Chris@441 197 return command->finish();
Chris@441 198 }
Chris@441 199
Chris@441 200 virtual SortType getSortType(int column) const
Chris@441 201 {
Chris@618 202 if (column == 4) return SortAlphabetical;
Chris@441 203 return SortNumeric;
Chris@441 204 }
Chris@441 205
Chris@442 206 virtual void addPoint(const Point &point)
Chris@442 207 {
Chris@442 208 if (point.value != 0.f) m_haveDistinctValues = true;
Chris@442 209 IntervalModel<RegionRec>::addPoint(point);
Chris@442 210 }
Chris@442 211
Chris@441 212 protected:
Chris@441 213 float m_valueQuantization;
Chris@442 214 bool m_haveDistinctValues;
Chris@441 215 };
Chris@441 216
Chris@441 217 #endif