svcore  1.9
FlexiNoteModel.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #ifndef _FLEXINOTE_MODEL_H_
17 #define _FLEXINOTE_MODEL_H_
18 
19 #include "IntervalModel.h"
20 #include "NoteData.h"
21 #include "base/RealTime.h"
22 #include "base/Pitch.h"
24 
42 struct FlexiNote
43 {
44 public:
45  FlexiNote(long _frame) : frame(_frame), value(0.0f), duration(0), level(1.f) { }
46  FlexiNote(long _frame, float _value, int _duration, float _level, QString _label) :
47  frame(_frame), value(_value), duration(_duration), level(_level), label(_label) { }
48 
49  int getDimensions() const { return 3; }
50 
51  long frame;
52  float value;
53  int duration;
54  float level;
55  QString label;
56 
57  QString getLabel() const { return label; }
58 
59  void toXml(QTextStream &stream,
60  QString indent = "",
61  QString extraAttributes = "") const
62  {
63  stream <<
64  QString("%1<point frame=\"%2\" value=\"%3\" duration=\"%4\" level=\"%5\" label=\"%6\" %7/>\n")
65  .arg(indent).arg(frame).arg(value).arg(duration).arg(level)
66  .arg(XmlExportable::encodeEntities(label)).arg(extraAttributes);
67  }
68 
69  QString toDelimitedDataString(QString delimiter, int sampleRate) const
70  {
71  QStringList list;
72  list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
73  list << QString("%1").arg(value);
74  list << RealTime::frame2RealTime(duration, sampleRate).toString().c_str();
75  list << QString("%1").arg(level);
76  if (label != "") list << label;
77  return list.join(delimiter);
78  }
79 
80  struct Comparator {
81  bool operator()(const FlexiNote &p1,
82  const FlexiNote &p2) const {
83  if (p1.frame != p2.frame) return p1.frame < p2.frame;
84  if (p1.value != p2.value) return p1.value < p2.value;
85  if (p1.duration != p2.duration) return p1.duration < p2.duration;
86  if (p1.level != p2.level) return p1.level < p2.level;
87  return p1.label < p2.label;
88  }
89  };
90 
91  struct OrderComparator {
92  bool operator()(const FlexiNote &p1,
93  const FlexiNote &p2) const {
94  return p1.frame < p2.frame;
95  }
96  };
97 };
98 
99 
100 class FlexiNoteModel : public IntervalModel<FlexiNote>, public NoteExportable
101 {
102  Q_OBJECT
103 
104 public:
105  FlexiNoteModel(int sampleRate, int resolution,
106  bool notifyOnAdd = true) :
107  IntervalModel<FlexiNote>(sampleRate, resolution, notifyOnAdd),
109  {
111  }
112 
113  FlexiNoteModel(int sampleRate, int resolution,
114  float valueMinimum, float valueMaximum,
115  bool notifyOnAdd = true) :
116  IntervalModel<FlexiNote>(sampleRate, resolution,
117  valueMinimum, valueMaximum,
118  notifyOnAdd),
120  {
122  }
123 
124  virtual ~FlexiNoteModel()
125  {
127  }
128 
129  float getValueQuantization() const { return m_valueQuantization; }
131  float getValueMinimum() const { return 33; }
132  float getValueMaximum() const { return 88; }
133 
134  QString getTypeName() const { return tr("FlexiNote"); }
135 
136  virtual bool canPlay() const { return true; }
137 
138  virtual QString getDefaultPlayClipId() const
139  {
140  return "elecpiano";
141  }
142 
143  virtual void toXml(QTextStream &out,
144  QString indent = "",
145  QString extraAttributes = "") const
146  {
147  std::cerr << "FlexiNoteModel::toXml: extraAttributes = \""
148  << extraAttributes.toStdString() << std::endl;
149 
151  (out,
152  indent,
153  QString("%1 subtype=\"flexinote\" valueQuantization=\"%2\"")
154  .arg(extraAttributes).arg(m_valueQuantization));
155  }
156 
161  virtual int getColumnCount() const
162  {
163  return 6;
164  }
165 
166  virtual QString getHeading(int column) const
167  {
168  switch (column) {
169  case 0: return tr("Time");
170  case 1: return tr("Frame");
171  case 2: return tr("Pitch");
172  case 3: return tr("Duration");
173  case 4: return tr("Level");
174  case 5: return tr("Label");
175  default: return tr("Unknown");
176  }
177  }
178 
179  virtual QVariant getData(int row, int column, int role) const
180  {
181  if (column < 4) {
182  return IntervalModel<FlexiNote>::getData(row, column, role);
183  }
184 
186  if (i == m_points.end()) return QVariant();
187 
188  switch (column) {
189  case 4: return i->level;
190  case 5: return i->label;
191  default: return QVariant();
192  }
193  }
194 
195  virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
196  {
197  if (column < 4) {
199  (row, column, value, role);
200  }
201 
202  if (role != Qt::EditRole) return 0;
204  if (i == m_points.end()) return 0;
205  EditCommand *command = new EditCommand(this, tr("Edit Data"));
206 
207  Point point(*i);
208  command->deletePoint(point);
209 
210  switch (column) {
211  case 4: point.level = value.toDouble(); break;
212  case 5: point.label = value.toString(); break;
213  }
214 
215  command->addPoint(point);
216  return command->finish();
217  }
218 
219  virtual SortType getSortType(int column) const
220  {
221  if (column == 5) return SortAlphabetical;
222  return SortNumeric;
223  }
224 
230  {
232  }
233 
234  NoteList getNotesWithin(int startFrame, int endFrame) const
235  {
236  PointList points = getPoints(startFrame, endFrame);
237  NoteList notes;
238  for (PointList::iterator pli = points.begin(); pli != points.end(); ++pli) {
239  int duration = pli->duration;
240  if (duration == 0 || duration == 1) {
241  duration = getSampleRate() / 20;
242  }
243  int pitch = lrintf(pli->value);
244 
245  int velocity = 100;
246  if (pli->level > 0.f && pli->level <= 1.f) {
247  velocity = lrintf(pli->level * 127);
248  }
249 
250  NoteData note(pli->frame, duration, pitch, velocity);
251 
252  if (getScaleUnits() == "Hz") {
253  note.frequency = pli->value;
255  note.isMidiPitchQuantized = false;
256  }
257  notes.push_back(note);
258  }
259  return notes;
260  }
261 
262 protected:
264 };
265 
266 #endif
FlexiNoteModel(int sampleRate, int resolution, bool notifyOnAdd=true)
std::multiset< FlexiNote, typename FlexiNote ::OrderComparator > PointList
Definition: SparseModel.h:69
static PlayParameterRepository * getInstance()
virtual Command * getSetDataCommand(int row, int column, const QVariant &value, int role)
float frequency
Definition: NoteData.h:31
FlexiNoteModel(int sampleRate, int resolution, float valueMinimum, float valueMaximum, bool notifyOnAdd=true)
virtual QVariant getData(int row, int column, int role) const
TabularModel methods.
static RealTime frame2RealTime(long frame, unsigned int sampleRate)
Convert a sample frame at the given sample rate into a RealTime.
Definition: RealTime.cpp:450
bool operator()(const FlexiNote &p1, const FlexiNote &p2) const
virtual void toXml(QTextStream &out, QString indent="", QString extraAttributes="") const
Stream this exportable object out to XML on a text stream.
virtual int getColumnCount() const
TabularModel methods.
QString getLabel() const
FlexiNote(long _frame, float _value, int _duration, float _level, QString _label)
PointList::const_iterator PointListConstIterator
Definition: SparseModel.h:71
bool isMidiPitchQuantized
Definition: NoteData.h:32
virtual int getSampleRate() const
Definition: SparseModel.h:53
QString getTypeName() const
Return the type of the model.
void removePlayable(const Playable *playable)
FlexiNoteModel – a concrete IntervalModel for notes.
float getValueMinimum() const
NoteList getNotes() const
NoteExportable methods.
virtual ~FlexiNoteModel()
virtual QVariant getData(int row, int column, int role) const
TabularModel methods.
Definition: IntervalModel.h:68
virtual bool canPlay() const
virtual QString getHeading(int column) const
static int getPitchForFrequency(float frequency, float *centsOffsetReturn=0, float concertA=0.0)
Return the nearest MIDI pitch to the given frequency.
Definition: Pitch.cpp:35
void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
static QString encodeEntities(QString)
virtual QString getScaleUnits() const
virtual int getStartFrame() const
Definition: SparseModel.h:484
void setValueQuantization(float q)
QString label
static QString notes[]
Definition: Pitch.cpp:87
virtual const SparseModel< FlexiNote >::PointList & getPoints() const
Definition: IntervalModel.h:60
QString toDelimitedDataString(QString delimiter, int sampleRate) const
Model containing sparse data (points with some properties) of which the properties include a duration...
Definition: IntervalModel.h:29
FlexiNote(long _frame)
float m_valueQuantization
virtual int getEndFrame() const
Definition: SparseModel.h:496
float getValueMaximum() const
std::vector< NoteData > NoteList
Definition: NoteData.h:44
virtual Command * getSetDataCommand(int row, int column, const QVariant &value, int role)
Definition: IntervalModel.h:89
virtual QString getDefaultPlayClipId() const
virtual SortType getSortType(int column) const
bool operator()(const FlexiNote &p1, const FlexiNote &p2) const
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Stream this exportable object out to XML on a text stream.
int getDimensions() const
float getValueQuantization() const
std::string toString(bool align=false) const
Return a human-readable debug-type string to full precision (probably not a format to show to a user ...
Definition: RealTime.cpp:191
void addPlayable(const Playable *playable)
PointListIterator getPointListIteratorForRow(int row)
Definition: SparseModel.h:405
int midiPitch
Definition: NoteData.h:30
NoteList getNotesWithin(int startFrame, int endFrame) const